chore: import vocalinux project #33
@@ -0,0 +1,3 @@
|
||||
# Python bytecode caches
|
||||
__pycache__/
|
||||
*.pyc
|
||||
@@ -0,0 +1,265 @@
|
||||
# AGENTS.md — Vocalinux
|
||||
|
||||
Voice dictation for Linux: GTK 3 tray app (Python) plus a Next.js marketing site in `web/`. Default speech engine is **whisper.cpp** (`pywhispercpp`); OpenAI Whisper, Vosk, and a user-configured remote API are optional. Do not invent features, user counts, or privacy claims.
|
||||
|
||||
## Commit attribution
|
||||
|
||||
Agents must not add themselves as commit co-authors or add `Co-authored-by`
|
||||
trailers for agents.
|
||||
|
||||
## Critical: git worktrees for every branch and PR
|
||||
|
||||
Never create a branch, commit, or open a pull request in the primary checkout. Always use a linked git worktree so the main working tree stays on `main` and stays clean. Do not `git switch` / `git checkout` a feature branch in the primary directory, and do not leave it dirty.
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git worktree add /tmp/vocalinux-<task> -b <type>/<short-name> origin/main
|
||||
|
||||
# All edits, commits, and `gh pr create` happen inside that worktree.
|
||||
|
||||
git worktree remove /tmp/vocalinux-<task>
|
||||
git worktree prune
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- One worktree per branch, one branch per PR
|
||||
- Place worktrees **outside** the primary working tree (`/tmp/vocalinux-<task>` or a sibling directory such as `../.worktrees/vocalinux-<task>`)
|
||||
- Never run two tasks in the same worktree
|
||||
- Never commit directly to `main`
|
||||
- Clean up the worktree after the PR is pushed
|
||||
|
||||
## Toolchain
|
||||
|
||||
| Piece | Current |
|
||||
|---|---|
|
||||
| Python | `>=3.11` (`requires-python` in `pyproject.toml`; CI: 3.11–3.14). Floor, classifiers, CI matrix and `install.sh` must agree — `tests/test_python_version_policy.py` |
|
||||
| GTK | Runtime `venv/` uses distro `python3-gi` (PyGObject), never pip-install it; uv builds the locked PyGObject in the separate dev `.venv/` on supported distros |
|
||||
| uv | `>=0.12,<0.14` (`[tool.uv]` in `pyproject.toml`). `uv.lock` is the source of truth; CI runs `uv sync --locked` / `uv run --locked`, which fails on drift |
|
||||
| just | https://just.systems or distro package `just` |
|
||||
| Format / lint / types | Black + isort (line length 100), flake8 (`E9,F63,F7,F82` only), mypy `src/` (targets 3.11 and runs as a CI lint gate). The tools live in the `lint` dependency group, not the `dev` extra, so CI can install them without building the project |
|
||||
| Website | Next.js / TypeScript in `web/` — see `web/AGENTS.md` |
|
||||
|
||||
Two virtualenvs, on purpose:
|
||||
|
||||
- **`.venv/`** — uv's, for dev tooling. `just deps` checks native headers before syncing it (on Fedora 40+, install `glib2-devel`, `cairo-gobject-devel`, `gobject-introspection-devel`, `libffi-devel` and the PortAudio headers); every other Python `just` recipe uses `uv run --no-sync` so it does not prune extras that `just deps-all` installed. No activation needed.
|
||||
- **`venv/`** — what `install.sh` builds for the app itself, from the *system* Python so distro `gi` is importable.
|
||||
|
||||
Never run `install.sh` from an activated `.venv`: it drops an inherited `VIRTUAL_ENV` from `PATH` and picks `$SYSTEM_PYTHON` (default `/usr/bin/python3`) precisely because a venv built from uv's interpreter cannot see distro PyGObject.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
./install.sh --dev # system deps + venv + editable install + tests
|
||||
# non-interactive / no TTY:
|
||||
./install.sh --dev --auto
|
||||
./install.sh --dev --auto --no-rebuild-whispercpp # skip cmake/Vulkan rebuild
|
||||
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
Manual venv (must see distro `gi`):
|
||||
|
||||
```bash
|
||||
uv venv --system-site-packages --python /usr/bin/python3
|
||||
source venv/bin/activate
|
||||
# exclude pygobject from uv sync/export:
|
||||
# --no-install-package pygobject / --no-emit-package pygobject
|
||||
uv pip install -e ".[dev,vad]"
|
||||
```
|
||||
|
||||
`install.sh` flags: `--engine=whisper_cpp|whisper|vosk|remote_api`, `--test`, `--skip-models`, `--venv-dir=PATH`. Default engine is `whisper_cpp`.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
just lint # flake8 (critical) + black --check + isort --check
|
||||
just format # black + isort
|
||||
just typecheck # mypy src/ (CI lint gate)
|
||||
just test # pytest -v
|
||||
just test-cov # pytest --cov=src --cov-report=html
|
||||
just deps # sync .venv with dev+vad extras and the lint group
|
||||
just deps-all # also whisper/vosk/docs; later recipes use --no-sync so they keep it
|
||||
just lock # regenerate uv.lock, requirements/*.txt and the Flatpak dep manifest
|
||||
just lock-check # fail if uv.lock is stale vs pyproject.toml
|
||||
just distro-packages # regenerate install.d/package_map.sh from YAML
|
||||
just distro-packages-check # fail if the generated package map is stale
|
||||
just flatpak-deps # regenerate the Flatpak dep manifest from runtime + [vad] (needs PyPI)
|
||||
just flatpak-deps-check # fail if that manifest is behind the export
|
||||
just model-checksums # refresh pinned model digests after adding a model
|
||||
just appimage # build the AppImage in its pinned base image (needs docker)
|
||||
just appimage-boot fedora:42 # boot that AppImage in a distro container
|
||||
just native-packages # build the .deb and .rpm in the pinned base image (needs docker)
|
||||
just native-smoke fedora:42 # install the built package in a distro container
|
||||
just aur-gate # build canonical sdist + unchanged AUR fixture on current Arch (needs uv/docker)
|
||||
just install-gate debian:12 # run install.sh unattended in a distro container
|
||||
just remote-install-gate debian:12 # remote curl|bash path end to end against HEAD (needs docker)
|
||||
just verify-release # check a published release as published (needs gh)
|
||||
just reproducible-wheel # independent locked wheel builds; stages verified dist/ (needs uv)
|
||||
just pre-commit # pre-commit run --all-files
|
||||
just run-debug # vocalinux --debug
|
||||
just run-source-debug
|
||||
```
|
||||
|
||||
```bash
|
||||
pytest
|
||||
pytest tests/test_command_processor.py
|
||||
pytest tests/test_command_processor.py::TestCommandProcessor::test_initialization
|
||||
pytest -m "not slow"
|
||||
pytest -m "not integration"
|
||||
python -m vocalinux.main --debug
|
||||
python -m vocalinux.main --transcribe-file path/to/audio.wav # diarized file transcription
|
||||
```
|
||||
|
||||
Website: `web/AGENTS.md`, `web/PRODUCT.md`, `web/DESIGN.md`. Do not duplicate site commands here.
|
||||
|
||||
## Dependencies (uv)
|
||||
|
||||
Use **uv 0.13.3** for `just lock` and `just export-check`, matching CI. Other versions in the supported contributor range can order equivalent platform markers differently; export verification compares files byte-for-byte. Update the CI pins and regenerate exports together when changing the generation version.
|
||||
|
||||
`uv.lock` is authoritative. `just lock` regenerates it, the hash-pinned `requirements/*.txt` exports, and `packaging/flatpak/python3-dependencies.yaml`. The AppImage build installs from `runtime`/`vad` plus `appimage.txt`; `install.sh` consumes the runtime and selected extras with `--require-hashes --no-deps --no-build-isolation`, then installs the project with `--no-deps --no-build-isolation`. **Do not edit `requirements/*.txt` by hand**, nor the url/sha256 pairs in `packaging/flatpak/python3-dependencies.yaml`. Change `pyproject.toml` (or `requirements/whisper.in` for the Whisper engine, `requirements/appimage*.in` for the AppImage), run `just lock`, and commit the lock plus the exports with the manifest change.
|
||||
|
||||
| Constraint | Rule |
|
||||
|---|---|
|
||||
| PyGObject | The runtime installer uses distro `python3-gi` via `--system-site-packages`; do not pip-install it into `venv/`. The dev `.venv/` instead builds the locked version with uv when glib 2.80+ and native headers are available. uv-managed interpreters do not see distro `gi` unless the venv is created with `--system-site-packages` |
|
||||
| `[vosk]` extra | Wheel-only on PyPI (no sdist). Never part of a source-buildable lock. `install.sh --engine=vosk` installs it |
|
||||
| Whisper CPU torch | `requirements/whisper.txt` is compiled from `requirements/whisper.in`. Pin `torch` to a `+cpu` local version — PyPI CUDA wheels win resolution regardless of index order. OpenAI Whisper does not use `torchaudio`, and the CPU index can lag torch |
|
||||
| pywhispercpp | Pinned in `install.sh` as `PYWHISPERCPP_VERSION` (keep in sync with `uv.lock`) |
|
||||
| Installer build tools | `[dependency-groups].installer-build` exports to `requirements/installer-build.txt`. Bootstrap uses hashed wheels on new and reused venvs; source builds use these tools without build isolation. Its setuptools `>=83` floor keeps the pinned installer tools patched; do not add it to `[build-system]` (Arch). Backend rebuilds select pywhispercpp's complete hash block from `runtime.txt` via `scripts/installer_requirements.py`, with `--no-deps` so they cannot replace the runtime |
|
||||
| Release build tools | `[dependency-groups].release-build` exports to `requirements/release-build.txt`. `scripts/build_reproducible_wheel.py` builds in two fresh source trees/venvs with hashed tools and `--no-isolation`, compares wheel bytes, and stages only canonical distributions in `dist/`. These build-only venvs exclude system site-packages: host setuptools plugins must not influence locked builds, and packaging does not import GTK. Repeat runs clean recognized diagnostics and staged archives matching retained canonical digests; staged copies are deleted first so interrupted cleanup remains retryable. Unrelated/modified files are preserved and block cleanup. Never wipe all of `build/`. PR and release CI use Python 3.11 and pinned uv. Failed build outputs/logs stay under `build/reproducible-wheel/`, excluded from release artifacts |
|
||||
| AUR source publication | Use the canonical release sdist, not a GitHub tag archive. `scripts/prepare_aur_source.py` (run with the locked `release-build` group) requires its published checksum and provenance from the exact release workflow/tag/commit before preparing a pinned PKGBUILD. Release CI builds/installs that unchanged recipe on current Arch; publication consumes only the gated artifact with `updpkgsums: false`. PR/local fixtures must explicitly use `--local-unattested` and are never publication inputs. `just aur-gate` keeps distributions, diagnostics and tooling in its own temporary directory, leaving shared packaging outputs and dev environments untouched; failures retain that directory and print its path. `vocalinux-bin` publication depends only on release creation and both AppImages, not the source gate or global checksums. Existing AUR provider stubs/pinned import smoke remain limited as documented in `docs/AUR.md` |
|
||||
| Installer Whisper export | Compiled universally from Python 3.11, constrained by `runtime.txt` and `installer-build.txt` to keep shared pins consistent. Uses a `+cpu` torch pin and best-match index resolution so the CPU index's older copies of shared packages do not downgrade the runtime |
|
||||
| Remote installer | After cloning, hand off to the tagged `install.sh` with the original arguments and remote venv path. The installer and its exports must come from the same revision, including when the tag predates the pinned installer |
|
||||
| `[vad]` extra | `onnxruntime` for Silero VAD |
|
||||
| One export per extra | Every extra in `pyproject.toml` needs a hash-pinned `requirements/<extra>.txt` (underscores become dashes), written by a `uv export` line in `just lock`. `install.sh` installs six of them, so an extra with no export is an install path with nothing pinned, which is how `[parakeet]`, `[faster_whisper]` and `[vosk]` reached users. `tests/test_dependency_exports.py` enumerates the extras and the installer's call sites rather than trusting the recipe to stay complete; `docs` is the one exemption and it carries its reason in `EXPORT_EXEMPT` |
|
||||
| Exports match the lock | `just export-check` re-runs every `uv export` line in `just lock` and fails if a committed export is behind `uv.lock`. It reads those lines out of the recipe, so an export added there is checked without touching `scripts/check_exports.py`, and it runs under `UV_OFFLINE=1`: `uv export` reads the lock and nothing else. The lint job runs it, because an export named in the recipe and never regenerated is a snapshot, not a pin. `uv pip compile` targets are out of scope by design (they resolve against live indexes) |
|
||||
| AppImage PyGObject | Pinned separately in `requirements/appimage.in`, and below 3.52: the AppImage bundles its own interpreter and builds PyGObject against the base image's girepository-1.0, while uv.lock's 3.56 needs girepository-2.0 (glib 2.80+) |
|
||||
| AppImage build inputs | Base image, tooling, interpreter, shaderc and the Vulkan headers are pinned in `packaging/appimage/tool_checksums.txt`. Build with `just appimage` (docker) — building on the host ships the host's glibc, which is what kept the AppImage off Debian 12 |
|
||||
| AppImage boot matrix | `packaging/appimage/boot-test.sh` runs the finished AppImage in distro containers, and the matrix in `unified-pipeline.yml` must keep distros both older and newer than the build image: the old ones prove the glibc floor, the new ones catch a bundle that breaks the host binaries it spawns. A distro added there needs its package recipe in the script — `tests/test_appimage_packaging.py` checks both |
|
||||
| Native packages (.deb / .rpm) | Thin packages built by nfpm in the pinned Debian 12 image (`packaging/native/tool_checksums.txt` pins the image and the nfpm releases). Python, GTK and PyGObject come from the distro; only `pywhispercpp` and `pynput` are vendored under `/usr/lib/vocalinux/vendor` (unpackaged on Debian/Fedora). `packaging/native/smoke-test.sh` installs the package per-distro and runs `vocalinux --version` plus an import smoke — `tests/test_native_packaging.py` keeps the deps lists, vendored set and CI matrix consistent offline |
|
||||
| Snap Python inputs | `snap/local/build.py` uses `requirements/installer-build.txt` in an isolated, build-only venv and installs `requirements/runtime.txt` with hashes, no dependency resolution or build isolation. The project installs without dependencies or index access; never strip PyGObject from `pyproject.toml`. GI comes from the GNOME extension. Keep portable CPU flags and force the pinned pywhispercpp sdist without a wheel cache. PR/release CI installs the real artifact via `snap/local/smoke-test.sh` before publication. Native Ubuntu/GNOME/Snapcraft inputs remain channel-controlled, not byte-for-byte reproducible — see `docs/SNAP.md` |
|
||||
| Flatpak deps | `packaging/flatpak/python3-dependencies.yaml` is generated from `requirements/vad.txt` (runtime dependencies plus the `[vad]` extra) by `scripts/sync_flatpak_deps.py` (`just flatpak-deps`, which `just lock` runs itself). It resolves each artifact by the digest uv already recorded, so the Flatpak downloads the bytes in `uv.lock`; `onnxruntime` is pinned to CPython wheels for each Flatpak architecture and the GNOME 50 Python version. The project installs there with `pip3 install --no-deps`, so nothing inside the build evaluates `pyproject.toml` — `tests/test_flatpak_packaging.py` checks the invariant offline |
|
||||
| Speech models | Verified against digests pinned in `src/vocalinux/utils/model_checksums.txt` before install, by both `install.sh` and the runtime downloaders. **Fails closed** — an unpinned model is refused. Regenerate with `just model-checksums` (never by hand); `tests/test_model_checksums.py` fails if it falls behind. whisper.cpp URLs use a pinned Hugging Face commit, never `main` |
|
||||
|
||||
Optional extras: `vosk`, `whisper`, `vad`, `dev`.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
src/vocalinux/
|
||||
├── main.py, version.py, common_types.py, dbus_service.py, post_processor.py
|
||||
├── audio/
|
||||
│ ├── capture.py # PortAudio capture sources and device handling
|
||||
│ ├── pipewire.py # PipeWire system-audio capture
|
||||
│ └── playback_ducker.py # lower default sink while dictating
|
||||
├── single_instance.py # $XDG_DATA_HOME/vocalinux/instance.lock
|
||||
├── auto_pause_monitor.py # unload model while configured apps run
|
||||
├── model_keepalive.py # idle unload
|
||||
├── suspend_handler.py # logind PrepareForSleep
|
||||
├── custom_dictionary.py # terms bias + transcript correction file contracts
|
||||
├── gateway_embed/ # optional local VocaGateway lifecycle
|
||||
├── speech_recognition/
|
||||
│ ├── recognition_manager.py # VAD, segmentation, and engine dispatch
|
||||
│ ├── engines/ # engine implementations and availability
|
||||
│ ├── command_processor.py # voice commands
|
||||
│ ├── command_phrases.py # voice command phrases and localized forms
|
||||
│ ├── diarization.py # TinyDiarize per-speaker file transcription (--transcribe-file / tray)
|
||||
│ ├── silero_vad.py
|
||||
│ └── data/ # bundled silero_vad.onnx
|
||||
├── text_injection/
|
||||
│ ├── text_injector.py # DesktopEnvironment backend selection
|
||||
│ ├── focused_window.py # focused application detection
|
||||
│ ├── remote_desktop_portal.py # Wayland Remote Desktop Portal support
|
||||
│ └── ibus_engine.py # Wayland IBus injection
|
||||
├── ui/
|
||||
│ ├── tray_indicator.py, settings_dialog.py, settings_about.py
|
||||
│ ├── settings_engines.py, first_run_dialog.py, dictation_overlay.py
|
||||
│ ├── dictation_pad.py
|
||||
│ ├── transcript_dialog.py # speaker-tagged transcript viewer/export
|
||||
│ ├── config_manager.py, action_handler.py, audio_feedback.py
|
||||
│ ├── autostart_manager.py, keyboard_shortcuts.py, notifications.py
|
||||
│ ├── logging_dialog.py, logging_manager.py, transcription_history.py
|
||||
│ └── keyboard_backends/ # pynput (X11), evdev (Wayland)
|
||||
├── utils/
|
||||
│ ├── paths.py, resource_manager.py, host_process.py
|
||||
│ ├── update_checker.py, update_monitor.py, gtk_color_scheme.py
|
||||
│ ├── pywhispercpp_loader.py # bundled-lib preloader for source-built installs
|
||||
│ └── whispercpp_model_info.py, vosk_model_info.py
|
||||
└── resources/ # SVG icons + WAV cues (also repo resources/)
|
||||
```
|
||||
|
||||
Also: `tests/`, `docs/`, `packaging/` (AppImage, AUR, Flatpak, native .deb/.rpm), `scripts/`,
|
||||
`install.sh` (bootstrap and orchestration), `install.d/` (sourced installer modules),
|
||||
`uninstall.sh`, `web/`. `scripts/distro-package-map.yaml` owns installer package
|
||||
names; `install.d/package_map.sh` is generated by `just distro-packages`.
|
||||
|
||||
| Task | Start here |
|
||||
|---|---|
|
||||
| Voice command | `speech_recognition/command_processor.py` |
|
||||
| Engine / models | `speech_recognition/recognition_manager.py` |
|
||||
| Text injection | `text_injection/text_injector.py`, `focused_window.py`, `remote_desktop_portal.py`, `ibus_engine.py` |
|
||||
| Settings | `ui/config_manager.py`, `ui/settings_dialog.py` |
|
||||
| Hotkeys | `ui/keyboard_shortcuts.py`, `ui/keyboard_backends/` |
|
||||
|
||||
## Style
|
||||
|
||||
- Type hints on all function signatures. `Protocol` interfaces live in `common_types.py`
|
||||
- Imports: stdlib → third-party → local (`isort` black profile)
|
||||
- Names: `PascalCase` classes, `snake_case` functions, `UPPER_SNAKE_CASE` constants, `_private` methods
|
||||
- `logger = logging.getLogger(__name__)` per module
|
||||
- Triple-quoted docstrings on modules, classes, and public functions
|
||||
- Specific exceptions; log errors with context
|
||||
- `subprocess` calls that run a **host** binary pass `env=host_env()` (`utils/host_process.py`): a host binary inheriting the AppImage's library paths dies on the wrong GLib. The one spawn of our own interpreter (`start_engine_process`) passes the environment untouched — it needs the bundle. `tests/test_host_process.py` walks the AST and fails on either mistake
|
||||
- Tests: `tests/test_*.py`, `test_*` functions, `unittest.TestCase` or pytest; `pytest-mock` via `mocker`
|
||||
- Markers: `@pytest.mark.slow`, `integration`, `audio` (hardware). Default timeout 10s (`pytest-timeout`)
|
||||
|
||||
## Git and PRs
|
||||
|
||||
Conventional Commits: `type(scope): short description` with optional body and `Fixes #123`.
|
||||
|
||||
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`.
|
||||
|
||||
```
|
||||
feat(commands): add "select all" voice command
|
||||
fix(tray): resolve icon not updating on Wayland
|
||||
docs(readme): update installation instructions
|
||||
```
|
||||
|
||||
Branch prefixes: `feature/`, `fix/`, `docs/`, `refactor/`, `test/`, `release/` (e.g. `release/v0.7.0-beta`).
|
||||
|
||||
- Never push to `main`. Never commit on `main`
|
||||
- Every change goes through a PR (including docs)
|
||||
- Wait for CI (`.github/workflows/unified-pipeline.yml`) before asking for merge
|
||||
- Squash merge
|
||||
- **Do not merge the PR yourself**
|
||||
- Fill `.github/PULL_REQUEST_TEMPLATE.md`
|
||||
|
||||
Releases: follow `docs/RELEASE_PROCESS.md`. Version source of truth is `src/vocalinux/version.py`; sync README, `docs/INSTALL.md`, `docs/UPDATE.md`, `web/src/app/page.tsx`, `web/package.json`. Prep on `release/vX.Y.Z-PHASE`; tag **after** merge.
|
||||
|
||||
## Website
|
||||
|
||||
Site-only work: `web/AGENTS.md` (commands, layout map). Product claims: `web/PRODUCT.md`. Visual system: `web/DESIGN.md`. Git/worktree/PR rules are this file — do not duplicate them under `web/`.
|
||||
|
||||
## Runtime (any Linux dev machine)
|
||||
|
||||
- Create runtime/dev venvs with `--system-site-packages`. Build-only venvs for `scripts/build_reproducible_wheel.py`, `just aur-gate` preparation and `snap/local/build.py` are the exception: exclude host packages to keep the locked tools isolated; the Snap runtime gets GI from its GNOME command chain. Never prune the developer environment to run a packaging gate
|
||||
- Kill the app by PID, never `pkill -f vocalinux` (matches editors, shells, and cwd paths)
|
||||
- Stale instance: `$XDG_DATA_HOME/vocalinux/instance.lock` (default `~/.local/share/vocalinux/instance.lock`)
|
||||
- Default dictation shortcut: hold Right Alt (push-to-talk). Existing `~/.config/vocalinux/config.json` wins
|
||||
- Headless speech smoke: `pywhispercpp.model.Model` + `CommandProcessor` (first run may download the tiny model)
|
||||
|
||||
Update this file when commands, layout, or agent rules change.
|
||||
|
||||
## Agent skills
|
||||
|
||||
### Issue tracker
|
||||
|
||||
Issues live in Gitea at git.bongbetic.com, managed with the tea CLI. See `docs/agents/issue-tracker.md`.
|
||||
|
||||
### Triage labels
|
||||
|
||||
Default five-role vocabulary (needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix). See `docs/agents/triage-labels.md`.
|
||||
|
||||
### Domain docs
|
||||
|
||||
Single-context: one GLOSSARY.md plus docs/adr/ at the repo root. See `docs/agents/domain.md`.
|
||||
@@ -0,0 +1,51 @@
|
||||
# Changelog
|
||||
|
||||
Release history for Vocalinux.
|
||||
|
||||
## Where to read notes
|
||||
|
||||
| Source | Contents |
|
||||
|--------|----------|
|
||||
| [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases) | Canonical release notes per tag |
|
||||
| [docs/UPDATE.md](docs/UPDATE.md) | Upgrade steps plus retained release notes for recent versions |
|
||||
| [vocalinux.com/changelog](https://vocalinux.com/changelog) | Shorter website changelog |
|
||||
|
||||
## Current stable
|
||||
|
||||
**[v0.18.5](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.5)** (2026-10-27)
|
||||
|
||||
Patch on the stable line: a stop that races a recording start can no longer leave the microphone recording with no way to halt it, and a stalled microphone read can no longer hang Stop forever, keyboards survive suspend and the GNOME lock screen again because the evdev grab is released when forwarding cannot run, Dictation Pad and Settings no longer bind to other windows or travel workspaces together on Wayland, Ctrl+mouse-wheel zoom works again, the installer gains an upgrade mode that keeps your existing configuration, paste-injection copies are marked sensitive on wl-clipboard 2.2+ so clipboard managers that honor the hint keep them out of history, and AUR source publication is gated on attested release sdists.
|
||||
|
||||
See [docs/UPDATE.md](docs/UPDATE.md#whats-new-in-v0185) for the highlight table, or the [GitHub Release](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.5).
|
||||
|
||||
**[v0.18.4](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.4)** (2026-10-21)
|
||||
|
||||
Patch on the stable line: long push-to-talk dictations are queued in segments instead of being cut off at the buffer cap, Settings never downloads or switches a model without an explicit confirmation and a cancelled download stays cancelled, Test Dictation keeps its own result while the Dictation Pad is open, the GPU picker follows ggml's device list and CPU runs use most of your cores, the recording hotkey cancels a transcription in progress, the Flatpak bundles onnxruntime for Silero VAD and uses the X11 listener on X11 sessions, Wayland injection fixes cover the RemoteDesktop portal, XWayland apps outside IBus and the first recording after launch, Parakeet installs work again, update checks can be turned off, and Slovenian is a supported language.
|
||||
|
||||
See [docs/UPDATE.md](docs/UPDATE.md#whats-new-in-v0184) for the highlight table, or the [GitHub Release](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.4).
|
||||
|
||||
**[v0.18.3](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.3)** (2026-10-17)
|
||||
|
||||
Patch on the stable line: "new line" and "new paragraph" voice commands now insert real line breaks standalone and mid-utterance, hotkeys work again on GNOME Shell X11 and quitting no longer collapses multi-layout keyboards, every packaged channel builds the bundled engine at the portable x86-64 baseline so older CPUs stop crashing, the Snap package drops the `uinput` plug the Store denied so revisions publish again, the Flatpak remote publish warns loudly instead of skipping silently, and Transcribe File's modal download dialog releases its grab so the transcript's buttons are clickable.
|
||||
|
||||
See [docs/UPDATE.md](docs/UPDATE.md#whats-new-in-v0183) for the highlight table, or the [GitHub Release](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.3).
|
||||
|
||||
**[v0.18.2](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.2)** (2026-10-12)
|
||||
|
||||
Patch on the stable line: the dictation overlay orb now pulses and ripples with live mic level, Nix users get a flake package with NixOS and Home Manager modules plus Vulkan GPU inference for whisper.cpp, held keyboards are left ungrabbed at startup so typing during launch cannot strand a key, the bundled engine no longer crashes on older CPUs, and the piped installer keeps working when it needs to prompt you.
|
||||
|
||||
See [docs/UPDATE.md](docs/UPDATE.md#whats-new-in-v0182) for the highlight table, or the [GitHub Release](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.2).
|
||||
|
||||
**[v0.18.1](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.1)** (2026-10-08)
|
||||
|
||||
Patch on the stable line: a Settings Proxy page for model downloads and update checks behind SOCKS5/HTTP proxies, opt-in JSONL transcript persistence so a failed injection no longer loses the text, .deb and .rpm release packages for Debian and Fedora, a slimmer tray menu (Start on Login and About now live only in Settings), and reliability fixes for the Dictation Pad on Wayland, evdev keyboard discovery, KDE Plasma 6 letter case, a dead Initial Prompt field in Settings, save dialogs that could double the `.txt` extension, and a Speech Model picker that stages changes until you confirm the download.
|
||||
|
||||
See [docs/UPDATE.md](docs/UPDATE.md#whats-new-in-v0181) for the highlight table, or the [GitHub Release](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.1).
|
||||
|
||||
## Earlier versions
|
||||
|
||||
Browse tags on [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases). Version history used for maintainer planning also appears in [docs/RELEASE_PROCESS.md](docs/RELEASE_PROCESS.md).
|
||||
|
||||
## Format
|
||||
|
||||
We follow [Semantic Versioning](https://semver.org/). Pre-releases use suffixes such as `-alpha`, `-beta`, and `-rc.N`. Maintainer release steps: [docs/RELEASE_PROCESS.md](docs/RELEASE_PROCESS.md).
|
||||
@@ -0,0 +1,127 @@
|
||||
# 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:
|
||||
|
||||
- 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:
|
||||
|
||||
- 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
|
||||
jatinkrmalik@gmail.com.
|
||||
|
||||
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](https://www.contributor-covenant.org), version 2.1,
|
||||
available at
|
||||
https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@@ -0,0 +1,289 @@
|
||||
# Contributing to Vocalinux
|
||||
|
||||
Thanks for your interest in contributing. This guide covers setup, style, testing, and pull requests.
|
||||
|
||||
## Code of conduct
|
||||
|
||||
Participation is covered by our [Code of Conduct](CODE_OF_CONDUCT.md). Be respectful and constructive.
|
||||
|
||||
## Ways to contribute
|
||||
|
||||
- **Report bugs** - [Open an issue](https://github.com/VocaHQ/vocalinux/issues/new?template=bug_report.md)
|
||||
- **Suggest features** - [Feature request](https://github.com/VocaHQ/vocalinux/issues/new?template=feature_request.md) or [Discussions](https://github.com/VocaHQ/vocalinux/discussions)
|
||||
- **Improve documentation** - Fixes and clarity are always useful
|
||||
- **Fix bugs or add features** - Check [open issues](https://github.com/VocaHQ/vocalinux/issues), especially [`good first issue`](https://github.com/VocaHQ/vocalinux/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
|
||||
|
||||
## Development setup
|
||||
|
||||
### Automated (recommended)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/YOUR-USERNAME/vocalinux.git
|
||||
cd vocalinux
|
||||
./install.sh --dev
|
||||
```
|
||||
|
||||
This installs system dependencies, creates `venv/` with an editable install and dev
|
||||
tools, and runs the test suite. See [The two environments](#the-two-environments).
|
||||
|
||||
### Manual setup
|
||||
|
||||
1. Fork and clone the repository.
|
||||
|
||||
2. Install system dependencies (examples):
|
||||
|
||||
**Ubuntu 24.04+:**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y python3-pip python3-gi python3-gi-cairo \
|
||||
gir1.2-gtk-3.0 gir1.2-ibus-1.0 libgirepository-2.0-dev libgirepository1.0-dev \
|
||||
build-essential pkg-config libcairo2-dev libffi-dev \
|
||||
python3-dev portaudio19-dev python3-venv xdotool
|
||||
```
|
||||
|
||||
**Debian 12 (installer environment only):**
|
||||
```bash
|
||||
sudo apt install -y python3-pip python3-gi python3-gi-cairo \
|
||||
gir1.2-gtk-3.0 gir1.2-ibus-1.0 libgirepository1.0-dev libcairo2-dev \
|
||||
build-essential pkg-config libffi-dev \
|
||||
python3-dev portaudio19-dev python3-venv xdotool
|
||||
```
|
||||
|
||||
**Debian 13+:**
|
||||
```bash
|
||||
sudo apt install -y python3-pip python3-gi python3-gi-cairo \
|
||||
gir1.2-gtk-3.0 gir1.2-ibus-1.0 libgirepository-2.0-dev libcairo2-dev \
|
||||
build-essential pkg-config libffi-dev \
|
||||
python3-dev portaudio19-dev python3-venv xdotool
|
||||
```
|
||||
|
||||
**Fedora 40+:**
|
||||
```bash
|
||||
sudo dnf install -y python3-pip python3-gobject gtk3 ibus-devel \
|
||||
gobject-introspection-devel glib2-devel python3-devel portaudio-devel \
|
||||
cairo-devel cairo-gobject-devel libffi-devel python3-virtualenv pkg-config cmake \
|
||||
gcc-c++ make xdotool
|
||||
```
|
||||
|
||||
AppIndicator (system tray):
|
||||
```bash
|
||||
# Older Ubuntu:
|
||||
sudo apt install -y gir1.2-appindicator3-0.1
|
||||
# Debian 12+ or newer Ubuntu:
|
||||
sudo apt install -y gir1.2-ayatanaappindicator3-0.1
|
||||
```
|
||||
|
||||
**macOS (tooling only):** `brew install portaudio pkg-config`; use
|
||||
`xcode-select --install` if a C compiler is missing. PyGObject/pycairo and their
|
||||
header checks apply only on Linux, which is required to run the desktop app.
|
||||
|
||||
3. Create the environment and install:
|
||||
|
||||
```bash
|
||||
# Requires uv (https://docs.astral.sh/uv/); creates .venv/ with dev + vad extras
|
||||
just deps
|
||||
```
|
||||
|
||||
Missing native build headers are reported with install commands before syncing.
|
||||
For older Linux releases, use the installer environment described below.
|
||||
|
||||
4. Run:
|
||||
|
||||
```bash
|
||||
just run-source-debug
|
||||
```
|
||||
|
||||
5. Optional pre-commit hooks:
|
||||
|
||||
```bash
|
||||
uv run --no-sync pre-commit install
|
||||
```
|
||||
|
||||
Hooks are optional. CI runs the same checks.
|
||||
|
||||
### The two environments
|
||||
|
||||
The repository uses two virtual environments on purpose. Do not merge them:
|
||||
|
||||
| Directory | Created by | Python | Used for |
|
||||
|-----------|-----------|--------|----------|
|
||||
| `.venv/` | `just deps` (uv) | pinned in `.python-version` | dev tooling: pytest, black, mypy, `just` recipes |
|
||||
| `venv/` | `./install.sh` | the system Python | running the installed app, which needs distro PyGObject |
|
||||
|
||||
- On Linux, `.venv/` builds the locked PyGObject, requiring glib 2.80+ and the
|
||||
headers above. On Debian 12 or Fedora 39 and older, use `./install.sh --dev`,
|
||||
then `venv/bin/pytest` or `venv/bin/python -m vocalinux.main --debug` instead.
|
||||
- `venv/` uses distro PyGObject via `--system-site-packages`. The installer ignores
|
||||
an activated venv and rebuilds one created by the wrong interpreter. It uses
|
||||
`/usr/bin/python3` unless overridden, e.g. `SYSTEM_PYTHON=/usr/bin/python3.12 ./install.sh`.
|
||||
|
||||
`just appimage` bundles its own Python/PyGObject in the pinned Ubuntu Docker image.
|
||||
For GI failures, check `Checking bundled PyGObject after linuxdeploy` and the smoke
|
||||
test's path diagnostics; installing `python3-gobject` on the host won't fix the bundle.
|
||||
|
||||
## Making changes
|
||||
|
||||
### Branch naming
|
||||
|
||||
```bash
|
||||
git checkout main
|
||||
git pull origin main
|
||||
git checkout -b feature/your-feature-name
|
||||
# or fix/, docs/, refactor/, test/
|
||||
```
|
||||
|
||||
Never push directly to `main`. Open a pull request for every change.
|
||||
|
||||
### Code style
|
||||
|
||||
| Tool | Role |
|
||||
|------|------|
|
||||
| Black | Formatting (line length 100) |
|
||||
| isort | Import sorting (black profile) |
|
||||
| flake8 | Linting |
|
||||
| mypy | Type checking (`just typecheck`) |
|
||||
|
||||
```bash
|
||||
just format # black + isort
|
||||
just lint # flake8 + black --check + isort --check
|
||||
just typecheck # mypy src/
|
||||
```
|
||||
|
||||
### Project structure
|
||||
|
||||
```
|
||||
vocalinux/
|
||||
├── src/vocalinux/ # Application
|
||||
│ ├── main.py
|
||||
│ ├── speech_recognition/ # Engines + command processor
|
||||
│ ├── text_injection/ # X11 / Wayland injection
|
||||
│ ├── ui/ # GTK tray, settings, config
|
||||
│ └── utils/
|
||||
├── tests/
|
||||
├── resources/ # Icons and sounds
|
||||
├── docs/
|
||||
├── install.d/ # Installer modules, including generated package data
|
||||
├── packaging/ # AppImage, AUR, Flatpak
|
||||
├── scripts/ # Maintenance tools and distro package-map source
|
||||
├── snap/ # Snap recipe
|
||||
└── web/ # Marketing site (Next.js)
|
||||
```
|
||||
|
||||
| Task | Start here |
|
||||
|------|------------|
|
||||
| Voice command | `src/vocalinux/speech_recognition/command_processor.py` |
|
||||
| UI | `src/vocalinux/ui/` |
|
||||
| Recognition engines | `src/vocalinux/speech_recognition/recognition_manager.py` |
|
||||
| Text injection | `src/vocalinux/text_injection/text_injector.py` |
|
||||
| Settings / config | `src/vocalinux/ui/config_manager.py`, `settings_dialog.py` |
|
||||
| Installer package names | `scripts/distro-package-map.yaml` |
|
||||
|
||||
### Installer package map
|
||||
|
||||
`scripts/distro-package-map.yaml` is the source of truth for package names,
|
||||
alternatives, and conditional package probes used by `install.sh`. Do not edit
|
||||
the generated `install.d/package_map.sh` directly. After changing the YAML, run:
|
||||
|
||||
```bash
|
||||
just distro-packages
|
||||
just distro-packages-check
|
||||
```
|
||||
|
||||
Commit both the YAML and generated shell module. Package-manager control flow
|
||||
and installation policy remain handwritten in
|
||||
`install.d/system_dependencies.sh`; user systems never parse the YAML. The
|
||||
remote bootstrap's pre-checkout `git` installation is the deliberate exception
|
||||
because the generated module is not available yet.
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
just test
|
||||
just test-cov
|
||||
uv run --extra dev --extra vad --group lint pytest tests/test_command_processor.py
|
||||
```
|
||||
|
||||
- Place tests in `tests/` as `test_*.py`
|
||||
- Aim for solid coverage on new code (roughly 80%+)
|
||||
- Use `pytest-mock` via the `mocker` fixture
|
||||
|
||||
```python
|
||||
def test_command_processor_new_line(mocker):
|
||||
"""Test that 'new line' command returns correct action."""
|
||||
processor = CommandProcessor()
|
||||
result = processor.process("new line")
|
||||
assert result.action == "new_line"
|
||||
```
|
||||
|
||||
### Remote API test server
|
||||
|
||||
```bash
|
||||
python scripts/test_remote_server.py
|
||||
python scripts/test_remote_server.py --port 9000
|
||||
python scripts/test_remote_server.py --delay 2
|
||||
```
|
||||
|
||||
Endpoints:
|
||||
|
||||
- whisper.cpp style: `http://localhost:8080/inference`
|
||||
- OpenAI-compatible: `http://localhost:8080/v1/audio/transcriptions`
|
||||
|
||||
In Settings → Speech Model, select **Remote API**, set the server URL, choose the endpoint format, and use **Test Connection**.
|
||||
|
||||
## Pull requests
|
||||
|
||||
> Automated agents may append three robot emoji (🤖) to the PR title to opt into the agent fast-track merge path when that process is active.
|
||||
|
||||
### Before you open a PR
|
||||
|
||||
- [ ] Style checks pass (`just lint`, `just typecheck`)
|
||||
- [ ] Tests pass (`just test`)
|
||||
- [ ] Docs updated when behavior or install steps change
|
||||
- [ ] Commits use [Conventional Commits](https://www.conventionalcommits.org/)
|
||||
|
||||
```
|
||||
type(scope): short description
|
||||
|
||||
Longer description if needed.
|
||||
|
||||
Fixes #123
|
||||
```
|
||||
|
||||
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
feat(commands): add "select all" voice command
|
||||
fix(tray): resolve icon not updating on Wayland
|
||||
docs(readme): update installation instructions
|
||||
```
|
||||
|
||||
### Submit
|
||||
|
||||
1. Push your branch to your fork
|
||||
2. Open a PR against `main` and fill out the template
|
||||
3. Link related issues
|
||||
4. Wait for CI; address review feedback
|
||||
5. Maintainers squash-merge when approved
|
||||
|
||||
## Releases
|
||||
|
||||
Maintainers follow [docs/RELEASE_PROCESS.md](docs/RELEASE_PROCESS.md) (version files, docs, website, tag, automated publish). Do not tag releases from feature branches.
|
||||
|
||||
## Community
|
||||
|
||||
- [SUPPORT.md](SUPPORT.md) - where to get help
|
||||
- [Discord](https://discord.gg/t6muquAJbm) - fastest place to talk with maintainers and other contributors
|
||||
- [GitHub Discussions](https://github.com/VocaHQ/vocalinux/discussions)
|
||||
- [GitHub Issues](https://github.com/VocaHQ/vocalinux/issues)
|
||||
- [@vocahq on X](https://x.com/vocahq)
|
||||
|
||||
## License
|
||||
|
||||
Contributions are licensed under the [GNU Affero General Public License v3.0](LICENSE)
|
||||
(AGPL-3.0), matching the other [VocaHQ](https://github.com/VocaHQ) distribution
|
||||
projects ([VocaMac](https://github.com/VocaHQ/vocamac),
|
||||
[VocaPhone](https://github.com/VocaHQ/vocaphone),
|
||||
[VocaGateway](https://github.com/VocaHQ/vocagateway)). By opening a pull request, you
|
||||
agree that your contribution may be distributed under that license.
|
||||
@@ -0,0 +1,661 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
@@ -0,0 +1,4 @@
|
||||
include vocalinux.desktop
|
||||
include resources/icons/scalable/*.svg
|
||||
include resources/sounds/*.wav
|
||||
recursive-include src/vocalinux/resources *
|
||||
@@ -1,16 +1,463 @@
|
||||
# ci-template
|
||||
<div align="center">
|
||||
|
||||
Gitea template repo. Create a new repo with **Use this template** (tick "Git Content") to start with the Bongbetic CI
|
||||
quality gates already in place: `.gitea/workflows/ci.yml`, `.jscpd.json`, `CI.md`.
|
||||
<img src="https://vocalinux.com/brand/vocalinux-mark-circle.svg" width="50" height="50" alt="Vocalinux">
|
||||
|
||||
After creating the repo:
|
||||
# Vocalinux
|
||||
|
||||
1. Add your language linter steps in the `lint` job (marker `# @@LINT_STEPS@@` in `ci.yml`). Snippets for Python,
|
||||
Node and Rust live in the `ci-tools` repo under `snippets/`.
|
||||
2. Add the secrets listed in `CI.md`.
|
||||
3. After the first CI run, require `CI / security (pull_request)` and `CI / lint (pull_request)` on `main`
|
||||
(`ci-tools/bin/new-repo-ci.sh --protect-only <repo>`, or Settings, Branches).
|
||||
**Voice dictation for Linux**
|
||||
|
||||
For repos that already exist, use `ci-tools/bin/new-repo-ci.sh`, which opens a PR instead.
|
||||
[](docs/DISTRO_COMPATIBILITY.md)
|
||||
[](docs/DISTRO_COMPATIBILITY.md)
|
||||
[](docs/DISTRO_COMPATIBILITY.md)
|
||||
[](docs/DISTRO_COMPATIBILITY.md)
|
||||
[](docs/DISTRO_COMPATIBILITY.md)
|
||||
|
||||
Delete this README in the new repo.
|
||||
[](https://github.com/VocaHQ/vocalinux#privacy-and-security)
|
||||
[](https://github.com/VocaHQ/vocalinux#features)
|
||||
[](https://www.gnu.org/licenses/agpl-3.0)
|
||||
[](https://www.python.org/downloads/)
|
||||
[](https://github.com/VocaHQ/vocalinux/releases)
|
||||
|
||||
[](https://github.com/VocaHQ/vocalinux/releases/latest)
|
||||
[](https://github.com/VocaHQ/vocalinux/releases/latest)
|
||||
[](https://github.com/VocaHQ/vocalinux/releases/latest)
|
||||
[](#flatpak-any-distro)
|
||||
[](https://snapcraft.io/vocalinux)
|
||||
[](https://aur.archlinux.org/packages/vocalinux)
|
||||
[](https://pypi.org/project/vocalinux/)
|
||||
[](packaging/nix/README.md)
|
||||
|
||||
[](https://discord.gg/t6muquAJbm)
|
||||
[](https://vocahq.com)
|
||||
[](https://x.com/vocahq)
|
||||
|
||||
[Website](https://vocalinux.com) · [Install](#install) · [Docs](#documentation) · [Releases](https://github.com/VocaHQ/vocalinux/releases)
|
||||
|
||||
</div>
|
||||
|
||||
Vocalinux turns speech into typed text in whatever app has focus. It is a free, AGPL-3.0-licensed desktop app for X11 and Wayland. After you download a model, local engines (whisper.cpp by default, plus OpenAI Whisper, Faster Whisper, VOSK, and Parakeet) run speech-to-text on your machine. An optional remote HTTP API is off unless you configure it.
|
||||
|
||||
No Voca account is required. Models download once. After that, speech-to-text stays on your machine.
|
||||
|
||||
**Current release:** [v0.18.5](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.5). Patch: a stop that races a recording start can no longer leave the mic recording forever, keyboards stay alive through suspend and the GNOME lock screen, Ctrl+mouse-wheel zoom works again, Dictation Pad and Settings stop travelling workspaces together, paste-injection copies are marked sensitive for clipboard history on wl-clipboard 2.2+, and `install.sh` gains an upgrade mode that keeps your existing configuration. Details: [docs/UPDATE.md](docs/UPDATE.md).
|
||||
|
||||
## Features
|
||||
|
||||
- **On-device after model download**: Local engines; speech-to-text stays on your machine
|
||||
- **X11 and Wayland**: Text injection via xdotool, IBus, wtype, ydotool, or clipboard fallback
|
||||
- **Several engines**: whisper.cpp (default), OpenAI Whisper, Faster Whisper, VOSK, Parakeet, plus optional remote HTTP API or local VocaGateway from Settings (not on-device)
|
||||
- **GPU acceleration**: Vulkan for AMD, Intel, and NVIDIA with whisper.cpp
|
||||
- **Toggle or push-to-talk**: New installs default to hold Right Alt; existing configs keep their shortcut
|
||||
- **System tray + settings**: Searchable sidebar, Speech Model simple setup with Advanced as an island, status icons, audio feedback
|
||||
- **Start on login**: XDG autostart (desktop session, not a systemd service)
|
||||
- **Packaging**: install script, `.deb` / `.rpm`, AppImage, AUR, PyPI, Snap (`--edge`), Flatpak (release bundles and local build; not on Flathub), Nix flake
|
||||
|
||||
## Screenshots
|
||||
|
||||
Vocalinux in action. Full gallery on the [website screenshots page](https://vocalinux.com/screenshots/).
|
||||
|
||||
### Product
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" width="50%">
|
||||
<img src="web/public/screenshots/00-transcription.png" alt="Transcription in Action" width="350"><br>
|
||||
<em>Real-time voice-to-text transcription</em>
|
||||
</td>
|
||||
<td align="center" width="50%">
|
||||
<img src="web/public/screenshots/02-system-tray.png" alt="System Tray" width="350"><br>
|
||||
<em>System tray with listening indicator</em>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="web/public/screenshots/05-about-view.png" alt="About View" width="350"><br>
|
||||
<em>About & Updates in Settings</em>
|
||||
</td>
|
||||
<td align="center">
|
||||
<img src="web/public/screenshots/03-log-viewer.png" alt="Log Viewer" width="350"><br>
|
||||
<em>Log viewer for debugging</em>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Settings
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" width="33%">
|
||||
<img src="web/public/screenshots/settings-speech-engine.png" alt="Speech Engine settings" width="260"><br>
|
||||
<em>Speech Engine</em>
|
||||
</td>
|
||||
<td align="center" width="33%">
|
||||
<img src="web/public/screenshots/settings-recognition.png" alt="Recognition settings" width="260"><br>
|
||||
<em>Recognition</em>
|
||||
</td>
|
||||
<td align="center" width="33%">
|
||||
<img src="web/public/screenshots/settings-audio.png" alt="Audio settings" width="260"><br>
|
||||
<em>Audio</em>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="web/public/screenshots/settings-performance.png" alt="Performance settings" width="260"><br>
|
||||
<em>Performance</em>
|
||||
</td>
|
||||
<td align="center">
|
||||
<img src="web/public/screenshots/settings-general.png" alt="General settings" width="260"><br>
|
||||
<em>General</em>
|
||||
</td>
|
||||
<td align="center">
|
||||
<img src="web/public/screenshots/settings-advanced.png" alt="Advanced tuning and settings" width="260"><br>
|
||||
<em>Advanced</em>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<img src="web/public/screenshots/06-dictation-overlay-listening.png" alt="Dictation overlay listening" width="96"><br>
|
||||
<em>Floating overlay while listening (green)</em>
|
||||
</td>
|
||||
<td align="center">
|
||||
<img src="web/public/screenshots/07-dictation-overlay-processing.png" alt="Dictation overlay processing" width="96"><br>
|
||||
<em>Floating overlay while processing (amber)</em>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Install
|
||||
|
||||
### Recommended (interactive installer)
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
Prefer to review the script first: open `/tmp/vl.sh` before running it, or clone the repo and run `./install.sh` locally.
|
||||
|
||||
The installer detects hardware, recommends an engine, downloads a default model (~74MB for whisper.cpp tiny), installs neural VAD when ONNX Runtime is available, and sets up desktop integration. Typical install time with whisper.cpp is about 1-2 minutes.
|
||||
|
||||
| Engine | When to use |
|
||||
|--------|-------------|
|
||||
| **whisper.cpp** (default) | Best default; Vulkan GPU on AMD, Intel, and NVIDIA |
|
||||
| **Whisper** (OpenAI) | PyTorch path; NVIDIA/CUDA |
|
||||
| **Faster Whisper** | CPU-friendly Whisper via CTranslate2 / INT8 |
|
||||
| **VOSK** | Low RAM / minimal footprint |
|
||||
| **Parakeet** | CPU; NVIDIA NeMo ASR via sherpa-onnx; 25 European languages |
|
||||
| **Remote API** | Offload to a server you configure |
|
||||
|
||||
Non-interactive options:
|
||||
|
||||
```bash
|
||||
bash /tmp/vl.sh --auto # whisper.cpp defaults
|
||||
bash /tmp/vl.sh --auto --engine=whisper # OpenAI Whisper
|
||||
bash /tmp/vl.sh --auto --engine=faster_whisper # Faster Whisper (CPU)
|
||||
bash /tmp/vl.sh --auto --engine=vosk # VOSK only
|
||||
bash /tmp/vl.sh --auto --engine=parakeet # Parakeet (CPU)
|
||||
```
|
||||
|
||||
For a specific release tag, see [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases) or `./install.sh --tag=v0.18.5`.
|
||||
|
||||
### Arch Linux (AUR)
|
||||
|
||||
```bash
|
||||
yay -S vocalinux
|
||||
```
|
||||
|
||||
See [docs/AUR.md](docs/AUR.md).
|
||||
|
||||
### AppImage
|
||||
|
||||
Download the `x86_64` or `aarch64` AppImage from [Releases](https://github.com/VocaHQ/vocalinux/releases), mark it executable, and run it. Built against glibc 2.35 (Debian 12+, Ubuntu 22.04+, Fedora 36+, Arch, Tumbleweed). Host text-injection tools (`xdotool` on X11; `wtype` / `ydotool` / clipboard tools on Wayland) are still required. Current AppImages rebuild whisper.cpp with Vulkan and use the host GPU driver. Prefer the installer when you want system deps, a CUDA build, and models set up automatically.
|
||||
|
||||
### Distro packages (.deb / .rpm)
|
||||
|
||||
Download the `.deb` (Debian 12+, Ubuntu 24.04+) or `.rpm` (Fedora) matching your CPU from [Releases](https://github.com/VocaHQ/vocalinux/releases) and install with `sudo apt install ./vocalinux_*.deb` or `sudo dnf install ./vocalinux-*.rpm`. Thin packages: Python and GTK come from the distro. No auto-update; CPU whisper.cpp. Details in [docs/INSTALL.md](docs/INSTALL.md).
|
||||
|
||||
### Flatpak (any distro)
|
||||
|
||||
Install and auto-update via the self-hosted VocaHQ remote (`flatpak update` picks up each release):
|
||||
|
||||
```bash
|
||||
flatpak install https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref
|
||||
```
|
||||
|
||||
The `.flatpakref` adds the `vocahq` remote and resolves the GNOME runtime through Flathub. Manually instead:
|
||||
|
||||
```bash
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
|
||||
flatpak install vocahq com.vocalinux.Vocalinux
|
||||
```
|
||||
|
||||
Or sideload a GitHub Release bundle (`Vocalinux-<version>-x86_64.flatpak` or `-aarch64.flatpak`) after the Flathub GNOME runtime is present — bundles do not auto-update:
|
||||
|
||||
```bash
|
||||
flatpak install --user ./Vocalinux-<version>-x86_64.flatpak
|
||||
```
|
||||
|
||||
Local build:
|
||||
|
||||
```bash
|
||||
flatpak install flathub org.gnome.Platform//50 org.gnome.Sdk//50
|
||||
flatpak-builder --user --install --force-clean build-dir \
|
||||
packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
flatpak run com.vocalinux.Vocalinux
|
||||
```
|
||||
|
||||
Ships whisper.cpp with Vulkan. It is **not on Flathub** (submission [flathub#9368](https://github.com/flathub/flathub/pull/9368) closed 2026-07-23 on policy grounds). Details: [packaging/flatpak/README.md](packaging/flatpak/README.md).
|
||||
|
||||
### Snap (Ubuntu Snap Store)
|
||||
|
||||
Listing: [snapcraft.io/vocalinux](https://snapcraft.io/vocalinux). `stable` is promoted from `candidate` after QA. Tagged releases also attach `vocalinux_<version>_amd64.snap` on GitHub.
|
||||
|
||||
```bash
|
||||
sudo snap install vocalinux --edge
|
||||
sudo snap connect vocalinux:audio-record # if mic is not auto-connected
|
||||
sudo snap connect vocalinux:raw-input # global keyboard shortcuts (evdev)
|
||||
sudo snap connect vocalinux:hardware-observe # list keyboards (/proc/bus/input/devices)
|
||||
```
|
||||
|
||||
Native Wayland typing uses the RemoteDesktop portal: the compositor asks once on first dictation, nothing to connect. The recipe ships **no `uinput` plug** and no ydotool; the Store denied the super-privileged grant, which held the 0.17.0+ revisions and left **v0.16.2 (rev 7)** on edge. On KDE Plasma, KWin's portal can mistype letter case ([KDE bug 489021](https://bugs.kde.org/show_bug.cgi?id=489021)); set Virtual Keyboard to "IBus Wayland" so dictation types correctly.
|
||||
|
||||
GitHub `.snap` files through v0.18.2 declare `uinput`, so KDE users who want ydotool can sideload that build and connect the plug manually:
|
||||
|
||||
```bash
|
||||
sudo snap install --dangerous ./vocalinux_0.18.2_amd64.snap
|
||||
sudo snap connect vocalinux:uinput # only in the v0.18.x sideload; the recipe no longer ships it
|
||||
```
|
||||
|
||||
### Nix / NixOS (flake)
|
||||
|
||||
```bash
|
||||
nix run github:VocaHQ/vocalinux # try it
|
||||
nix profile install github:VocaHQ/vocalinux
|
||||
```
|
||||
|
||||
The flake also ships `nixosModules.vocalinux` and `homeManagerModules.vocalinux` for declarative installs (`programs.vocalinux.enable = true`). The bundled pywhispercpp builds with Vulkan GPU inference. Details: [packaging/nix/README.md](packaging/nix/README.md).
|
||||
|
||||
### From source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/VocaHQ/vocalinux.git
|
||||
cd vocalinux
|
||||
./install.sh
|
||||
# or pick the engine up front
|
||||
./install.sh --engine=whisper_cpp
|
||||
./install.sh --engine=vosk
|
||||
./install.sh --engine=parakeet --auto
|
||||
```
|
||||
|
||||
### After installation
|
||||
|
||||
```bash
|
||||
vocalinux # if ~/.local/bin is on PATH
|
||||
# or
|
||||
~/.local/share/vocalinux/venv/bin/vocalinux
|
||||
```
|
||||
|
||||
You can also launch Vocalinux from your application menu.
|
||||
|
||||
### Nightly builds
|
||||
|
||||
Daily builds from `main` appear on [Releases](https://github.com/VocaHQ/vocalinux/releases). Use the latest stable or beta release for production; nightlies are untested.
|
||||
|
||||
## Requirements
|
||||
|
||||
| | |
|
||||
|--|--|
|
||||
| **OS** | Linux (Ubuntu 24.04+, Debian 12+, Fedora 42+, Arch, openSUSE Tumbleweed) |
|
||||
| **Python** | 3.11 or newer |
|
||||
| **Display** | X11 or Wayland |
|
||||
| **Hardware** | Microphone; GPU optional (Vulkan) |
|
||||
|
||||
The distro must ship Python 3.11+ because Vocalinux uses distro PyGObject (`python3-gi`). Ubuntu 22.04 (Python 3.10) and Debian 11 (3.9) are below that floor. Distribution notes: [docs/DISTRO_COMPATIBILITY.md](docs/DISTRO_COMPATIBILITY.md).
|
||||
|
||||
## Usage
|
||||
|
||||
### Dictation
|
||||
|
||||
1. **Push-to-talk (default on new installs):** hold Right Alt (Option on Mac-layout keyboards) and speak
|
||||
2. Speak into the microphone
|
||||
3. **Release** to stop, or switch to **Toggle mode** in Settings (double-tap a key to start/stop)
|
||||
|
||||
Existing configs keep their saved shortcut.
|
||||
|
||||
### Voice commands
|
||||
|
||||
English phrases always work. With a non-English recognition language, matching
|
||||
punctuation / line-break phrases in that language are also recognized
|
||||
(Italian *virgola* / *punto*, French *virgule* / *point*, etc.).
|
||||
|
||||
| Command | Action |
|
||||
|---------|--------|
|
||||
| "new line" | Line break |
|
||||
| "period" / "full stop" / "dot" | `.` |
|
||||
| "comma" | `,` |
|
||||
| "question mark" | `?` |
|
||||
| "exclamation mark" | `!` |
|
||||
| "delete that" | Delete last sentence |
|
||||
| "capitalize" | Capitalize next word |
|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
vocalinux --help
|
||||
vocalinux --version
|
||||
vocalinux --debug
|
||||
vocalinux --engine whisper_cpp # default
|
||||
vocalinux --engine whisper
|
||||
vocalinux --engine faster_whisper
|
||||
vocalinux --engine vosk
|
||||
vocalinux --engine parakeet
|
||||
vocalinux --engine remote_api
|
||||
vocalinux --model medium
|
||||
vocalinux --model medium.en-q5_0 # exact whisper.cpp variant
|
||||
vocalinux --model large-v3-turbo
|
||||
vocalinux --wayland
|
||||
vocalinux --start-minimized
|
||||
```
|
||||
|
||||
### Autostart
|
||||
|
||||
**Start on Login** creates an XDG autostart desktop entry (`~/.config/autostart/`). It does not install a systemd unit. Enable from the first-run dialog, tray menu, or Settings.
|
||||
|
||||
### Configuration
|
||||
|
||||
Stored at `~/.config/vocalinux/config.json`. Prefer the Settings dialog for day-to-day changes. **Settings → Speech Model** starts with a simple setup; expand **Advanced** for engine, size, and specialization. Set `post_processing.script_path` to an executable to transform each transcription result (stdin → stdout) before it is injected; leave empty to disable.
|
||||
|
||||
Neural VAD (Silero) is used when `onnxruntime` is available; install via `pip install "vocalinux[vad]"` for manual/PyPI installs. The installer attempts this automatically.
|
||||
|
||||
## Documentation
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [Installation](docs/INSTALL.md) | Installer, AppImage, AUR, Flatpak, Snap, Nix flake, running |
|
||||
| [Manual / PyPI install](docs/INSTALL_MANUAL.md) | Package lists and pip workflows |
|
||||
| [Troubleshooting](docs/TROUBLESHOOTING.md) | Common failures |
|
||||
| [User guide](docs/USER_GUIDE.md) | Dictation, engines, models, tips |
|
||||
| [Update guide](docs/UPDATE.md) | Upgrade steps and release notes |
|
||||
| [Changelog](CHANGELOG.md) | Release history pointers |
|
||||
| [Support](SUPPORT.md) | Where to get help |
|
||||
| [Distribution compatibility](docs/DISTRO_COMPATIBILITY.md) | Distro matrix and session notes |
|
||||
| [Remote HTTP API](docs/HTTP_REMOTE.md) | Offload transcription to a server |
|
||||
| [Local VocaGateway (optional)](docs/GATEWAY_EMBED.md) | Start a local gateway from Settings; not on-device |
|
||||
| [Contributing](CONTRIBUTING.md) | Dev setup, style, PR process |
|
||||
| [Security](SECURITY.md) | Supported versions and vulnerability reporting |
|
||||
| [Docs index](docs/README.md) | Full documentation map |
|
||||
|
||||
## Privacy and security
|
||||
|
||||
- Local engines process audio on-device after you download a model; no Voca account required
|
||||
- Optional remote API is off by default and only used when you configure a server
|
||||
- Model downloads are checked against pinned checksums
|
||||
|
||||
Report vulnerabilities privately per [SECURITY.md](SECURITY.md).
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
git clone https://github.com/VocaHQ/vocalinux.git
|
||||
cd vocalinux
|
||||
./install.sh --dev
|
||||
source venv/bin/activate
|
||||
pytest
|
||||
python -m vocalinux.main --debug
|
||||
```
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md) for the two-venv layout, `just` recipes, and PR guidelines.
|
||||
|
||||
## Roadmap
|
||||
|
||||
Shipped: graphical settings, multi-language support, whisper.cpp default, Vulkan GPU, Wayland/IBus, Flatpak packaging, AppImage, `.deb` / `.rpm` packages, in-app update checker, Parakeet and Faster Whisper engines, Snap recipe.
|
||||
|
||||
Planned:
|
||||
|
||||
- [ ] Application-specific voice commands
|
||||
- [ ] User-customizable voice command map
|
||||
- [ ] Flathub publication (not currently listed; see #167)
|
||||
|
||||
## Voca ecosystem
|
||||
|
||||
Vocalinux is part of [VocaHQ](https://vocahq.com). On-device speech-to-text first, one app per platform. Optional [VocaGateway](https://vocagateway.vocahq.com) is self-hosted and not on-device.
|
||||
|
||||
| Platform | Project | Website | GitHub |
|
||||
|----------|---------|---------|--------|
|
||||
| Linux | **VocaLinux** | [vocalinux.com](https://vocalinux.com) | [VocaHQ/vocalinux](https://github.com/VocaHQ/vocalinux) |
|
||||
| macOS | **VocaMac** | [vocamac.com](https://vocamac.com) | [VocaHQ/vocamac](https://github.com/VocaHQ/vocamac) |
|
||||
| Windows | **VocaWin** | [vocawin.com](https://vocawin.com) | [VocaHQ/vocawin](https://github.com/VocaHQ/vocawin) |
|
||||
| Phone | **VocaPhone** | [vocaphone.vocahq.com](https://vocaphone.vocahq.com) | [VocaHQ/vocaphone](https://github.com/VocaHQ/vocaphone) |
|
||||
| Gateway | **VocaGateway** | [vocagateway.vocahq.com](https://vocagateway.vocahq.com) | [VocaHQ/vocagateway](https://github.com/VocaHQ/vocagateway) |
|
||||
|
||||
Talk to us: [Discord](https://discord.gg/t6muquAJbm) · [X @vocahq](https://x.com/vocahq) · [hello@vocahq.com](mailto:hello@vocahq.com)
|
||||
|
||||
## Contributing
|
||||
|
||||
Bug reports, docs, and code are welcome. Start with [CONTRIBUTING.md](CONTRIBUTING.md) and [good first issues](https://github.com/VocaHQ/vocalinux/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
|
||||
|
||||
- [Report a bug](https://github.com/VocaHQ/vocalinux/issues/new?template=bug_report.md)
|
||||
- [Request a feature](https://github.com/VocaHQ/vocalinux/issues/new?template=feature_request.md)
|
||||
- [Discussions](https://github.com/VocaHQ/vocalinux/discussions)
|
||||
|
||||
### Contributors
|
||||
|
||||
Thanks to everyone who has contributed code, docs, or fixes:
|
||||
|
||||
<a href="https://github.com/VocaHQ/vocalinux/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=VocaHQ/vocalinux" alt="Vocalinux contributors" />
|
||||
</a>
|
||||
|
||||
## Repository mirrors
|
||||
|
||||
GitHub is the primary forge for issues, PRs, CI, and releases.
|
||||
|
||||
| Role | URL |
|
||||
|------|-----|
|
||||
| Primary | https://github.com/VocaHQ/vocalinux |
|
||||
| Read-only mirror (Codeberg) | https://codeberg.org/jatinkrmalik/vocalinux |
|
||||
|
||||
Open issues and pull requests on GitHub only.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the **GNU Affero General Public License v3.0**
|
||||
([AGPL-3.0](LICENSE)), aligning with the other [VocaHQ](https://github.com/VocaHQ)
|
||||
distribution projects.
|
||||
|
||||
You may use, study, modify, and redistribute the software under AGPL-3.0. If you
|
||||
run a modified version as a network service, AGPL also requires that you make the
|
||||
corresponding source available.
|
||||
|
||||
## Star Chart
|
||||
|
||||
[](https://www.star-history.com/?type=date&repos=VocaHQ%2Fvocalinux)
|
||||
|
||||
### Optional Orukeet model
|
||||
|
||||
With the Parakeet engine installed, Settings → Speech Model → Parakeet also
|
||||
offers `orukeet-v0.1.0`. It uses the existing local sherpa-onnx recognizer for
|
||||
25 European languages; the recommended Parakeet model and default whisper.cpp
|
||||
engine stay unchanged.
|
||||
|
||||
The download comes from a pinned revision of
|
||||
[oruk/orukeet on Hugging Face](https://huggingface.co/oruk/orukeet). Vocalinux
|
||||
checks every file against its bundled SHA-256 pins and checks the publisher's
|
||||
release manifest against those same pins. The manifest download participates
|
||||
in Hugging Face's normal model-download accounting. Cached recognition works
|
||||
offline and does not send audio or usage events. The model occupies about
|
||||
641 MiB; its CC BY-SA 4.0 weights license and NVIDIA attribution are included.
|
||||
|
||||
### Optional Underdog Bark 3.0 models
|
||||
|
||||
Settings → Speech Model → Parakeet also offers two builds of
|
||||
[Underdog Bark 3.0](https://huggingface.co/ConwayResearch/Underdog-Bark-3.0), an
|
||||
English fine-tune of Parakeet TDT 0.6B v3 (CC BY 4.0): `bark-3.0` (int8, 653 MiB)
|
||||
and `bark-3.0-int4` (4-bit, 379 MiB, about half the memory, slower). Both come
|
||||
from a pinned revision of
|
||||
[velddev/Underdog-Bark-3.0-sherpa-onnx](https://huggingface.co/velddev/Underdog-Bark-3.0-sherpa-onnx),
|
||||
an unofficial sherpa-onnx conversion not made or endorsed by Conway Research.
|
||||
They run on the existing sherpa-onnx recognizer, every file is checked against
|
||||
its bundled SHA-256 pin, and the downloads include the license and attribution
|
||||
notice.
|
||||
Choose one for English dictation of conversational speech, `bark-3.0-int4` when
|
||||
memory is tight; for read or multilingual speech keep `v3-european`.
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
# Security policy
|
||||
|
||||
## Supported versions
|
||||
|
||||
Only the current stable minor line receives security fixes:
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | --------- |
|
||||
| 0.18.x | Yes |
|
||||
| 0.17.x | No |
|
||||
| 0.16.x | No |
|
||||
| 0.15.x | No |
|
||||
| older | No |
|
||||
|
||||
Upgrade to the latest release for security and reliability fixes. See [docs/UPDATE.md](docs/UPDATE.md).
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
Do not open a public GitHub issue for security vulnerabilities.
|
||||
|
||||
**Preferred:** email the maintainer at **jatinkrmalik@gmail.com** with subject:
|
||||
|
||||
`Vocalinux Security Vulnerability Report`
|
||||
|
||||
Include:
|
||||
|
||||
- Clear description of the issue
|
||||
- Steps to reproduce
|
||||
- Potential impact
|
||||
- Suggested fix (optional)
|
||||
|
||||
You should receive acknowledgment within 48 hours. We will assess severity, share an expected timeline, coordinate disclosure, and credit you in release notes if you want credit.
|
||||
|
||||
If email is unavailable, use [GitHub private vulnerability reporting](https://github.com/VocaHQ/vocalinux/security/advisories/new) when enabled for the repository.
|
||||
|
||||
## Privacy design
|
||||
|
||||
Vocalinux is built for local-first dictation:
|
||||
|
||||
- Local engines process audio on-device after you download a model
|
||||
- No Voca account is required for local engines
|
||||
- No usage telemetry in the installed application
|
||||
- Models download once and stay in local cache
|
||||
- Downloads are checked against pinned checksums before install
|
||||
|
||||
### Remote API (optional)
|
||||
|
||||
When the user enables **Remote API**, audio is uploaded to the configured server over HTTP(S). That path is off by default. Operators should use TLS and authentication for any network outside a trusted LAN. See [docs/HTTP_REMOTE.md](docs/HTTP_REMOTE.md).
|
||||
|
||||
### Engines
|
||||
|
||||
| Engine | Processing | Notes |
|
||||
|--------|------------|--------|
|
||||
| whisper.cpp (default) | Local | Vulkan GPU optional; models cached under XDG data |
|
||||
| OpenAI Whisper | Local | PyTorch; NVIDIA/CUDA common |
|
||||
| Faster Whisper | Local | CTranslate2 / INT8 Whisper on CPU; optional extra |
|
||||
| VOSK | Local | Lightweight CPU path |
|
||||
| Parakeet | Local | NVIDIA NeMo ASR via sherpa-onnx; CPU |
|
||||
| Remote API | User-configured server | Opt-in only |
|
||||
|
||||
### File locations
|
||||
|
||||
| Path | Purpose | Permissions (typical) |
|
||||
|------|---------|------------------------|
|
||||
| `~/.config/vocalinux/` | Configuration | User-only (mode 700) |
|
||||
| `~/.local/share/vocalinux/` | Data and models | User-only (mode 700) |
|
||||
|
||||
### Known limitations
|
||||
|
||||
1. **Text injection** uses tools such as xdotool, wtype, ydotool, or IBus; desktop input APIs have their own privilege model
|
||||
2. **Global shortcuts** need access to input devices (e.g. evdev on some setups)
|
||||
3. **Virtual environments** isolate Python packages but do not sandbox the desktop session
|
||||
|
||||
## Keeping installs current
|
||||
|
||||
```bash
|
||||
# Re-run the official installer (preserves config and models)
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
Or follow [docs/UPDATE.md](docs/UPDATE.md) for source, AUR, AppImage, Snap, and Flatpak paths.
|
||||
|
||||
## Contact
|
||||
|
||||
| Topic | Contact |
|
||||
|-------|---------|
|
||||
| Security | jatinkrmalik@gmail.com |
|
||||
| General bugs | https://github.com/VocaHQ/vocalinux/issues |
|
||||
@@ -0,0 +1,40 @@
|
||||
# Support
|
||||
|
||||
Where to get help with Vocalinux.
|
||||
|
||||
## Documentation
|
||||
|
||||
| Topic | Doc |
|
||||
|-------|-----|
|
||||
| Install | [docs/INSTALL.md](docs/INSTALL.md) |
|
||||
| Manual / PyPI install | [docs/INSTALL_MANUAL.md](docs/INSTALL_MANUAL.md) |
|
||||
| Troubleshooting | [docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) |
|
||||
| Day-to-day use | [docs/USER_GUIDE.md](docs/USER_GUIDE.md) |
|
||||
| Upgrading | [docs/UPDATE.md](docs/UPDATE.md) |
|
||||
| Distros and sessions | [docs/DISTRO_COMPATIBILITY.md](docs/DISTRO_COMPATIBILITY.md) |
|
||||
| Remote transcription API | [docs/HTTP_REMOTE.md](docs/HTTP_REMOTE.md) |
|
||||
| Full index | [docs/README.md](docs/README.md) |
|
||||
| Website | [vocalinux.com](https://vocalinux.com) |
|
||||
|
||||
## Community
|
||||
|
||||
| Channel | Use for |
|
||||
|---------|---------|
|
||||
| [Discord](https://discord.gg/t6muquAJbm) | Fastest place to talk with maintainers |
|
||||
| [GitHub Discussions](https://github.com/VocaHQ/vocalinux/discussions) | Questions, setup help, ideas |
|
||||
| [Bug report](https://github.com/VocaHQ/vocalinux/issues/new?template=bug_report.md) | Something is broken |
|
||||
| [Feature request](https://github.com/VocaHQ/vocalinux/issues/new?template=feature_request.md) | New capability proposals |
|
||||
|
||||
When filing a bug, include OS/distro, `vocalinux --version`, install method, display server (X11/Wayland), engine, and a `vocalinux --debug` snippet.
|
||||
|
||||
## Security
|
||||
|
||||
Do not post vulnerability details in public issues. Follow [SECURITY.md](SECURITY.md).
|
||||
|
||||
## Contributing
|
||||
|
||||
Code and docs: [CONTRIBUTING.md](CONTRIBUTING.md). Community standards: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
|
||||
|
||||
## Maintainer contact
|
||||
|
||||
General product questions are best on Discussions or Discord so others can find the answer. Security only: see [SECURITY.md](SECURITY.md).
|
||||
@@ -0,0 +1,18 @@
|
||||
coverage:
|
||||
# Badge colors: red below 50%, yellow 50–80%, green at 80%+ (matches project target)
|
||||
range: 50..80
|
||||
round: down
|
||||
precision: 2
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: auto
|
||||
threshold: 0.5%
|
||||
patch:
|
||||
default:
|
||||
target: 80%
|
||||
|
||||
comment:
|
||||
layout: "diff, flags, files"
|
||||
behavior: default
|
||||
require_changes: false
|
||||
@@ -0,0 +1,111 @@
|
||||
# Architecture
|
||||
|
||||
Vocalinux is a GTK 3 desktop application. `main.py` wires together the
|
||||
configuration manager, recognition manager, tray UI, D-Bus service, and text
|
||||
injector. Audio capture and recognition run outside the GTK event loop.
|
||||
|
||||
## Module map
|
||||
|
||||
- `main.py` composes the application services and callbacks.
|
||||
- `audio/capture.py` and `audio/pipewire.py` provide capture sources.
|
||||
- `speech_recognition/` owns VAD, segment processing, command handling, and
|
||||
engine implementations under `engines/`.
|
||||
- `post_processor.py` runs configured transcript processing scripts.
|
||||
- `text_injection/` contains `TextInjector`, focused-window detection, IBus,
|
||||
and Remote Desktop Portal support.
|
||||
- `ui/` contains the tray, Settings, dictation pad, history, and keyboard
|
||||
backend modules.
|
||||
- `dbus_service.py` exposes desktop control methods. `gateway_embed/` manages
|
||||
the optional local VocaGateway integration.
|
||||
|
||||
## Dictation data flow
|
||||
|
||||
```text
|
||||
PortAudio or PipeWire
|
||||
|
|
||||
v
|
||||
audio/capture.py and audio/pipewire.py
|
||||
|
|
||||
v
|
||||
recognition_manager.py: VAD and silence segmentation
|
||||
| |
|
||||
| Silero VAD, when available
|
||||
| amplitude VAD otherwise
|
||||
v
|
||||
bounded segment queue
|
||||
|
|
||||
v
|
||||
recognition worker -> selected speech engine -> corrections and commands
|
||||
|
|
||||
v
|
||||
text callback -> post_processor.py -> TextInjector backend
|
||||
```
|
||||
|
||||
`PortAudioCaptureSource` and the PipeWire source provide mono 16 kHz PCM chunks.
|
||||
The recognition manager owns dictation segmentation. It uses Silero VAD when
|
||||
available and amplitude thresholds otherwise, then places finalized segments
|
||||
on a bounded queue. A recognition worker consumes the queue, dispatches each
|
||||
segment to the selected engine, applies dictionary corrections and voice
|
||||
command parsing, and invokes callbacks.
|
||||
|
||||
The text callback submits work to one ordered post-processing worker. That
|
||||
worker runs the configured post-processing script, then injects text or places
|
||||
it in the in-app dictation pad. `TextInjector` selects a backend from the
|
||||
detected `DesktopEnvironment`: X11 uses xdotool, Wayland can use wtype or
|
||||
ydotool, and the IBus and Remote Desktop Portal paths support their respective
|
||||
sessions.
|
||||
|
||||
## Threads and state ownership
|
||||
|
||||
- The GTK main thread owns widgets, dialog state, tray state, and the GLib main
|
||||
loop. UI-facing state callbacks use `GLib.idle_add` where needed; the D-Bus
|
||||
control service also marshals Toggle, Start, and Stop calls to this loop.
|
||||
- The audio capture thread reads the capture source, tracks the current audio
|
||||
buffer and VAD state, and enqueues completed segments. The recognition worker
|
||||
owns queue consumption and transcription callback execution.
|
||||
- The recognition manager's model lock protects engine and recognizer access
|
||||
during transcription, initialization, and cleanup. The segment queue is
|
||||
thread-safe; capture-buffer handoff uses its buffer lock.
|
||||
- Text callbacks enqueue work on a single post-processing worker so script
|
||||
execution and injection stay in spoken order. Clipboard restoration can run
|
||||
on a separate worker. `TextInjector` protects its injection and clipboard
|
||||
restore bookkeeping with locks and generation state.
|
||||
- Keyboard backends use listener or monitor threads for pynput and evdev.
|
||||
IBus and Remote Desktop Portal injection also use worker threads for their
|
||||
input and D-Bus work.
|
||||
- GLib timeouts drive UI polling and progress updates. Recognition and capture
|
||||
workers use their own queue and event waits rather than GTK timers.
|
||||
|
||||
## Speech engines
|
||||
|
||||
`common_types.SpeechEngine` defines the runtime-checkable engine contract.
|
||||
`speech_recognition/engines/available_engines()` reports optional engines in
|
||||
Settings display order without importing the large Whisper packages just to
|
||||
probe availability. `SettingsDialog` retains a compatibility wrapper for its
|
||||
legacy engine-to-availability mapping.
|
||||
|
||||
`SpeechRecognitionManager._process_audio_buffer()` uses an engine-name dispatch
|
||||
table to call the existing per-engine transcription methods. The manager owns
|
||||
engine selection, model lifecycle, segment language snapshots, and the model
|
||||
lock. Optional engine packages are loaded only when their engine is selected.
|
||||
|
||||
## Configuration and Settings
|
||||
|
||||
`ui/config_manager.py` defines `DEFAULT_CONFIG`, loads the user's JSON config,
|
||||
and recursively overlays saved values on those defaults. It persists changes
|
||||
through `save_config()`. Settings controls generally apply changes as they are
|
||||
made and use callbacks to update the running engine or related services; values
|
||||
that require a model reload take effect during that reload.
|
||||
|
||||
The Settings UI is split across `settings_dialog.py`, `settings_about.py`, and
|
||||
`settings_engines.py`. Other UI responsibilities live in focused modules such
|
||||
as `tray_indicator.py`, `dictation_overlay.py`, `transcription_history.py`,
|
||||
`keyboard_shortcuts.py`, and `keyboard_backends/`.
|
||||
|
||||
## Services and optional integrations
|
||||
|
||||
`dbus_service.py` owns the `com.vocalinux.Vocalinux` session-bus name and
|
||||
provides Toggle, Start, and Stop methods for external controls.
|
||||
`gateway_embed/` manages the optional local VocaGateway container lifecycle,
|
||||
status, pairing, and configuration. It is separate from the default
|
||||
on-device whisper.cpp engine.
|
||||
@@ -0,0 +1,116 @@
|
||||
# Arch User Repository (AUR)
|
||||
|
||||
## Users
|
||||
|
||||
```bash
|
||||
yay -S vocalinux # canonical release sdist, built against Arch dependencies
|
||||
yay -S vocalinux-git # community package; tracks main
|
||||
```
|
||||
|
||||
`vocalinux`, `vocalinux-bin` and `vocalinux-git` conflict; install only one.
|
||||
|
||||
`packaging/aur/vocalinux-bin/` builds a `-bin` variant that installs the
|
||||
prebuilt AppImage from the release — no Python, engine, or GPU dependency
|
||||
builds, since the bundle carries them (#817). Its publication waits only for
|
||||
release creation and both AppImages, not the source-package gate or other
|
||||
packaging jobs. It first pins the per-arch AppImage digests in the PKGBUILD,
|
||||
then pushes to AUR in the `Publish AUR -bin package` step.
|
||||
|
||||
## Maintainers (one-time setup)
|
||||
|
||||
Release tags prepare and test the source PKGBUILD from
|
||||
`packaging/aur/vocalinux/PKGBUILD`, then auto-push the verified file when these
|
||||
secrets exist:
|
||||
|
||||
| Secret | Value |
|
||||
|--------|--------|
|
||||
| `AUR_SSH_PRIVATE_KEY` | Private key whose public half is on your AUR account |
|
||||
| `AUR_USERNAME` | AUR username (git author) |
|
||||
| `AUR_EMAIL` | AUR account email |
|
||||
|
||||
```bash
|
||||
# 1. AUR account + SSH pubkey: https://aur.archlinux.org/register
|
||||
ssh-keygen -t ed25519 -C "vocalinux-aur" -f ./aur_ed25519 -N ""
|
||||
# upload aur_ed25519.pub on AUR; put aur_ed25519 in AUR_SSH_PRIVATE_KEY
|
||||
|
||||
# 2. Create empty package once
|
||||
git clone ssh://aur@aur.archlinux.org/vocalinux.git
|
||||
|
||||
# 3. Next v* tag runs Publish to AUR (skipped if secret missing)
|
||||
```
|
||||
|
||||
Sources: `packaging/aur/vocalinux/PKGBUILD`. Community git package: https://aur.archlinux.org/packages/vocalinux-git
|
||||
|
||||
## Source archive and trust model
|
||||
|
||||
The source package consumes the **canonical sdist attached to the GitHub release**,
|
||||
the same bytes published to PyPI, not GitHub's automatically generated tag archive.
|
||||
The sdist is produced by the locked reproducible-wheel gate. Only wheels are
|
||||
compared for reproducibility; sdists are built and validated, not compared.
|
||||
|
||||
`scripts/prepare_aur_source.py` verifies the downloaded sdist against the published
|
||||
`SHA256SUMS` and runs `gh attestation verify`, requiring the VocaHQ/vocalinux
|
||||
repository, `.github/workflows/release.yml` signer, exact tag ref, and expected
|
||||
source commit. Missing hashes, mismatches, rejected provenance, or mismatched
|
||||
tag/package versions stop preparation. It preserves the original archive bytes
|
||||
and pins their digest in the prepared PKGBUILD. `_tag` retains the release tag;
|
||||
`_version` is the PEP 440-normalized sdist version, including for prereleases.
|
||||
|
||||
This verification is a **maintainer publication gate**. An AUR user's `makepkg`
|
||||
checks the pinned SHA-256; it does not independently verify GitHub provenance.
|
||||
Arch still owns the dependency/toolchain versions: this does not claim that AUR
|
||||
builds use our Python lock or reproduce the PyPI wheel byte-for-byte.
|
||||
|
||||
## CI gates
|
||||
|
||||
### PR and local source gate
|
||||
|
||||
Python/AUR changes and changes to the source manifest, README or license build the
|
||||
canonical sdist from the current checkout's reproducible-wheel gate, then prepare
|
||||
an explicitly `--local-unattested` fixture. The `Build AUR package (gate)` job in
|
||||
`unified-pipeline.yml` builds and installs its PKGBUILD on `archlinux:latest`.
|
||||
Run `just aur-gate` locally (needs uv and Docker); it includes the reproducible-wheel
|
||||
build and uses a fresh temporary directory for the distributions, diagnostics,
|
||||
tooling and prepared fixture. Existing `dist/`, `build/reproducible-wheel/` and
|
||||
the developer environment are untouched, so other packaging commands can run
|
||||
before or after it. Successful runs clean the temporary directory; failed runs
|
||||
retain it and print its path for diagnosis.
|
||||
|
||||
### Release gate
|
||||
|
||||
After the release checksum/provenance job succeeds, `aur-source-test` downloads
|
||||
the **published** sdist and manifest, verifies them, and prepares the PKGBUILD.
|
||||
The same Arch gate makes `makepkg` download the actual source URL afresh
|
||||
(`AUR_FETCH_SOURCE=1`) and verify its checksum, runs `namcap` on the recipe and
|
||||
package, installs the package, checks the installed distribution version, and
|
||||
runs the import smoke. It does not rewrite the source URL or disable source
|
||||
checksum checks. The tested recipe and downloaded archive must match the
|
||||
prepared PKGBUILD and provenance-verified sdist byte-for-byte.
|
||||
|
||||
Only after this succeeds is `aur-source-pkgbuild` uploaded for `publish-aur`.
|
||||
Publication downloads that exact file; there is no version rewrite or
|
||||
`updpkgsums` afterwards. The gate runs even without AUR credentials; only the
|
||||
final push is secret-gated. This intentionally makes source publication wait
|
||||
for the release's checksums and attestations. `vocalinux-bin` uses a separate
|
||||
AppImage publication path independent of this source gate and the global
|
||||
checksum job; its PR smoke still uses a stub AppImage.
|
||||
|
||||
Both gates deliberately use rolling `archlinux:latest`: #757 was Arch's
|
||||
setuptools moving underneath us. `python-pywhispercpp` (virtual, provided by the
|
||||
AUR backends) and `python-pynput` (AUR) cannot come from the repos, so the gate
|
||||
satisfies them with a stub for dependency resolution and pip-installs their
|
||||
pinned versions from `requirements/runtime.txt` for the import smoke. It does
|
||||
not test those AUR providers or prove dependency completeness in a minimal host.
|
||||
What those providers actually ship remains a separate monitoring question.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**`ERROR Missing dependencies: setuptools<82`**
|
||||
|
||||
The AUR package builds with `python -m build --wheel --no-isolation`, so it uses Arch extra `python-setuptools` (currently 84). Vocalinux 0.16.1 drops the `<82` cap in `pyproject.toml`. Rebuild 0.16.1 or later.
|
||||
|
||||
**`'_pywhispercpp.whisper_full_params' object has no attribute 'context_params'`**
|
||||
|
||||
AUR `python-pywhispercpp-cpu` / `-cuda` / `-rocm` are still 1.4.x. Those wheels accept `context_params` in Python and then crash in the native object. 0.16.1 skips that argument on pywhispercpp older than 1.5 and still loads the model (default GPU, no device picker). PyPI and `install.sh` already use 1.5.0.
|
||||
|
||||
There is no AUR `python-pywhispercpp-vulkan` package. GPU Vulkan 1.5 is the `install.sh` / AppImage path, not the AUR python backends.
|
||||
@@ -0,0 +1,125 @@
|
||||
# Custom Dictionary Support Design
|
||||
|
||||
## Scope
|
||||
|
||||
Custom dictionary support has two separate jobs:
|
||||
|
||||
1. **Custom terms** bias local Whisper, whisper.cpp, and Faster Whisper recognition
|
||||
toward names and jargon.
|
||||
2. **Transcript corrections** deterministically replace a known misheard phrase
|
||||
after transcription.
|
||||
|
||||
They appear together on the **Custom Dictionary** Settings page, but are not
|
||||
interchangeable. A correction replacement does not implicitly become a prompt
|
||||
term. That coupling would make recognition bias depend on correction order and
|
||||
would make the external terms contract surprising.
|
||||
|
||||
## File contracts
|
||||
|
||||
Both files live in VocaLinux's XDG-aware configuration directory:
|
||||
`$XDG_CONFIG_HOME/vocalinux` (or `~/.config/vocalinux` when unset).
|
||||
|
||||
| File | Contract | Consumer |
|
||||
| --- | --- | --- |
|
||||
| `dictionary.txt` | UTF-8 (BOM accepted), one term per line. Blank lines and lines beginning with `#` are ignored. Terms are de-duplicated case-insensitively while retaining the first spelling. | VocaLinux and an external accessibility scanner. |
|
||||
| `custom-dictionary-corrections.json` | UTF-8 JSON object: `{"version": 1, "corrections": [{"heard": "super base", "replacement": "Supabase"}]}`. | VocaLinux only. |
|
||||
|
||||
The terms file remains deliberately simple and scanner-friendly. Corrections
|
||||
need two unambiguous fields, a version, and exact replacement casing, so JSON is
|
||||
used rather than overloading the line file with an ambiguous delimiter grammar.
|
||||
The UI writes either file by atomic replacement; a failed UI save preserves the
|
||||
old file and reports an error.
|
||||
|
||||
The application reads both files for each completed transcript. An externally
|
||||
edited file therefore takes effect on the next dictation segment without an app
|
||||
restart. Missing, unreadable, malformed, or unsupported correction files are
|
||||
ignored safely; dictation continues without their entries.
|
||||
|
||||
The terms file may contain any number of lines, but VocaLinux limits a single
|
||||
prompt to the first 200 valid terms and 2,000 characters. This bounds decoding
|
||||
work while leaving the scanner's complete line-file contract intact. The Custom
|
||||
Dictionary page keeps both an add/remove editor and a validated file chooser
|
||||
for the terms file.
|
||||
|
||||
## Processing and engine behavior
|
||||
|
||||
For every completed audio segment, VocaLinux applies this order:
|
||||
|
||||
1. The selected engine transcribes audio.
|
||||
2. Live phrase corrections run against the raw transcript.
|
||||
3. Voice-command interpretation runs on that corrected text.
|
||||
4. Remaining text and actions are dispatched.
|
||||
|
||||
Corrections run before commands so a correction can prevent a command-like
|
||||
misrecognition from being acted on. This also means users must not create a
|
||||
replacement that deliberately creates a voice command unless that is intended.
|
||||
|
||||
Corrections match literal phrases case-insensitively, only where the adjacent
|
||||
characters are not Unicode word characters (or common combining marks). Longer
|
||||
phrases win over shorter overlaps; equal-length entries retain JSON order.
|
||||
Replacement text is inserted exactly as written. Inputs are normalized to NFC
|
||||
for matching, so composed/decomposed accents are handled consistently.
|
||||
|
||||
| Engine | Custom terms | Corrections |
|
||||
| --- | --- | --- |
|
||||
| OpenAI Whisper | `initial_prompt` | Yes |
|
||||
| whisper.cpp | Advanced initial prompt followed by custom terms; explicit empty prompt clears reused native state | Yes |
|
||||
| Faster Whisper | `initial_prompt` | Yes |
|
||||
| VOSK | No prompt-bias API | Yes |
|
||||
| Parakeet | No prompt-bias API | Yes |
|
||||
| Remote API | No prompt is added to current request formats | Yes |
|
||||
|
||||
`--dictionary-file PATH` preserves the #767 session-only behavior: `PATH` is
|
||||
used as the custom terms file, it enables terms for that session, and Settings
|
||||
does not modify the saved terms file or enablement. Corrections remain loaded
|
||||
from the standard JSON file. The previous experimental #768
|
||||
`text_injection.custom_dictionary` config list is read only as a fallback until
|
||||
the JSON corrections file exists; it is never silently deleted or migrated.
|
||||
|
||||
The #767 persisted configuration keys are retained unchanged:
|
||||
`dictionary.enabled`, `dictionary.file_path` (default
|
||||
`~/.config/vocalinux/dictionary.txt`), and `dictionary.max_words`. Existing
|
||||
Peony settings therefore continue to select the scanner's `dictionary.txt`
|
||||
file. New configured paths are accepted only when they can be expanded and are
|
||||
either absent (so the UI can create them) or readable regular files; a failed
|
||||
save leaves the prior setting in place. Invalid configured and `--dictionary-file`
|
||||
paths are safely ignored and shown as unavailable rather than raising.
|
||||
|
||||
## Alternatives rejected
|
||||
|
||||
- **One mixed line file:** cannot express arbitrary phrases and replacements
|
||||
without reserving/escaping delimiters, which weakens the scanner contract.
|
||||
- **Corrections in `config.json`:** makes a scanner compete with application
|
||||
settings writes and offers no durable external-file schema.
|
||||
- **Post-command correction:** allows command-like transcription errors to be
|
||||
acted on before they can be fixed.
|
||||
- **Automatically adding correction replacements to prompts:** rejected because
|
||||
replacements are not automatically included in the recognition prompt;
|
||||
corrections work post-transcription on every engine.
|
||||
|
||||
## Human test checklist
|
||||
|
||||
1. Add `VocaLinux`, `PyGObject`, and a non-ASCII term in **Custom terms**;
|
||||
confirm `dictionary.txt` is UTF-8, one line per term, and an external
|
||||
edit changes the next Whisper, whisper.cpp, and Faster Whisper dictation segment.
|
||||
2. Add `super base` → `Supabase`; test lowercase, uppercase, punctuation, an
|
||||
overlapping short correction, `C++`, and non-ASCII text. Confirm replacement
|
||||
casing is exact and embedded text (for example `supersize`) is not replaced.
|
||||
3. With voice commands enabled, add a correction that changes a command-like
|
||||
misrecognition into ordinary text. Confirm it is injected rather than acted
|
||||
on. Also verify an intentionally command-like replacement is avoided.
|
||||
4. Edit each file externally while VocaLinux is running. Test an invalid JSON
|
||||
correction file and invalid UTF-8 terms file; confirm dictation continues and
|
||||
the Settings status/save feedback is clear.
|
||||
5. Test the UI with keyboard only: Add buttons via Enter, empty validation,
|
||||
update/remove feedback, narrow window, long entries, and high-contrast theme.
|
||||
6. Test all engines: Whisper, whisper.cpp, and Faster Whisper should use terms and
|
||||
corrections; VOSK, Parakeet, and remote API should use corrections only, with
|
||||
the VOSK terms warning.
|
||||
7. Start with `--dictionary-file /path/to/terms.txt`; confirm the session uses
|
||||
that file, Settings disables terms editing, saved settings remain unchanged,
|
||||
and corrections still apply.
|
||||
8. Start with an unresolved path such as `--dictionary-file ~missing-user/terms.txt`
|
||||
and configure an unreadable path through the file chooser. Confirm Settings
|
||||
reports the path safely, dictation continues without terms, and the prior
|
||||
saved `dictionary.file_path` remains intact.
|
||||
@@ -0,0 +1,563 @@
|
||||
# Linux distribution compatibility
|
||||
|
||||
How Vocalinux behaves across distributions, what is tested, and what to install manually when needed.
|
||||
|
||||
For install steps, prefer [INSTALL.md](INSTALL.md). Flatpak packaging (useful on immutable or non-standard layouts): [packaging/flatpak/README.md](../packaging/flatpak/README.md). Snap Store listing: [snapcraft.io/vocalinux](https://snapcraft.io/vocalinux) (`--edge`; pack/upload steps in [INSTALL.md](INSTALL.md)). Flatpak is not on Flathub: submission [flathub#9368](https://github.com/flathub/flathub/pull/9368) closed 2026-07-23 on policy grounds; channel tracked in [#167](https://github.com/VocaHQ/vocalinux/issues/167).
|
||||
|
||||
## Cross-distro behavior
|
||||
|
||||
The installer and launch wrappers handle most path differences.
|
||||
|
||||
### GI_TYPELIB_PATH detection
|
||||
|
||||
The installer uses a multi-step approach to detect the correct GI_TYPELIB_PATH:
|
||||
|
||||
1. **Primary Method**: Uses `pkg-config --variable=typelibdir gobject-introspection-1.0` (most reliable)
|
||||
2. **Fallback Paths**: Checks common distribution-specific paths in priority order:
|
||||
- Ubuntu/Debian multi-arch: `/usr/lib/x86_64-linux-gnu/girepository-1.0`
|
||||
- ARM64: `/usr/lib/aarch64-linux-gnu/girepository-1.0`
|
||||
- Fedora/RHEL: `/usr/lib64/girepository-1.0`
|
||||
- Arch/Generic: `/usr/lib/girepository-1.0`
|
||||
- Local installs: `/usr/local/lib/girepository-1.0`
|
||||
|
||||
3. **Architecture Support**: Detected paths for x86_64, ARM64, ARMHF, RISC-V, POWER, and s390x
|
||||
|
||||
### Wrapper Scripts
|
||||
|
||||
The installer creates wrapper scripts (`~/.local/bin/vocalinux` and `~/.local/bin/vocalinux-gui`) that:
|
||||
- Set the correct `GI_TYPELIB_PATH` environment variable
|
||||
- Handle input group permissions for Wayland keyboard shortcuts
|
||||
- Provide seamless cross-distro compatibility
|
||||
|
||||
### Desktop Entry
|
||||
|
||||
The `.desktop` entry is automatically configured with the detected `GI_TYPELIB_PATH`, ensuring the application launches correctly from the application menu regardless of distribution.
|
||||
|
||||
## Officially Supported Distributions
|
||||
|
||||
These distributions are tested and known to work well with Vocalinux. A
|
||||
derivative is judged by the Python and package repositories it ships rather
|
||||
than by its own version number, which rarely tracks the base release. In
|
||||
particular, `install.sh` does not interpret a Debian-based derivative's product
|
||||
version as a Debian release number.
|
||||
|
||||
| Distribution | Version | Status | Notes |
|
||||
|--------------|---------|--------|-------|
|
||||
| Ubuntu | 24.04+ | ✅ Full Support | 22.04 ships Python 3.10, below the 3.11 floor |
|
||||
| Debian | 12+, Testing | ✅ Full Support | Primary target; use Ayatana AppIndicator |
|
||||
| Fedora | 42+ | ✅ Good Support | Uses lib64 paths; 42 is the oldest Fedora upstream still supports, and the one in the CI matrix |
|
||||
| Arch Linux | Rolling | ✅ Good Support | Community tested, rolling release compatible |
|
||||
| openSUSE | Tumbleweed | ✅ Good Support | Good support with zypper package manager |
|
||||
| Linux Mint | On Ubuntu 24.04+ | ✅ Good Support | Mint 22 qualifies; Mint 21 is on Ubuntu 22.04, below the floor |
|
||||
| Pop!_OS | 24.04+ | ✅ Good Support | Uses Ubuntu's own numbering |
|
||||
| elementary OS | On Ubuntu 24.04+ | ✅ Good Support | elementary 8 qualifies; 7 is on Ubuntu 22.04 |
|
||||
| Zorin OS | On Ubuntu 24.04+ | ✅ Good Support | Zorin 17 is on Ubuntu 22.04, below the floor |
|
||||
| Manjaro | Rolling | ✅ Good Support | Arch base, inherits Arch compatibility |
|
||||
| EndeavourOS | Rolling | ✅ Good Support | Arch base, inherits Arch compatibility |
|
||||
|
||||
## Experimental Support
|
||||
|
||||
These distributions may work but have known limitations or are less tested:
|
||||
|
||||
| Distribution | Status | Known Issues |
|
||||
|--------------|--------|--------------|
|
||||
| Gentoo | ⚠️ Experimental | No package manager support, manual install required. Packages are compiled from source which takes longer. |
|
||||
| Alpine Linux | ⚠️ Experimental | Uses musl libc (not glibc). Some Python packages may not have pre-built wheels and may need to be compiled. |
|
||||
| Void Linux | ⚠️ Experimental | Untested, manual install required. Uses xbps package manager. |
|
||||
| Solus | ⚠️ Experimental | Untested, manual install required. Uses eopkg package manager. |
|
||||
| Mageia | ⚠️ Experimental | Untested, uses dnf/urpmi package managers. |
|
||||
|
||||
## Not Supported
|
||||
|
||||
These distributions are known to be incompatible:
|
||||
|
||||
| Distribution | Status | Reason |
|
||||
|--------------|--------|--------|
|
||||
| Debian 11 and earlier | ❌ Not Supported | EOL and below the Python 3.11 floor; the installer requires Debian 12+ |
|
||||
| NixOS | ❌ Not Supported | Completely different filesystem layout (/nix/store), incompatible with standard installer |
|
||||
|
||||
## Requirements by Distribution
|
||||
|
||||
These are baseline commands for manual installations. The exact inventory used
|
||||
by `install.sh`, including package alternatives and conditional dependencies,
|
||||
lives in [`scripts/distro-package-map.yaml`](../scripts/distro-package-map.yaml).
|
||||
For the complete manual setup sequence, including native build prerequisites,
|
||||
use [INSTALL_MANUAL.md](INSTALL_MANUAL.md#system-packages-by-distribution).
|
||||
|
||||
### Ubuntu/Debian-based
|
||||
```bash
|
||||
sudo apt install -y python3-gi gir1.2-gtk-3.0 gir1.2-ibus-1.0 gir1.2-gdkpixbuf-2.0 \
|
||||
portaudio19-dev python3-dev python3-venv pkg-config
|
||||
```
|
||||
|
||||
**Note for Debian 12+:** Use `gir1.2-ayatanaappindicator3-0.1` instead of `gir1.2-appindicator3-0.1`
|
||||
|
||||
### Debian-specific notes
|
||||
|
||||
Debian's standard repositories differ from Ubuntu in a few ways that matter for Vocalinux:
|
||||
|
||||
**pywhispercpp build prerequisites.** On a clean Debian install the following packages are not
|
||||
pulled in transitively (unlike Ubuntu) but are required when `pywhispercpp` must be compiled
|
||||
from source (e.g. for GPU support):
|
||||
|
||||
```bash
|
||||
sudo apt install -y libssl-dev autoconf automake libtool patchelf
|
||||
```
|
||||
|
||||
The installer now installs these automatically, but if you hit a CMake error like
|
||||
`Could not find OpenSSL` during a manual reinstall, add the above first.
|
||||
|
||||
**ydotool.** `ydotool` is not packaged in Debian's standard repos. The installer falls back
|
||||
gracefully to IBus or `wtype` for most Wayland compositors. KDE Plasma Wayland users should
|
||||
first select **IBus Wayland** in **System Settings -> Keyboard -> Virtual Keyboard**. If you
|
||||
specifically need `ydotool` as a fallback, compile it from source:
|
||||
|
||||
```bash
|
||||
sudo apt install -y git cmake libevdev-dev
|
||||
git clone https://github.com/ReimuNotMoe/ydotool.git /tmp/ydotool
|
||||
cmake -S /tmp/ydotool -B /tmp/ydotool/build
|
||||
sudo cmake --build /tmp/ydotool/build --target install
|
||||
sudo systemctl enable --now ydotoold
|
||||
```
|
||||
|
||||
**Scoped source builds.** If you need to force `pywhispercpp` to rebuild from source, use the
|
||||
package-scoped flag to avoid compiling unrelated deps like NumPy from source (which takes a very
|
||||
long time and can fail):
|
||||
|
||||
```bash
|
||||
source ~/.local/share/vocalinux/venv/bin/activate
|
||||
PYWHISPERCPP_CLEAN=1 pip install --force-reinstall --no-binary=pywhispercpp pywhispercpp
|
||||
deactivate
|
||||
```
|
||||
|
||||
**Verifying libwhisper.so resolution.** If Vocalinux starts with
|
||||
`libwhisper.so.1: cannot open shared object file`, check for unresolved symbols:
|
||||
|
||||
```bash
|
||||
ldd $(find ~/.local/share/vocalinux/venv -name '*.so' -path '*/pywhispercpp*' 2>/dev/null | head -1) | grep 'not found'
|
||||
```
|
||||
|
||||
If any libraries are listed, re-run the installer with `--rebuild-whispercpp` or switch to
|
||||
the VOSK engine (`--engine=vosk`) as a fully-packaged alternative.
|
||||
|
||||
### Fedora/RHEL-based
|
||||
```bash
|
||||
sudo dnf install -y python3-gobject gtk3-devel ibus-devel cairo-devel gobject-introspection-devel \
|
||||
portaudio-devel python3-devel python3-virtualenv pkg-config
|
||||
```
|
||||
|
||||
### Arch Linux-based
|
||||
```bash
|
||||
sudo pacman -S --needed python-gobject gtk3 ibus gobject-introspection \
|
||||
portaudio python pkg-config
|
||||
```
|
||||
|
||||
### openSUSE
|
||||
```bash
|
||||
PYVER=$(python3 -c 'import sys; print(f"python{sys.version_info.major}{sys.version_info.minor}")')
|
||||
|
||||
sudo zypper install -y \
|
||||
"${PYVER}-pip" "${PYVER}-gobject" "${PYVER}-gobject-cairo" \
|
||||
"${PYVER}-devel" "${PYVER}-virtualenv" \
|
||||
gtk3 ibus typelib-1_0-IBus-1_0 \
|
||||
typelib-1_0-AyatanaAppIndicator3-0_1 libayatana-appindicator3-1 \
|
||||
typelib-1_0-Notify-0_7 libnotify4 \
|
||||
gobject-introspection-devel portaudio-devel pkg-config cmake wget curl unzip \
|
||||
gcc gcc-c++ make patchelf \
|
||||
xdotool wtype
|
||||
|
||||
# Optional: only needed for whisper.cpp Vulkan GPU builds
|
||||
sudo zypper install -y vulkan-tools vulkan-devel shaderc
|
||||
```
|
||||
|
||||
**Note:** openSUSE Tumbleweed often uses versioned Python package names such as
|
||||
`python313-devel`. The `-devel` suffix means development headers for compiling
|
||||
native dependencies; it does **not** mean beta or unstable packages. If
|
||||
`${PYVER}-virtualenv` is unavailable on your snapshot, try `${PYVER}-venv`.
|
||||
|
||||
### Gentoo
|
||||
```bash
|
||||
sudo emerge dev-python/pygobject:3 x11-libs/gtk+:3 dev-libs/libayatana-appindicator \
|
||||
media-libs/portaudio dev-lang/python:3.11
|
||||
```
|
||||
|
||||
**Note:** Gentoo compiles packages from source, which will take longer.
|
||||
|
||||
### Alpine Linux
|
||||
```bash
|
||||
sudo apk add py3-gobject3 py3-pip gtk+3.0 py3-cairo portaudio-dev \
|
||||
py3-virtualenv pkgconf
|
||||
```
|
||||
|
||||
**Note:** Alpine uses musl libc. Some Python packages may need to be compiled from source.
|
||||
|
||||
### Void Linux
|
||||
```bash
|
||||
sudo xbps-install -Sy python3-pip python3-gobject gtk+3 libappindicator \
|
||||
gobject-introspection portaudio-devel python3-devel pkg-config
|
||||
```
|
||||
|
||||
### Solus
|
||||
```bash
|
||||
sudo eopkg install python3-pip python3-gobject gtk3 libappindicator \
|
||||
gobject-introspection-devel portaudio-devel python3-virtualenv pkg-config
|
||||
```
|
||||
|
||||
### Mageia
|
||||
```bash
|
||||
sudo dnf install -y python3-gobject gtk3-devel gobject-introspection-devel \
|
||||
portaudio-devel python3-devel python3-virtualenv pkg-config
|
||||
# or
|
||||
sudo urpmi -y python3-gobject gtk3-devel gobject-introspection-devel \
|
||||
portaudio-devel python3-devel python3-virtualenv pkg-config
|
||||
```
|
||||
|
||||
## PyPI, pip, and pipx Installation
|
||||
|
||||
The PyPI package is useful when you want a standard Python package install, or
|
||||
when you want to manage Vocalinux with `pipx`. However, **Vocalinux requires
|
||||
system desktop packages** that cannot be installed by pip or pipx.
|
||||
|
||||
Use the official installer when possible. It installs the required system
|
||||
packages, creates the virtual environment, installs Vocalinux, sets up desktop
|
||||
integration, and downloads the default speech model:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
### Important: Install System Packages First
|
||||
|
||||
Before running `pip install vocalinux`, `pip install "vocalinux[vosk]"`, or
|
||||
`pipx install vocalinux`, you **must** install the required system packages:
|
||||
|
||||
#### Ubuntu/Debian
|
||||
```bash
|
||||
sudo apt install python3-gi gir1.2-gtk-3.0 gir1.2-ibus-1.0 gir1.2-ayatanaappindicator3-0.1 \
|
||||
libgirepository1.0-dev libcairo2-dev portaudio19-dev python3-dev \
|
||||
python3-venv pkg-config xdotool wtype wl-clipboard xclip xsel
|
||||
```
|
||||
|
||||
On Ubuntu 24.04+ or Pop!_OS, install `libgirepository-2.0-dev` if
|
||||
`libgirepository1.0-dev` is not available.
|
||||
|
||||
#### Fedora
|
||||
```bash
|
||||
sudo dnf install python3-gobject gtk3 gtk3-devel ibus-devel cairo-devel libayatana-appindicator-gtk3 \
|
||||
gobject-introspection-devel portaudio-devel python3-devel \
|
||||
python3-virtualenv pkg-config xdotool wtype wl-clipboard xclip xsel
|
||||
```
|
||||
|
||||
#### Arch Linux
|
||||
```bash
|
||||
sudo pacman -S python-gobject gtk3 ibus libayatana-appindicator gobject-introspection \
|
||||
python-cairo portaudio python-virtualenv pkg-config xdotool wtype wl-clipboard xclip xsel
|
||||
```
|
||||
|
||||
#### openSUSE
|
||||
```bash
|
||||
PYVER=$(python3 -c 'import sys; print(f"python{sys.version_info.major}{sys.version_info.minor}")')
|
||||
|
||||
sudo zypper install "${PYVER}-gobject" "${PYVER}-gobject-cairo" gtk3 ibus typelib-1_0-IBus-1_0 \
|
||||
gcc gcc-c++ make patchelf \
|
||||
typelib-1_0-AyatanaAppIndicator3-0_1 libayatana-appindicator3-1 \
|
||||
typelib-1_0-Notify-0_7 libnotify4 \
|
||||
portaudio-devel "${PYVER}-devel" "${PYVER}-virtualenv" pkg-config xdotool wtype wl-clipboard xclip xsel
|
||||
```
|
||||
|
||||
### pip Installation Steps
|
||||
|
||||
1. **Install system packages** (see above for your distribution)
|
||||
|
||||
2. **Create a virtual environment with system site-packages enabled**:
|
||||
```bash
|
||||
python3 -m venv ~/.local/share/vocalinux-pypi/venv --system-site-packages
|
||||
source ~/.local/share/vocalinux-pypi/venv/bin/activate
|
||||
pip install --upgrade pip setuptools wheel
|
||||
```
|
||||
|
||||
`--system-site-packages` lets the venv use distro-provided GTK bindings such
|
||||
as `python3-gi`, which are often more reliable than building PyGObject from
|
||||
source in a venv.
|
||||
|
||||
3. **Install Vocalinux from PyPI**:
|
||||
```bash
|
||||
pip install vocalinux
|
||||
# vosk engine: pip install "vocalinux[vosk]"
|
||||
```
|
||||
|
||||
4. **Run Vocalinux**:
|
||||
```bash
|
||||
vocalinux
|
||||
```
|
||||
|
||||
### pipx Installation Steps
|
||||
|
||||
1. **Install system packages** (see above for your distribution)
|
||||
|
||||
2. **Install pipx** (if not already installed):
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt install pipx
|
||||
pipx ensurepath
|
||||
|
||||
# Fedora
|
||||
sudo dnf install pipx
|
||||
pipx ensurepath
|
||||
|
||||
# Arch Linux
|
||||
sudo pacman -S pipx
|
||||
pipx ensurepath
|
||||
```
|
||||
|
||||
3. **Install Vocalinux**:
|
||||
```bash
|
||||
pipx install vocalinux
|
||||
# vosk engine: pipx install "vocalinux[vosk]"
|
||||
```
|
||||
|
||||
4. **Run Vocalinux**:
|
||||
```bash
|
||||
vocalinux
|
||||
```
|
||||
|
||||
### Why System Packages Are Required
|
||||
|
||||
Vocalinux uses GTK3 for its GUI, AppIndicator/Ayatana for the system tray icon,
|
||||
PortAudio for microphone capture, and tools such as `xdotool`, `wtype`, and clipboard utilities (`wl-clipboard`, `xclip`, `xsel`) for
|
||||
text injection and layout-independent Wayland paste fallback. These are system libraries and desktop tools that must be
|
||||
installed with your distribution's package manager. Python packages from PyPI
|
||||
can provide Python bindings, but they do not provide the underlying GTK
|
||||
typelibs, tray support, audio development libraries, or text injection binaries.
|
||||
|
||||
### Troubleshooting pip/pipx Installation
|
||||
|
||||
If `vocalinux` fails to start:
|
||||
|
||||
1. **Check for missing system packages** - The error message will indicate which packages are missing
|
||||
2. **Verify GI_TYPELIB_PATH** - In rare cases, you may need to set this environment variable:
|
||||
```bash
|
||||
export GI_TYPELIB_PATH=/usr/lib/x86_64-linux-gnu/girepository-1.0
|
||||
vocalinux
|
||||
```
|
||||
3. **Check package metadata** - Run `pip show vocalinux` or
|
||||
`pipx runpip vocalinux show vocalinux` to confirm which version was installed.
|
||||
4. **Check Python dependencies** - Run `pip check` inside the venv, or
|
||||
`pipx runpip vocalinux check` for pipx.
|
||||
|
||||
If Vocalinux reports that a speech recognition model is missing, open Settings
|
||||
and download a model, or use the official installer to download the default model
|
||||
during setup.
|
||||
|
||||
### Recommended Alternative
|
||||
|
||||
For the best experience with automatic dependency handling, use the official installer:
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
This installer automatically detects your distribution and installs all required system packages.
|
||||
|
||||
## Text Injection Tools
|
||||
|
||||
Vocalinux requires text injection tools to work with X11 or Wayland:
|
||||
|
||||
### For X11
|
||||
- **xdotool**: Required for X11 sessions
|
||||
|
||||
### For Wayland
|
||||
- **IBus**: Recommended for KDE Plasma Wayland and generally the most reliable direct text input path
|
||||
- **wtype**: Recommended for wlroots-style Wayland compositors such as sway
|
||||
- **ydotool**: Universal alternative that works with both X11 and Wayland. Current distro packages use the per-user `ydotool.service`; source builds can install the system-level `ydotoold.service`. Vocalinux uses clipboard paste with `wl-clipboard`, `xclip`, or `xsel` to avoid non-US layout scrambling.
|
||||
- **xdotool**: May work via XWayland fallback
|
||||
|
||||
### Installation by Distribution
|
||||
```bash
|
||||
# Ubuntu/Debian/Fedora/Arch/openSUSE
|
||||
sudo apt install xdotool wtype wl-clipboard xclip xsel # Ubuntu/Debian
|
||||
sudo dnf install xdotool wtype wl-clipboard xclip xsel # Fedora
|
||||
sudo pacman -S xdotool wtype wl-clipboard xclip xsel # Arch
|
||||
sudo zypper install xdotool wtype wl-clipboard xclip xsel # openSUSE
|
||||
```
|
||||
|
||||
Ubuntu releases which package `ydotool` install a **user** unit named
|
||||
`ydotool.service`. Enable it only for the account running Vocalinux:
|
||||
|
||||
```bash
|
||||
sudo apt install ydotool
|
||||
sudo usermod -aG input $USER # then log out and back in
|
||||
systemctl --user enable --now ydotool.service
|
||||
```
|
||||
|
||||
Do **not** use `sudo systemctl --global enable ydotool.service`. Global user-unit
|
||||
enablement also starts the input-injection daemon for the display-manager greeter
|
||||
and other accounts. If it was previously enabled globally, repair the setup with:
|
||||
|
||||
```bash
|
||||
sudo systemctl --global disable ydotool.service
|
||||
systemctl --user enable --now ydotool.service
|
||||
```
|
||||
|
||||
The command is different for the Debian source-build path documented above: the
|
||||
upstream install supplies the system unit `ydotoold.service`, so
|
||||
`sudo systemctl enable --now ydotoold.service` is correct only for that route.
|
||||
|
||||
## Manual Installation
|
||||
|
||||
For unsupported or experimental distributions:
|
||||
|
||||
1. **Run the dependency checker:**
|
||||
```bash
|
||||
bash scripts/check-system-deps.sh
|
||||
```
|
||||
|
||||
2. **Install missing dependencies** using your package manager based on the checker output
|
||||
|
||||
3. **Run the installer with --skip-system-deps:**
|
||||
```bash
|
||||
./install.sh --skip-system-deps
|
||||
```
|
||||
|
||||
4. **Or install from source in a virtual environment:**
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -e .[whisper]
|
||||
```
|
||||
|
||||
## Desktop Environment Compatibility
|
||||
|
||||
| Desktop Environment | Status | Notes |
|
||||
|---------------------|--------|-------|
|
||||
| GNOME | ✅ Full Support | Primary target, uses AppIndicator |
|
||||
| KDE Plasma | ✅ Full Support | On Wayland, select IBus Wayland in System Settings -> Keyboard -> Virtual Keyboard |
|
||||
| Xfce | ✅ Full Support | Works with AppIndicator |
|
||||
| Cinnamon | ✅ Full Support | Works with AppIndicator |
|
||||
| MATE | ✅ Full Support | Works with AppIndicator |
|
||||
| LXQt | ✅ Full Support | Works with AppIndicator |
|
||||
| sway | ✅ Good Support | Wayland native, uses wtype |
|
||||
| i3 | ✅ Good Support | X11, uses xdotool |
|
||||
| Hyprland | ⚠️ Experimental | Wayland, may need wtype configuration |
|
||||
|
||||
### Autostart Compatibility
|
||||
|
||||
Vocalinux uses **XDG autostart desktop entries** for "Start on Login".
|
||||
|
||||
- Desktop-session autostart file location:
|
||||
- `$XDG_CONFIG_HOME/autostart/vocalinux.desktop`, or
|
||||
- `~/.config/autostart/vocalinux.desktop` (fallback)
|
||||
- This launches Vocalinux as a user GUI app after login.
|
||||
- Vocalinux does **not** create a `systemd` service/unit for this feature.
|
||||
|
||||
Practical caveat:
|
||||
|
||||
- Mainstream desktop environments generally honor XDG autostart.
|
||||
- Minimal/custom WM sessions may need an explicit autostart manager or WM startup hook.
|
||||
|
||||
## Display Server
|
||||
|
||||
| Display Server | Status | Notes |
|
||||
|----------------|--------|-------|
|
||||
| X11 | ✅ Full Support | Uses xdotool for text injection |
|
||||
| Wayland | ✅ Full Support | Uses IBus, wtype, ydotool, or xdotool fallback depending on compositor |
|
||||
| XWayland | ✅ Full Support | Automatically detected, falls back to xdotool if needed |
|
||||
|
||||
## Architecture Support
|
||||
|
||||
| Architecture | Status | Notes |
|
||||
|--------------|--------|-------|
|
||||
| x86_64 (AMD64) | ✅ Full Support | Primary target |
|
||||
| arm64 (AArch64) | ✅ Good Support | Tested on Raspberry Pi, ARM64 servers |
|
||||
| armhf | ⚠️ Experimental | Limited testing |
|
||||
| riscv64 | ⚠️ Experimental | Limited testing, may need to compile dependencies |
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
When reporting issues, please include:
|
||||
|
||||
1. **Distribution information:**
|
||||
```bash
|
||||
cat /etc/os-release
|
||||
```
|
||||
|
||||
2. **Desktop environment:**
|
||||
```bash
|
||||
echo $XDG_CURRENT_DESKTOP
|
||||
echo $SESSION_TYPE
|
||||
```
|
||||
|
||||
3. **Dependency checker output:**
|
||||
```bash
|
||||
bash scripts/check-system-deps.sh
|
||||
```
|
||||
|
||||
4. **Python version:**
|
||||
```bash
|
||||
python3 --version
|
||||
```
|
||||
|
||||
5. **Error messages or logs:**
|
||||
- Any error messages from the installer
|
||||
- Output from running `vocalinux-gui` from terminal
|
||||
- Relevant journal logs if applicable
|
||||
|
||||
6. **Steps to reproduce:**
|
||||
- What you were trying to do
|
||||
- What happened instead
|
||||
- Expected behavior
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
Use this checklist when testing on a new distribution:
|
||||
|
||||
### Pre-Install
|
||||
- [ ] Run dependency checker: `bash scripts/check-system-deps.sh`
|
||||
- [ ] Note missing packages
|
||||
- [ ] Check desktop environment
|
||||
- [ ] Check display server (X11/Wayland)
|
||||
|
||||
### Installation
|
||||
- [ ] Run installer: `./install.sh`
|
||||
- [ ] Check for errors during installation
|
||||
- [ ] Verify virtual environment was created
|
||||
- [ ] Check wrapper scripts exist
|
||||
|
||||
### Post-Install
|
||||
- [ ] Launch from terminal: `~/.local/bin/vocalinux-gui`
|
||||
- [ ] Launch from application menu
|
||||
- [ ] Verify tray icon appears
|
||||
- [ ] Test keyboard shortcuts (Hold Right Alt by default)
|
||||
- [ ] Test audio recording
|
||||
- [ ] Test text injection in different applications
|
||||
- [ ] Test Settings dialog opens correctly
|
||||
- [ ] Test model download if using Whisper
|
||||
|
||||
### Known Issues to Watch For
|
||||
- AppIndicator not showing in tray
|
||||
- Audio device not detected
|
||||
- Text injection not working
|
||||
- Model download failures
|
||||
- Permission errors with udev/input
|
||||
|
||||
## Contributing Compatibility Fixes
|
||||
|
||||
If you successfully get Vocalinux working on an unsupported or experimental distribution:
|
||||
|
||||
1. Test thoroughly using the checklist above
|
||||
2. Document any distribution-specific requirements
|
||||
3. Submit a PR with:
|
||||
- Distribution detection logic (if needed)
|
||||
- Package installation commands
|
||||
- Any patches or workarounds required
|
||||
- Update to this compatibility document
|
||||
|
||||
## See also
|
||||
|
||||
- [Installation guide](INSTALL.md)
|
||||
- [Manual / PyPI install](INSTALL_MANUAL.md)
|
||||
- [Troubleshooting](TROUBLESHOOTING.md)
|
||||
- [User guide](USER_GUIDE.md)
|
||||
- [Update guide](UPDATE.md)
|
||||
- [GitHub issue tracker](https://github.com/VocaHQ/vocalinux/issues)
|
||||
@@ -0,0 +1,141 @@
|
||||
# Self-hosted Flatpak remote
|
||||
|
||||
Vocalinux publishes a signed OSTree Flatpak remote on every stable `v*` tag —
|
||||
the Homebrew-tap analogue to `VocaHQ/homebrew-vocamac`
|
||||
([issue #785](https://github.com/VocaHQ/vocalinux/issues/785)). The remote
|
||||
lives in the dedicated repo `VocaHQ/vocalinux-flatpak`, served by GitHub
|
||||
Pages:
|
||||
|
||||
```bash
|
||||
flatpak install https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref
|
||||
flatpak update # picks up each new release
|
||||
```
|
||||
|
||||
The `.flatpakref` adds the `vocahq` remote (via `SuggestRemoteName=`) and lets
|
||||
flatpak resolve `org.gnome.Platform//50` through its `RuntimeRepo=` pointer to
|
||||
Flathub — one command, no separate Flathub setup. The equivalent manual
|
||||
steps:
|
||||
|
||||
```bash
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
|
||||
flatpak install vocahq com.vocalinux.Vocalinux
|
||||
```
|
||||
|
||||
Only the app is ours; the GNOME runtime still comes from Flathub —
|
||||
`RuntimeRepo=` is a `.flatpakref` key (it is ignored on `.flatpakrepo`, which
|
||||
is why the app ref carries it, not the remote descriptor). GitHub Release
|
||||
`.flatpak` bundles ([#784](https://github.com/VocaHQ/vocalinux/issues/784))
|
||||
remain as a no-auto-update fallback, and are the only Flatpak path for
|
||||
prerelease tags, which never reach the remote.
|
||||
|
||||
## Maintainer setup (one time)
|
||||
|
||||
1. **Repo** — create `VocaHQ/vocalinux-flatpak` (public).
|
||||
2. **Pages** — Settings → Pages → "Deploy from a branch" → branch `gh-pages`,
|
||||
folder `/ (root)`. The first publish creates the branch, so Pages can be
|
||||
pointed at it afterwards; creating an empty `gh-pages` upfront works too.
|
||||
3. **Signing key** — OSTree remotes sign the summary and commits with GPG:
|
||||
|
||||
```bash
|
||||
gpg --quick-gen-key "Vocalinux Flatpak <flatpak@vocahq.com>" ed25519 sign never
|
||||
gpg --list-secret-keys # note the KEYID
|
||||
gpg --export-secret-keys --armor KEYID # -> FLATPAK_GPG_PRIVATE_KEY
|
||||
gpg --gen-revoke KEYID > flatpak-remote-revoke.asc # store it somewhere safe
|
||||
```
|
||||
|
||||
A passphrase-less key keeps CI simplest — libostree signs through
|
||||
gpg-agent, which has no `--passphrase-fd` to reach for. A passphrase works
|
||||
too: set `FLATPAK_GPG_PASSPHRASE` and the workflow presets it onto the
|
||||
keygrip via `gpg-preset-passphrase`.
|
||||
4. **Secrets on `VocaHQ/vocalinux`** (Settings → Secrets and variables →
|
||||
Actions):
|
||||
- `FLATPAK_GPG_PRIVATE_KEY` — the armored private key
|
||||
- `FLATPAK_GPG_PASSPHRASE` — optional
|
||||
- `FLATPAK_REPO_TOKEN` — a token with Contents: read and write on
|
||||
`VocaHQ/vocalinux-flatpak`. The fine-grained PAT scoped to just that
|
||||
repo is the recommended minimum; a broader classic PAT works too.
|
||||
5. **Variables (optional)** — same settings page, Variables tab:
|
||||
- `FLATPAK_REMOTE_REPO` — publish target (default
|
||||
`VocaHQ/vocalinux-flatpak`)
|
||||
- `FLATPAK_REMOTE_URL` — remote URL baked into the `.flatpakrepo`
|
||||
(default `https://vocahq.github.io/vocalinux-flatpak/repo`; set
|
||||
e.g. `https://flatpak.vocalinux.com/repo` for a custom domain)
|
||||
- `FLATPAKREPO_URL` — where users fetch `vocahq.flatpakrepo` (default
|
||||
`https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo`)
|
||||
- `FLATPAKREF_URL` — where users fetch the app `.flatpakref` (default
|
||||
`https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref`)
|
||||
6. **Trigger** — push a stable `v*` tag (alpha/beta/rc tags do not publish to
|
||||
the remote), or re-run `publish-flatpak-remote` on an existing release run
|
||||
after configuring the secrets.
|
||||
|
||||
Without the secrets the job skips itself (same pattern as `publish-aur`), so
|
||||
an unconfigured remote never fails a release.
|
||||
|
||||
## How a publish works
|
||||
|
||||
`release.yml → publish-flatpak-remote` runs on stable tags only, after the
|
||||
GitHub Release exists and the two arch builds finish:
|
||||
|
||||
1. Downloads `Vocalinux-<version>-{x86_64,aarch64}.flatpak` from the build
|
||||
jobs.
|
||||
2. Probes the remote repo for an existing `gh-pages` branch; only a confirmed
|
||||
first publish may skip the history checkout — a transient failure aborts
|
||||
instead of seeding an empty repo over the live remote. It then checks out
|
||||
`gh-pages` and copies `repo/` over, so existing objects and deltas
|
||||
survive — clients pull an incremental delta each release, not the whole
|
||||
app.
|
||||
3. `flatpak build-import-bundle --gpg-sign` imports each bundle under the
|
||||
signing key.
|
||||
4. `flatpak build-update-repo --generate-static-deltas --gpg-sign
|
||||
--gpg-import` rebuilds the summary, signs it, and generates static deltas.
|
||||
5. Regenerates `vocahq.flatpakrepo` (URL + base64 public key),
|
||||
`com.vocalinux.Vocalinux.flatpakref` (the one-command app ref carrying the
|
||||
`RuntimeRepo=` pointer to Flathub), `vocahq.gpg` (the bare public key, for
|
||||
the key-rotation path below), and the index page from
|
||||
`packaging/flatpak/index.html`.
|
||||
6. Publishes the directory back to `gh-pages` via
|
||||
`peaceiris/actions-gh-pages`.
|
||||
|
||||
## Verifying a publish
|
||||
|
||||
```bash
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
|
||||
flatpak remote-info vocahq com.vocalinux.Vocalinux # signed commit, both arches
|
||||
flatpak install vocahq com.vocalinux.Vocalinux
|
||||
flatpak run com.vocalinux.Vocalinux
|
||||
# after the next tag: flatpak update pulls the delta
|
||||
```
|
||||
|
||||
## Key rotation and loss
|
||||
|
||||
Generate a fresh key, replace `FLATPAK_GPG_PRIVATE_KEY` (and
|
||||
`FLATPAK_GPG_PASSPHRASE` if used), then re-run `publish-flatpak-remote`. The
|
||||
published `.flatpakrepo`/`.flatpakref` then carry the new `GPGKey=`, so new
|
||||
installs trust it immediately.
|
||||
|
||||
Existing installs must import the new key into the remote's trusted keyring —
|
||||
re-running `remote-add` does **not** replace it (with `--if-not-exists` it
|
||||
does nothing at all), and `flatpak update` fails verification until the key
|
||||
is updated. Point users at the public key published beside the repo:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://vocahq.github.io/vocalinux-flatpak/vocahq.gpg -o /tmp/vocahq.gpg
|
||||
flatpak remote-modify --gpg-import=/tmp/vocahq.gpg vocahq
|
||||
flatpak update
|
||||
```
|
||||
|
||||
`remote-modify --gpg-import` adds the key — the old one stays trusted, which
|
||||
is what makes a routine rotation seamless. To *revoke* a leaked key, drop the
|
||||
remote's keyring instead: delete and re-add the remote (installed apps keep
|
||||
their `vocahq` origin and update normally afterwards):
|
||||
|
||||
```bash
|
||||
flatpak remote-delete --force vocahq # --force: the remote is still in use
|
||||
flatpak remote-add vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
|
||||
flatpak update
|
||||
```
|
||||
|
||||
Either way is worth a line in that release's notes. The revoke certificate is
|
||||
for the day the key leaks, not for routine rotation.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Local VocaGateway from Vocalinux (optional)
|
||||
|
||||
Vocalinux can start a **local** [VocaGateway](https://github.com/VocaHQ/vocagateway)
|
||||
container from **Settings → Speech Model → Advanced**, next to Remote Server. This is an
|
||||
optional power-user path. It is **not** on-device processing: microphone audio
|
||||
still leaves the desktop client and is transcribed by the gateway process on
|
||||
your machine (or LAN).
|
||||
|
||||
The default speech engine remains **whisper.cpp** on-device. Enabling a local
|
||||
gateway never changes that default by itself. Use **Use this Gateway** only when
|
||||
you want Vocalinux to talk to the gateway over the existing Remote API settings
|
||||
(`remote_api_*`, endpoint `/v1/audio/transcriptions`). See [HTTP_REMOTE.md](HTTP_REMOTE.md).
|
||||
|
||||
## Requirements (Linux MVP)
|
||||
|
||||
- **podman** (preferred) or **docker**, with a working `compose` plugin (or
|
||||
`podman-compose` / `docker-compose`).
|
||||
- Vocalinux does **not** bundle a container engine inside the AppImage.
|
||||
- **Flatpak**: the sandbox cannot reach the host container socket. Run the
|
||||
native package or AppImage, or start VocaGateway on the host yourself and
|
||||
point Remote Server at it.
|
||||
|
||||
## What Vocalinux does
|
||||
|
||||
1. Pins upstream **VocaGateway `v0.1.0`** (git tag) under your XDG cache and uses
|
||||
that checkout's `compose.yaml` with Compose project name `vocagateway`.
|
||||
2. Writes a private bootstrap token under `~/.config/vocalinux/gateway_embed/`
|
||||
(mode `600`) and a matching Compose `.env`.
|
||||
3. Runs `compose -f compose.yaml --profile cpu up -d` for the `gateway` service.
|
||||
The v0.1.0 GitHub release has no published container image assets, so the first
|
||||
start **builds** the local image `vocagateway:v0.1.0` from that tag (override with
|
||||
`VOCAGATEWAY_IMAGE`; never `latest`). Later starts reuse the image/volume.
|
||||
4. Polls `GET /health/live` and `GET /health/ready`, and (when live) authenticated
|
||||
`GET /v1/admin/pairing` for phone pairing.
|
||||
5. Stops with `compose down` **without** `-v`, so the named data volume (models,
|
||||
config) is kept.
|
||||
|
||||
## Status labels
|
||||
|
||||
| Status | Meaning |
|
||||
| --- | --- |
|
||||
| Stopped | Not running. |
|
||||
| Starting | Compose up in progress, or live probe not green yet. |
|
||||
| Live | Process answers `/health/live`. |
|
||||
| Pairable | Live, plus a **non-loopback** phone URL and bearer token (QR-safe). |
|
||||
| Ready | `/health/ready` is 200 (model selected in the gateway WebUI). |
|
||||
| Error | Start/stop or probe failure (see the subtitle). |
|
||||
|
||||
Pairable can appear before Ready: you can pair a phone while a model is still
|
||||
downloading.
|
||||
|
||||
## LAN / phone
|
||||
|
||||
By default the published host is `127.0.0.1` (desktop-only). Turn on **Allow LAN
|
||||
access for Phone** to set `VOCAGATEWAY_PUBLISH_HOST=0.0.0.0` and to advertise a
|
||||
LAN URL in pairing. Open port `8765` in your firewall only on trusted networks.
|
||||
Never put `127.0.0.1` / `localhost` in the phone QR. If a LAN toggle fails,
|
||||
compose keeps the previous bind, Vocalinux restores the embed `.env`, and the
|
||||
switch snaps back with an error (Stop and Run again, or retry).
|
||||
|
||||
## Tray and Quit
|
||||
|
||||
The tray menu offers **Stop local Gateway** whenever compose is actually running
|
||||
(Starting, Live, Pairable, Ready, or Error), including a leftover from a previous
|
||||
Vocalinux session. Vocalinux does not auto-start the gateway on login in v1.
|
||||
|
||||
**Quit does not stop compose.** The pinned compose file uses `restart:
|
||||
unless-stopped`, so a LAN-published gateway on `0.0.0.0:8765` keeps running after
|
||||
you quit Vocalinux. The next launch restores the Allow LAN switch from the running
|
||||
compose publish host. Use **Stop local Gateway** in Settings or the tray when you
|
||||
want it gone. Do not assume Quit tears it down.
|
||||
|
||||
## Honesty
|
||||
|
||||
VocaGateway is optional self-hosted infrastructure for the Voca family. There is
|
||||
no Voca account and no hosted Voca cloud. Prefer a trusted LAN, Tailscale, or
|
||||
HTTPS. Do not expose port 8765 to the public internet.
|
||||
@@ -0,0 +1,282 @@
|
||||
# Remote HTTP transcription
|
||||
|
||||
Vocalinux can offload speech recognition to a remote HTTP server instead of running a local model. Use this when you want faster transcription on a more powerful machine, to share one model across clients, or to keep a laptop free of GPU/model overhead.
|
||||
|
||||
Vocalinux speaks two wire formats out of the box:
|
||||
|
||||
- **OpenAI-compatible**: `POST /v1/audio/transcriptions` (e.g. OpenAI, [Speaches](https://github.com/speaches-ai/speaches), LocalAI, FunASR/SenseVoice)
|
||||
- **whisper.cpp server**: `POST /inference` (the binary shipped with [whisper.cpp](https://github.com/ggerganov/whisper.cpp))
|
||||
|
||||
Pick whichever your server exposes. The rest of this guide applies to both.
|
||||
|
||||
> **Tip: share the server with your phone.** These HTTP formats are open enough that the same self-hosted server can also back mobile dictation apps. On Android, apps like *Dictate* and *Transcribro* speak OpenAI-compatible Whisper; on iOS, Shortcuts-based dictation clients can hit the same endpoint. Run one Whisper server, point your laptop and phone at it, and you get consistent dictation everywhere without uploading audio to a third party.
|
||||
|
||||
## Local VocaGateway (optional)
|
||||
|
||||
On Linux you can start an optional local [VocaGateway](https://github.com/VocaHQ/vocagateway) from **Settings → Speech Model → Advanced** (podman-first, docker fallback). That path uses the same Remote API settings described below, with endpoint `/v1/audio/transcriptions`. It is **not** on-device recognition: audio goes to the gateway container on your machine. Details: [GATEWAY_EMBED.md](GATEWAY_EMBED.md).
|
||||
|
||||
## How it works
|
||||
|
||||
When the **Remote API** engine is active, Vocalinux:
|
||||
|
||||
1. Captures microphone audio locally (16 kHz, mono, 16-bit PCM).
|
||||
2. On end-of-utterance, packages the buffer as a WAV file in memory.
|
||||
3. Uploads it using the configured HTTP format.
|
||||
4. Reads the transcribed text from the JSON response and types it into the focused window.
|
||||
|
||||
No audio is written to disk. VAD and segmentation stay local; only the heavy ASR step is remote.
|
||||
|
||||
## Server-side setup
|
||||
|
||||
You need a server that accepts audio uploads and returns text. Three common setups:
|
||||
|
||||
### Option A: whisper.cpp server
|
||||
|
||||
Build and run the bundled HTTP server from the [whisper.cpp](https://github.com/ggerganov/whisper.cpp) repo:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ggerganov/whisper.cpp
|
||||
cd whisper.cpp
|
||||
make server
|
||||
./models/download-ggml-model.sh medium.en
|
||||
./build/bin/whisper-server \
|
||||
--model models/ggml-medium.en.bin \
|
||||
--host 0.0.0.0 \
|
||||
--port 8080
|
||||
```
|
||||
|
||||
The server now listens on `http://<server-ip>:8080`. The endpoint is `/inference`.
|
||||
|
||||
### Option B: OpenAI-compatible server (Speaches, LocalAI, etc.)
|
||||
|
||||
Run any server that implements `POST /v1/audio/transcriptions`. Example with [Speaches](https://github.com/speaches-ai/speaches):
|
||||
|
||||
```bash
|
||||
docker run --rm -p 8000:8000 ghcr.io/speaches-ai/speaches:latest
|
||||
```
|
||||
|
||||
The endpoint is `/v1/audio/transcriptions`.
|
||||
|
||||
### Option C: FunASR/SenseVoice local server
|
||||
|
||||
[FunASR](https://github.com/modelscope/FunASR) can run a local
|
||||
OpenAI-compatible transcription service, which keeps audio on your own machine
|
||||
or LAN while letting Vocalinux use SenseVoice or Paraformer-family models:
|
||||
|
||||
```bash
|
||||
pip install 'torch>=2.13.0' torchaudio
|
||||
pip install funasr vllm fastapi uvicorn python-multipart
|
||||
funasr-server --device cuda
|
||||
```
|
||||
|
||||
The server listens on `http://localhost:8000` by default and exposes
|
||||
`POST /v1/audio/transcriptions`. In Vocalinux, set:
|
||||
|
||||
- **Server URL**: `http://localhost:8000`
|
||||
- **API Endpoint**: `OpenAI/FunASR (/v1/audio/transcriptions)`
|
||||
- **Model**: `sensevoice`
|
||||
|
||||
Use `--device cpu` for CPU-only testing if your FunASR install supports it. A
|
||||
remote GPU host works too: bind the server to the LAN interface, open the port,
|
||||
and point Vocalinux at that host.
|
||||
|
||||
### Network checklist
|
||||
|
||||
- The server must be reachable from the client over HTTP or HTTPS.
|
||||
- If you bind to `0.0.0.0`, open the port in your firewall (`ufw allow 8080/tcp`, etc.).
|
||||
- For anything outside a trusted LAN, terminate TLS in front of the server (Caddy, nginx, Traefik) and require an API key. The audio you upload is private speech.
|
||||
- If you also use the server from a mobile dictation app, terminate TLS even on a LAN. Most Android and iOS apps refuse cleartext HTTP.
|
||||
|
||||
## Client-side setup (Vocalinux)
|
||||
|
||||
### Via the Settings dialog
|
||||
|
||||
The remote engine is a power-user option in the **Speech Engine** settings.
|
||||
|
||||
1. Launch Vocalinux and open **Settings → Speech Engine → Remote Server**.
|
||||
2. Toggle **Use remote server** on. This overrides whatever local engine is selected above it.
|
||||
3. Fill in the fields:
|
||||
- **Server URL**: base URL of the server, e.g. `http://192.168.1.100:8080` (no trailing slash needed; one is stripped automatically).
|
||||
- **API Key** (optional): sent as `Authorization: Bearer <key>`. Leave blank if your server doesn't require auth.
|
||||
- **API Endpoint**: pick **Whisper.cpp (`/inference`)** or **OpenAI/FunASR (`/v1/audio/transcriptions`)** to match your server.
|
||||
- **Model**: model identifier sent to OpenAI-compatible servers. Use `whisper-1` for classic Whisper servers, or `sensevoice` for FunASR/SenseVoice.
|
||||
4. Click **Test Connection**. Success means the URL is reachable and credentials (if any) are accepted. A failure here is only a warning; Vocalinux will try again on the first transcription.
|
||||
|
||||
Settings auto-save and re-initialise the engine immediately, so you can start dictating as soon as the test passes. Toggling the switch off restores the local engine selected on the Speech Engine page in Settings.
|
||||
|
||||
### Via the config file
|
||||
|
||||
The same options live in `~/.config/vocalinux/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"speech_recognition": {
|
||||
"engine": "remote_api",
|
||||
"remote_api_url": "http://192.168.1.100:8080",
|
||||
"remote_api_key": "",
|
||||
"remote_api_endpoint": "/inference",
|
||||
"remote_api_model": "whisper-1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Restart Vocalinux after editing the file by hand.
|
||||
|
||||
FunASR/SenseVoice example:
|
||||
|
||||
```json
|
||||
{
|
||||
"speech_recognition": {
|
||||
"engine": "remote_api",
|
||||
"remote_api_url": "http://localhost:8000",
|
||||
"remote_api_key": "",
|
||||
"remote_api_endpoint": "/v1/audio/transcriptions",
|
||||
"remote_api_model": "sensevoice"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Wire protocol reference
|
||||
|
||||
If you're writing a custom server, this is exactly what the client sends.
|
||||
|
||||
### Request (whisper.cpp format, `/inference`)
|
||||
|
||||
```
|
||||
POST {server_url}/inference HTTP/1.1
|
||||
Authorization: Bearer <api_key> # only if configured
|
||||
Content-Type: multipart/form-data; boundary=...
|
||||
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="file"; filename="audio.wav"
|
||||
Content-Type: audio/wav
|
||||
|
||||
<WAV bytes: 16 kHz, mono, 16-bit PCM>
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="temperature"
|
||||
|
||||
0.0
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="temperature_inc"
|
||||
|
||||
0.2
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="response_format"
|
||||
|
||||
json
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="language"
|
||||
|
||||
en
|
||||
--boundary--
|
||||
```
|
||||
|
||||
### Request (OpenAI-compatible format, `/v1/audio/transcriptions`)
|
||||
|
||||
```
|
||||
POST {server_url}/v1/audio/transcriptions HTTP/1.1
|
||||
Authorization: Bearer <api_key>
|
||||
Content-Type: multipart/form-data; boundary=...
|
||||
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="file"; filename="audio.wav"
|
||||
Content-Type: audio/wav
|
||||
|
||||
<WAV bytes>
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="model"
|
||||
|
||||
whisper-1
|
||||
--boundary
|
||||
Content-Disposition: form-data; name="language"
|
||||
|
||||
en
|
||||
--boundary--
|
||||
```
|
||||
|
||||
### Response (`/inference` and `/v1/audio/transcriptions`)
|
||||
|
||||
```json
|
||||
{ "text": "the transcribed utterance" }
|
||||
```
|
||||
|
||||
For OpenAI-compatible FunASR/SenseVoice wrappers, extra metadata is allowed and
|
||||
ignored by Vocalinux:
|
||||
|
||||
```json
|
||||
{
|
||||
"text": "the transcribed utterance",
|
||||
"language": "en",
|
||||
"emotion": "neutral",
|
||||
"segments": [
|
||||
{ "text": "the transcribed utterance", "start": 0.0, "end": 1.4 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
If `text` is not present, Vocalinux also accepts `transcript`, `transcription`,
|
||||
or a `segments` list with per-segment `text` fields. If a SenseVoice wrapper
|
||||
returns rich labels inline, for example `<|en|><|NEUTRAL|><|Speech|>hello`,
|
||||
Vocalinux strips the leading labels before text injection.
|
||||
|
||||
Empty utterances should return `{"text": ""}`. HTTP 4xx/5xx responses are surfaced as transcription errors in the Vocalinux log.
|
||||
|
||||
### Language handling
|
||||
|
||||
- Vocalinux's UI language `auto` is sent as **no `language` field** (server auto-detects).
|
||||
- `en-us` is normalised to `en`.
|
||||
- Anything else is forwarded verbatim.
|
||||
|
||||
### Timeouts
|
||||
|
||||
- Connection test: **5 s**
|
||||
- Transcription request: **30 s**
|
||||
|
||||
A request that exceeds the transcription timeout is logged and dropped; the next utterance is sent fresh.
|
||||
|
||||
## Verifying with `curl`
|
||||
|
||||
Quick sanity check without launching the GUI:
|
||||
|
||||
```bash
|
||||
# Whisper.cpp server
|
||||
curl -F file=@sample.wav \
|
||||
-F temperature=0.0 \
|
||||
-F response_format=json \
|
||||
http://192.168.1.100:8080/inference
|
||||
|
||||
# OpenAI-compatible
|
||||
curl -H "Authorization: Bearer $API_KEY" \
|
||||
-F file=@sample.wav \
|
||||
-F model=whisper-1 \
|
||||
http://192.168.1.100:8000/v1/audio/transcriptions
|
||||
|
||||
# FunASR/SenseVoice
|
||||
curl -F file=@sample.wav \
|
||||
-F model=sensevoice \
|
||||
http://localhost:8000/v1/audio/transcriptions
|
||||
```
|
||||
|
||||
The multipart endpoints should return JSON with a text field or one of the
|
||||
compatible response shapes above.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Likely cause | Fix |
|
||||
|---|---|---|
|
||||
| Connection test reports "failed" | Wrong host/port, firewall, or server not running | Check `curl <url>` from the client; check server logs |
|
||||
| HTTP 401/403 | API key missing or wrong | Set the **API Key** field; ensure the server is configured for that key |
|
||||
| HTTP 404 on first send | Endpoint format mismatch | Switch the **API Endpoint** dropdown to the format your server actually exposes |
|
||||
| FunASR/SenseVoice server returns model errors | Model field does not match the served model | Try `sensevoice`, `paraformer`, or the exact model configured on the server |
|
||||
| SenseVoice labels appear in injected text | Wrapper returned labels somewhere other than the leading transcript prefix | Return plain text in `text` and put language/emotion/speech labels in JSON metadata |
|
||||
| Transcription always empty | Server rejected the WAV (sample rate, channels) | Confirm server accepts 16 kHz mono 16-bit WAV; check server logs |
|
||||
| First transcription is slow | Cold model load on the server | Warm the server before dictating, or increase the client timeout server-side |
|
||||
| Garbled text in foreign language | Wrong `language` setting | Set the language explicitly in Settings instead of `auto` |
|
||||
|
||||
Logs live at `~/.local/share/vocalinux/vocalinux.log` (or wherever your `XDG_DATA_HOME` points). Look for lines tagged `Remote API` for client-side detail.
|
||||
|
||||
## Security notes
|
||||
|
||||
- The API key is stored in plain JSON in `~/.config/vocalinux/config.json`. Treat that file the same way you treat any other secret on disk.
|
||||
- Audio is sent as raw WAV. Anyone on the wire can hear it, so use HTTPS outside a fully trusted network.
|
||||
- Vocalinux does **not** validate TLS certificate pins; standard system trust is used. Self-signed certs require importing the CA into your system trust store.
|
||||
@@ -0,0 +1,348 @@
|
||||
# Installation guide
|
||||
|
||||
How to install Vocalinux on Linux. Short overview: [project README](../README.md).
|
||||
|
||||
| Path | When to use |
|
||||
|------|-------------|
|
||||
| [Recommended installer](#recommended-installer) | Most users |
|
||||
| [AppImage](#appimage) | Portable binary; no system package install |
|
||||
| [Distro packages (.deb / .rpm)](#distro-packages-deb--rpm) | Debian 12+, Ubuntu 24.04+, Fedora |
|
||||
| [AUR](#arch-linux-aur) | Arch / Manjaro |
|
||||
| [Flatpak](#flatpak) | Release `.flatpak` or local build |
|
||||
| [Snap](#snap-ubuntu-snap-store) | Ubuntu Snap Store (`--edge`) or GitHub `.snap` |
|
||||
| [Nix](#nix--nixos) | Flake package, Home Manager, or the NixOS module |
|
||||
| [From source](#from-source) | Contributors or custom trees |
|
||||
| [Manual / PyPI](INSTALL_MANUAL.md) | Full control or pip-only workflows |
|
||||
| [Troubleshooting](TROUBLESHOOTING.md) | Tray, audio, injection, models |
|
||||
|
||||
## Recommended installer
|
||||
|
||||
Download, review if you like, then run:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
Installs the latest release with **whisper.cpp** by default. For a pinned version, see [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases) or pass `--tag=...`.
|
||||
|
||||
The installer:
|
||||
|
||||
- Installs whisper.cpp (typically ~1-2 minutes; no full PyTorch stack)
|
||||
- Detects GPU / Vulkan (AMD, Intel, NVIDIA)
|
||||
- Installs neural VAD when ONNX Runtime is available
|
||||
- Downloads the default whisper.cpp tiny model (~74MB), verified against pinned checksums
|
||||
- Sets up desktop integration and launch wrappers
|
||||
|
||||
The source installer uses committed, hash-verified Python dependency exports,
|
||||
including its pip and source-build tools. GTK/PyGObject still comes from your
|
||||
distribution, and the venv retains access to system packages. A missing export
|
||||
or unavailable pinned package causes that installation step to fail; the
|
||||
existing optional-engine and VAD fallbacks still apply.
|
||||
|
||||
Remote installs run the installer from the selected release tag. Older tags
|
||||
therefore retain their original dependency-install behavior; downloading a new
|
||||
bootstrap script does not change an older release's pins.
|
||||
|
||||
### Installer modes
|
||||
|
||||
```bash
|
||||
./install.sh # Interactive (recommended)
|
||||
./install.sh --auto # Defaults: whisper.cpp
|
||||
./install.sh --auto --engine=whisper # OpenAI Whisper
|
||||
./install.sh --auto --engine=faster_whisper # Faster Whisper (CPU)
|
||||
./install.sh --auto --engine=vosk # VOSK only
|
||||
./install.sh --auto --engine=parakeet # Parakeet (CPU)
|
||||
./install.sh --auto --engine=remote_api # Remote HTTP API
|
||||
./install.sh --dev # Editable install + test tools
|
||||
./install.sh --help # Full flag list
|
||||
```
|
||||
|
||||
| Engine | When to use | Typical install |
|
||||
|--------|-------------|-----------------|
|
||||
| **whisper.cpp** (default) | Best default; Vulkan GPU | ~1-2 min, ~74MB model |
|
||||
| **Whisper** (OpenAI) | PyTorch / CUDA | ~5-10 min, large download |
|
||||
| **Faster Whisper** | CPU Whisper via CTranslate2 / INT8 | Model sizes like OpenAI Whisper |
|
||||
| **VOSK** | Low RAM / minimal | ~30 sec, ~40MB |
|
||||
| **Parakeet** | CPU; 25 European languages | Model ~639MB |
|
||||
| **Remote API** | User-configured HTTP server | No local model |
|
||||
|
||||
Useful flags: `--tag=TAG`, `--skip-models`, `--rebuild-whispercpp`, `--no-rebuild-whispercpp`, `--venv-dir=PATH`, `--test`.
|
||||
|
||||
`--engine=NAME` accepts `whisper_cpp` (default), `whisper`, `faster_whisper`, `vosk`, `parakeet`, `remote_api`.
|
||||
|
||||
### What the installer does
|
||||
|
||||
1. Detects the distribution and installs system packages
|
||||
2. Creates a Python venv from the system interpreter with `--system-site-packages` (for distro GTK / PyGObject)
|
||||
3. Installs Vocalinux and the chosen speech engine
|
||||
4. Optionally installs neural VAD (`onnxruntime`)
|
||||
5. Downloads a default speech model (checksum-verified)
|
||||
6. Installs icons, desktop entry, and `~/.local/bin` wrappers
|
||||
|
||||
## AppImage
|
||||
|
||||
From [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases):
|
||||
|
||||
```bash
|
||||
chmod +x Vocalinux-*-x86_64.AppImage # or aarch64
|
||||
./Vocalinux-*-x86_64.AppImage
|
||||
```
|
||||
|
||||
Built against glibc 2.35, so it starts on Debian 12+, Ubuntu 22.04+, Fedora 36+, Arch, and Tumbleweed. Older bases (RHEL 9, Debian 11, Ubuntu 20.04) are below that AppImage floor. The installer and PyPI package still require a distro that ships Python 3.11+, so they are not a workaround for Debian 11 or Ubuntu 20.04.
|
||||
|
||||
Still needs host text-injection tools (`xdotool` on X11; `wtype` / `ydotool` / clipboard tools on Wayland). Current AppImages rebuild whisper.cpp with Vulkan and use the host GPU driver (`vulkaninfo --summary`). Prefer the installer when you want system deps, a CUDA build, and models set up automatically.
|
||||
|
||||
## Distro packages (.deb / .rpm)
|
||||
|
||||
From [GitHub Releases](https://github.com/VocaHQ/vocalinux/releases), pick the file matching your distro and CPU:
|
||||
|
||||
```bash
|
||||
# Debian / Ubuntu (amd64; arm64 files are attached too)
|
||||
sudo apt install ./vocalinux_*_amd64.deb
|
||||
|
||||
# Fedora (x86_64; aarch64 files are attached too)
|
||||
sudo dnf install ./vocalinux-*.x86_64.rpm
|
||||
```
|
||||
|
||||
These are thin packages: Python, GTK, PyGObject and the AppIndicator typelib come from the distribution, and `apt`/`dnf` resolves them. `xdotool`, `wtype`, `ydotool`, the clipboard tools and IBus are `Recommends`, matching the optional feature set of the other paths. Only `pywhispercpp` and `pynput` are vendored inside the package — `pywhispercpp` is packaged by neither distro and `pynput` is missing on Fedora. They land under `/usr/lib/vocalinux/vendor`, on `sys.path` via the `vocalinux` launcher.
|
||||
|
||||
The `.deb` needs a distro that ships Python 3.11+: Debian 12+ and Ubuntu 24.04+ (Ubuntu 22.04 ships 3.10). whisper.cpp runs on CPU in these packages — the PyPI wheel, not the Vulkan build the AppImage carries. There is no auto-update: a new release is a new package install. A PPA and a COPR are not published yet.
|
||||
|
||||
On Wayland, the default Right Alt shortcut reads keyboard devices through evdev, so your user needs `input` group membership or the hotkey is silently disabled:
|
||||
|
||||
```bash
|
||||
sudo usermod -aG input $USER # then log out and back in
|
||||
```
|
||||
|
||||
Joining `input` grants read access to every keyboard and pointer device — X11 needs none of this. The launcher re-execs through `sg input` when `/etc/group` already lists the membership but the current session has not picked it up, so an `usermod` between package install and next login applies without a reboot. The source installer does this step for you; the packages cannot.
|
||||
|
||||
## Arch Linux (AUR)
|
||||
|
||||
```bash
|
||||
yay -S vocalinux
|
||||
```
|
||||
|
||||
See [AUR.md](AUR.md).
|
||||
|
||||
## Flatpak
|
||||
|
||||
Install and auto-update via the self-hosted VocaHQ remote (`flatpak update` picks up each release):
|
||||
|
||||
```bash
|
||||
flatpak install https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref
|
||||
```
|
||||
|
||||
The `.flatpakref` adds the `vocahq` remote and resolves the GNOME runtime through Flathub. Manually instead:
|
||||
|
||||
```bash
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --if-not-exists vocahq https://vocahq.github.io/vocalinux-flatpak/vocahq.flatpakrepo
|
||||
flatpak install vocahq com.vocalinux.Vocalinux
|
||||
```
|
||||
|
||||
Or sideload a GitHub Release bundle (`Vocalinux-<version>-x86_64.flatpak` or `-aarch64.flatpak`) after the Flathub GNOME runtime is present — bundles do not auto-update:
|
||||
|
||||
```bash
|
||||
flatpak install --user ./Vocalinux-<version>-x86_64.flatpak
|
||||
```
|
||||
|
||||
Local build (contributors):
|
||||
|
||||
```bash
|
||||
flatpak install flathub org.gnome.Platform//50 org.gnome.Sdk//50
|
||||
flatpak-builder --user --install --force-clean build-dir \
|
||||
packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
flatpak run com.vocalinux.Vocalinux
|
||||
```
|
||||
|
||||
Whisper.cpp + Vulkan. It is **not on Flathub** (submission [flathub#9368](https://github.com/flathub/flathub/pull/9368) closed 2026-07-23 on policy grounds). Details: [packaging/flatpak/README.md](../packaging/flatpak/README.md).
|
||||
|
||||
On native X11, hotkeys work without device access (GNOME X11 is the exception:
|
||||
its X server hides physical keys from the X11 listener, so it also needs
|
||||
`/dev/input`). On Wayland, the built-in hotkey needs `/dev/input` (`--device=input` on Flatpak 1.15.6 or newer, or
|
||||
`--device=all` on older versions); otherwise enable External Activation and
|
||||
bind a desktop shortcut to the D-Bus `Toggle` command in
|
||||
[Running without device access](../packaging/flatpak/README.md#running-without-device-access).
|
||||
Desktop shortcuts only toggle dictation, so they cannot support push-to-talk.
|
||||
|
||||
## Snap (Ubuntu Snap Store)
|
||||
|
||||
Listing: [snapcraft.io/vocalinux](https://snapcraft.io/vocalinux) (issue [#48](https://github.com/VocaHQ/vocalinux/issues/48)). Recipe: `snap/snapcraft.yaml`. Tagged `v*` releases attach `vocalinux_<version>_amd64.snap` to the GitHub Release and try Snap Store `edge` and `candidate` when credentials are set. `stable` is promoted from `candidate` after QA.
|
||||
|
||||
Build inputs, the PR/release artifact gate, and its verification limits are
|
||||
documented in [SNAP.md](SNAP.md).
|
||||
|
||||
Store install, once Canonical lists the revision:
|
||||
|
||||
```bash
|
||||
sudo snap install vocalinux --edge
|
||||
sudo snap connect vocalinux:audio-record # if mic is not auto-connected
|
||||
sudo snap connect vocalinux:raw-input # global keyboard shortcuts (evdev)
|
||||
sudo snap connect vocalinux:hardware-observe # list keyboards (/proc/bus/input/devices)
|
||||
```
|
||||
|
||||
Native Wayland typing uses the RemoteDesktop portal: the compositor asks once on first dictation, nothing to connect. The recipe ships **no `uinput` plug** and no ydotool; the Store denied the super-privileged grant ([the request thread](https://forum.snapcraft.io/t/53528)), which held the 0.17.0+ revisions and left **v0.16.2 (rev 7)** on edge. On KDE Plasma, KWin's portal can mistype letter case ([KDE bug 489021](https://bugs.kde.org/show_bug.cgi?id=489021)); set Virtual Keyboard to "IBus Wayland" so dictation types correctly.
|
||||
|
||||
Under strict confinement the snap reaches audio through the PulseAudio/PipeWire server, not the sound card, so Settings → Audio lists the server's microphones (via `pactl`) and records from the one you pick. whisper.cpp in the snap is built without a GPU backend and runs on the CPU, and host tools such as `nvidia-smi` and `vulkaninfo` are not visible inside it. For Vulkan acceleration use the [AppImage](#appimage) or the [installer](#recommended-installer) instead.
|
||||
|
||||
GitHub `.snap` files through v0.18.2 declare `uinput`, so KDE users who want ydotool can sideload that build and connect the plug manually:
|
||||
|
||||
```bash
|
||||
sudo snap install --dangerous ./vocalinux_0.18.2_amd64.snap
|
||||
sudo snap connect vocalinux:audio-record
|
||||
sudo snap connect vocalinux:raw-input
|
||||
sudo snap connect vocalinux:hardware-observe
|
||||
sudo snap connect vocalinux:uinput # only in the v0.18.x sideload; the recipe no longer ships it
|
||||
```
|
||||
|
||||
`--dangerous` is required because this file is not a Store revision and will not refresh from the Store; once the Store carries a newer revision, `sudo snap install vocalinux --edge` (or `snap refresh`) replaces it.
|
||||
|
||||
## Nix / NixOS
|
||||
|
||||
The repo is a flake: GTK, PyGObject and the AppIndicator typelib come from nixpkgs, and `pywhispercpp` (absent from nixpkgs, same gap as Debian and Fedora) is built from its vendored PyPI sdist. The wrapped binary carries every injector and clipboard tool on PATH.
|
||||
|
||||
```bash
|
||||
nix run github:VocaHQ/vocalinux # try it
|
||||
nix profile install github:VocaHQ/vocalinux
|
||||
```
|
||||
|
||||
On NixOS, `vocalinux.nixosModules.vocalinux` provides `programs.vocalinux.enable`, which installs the package and enables `hardware.uinput`. Add each dictating user to `input` and `uinput` for Wayland shortcuts and ydotool typing. Home Manager users get `vocalinux.homeManagerModules.vocalinux` with the same `programs.vocalinux` options — device permissions stay on the system side. Usage snippets and scope notes: [packaging/nix/README.md](../packaging/nix/README.md).
|
||||
|
||||
## From source
|
||||
|
||||
```bash
|
||||
git clone https://github.com/VocaHQ/vocalinux.git
|
||||
cd vocalinux
|
||||
./install.sh
|
||||
```
|
||||
|
||||
## System requirements
|
||||
|
||||
| Requirement | Details |
|
||||
|-------------|---------|
|
||||
| **OS** | Ubuntu 24.04+, Debian 12+, Fedora 42+, Arch, openSUSE Tumbleweed |
|
||||
| **Python** | 3.11 or newer |
|
||||
| **Display** | X11 or Wayland |
|
||||
| **Hardware** | Microphone; GPU optional (Vulkan) |
|
||||
| **Disk** | ~200MB with default whisper.cpp model |
|
||||
| **RAM** | 4GB minimum; 8GB comfortable |
|
||||
|
||||
The distro must ship Python 3.11+ because Vocalinux uses distro PyGObject (`python3-gi`). Ubuntu 22.04 (Python 3.10) and Debian 11 (3.9) are below that floor. Distro matrix: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
|
||||
|
||||
### GPU (optional)
|
||||
|
||||
whisper.cpp uses Vulkan when available (AMD, Intel, NVIDIA). Check with `vulkaninfo --summary`.
|
||||
|
||||
## Running Vocalinux
|
||||
|
||||
```bash
|
||||
vocalinux # if ~/.local/bin is on PATH
|
||||
~/.local/share/vocalinux/venv/bin/vocalinux # direct
|
||||
source venv/bin/activate && vocalinux # source checkout
|
||||
```
|
||||
|
||||
Or launch from the application menu.
|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
vocalinux --help
|
||||
vocalinux --version
|
||||
vocalinux --debug
|
||||
vocalinux --engine whisper_cpp
|
||||
vocalinux --engine whisper
|
||||
vocalinux --engine vosk
|
||||
vocalinux --engine parakeet
|
||||
vocalinux --engine remote_api
|
||||
vocalinux --model tiny
|
||||
vocalinux --model medium.en-q5_0
|
||||
vocalinux --model large-v3-turbo
|
||||
vocalinux --wayland
|
||||
vocalinux --start-minimized
|
||||
```
|
||||
|
||||
## Autostart
|
||||
|
||||
**Start on Login** writes an XDG autostart desktop entry (`~/.config/autostart/`). It does not install a systemd unit. Enable from the first-run dialog, tray menu, or Settings.
|
||||
|
||||
## Data locations (XDG)
|
||||
|
||||
| Directory | Purpose |
|
||||
|-----------|---------|
|
||||
| `~/.config/vocalinux/` | Configuration |
|
||||
| `~/.local/share/vocalinux/` | Data and speech models |
|
||||
| `~/.local/share/applications/` | Desktop entry |
|
||||
| `~/.local/share/icons/hicolor/scalable/apps/` | Icons |
|
||||
|
||||
## whisper.cpp (default engine)
|
||||
|
||||
Default engine: C++ Whisper port with Vulkan GPU support and lower install cost than the PyTorch Whisper stack.
|
||||
|
||||
| Size | Approx. | Use |
|
||||
|------|---------|-----|
|
||||
| tiny | ~74MB | Fast dictation (default) |
|
||||
| base | ~141MB | Balance |
|
||||
| small | ~465MB | Better accuracy |
|
||||
| medium | ~1.5GB | High accuracy |
|
||||
| large | ~3.0GB | Best accuracy |
|
||||
|
||||
In Settings → Speech Model, simple setup steers language and speed/accuracy. Expand **Advanced** for engine, **Model Size**, and **Specialization** (multilingual, English-only, quantized, Turbo, legacy large). More detail: [USER_GUIDE.md](USER_GUIDE.md).
|
||||
|
||||
Reuse an existing `pywhispercpp` build:
|
||||
|
||||
```bash
|
||||
./install.sh --auto # reuse if present
|
||||
./install.sh --auto --rebuild-whispercpp # force rebuild
|
||||
```
|
||||
|
||||
Switch engines in Settings → Speech Model (Advanced), or edit `~/.config/vocalinux/config.json` (`engine`: `whisper_cpp` | `whisper` | `vosk` | `parakeet` | `remote_api`).
|
||||
|
||||
## Uninstall
|
||||
|
||||
From a source checkout, `./uninstall.sh` removes the install and that checkout's `venv/`, `build/`, `dist/`, and Python bytecode. `--keep-config` and `--keep-data` leave `~/.config/vocalinux` and `~/.local/share/vocalinux` in place.
|
||||
|
||||
```bash
|
||||
./uninstall.sh
|
||||
./uninstall.sh --keep-config
|
||||
./uninstall.sh --keep-data
|
||||
```
|
||||
|
||||
The website command downloads this same script and runs it:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/uninstall.sh -o /tmp/vul.sh
|
||||
bash /tmp/vul.sh
|
||||
```
|
||||
|
||||
That removes Vocalinux from your home directory (config, data, launchers, desktop entry, icons). It does not delete `venv/`, `build/`, `dist/`, or `.pyc` files in the directory where you ran it.
|
||||
|
||||
From the source checkout, the equivalent by hand:
|
||||
|
||||
```bash
|
||||
rm -rf venv ~/.config/vocalinux ~/.local/share/vocalinux
|
||||
rm -f activate-vocalinux.sh
|
||||
rm -f ~/.local/share/applications/vocalinux.desktop
|
||||
rm -f ~/.local/share/icons/hicolor/scalable/apps/vocalinux*.svg
|
||||
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor
|
||||
```
|
||||
|
||||
## Update
|
||||
|
||||
See [UPDATE.md](UPDATE.md).
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
## More documentation
|
||||
|
||||
| Doc | Contents |
|
||||
|-----|----------|
|
||||
| [INSTALL_MANUAL.md](INSTALL_MANUAL.md) | Manual install, PyPI/pipx, per-distro packages |
|
||||
| [TROUBLESHOOTING.md](TROUBLESHOOTING.md) | Common failures and fixes |
|
||||
| [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md) | Support matrix |
|
||||
| [USER_GUIDE.md](USER_GUIDE.md) | Day-to-day use |
|
||||
| [SUPPORT.md](../SUPPORT.md) | Where to get help |
|
||||
| [Documentation index](README.md) | Full list |
|
||||
@@ -0,0 +1,194 @@
|
||||
# Manual installation and PyPI
|
||||
|
||||
Use this when the [recommended installer](INSTALL.md) is not a fit, or you want an explicit package list. Prefer `./install.sh` for a normal desktop install.
|
||||
|
||||
The commands below are human-readable baselines for manual installs. The
|
||||
installer's authoritative package inventory, including build helpers and
|
||||
fallbacks, is [`scripts/distro-package-map.yaml`](../scripts/distro-package-map.yaml).
|
||||
Its generated shell module is committed so installations do not need a YAML
|
||||
parser.
|
||||
|
||||
Related: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md), [TROUBLESHOOTING.md](TROUBLESHOOTING.md).
|
||||
|
||||
## System packages by distribution
|
||||
|
||||
Install desktop/system dependencies **before** creating a venv or running `pip install vocalinux`. Pip cannot install GTK typelibs, AppIndicator, PortAudio, or text-injection tools.
|
||||
|
||||
Debian 11 and earlier are unsupported; the Debian instructions start at Debian
|
||||
12, which is the oldest release with the required Python 3.11.
|
||||
|
||||
### Ubuntu
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y \
|
||||
python3-pip python3-venv python3-dev \
|
||||
python3-gi python3-gi-cairo \
|
||||
gir1.2-gtk-3.0 gir1.2-ibus-1.0 \
|
||||
libgirepository1.0-dev libcairo2-dev portaudio19-dev \
|
||||
build-essential pkg-config cmake libssl-dev autoconf automake libtool patchelf \
|
||||
wget curl unzip
|
||||
|
||||
# Tray: older Ubuntu → gir1.2-appindicator3-0.1
|
||||
# newer Ubuntu → gir1.2-ayatanaappindicator3-0.1
|
||||
sudo apt install -y gir1.2-ayatanaappindicator3-0.1
|
||||
|
||||
sudo apt install -y xdotool # X11
|
||||
sudo apt install -y wtype wl-clipboard xclip xsel # Wayland helpers
|
||||
```
|
||||
|
||||
On Ubuntu 24.04+ or Pop!_OS, install `libgirepository-2.0-dev` if `libgirepository1.0-dev` is missing.
|
||||
|
||||
### Debian 12
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y \
|
||||
python3-pip python3-venv python3-dev \
|
||||
python3-gi python3-gi-cairo \
|
||||
gir1.2-gtk-3.0 gir1.2-ibus-1.0 \
|
||||
libgirepository1.0-dev libcairo2-dev portaudio19-dev \
|
||||
build-essential pkg-config cmake libssl-dev autoconf automake libtool patchelf \
|
||||
wget curl unzip \
|
||||
gir1.2-ayatanaappindicator3-0.1 \
|
||||
xdotool wtype wl-clipboard xclip xsel
|
||||
```
|
||||
|
||||
### Debian 13+
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y \
|
||||
python3-pip python3-venv python3-dev \
|
||||
python3-gi python3-gi-cairo \
|
||||
gir1.2-gtk-3.0 gir1.2-ibus-1.0 \
|
||||
libgirepository-2.0-dev libcairo2-dev portaudio19-dev \
|
||||
build-essential pkg-config cmake libssl-dev autoconf automake libtool patchelf \
|
||||
wget curl unzip \
|
||||
gir1.2-ayatanaappindicator3-0.1 \
|
||||
xdotool wtype wl-clipboard xclip xsel
|
||||
```
|
||||
|
||||
Debian notes (OpenSSL build deps, ydotool, etc.): [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
|
||||
|
||||
### Fedora
|
||||
|
||||
```bash
|
||||
sudo dnf install -y \
|
||||
python3-pip python3-devel python3-virtualenv \
|
||||
python3-gobject gtk3 ibus-devel libayatana-appindicator-gtk3 \
|
||||
gobject-introspection-devel portaudio-devel cairo-devel \
|
||||
gcc gcc-c++ make pkg-config cmake patchelf \
|
||||
wget curl unzip xdotool wtype wl-clipboard xclip xsel
|
||||
```
|
||||
|
||||
### Arch Linux
|
||||
|
||||
Prefer the AUR package (`yay -S vocalinux`). Manual packages:
|
||||
|
||||
```bash
|
||||
sudo pacman -S --needed \
|
||||
python-pip python-gobject gtk3 ibus \
|
||||
libayatana-appindicator gobject-introspection \
|
||||
python-cairo portaudio python-virtualenv \
|
||||
base-devel pkg-config cmake patchelf \
|
||||
wget curl unzip xdotool wtype wl-clipboard xclip xsel
|
||||
```
|
||||
|
||||
### openSUSE Tumbleweed
|
||||
|
||||
```bash
|
||||
PYVER=$(python3 -c 'import sys; print(f"python{sys.version_info.major}{sys.version_info.minor}")')
|
||||
|
||||
sudo zypper install -y \
|
||||
"${PYVER}-pip" "${PYVER}-gobject" "${PYVER}-gobject-cairo" \
|
||||
"${PYVER}-devel" "${PYVER}-virtualenv" \
|
||||
gtk3 ibus typelib-1_0-IBus-1_0 \
|
||||
typelib-1_0-AyatanaAppIndicator3-0_1 libayatana-appindicator3-1 \
|
||||
typelib-1_0-Notify-0_7 libnotify4 \
|
||||
gobject-introspection-devel portaudio-devel pkg-config cmake \
|
||||
gcc gcc-c++ make patchelf \
|
||||
wget curl unzip xdotool wtype wl-clipboard xclip xsel
|
||||
|
||||
# Optional: whisper.cpp Vulkan builds
|
||||
sudo zypper install -y vulkan-tools vulkan-devel shaderc
|
||||
```
|
||||
|
||||
`-devel` packages are headers for compiling native Python deps, not "beta" packages. If `${PYVER}-virtualenv` is missing, try `${PYVER}-venv`.
|
||||
|
||||
### Other distributions
|
||||
|
||||
Gentoo, Alpine, Void, Solus, Mageia: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
|
||||
|
||||
## Install from a git checkout
|
||||
|
||||
Use the **system** Python (`/usr/bin/python3`). Distro PyGObject (`gi`) is compiled for that interpreter only, so a venv from pyenv/conda/uv cannot import it even with `--system-site-packages`.
|
||||
|
||||
```bash
|
||||
cd vocalinux
|
||||
/usr/bin/python3 -m venv venv --system-site-packages
|
||||
source venv/bin/activate
|
||||
pip install --upgrade pip setuptools wheel
|
||||
|
||||
pip install . # standard
|
||||
pip install ".[whisper]" # OpenAI Whisper extra
|
||||
pip install ".[faster_whisper]" # Faster Whisper (CTranslate2)
|
||||
pip install ".[parakeet]" # Parakeet (sherpa-onnx)
|
||||
pip install ".[vad]" # neural VAD
|
||||
pip install -e ".[dev,vad]" # development
|
||||
```
|
||||
|
||||
### Desktop integration
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.config/vocalinux \
|
||||
~/.local/share/vocalinux/models \
|
||||
~/.local/share/applications \
|
||||
~/.local/share/icons/hicolor/scalable/apps
|
||||
|
||||
cp vocalinux.desktop ~/.local/share/applications/
|
||||
VENV_PATH=$(realpath venv/bin/vocalinux)
|
||||
sed -i "s|^Exec=vocalinux|Exec=$VENV_PATH|" ~/.local/share/applications/vocalinux.desktop
|
||||
|
||||
cp resources/icons/scalable/*.svg ~/.local/share/icons/hicolor/scalable/apps/
|
||||
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor
|
||||
```
|
||||
|
||||
## Install from PyPI
|
||||
|
||||
Same system packages as above, then:
|
||||
|
||||
```bash
|
||||
python3 -m venv ~/.local/share/vocalinux-pypi/venv --system-site-packages
|
||||
source ~/.local/share/vocalinux-pypi/venv/bin/activate
|
||||
pip install --upgrade pip setuptools wheel
|
||||
pip install vocalinux
|
||||
# vosk engine: pip install "vocalinux[vosk]"
|
||||
# faster-whisper: pip install "vocalinux[faster_whisper]"
|
||||
# parakeet engine: pip install "vocalinux[parakeet]"
|
||||
vocalinux
|
||||
```
|
||||
|
||||
`--system-site-packages` lets the venv use distro GTK bindings (`python3-gi`). Building PyGObject from pip is often painful on Ubuntu/Debian.
|
||||
|
||||
If the app starts but no speech model is present, open Settings and download a model, or use the official installer which downloads the default model during setup.
|
||||
|
||||
### pipx
|
||||
|
||||
```bash
|
||||
# After system packages are installed:
|
||||
pipx install vocalinux
|
||||
vocalinux
|
||||
```
|
||||
|
||||
pipx still cannot install system desktop libraries. Install those first with your package manager.
|
||||
|
||||
## Why system packages are required
|
||||
|
||||
Vocalinux uses GTK3, AppIndicator/Ayatana, PortAudio, and tools such as `xdotool`, `wtype`, and clipboard utilities. Those come from the distro. PyPI only supplies Python packages and wheels.
|
||||
|
||||
## After install
|
||||
|
||||
- Run: [INSTALL.md](INSTALL.md#running-vocalinux)
|
||||
- Engines and models: [USER_GUIDE.md](USER_GUIDE.md)
|
||||
- Failures: [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
|
||||
@@ -0,0 +1,61 @@
|
||||
# Choosing a speech model
|
||||
|
||||
Vocalinux never downloads a speech model on its own. Changing the model pickers in
|
||||
Settings → Speech Model only selects a model. If that model is not on disk yet, the
|
||||
info card shows its download size and a **Download** button, and the transfer starts
|
||||
only after you confirm it. Cancelling the download, or declining the confirmation,
|
||||
puts the pickers back on the model you were already using.
|
||||
|
||||
This page is a static guide to help you pick. The numbers are approximate starting
|
||||
points, not measurements of your machine. If dictation feels slow, go one size down;
|
||||
if it makes too many mistakes and speed is fine, go one size up.
|
||||
|
||||
## whisper.cpp (default engine)
|
||||
|
||||
| Your hardware | Suggested size | Notes |
|
||||
|---|---|---|
|
||||
| Under 8 GB RAM, CPU only | Tiny | Fastest. Accuracy is noticeably lower. |
|
||||
| 8 to 16 GB RAM, CPU only | Tiny or Base | Base is a good default on a recent CPU. |
|
||||
| 16 GB RAM or more, CPU only | Base, or Small if you can wait | Small on CPU can take a few seconds per sentence. |
|
||||
| Vulkan GPU (AMD, Intel, NVIDIA) with under 8 GB RAM | Base | |
|
||||
| Vulkan GPU with 8 GB RAM or more | Small | Older or low power GPUs may still prefer Base. |
|
||||
| NVIDIA GPU (CUDA) with under 4 GB VRAM | Base | |
|
||||
| NVIDIA GPU (CUDA) with 4 to 8 GB VRAM | Small | |
|
||||
| NVIDIA GPU (CUDA) with 8 GB VRAM or more | Medium, or Large v3 Turbo | Large v3 Turbo is close to Large in accuracy at lower cost. |
|
||||
|
||||
Settings → Speech Model may show a line such as "Suggested for this computer: Small".
|
||||
That line is information only, based on the same rules as this table. It never changes
|
||||
your model and never starts a download.
|
||||
|
||||
## Model sizes and variants
|
||||
|
||||
Each size comes in several variants. The quantized ones (`q5_0`, `q5_1`, `q8_0`) are
|
||||
smaller files that use less memory, at a small cost in accuracy; `q8_0` is the
|
||||
closest to the full model. The `.en` variants are English only and are a little
|
||||
more accurate for English.
|
||||
|
||||
| Size | Full download | Q8_0 | Q5 | Parameters |
|
||||
|---|---|---|---|---|
|
||||
| Tiny | 74 MB | 32 MB | 15 MB (q5_1) | 39M |
|
||||
| Base | 141 MB | 82 MB | 60 MB (q5_1) | 74M |
|
||||
| Small | 465 MB | 190 MB | 163 MB (q5_1) | 244M |
|
||||
| Medium | 1.4 GB | 823 MB | 568 MB (q5_0) | 769M |
|
||||
| Large v3 Turbo | 1.6 GB | 874 MB | 574 MB (q5_0) | 809M |
|
||||
| Large (v3) | 2.9 GB | | 1.1 GB (q5_0) | 1550M |
|
||||
|
||||
Sizes are the catalog values Vocalinux shows before a download; the file on disk can
|
||||
differ slightly.
|
||||
|
||||
If you already have a quantized model of the size you want (for example Small Q8_0),
|
||||
there is no reason to download the full model of the same size.
|
||||
|
||||
## Other engines
|
||||
|
||||
- **Vosk**: the small models (about 40 MB) run on any CPU and are the lightest
|
||||
option.
|
||||
- **Faster Whisper** and **OpenAI Whisper**: the same size guidance as the table above.
|
||||
- **Parakeet**: one model of about 640 MB.
|
||||
- **Remote API**: transcription runs on your server, nothing is downloaded locally.
|
||||
|
||||
Models are stored under `~/.local/share/vocalinux/models/` by default. Deleting a file there
|
||||
removes the model; Vocalinux will show it as not downloaded again.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Documentation
|
||||
|
||||
User and maintainer documentation for Vocalinux.
|
||||
|
||||
| Document | Audience | Description |
|
||||
|----------|----------|-------------|
|
||||
| [INSTALL.md](INSTALL.md) | Users | Recommended install, AppImage, AUR, Flatpak, Snap, CLI |
|
||||
| [INSTALL_MANUAL.md](INSTALL_MANUAL.md) | Users | Manual install, system packages, PyPI/pipx |
|
||||
| [TROUBLESHOOTING.md](TROUBLESHOOTING.md) | Users | Common install and runtime failures |
|
||||
| [USER_GUIDE.md](USER_GUIDE.md) | Users | Dictation, engines, models, shortcuts, tips |
|
||||
| [UPDATE.md](UPDATE.md) | Users | How to upgrade; release notes by version |
|
||||
| [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md) | Users | Distro matrix, session caveats |
|
||||
| [HTTP_REMOTE.md](HTTP_REMOTE.md) | Power users | Remote HTTP transcription |
|
||||
| [FLATPAK_REMOTE.md](FLATPAK_REMOTE.md) | Users / maintainers | Self-hosted Flatpak remote and publishing |
|
||||
| [GATEWAY_EMBED.md](GATEWAY_EMBED.md) | Users | Optional local VocaGateway integration |
|
||||
| [CUSTOM_DICTIONARY_DESIGN.md](CUSTOM_DICTIONARY_DESIGN.md) | Contributors | Custom terms and correction design |
|
||||
| [ARCHITECTURE.md](ARCHITECTURE.md) | Contributors | Application modules, data flow, and threads |
|
||||
| [Performance benchmarks](benchmarks/README.md) | Contributors | Before and after charts for the performance pass |
|
||||
| [AUR.md](AUR.md) | Arch users / maintainers | AUR packages and publish secrets |
|
||||
| [RELEASE_PROCESS.md](RELEASE_PROCESS.md) | Maintainers | Version bump, checklist, tagging |
|
||||
|
||||
Project root:
|
||||
|
||||
| Document | Description |
|
||||
|----------|-------------|
|
||||
| [README.md](../README.md) | Project overview and quick start |
|
||||
| [CHANGELOG.md](../CHANGELOG.md) | Release history pointers |
|
||||
| [SUPPORT.md](../SUPPORT.md) | Where to get help |
|
||||
| [CONTRIBUTING.md](../CONTRIBUTING.md) | Development setup and pull requests |
|
||||
| [SECURITY.md](../SECURITY.md) | Vulnerability reporting and supported versions |
|
||||
| [CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md) | Community standards |
|
||||
|
||||
Website product and design notes live under [`web/`](../web/) (`PRODUCT.md`, `DESIGN.md`, `README.md`). Flatpak packaging: [`packaging/flatpak/README.md`](../packaging/flatpak/README.md).
|
||||
|
||||
Website: [vocalinux.com](https://vocalinux.com)
|
||||
@@ -0,0 +1,551 @@
|
||||
# Vocalinux Release Process
|
||||
|
||||
This document outlines the step-by-step process for creating a new release of Vocalinux.
|
||||
|
||||
## Overview
|
||||
|
||||
Vocalinux uses [Semantic Versioning](https://semver.org/) with pre-release suffixes:
|
||||
- **Alpha**: Early testing phase (e.g., `0.4.1-alpha`)
|
||||
- **Beta**: Feature-complete, testing phase (e.g., `0.5.0-beta`)
|
||||
- **RC** (Release Candidate): Final testing before stable (e.g., `0.5.0-rc1`)
|
||||
- **Stable**: Production-ready (e.g., `1.0.0`)
|
||||
|
||||
## Release Infrastructure (one-time setup)
|
||||
|
||||
These are configured once per repository. A tag pushed before they exist will fail
|
||||
in the corresponding job.
|
||||
|
||||
### PyPI trusted publishing (required)
|
||||
|
||||
`publish-pypi` authenticates with a short-lived OIDC token instead of a stored API
|
||||
token, so there is no `PYPI_API_TOKEN` secret to leak or rotate. It only works once
|
||||
PyPI knows about this workflow. On https://pypi.org/manage/project/vocalinux/settings/publishing/
|
||||
add a GitHub publisher:
|
||||
|
||||
| field | value |
|
||||
|---|---|
|
||||
| Owner | `VocaHQ` |
|
||||
| Repository | `vocalinux` |
|
||||
| Workflow name | `release.yml` |
|
||||
| Environment | `pypi` |
|
||||
|
||||
Until that publisher exists, `publish-pypi` fails with `invalid-publisher`. The old
|
||||
`PYPI_API_TOKEN` secret can be deleted from the repository once the first trusted
|
||||
publish succeeds.
|
||||
|
||||
### AUR (optional)
|
||||
|
||||
`publish-aur` skips itself when `AUR_SSH_PRIVATE_KEY` is unset. See docs/AUR.md.
|
||||
|
||||
## Quick Release Checklist
|
||||
|
||||
Use this checklist for every release:
|
||||
|
||||
```markdown
|
||||
## Version Bump Checklist for X.Y.Z-PHASE
|
||||
|
||||
### Core Version Files
|
||||
- [ ] `src/vocalinux/version.py` - Update `__version__` and `__version_info__`
|
||||
- [ ] `pyproject.toml` - Confirm `Development Status` classifier and `requires-python` are correct for this release phase
|
||||
|
||||
### Documentation
|
||||
- [ ] `README.md` - Update short current-release blurb (not full notes)
|
||||
- [ ] `CHANGELOG.md` - Point "Current stable" at the new tag
|
||||
- [ ] `docs/INSTALL.md` - Verify install examples use `main/install.sh` (not version-pinned raw URLs)
|
||||
- [ ] `docs/UPDATE.md` - Add "What's New" section for new version
|
||||
- [ ] `SECURITY.md` - Update supported versions table
|
||||
|
||||
### Website
|
||||
- [ ] `web/src/app/page.tsx` - Update `softwareVersion` in schema
|
||||
- [ ] `web/src/app/page.tsx` - Update version badge / live version surfaces if present
|
||||
- [ ] `web/src/app/changelog/page.tsx` - Add new release entry to changelog
|
||||
- [ ] `web/package.json` - Update version field
|
||||
- [ ] `web/package-lock.json` - Keep top-level/version metadata aligned with `web/package.json`
|
||||
- [ ] `web/PRODUCT.md` - Keep capabilities aligned with shipped features
|
||||
- [ ] Confirm install docs/website mention **AppImage** when this release ships AppImages
|
||||
|
||||
### Testing & Verification
|
||||
Install `just` from https://just.systems or the distro package `just`.
|
||||
- [ ] Run `just test` - All tests pass
|
||||
- [ ] Run `just lint` - No linting errors
|
||||
- [ ] Run `just typecheck` - No type errors
|
||||
- [ ] Run `just build` - Package builds successfully
|
||||
- [ ] Run `PYTHON=python3.11 just reproducible-wheel` - Independent wheels match
|
||||
- [ ] Run `npm run build` in `web/` - Website builds successfully
|
||||
|
||||
> Note: CI workflows also sync website version metadata from `src/vocalinux/version.py`, but source files should still be updated in-repo during release prep for review clarity.
|
||||
|
||||
### Git Operations
|
||||
- [ ] Create release branch: `git checkout -b release/vX.Y.Z-PHASE`
|
||||
- [ ] Commit all version changes
|
||||
- [ ] Push branch and create PR
|
||||
- [ ] After PR merge, create tag: `git tag -a vX.Y.Z-PHASE -m "Release X.Y.Z-PHASE"`
|
||||
- [ ] Push tag: `git push origin vX.Y.Z-PHASE`
|
||||
|
||||
### After the release run finishes
|
||||
- [ ] Run `just verify-release` - the published release verifies as published
|
||||
- [ ] Re-run it after any hand edit to the release: attaching an asset, or rewriting the notes
|
||||
```
|
||||
|
||||
`verify-release.yml` runs the same check when the release workflow finishes.
|
||||
It cannot see a hand edit made afterwards, which is how every v0.16.2 defect
|
||||
arrived, so run it yourself after touching a published release. The one
|
||||
exception is `snap-backfill.yml`: that workflow attaches the snap, rewrites
|
||||
`SHA256SUMS`, and then runs `scripts/verify_release.py` itself.
|
||||
|
||||
### Pre-publication wheel reproducibility
|
||||
|
||||
PR CI and the release workflow run `scripts/build_reproducible_wheel.py` before
|
||||
publication. It checks lock/export drift, installs the hash-pinned `release-build`
|
||||
toolchain into two fresh virtualenvs without system site-packages, and independently
|
||||
builds an sdist and its wheel in each source tree with `--no-isolation`.
|
||||
`SOURCE_DATE_EPOCH` comes from
|
||||
the checked-out commit. Both builds use the same Python 3.11 interpreter and
|
||||
platform; this checks repeatability under controlled inputs, not cross-platform
|
||||
or cross-Python-version reproducibility. Only wheels are compared byte-for-byte.
|
||||
|
||||
Build-only environments deliberately exclude host packages and setuptools plugins.
|
||||
Unlike runtime/development virtualenvs, they do not need distro PyGObject: the
|
||||
backend reads version metadata without importing GTK.
|
||||
|
||||
The script runs `twine check --strict` with the locked tools and stages only the
|
||||
canonical wheel and sdist in `dist/` after comparison succeeds. All release
|
||||
consumers reuse those distributions. Snap Store publication also waits for this
|
||||
gate. Verification builds never enter the release checksum manifest.
|
||||
|
||||
Locally, `PYTHON=python3.11 just reproducible-wheel` includes tracked working-tree
|
||||
edits and non-ignored new files, but excludes ignored build/egg-info/venv state.
|
||||
Repeat runs automatically clean the gate's previous logs and build archives.
|
||||
Staged files in `dist/` are removed only if their names and digests match the
|
||||
retained canonical archives. Unrelated or modified files, unexpected diagnostic
|
||||
files, and symlinks cause cleanup to stop before deleting anything; move those
|
||||
files aside first. The rest of `build/` is never cleaned. Logs, hashes and both
|
||||
builds are retained in `build/reproducible-wheel/`; CI uploads that directory on failure.
|
||||
Refresh the toolchain through `just lock`, not by editing its export by hand.
|
||||
Cleanup removes staged copies before their canonical originals, so an interrupted
|
||||
cleanup can safely be retried.
|
||||
The gate holds a checkout lock from before cleanup through final staging; a second
|
||||
active run fails without changing the first run's outputs. Archives are copied to
|
||||
an ignored temporary sibling of `dist/` and then atomically renamed into place,
|
||||
so interrupted staging leaves only complete archives in `dist/` and can be retried.
|
||||
|
||||
### AUR source publication gate
|
||||
|
||||
After `publish-checksums`, `aur-source-test` downloads the published canonical
|
||||
sdist and `SHA256SUMS`. `scripts/prepare_aur_source.py` checks the digest and
|
||||
cryptographically verifies provenance against this repository's release workflow,
|
||||
tag ref and source commit before preparing the checksum-pinned PKGBUILD.
|
||||
The exact prepared recipe is built, checked with namcap, installed and smoked on
|
||||
current Arch. `publish-aur` downloads only that verified PKGBUILD artifact and
|
||||
pushes it without further version/checksum rewrites (`updpkgsums: false`).
|
||||
|
||||
This gate runs even without AUR publication credentials. Failure prevents the
|
||||
AUR push, but does not unpublish GitHub/PyPI artifacts already released. It is
|
||||
separate from PR/local `--local-unattested` fixtures, which exercise the same
|
||||
preparation/build path but are never used for publication. See [AUR.md](AUR.md)
|
||||
for the trust model and the existing AUR-provider smoke-test limitations.
|
||||
`vocalinux-bin` publication waits only for release creation and both AppImages;
|
||||
source-gate failures or unrelated checksum producers do not block it.
|
||||
|
||||
## Detailed Release Steps
|
||||
|
||||
### Step 1: Determine Version Number
|
||||
|
||||
Follow semantic versioning:
|
||||
|
||||
```
|
||||
Given version MAJOR.MINOR.PATCH-PHASE:
|
||||
|
||||
MAJOR - Breaking changes (for 1.0.0: public API stable)
|
||||
MINOR - New features, backwards compatible
|
||||
PATCH - Bug fixes, backwards compatible
|
||||
PHASE - alpha, beta, rc1, rc2, etc. (omit for stable releases)
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
- Alpha → Beta: `0.4.1-alpha` → `0.5.0-beta` (new features, phase change)
|
||||
- Beta → RC: `0.5.0-beta` → `0.5.0-rc1` (same features, testing phase)
|
||||
- RC → Stable: `0.5.0-rc1` → `1.0.0` (first stable release)
|
||||
- Stable patch: `1.0.0` → `1.0.1` (bug fixes only)
|
||||
- Stable minor: `1.0.0` → `1.1.0` (new features)
|
||||
|
||||
### Step 2: Update Core Version Files
|
||||
|
||||
#### 2.1 Update `src/vocalinux/version.py`
|
||||
|
||||
```python
|
||||
__version__ = "0.5.0-beta"
|
||||
__version_info__ = (0, 5, 0, "beta")
|
||||
```
|
||||
|
||||
#### 2.2 Update `pyproject.toml`
|
||||
|
||||
Change the Development Status classifier:
|
||||
|
||||
```toml
|
||||
# For Alpha:
|
||||
"Development Status :: 3 - Alpha",
|
||||
|
||||
# For Beta:
|
||||
"Development Status :: 4 - Beta",
|
||||
|
||||
# For Stable:
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
```
|
||||
|
||||
### Patch releases within a minor line (e.g. 0.14.x)
|
||||
|
||||
When shipping bug fixes only (PATCH bump, same MINOR):
|
||||
|
||||
- **README / `docs/UPDATE.md` "What's New"** keeps the **minor-series feature list** (everything introduced in that 0.Y line) and adds a short **Bug fixes in this patch** subsection for the delta only. Do not make the marketing highlight table look featureless because this tag only contains fixes.
|
||||
- **Website changelog** (`web/src/app/changelog/page.tsx`) may list only the delta for the new entry; older entries stay historical.
|
||||
- **AppStream** (`packaging/flatpak/com.vocalinux.Vocalinux.metainfo.xml`): add a short `<release>` note for the patch delta only; leave the long product feature `<ul>` as series/product-level.
|
||||
- **SECURITY.md** supported versions table usually stays on the minor line (`0.14.x`) without a row per patch.
|
||||
- **AUR source PKGBUILD**: the release gate prepares `pkgver`, `_tag`, the normalized `_version`, and the canonical sdist digest, then tests that exact file. Do not introduce `SKIP` or rehash it during publication. The separate `vocalinux-bin` path still pins both AppImage digests before its own publication.
|
||||
- **Dates**: patch release dates must not predate the previous release in changelog / AppStream / version history.
|
||||
|
||||
### GitHub Release Notes Writing Rules
|
||||
|
||||
Use these rules for every GitHub Release body (and for the draft pasted into the release-prep PR). Website changelog entries stay shorter; see below.
|
||||
|
||||
#### Sources of truth
|
||||
|
||||
- Delta commits: `git log vPREV..HEAD` plus merged PR titles/bodies.
|
||||
- Closed issues via PR `Fixes` / `Closes` references only - do not invent issue numbers.
|
||||
- Do not invent benchmarks, user counts, testimonials, or features not in the tree.
|
||||
|
||||
#### Required structure
|
||||
|
||||
1. `# Vocalinux vX.Y.Z` title
|
||||
2. One to three plain sentences: what this release is for (no hype)
|
||||
3. `## Highlights` - markdown table, about 4-8 rows
|
||||
4. `## New Features` - bullets with PR + author; include issue closes when real
|
||||
5. `## Bug Fixes` - group by area (IBus, Installer, AUR, Text injection, …)
|
||||
6. Optional: `## Improvements`, `## Docs`, `## Packaging`
|
||||
7. `## Thanks` - external PR authors and issue reporters by `@handle`
|
||||
8. `## Install / Upgrade` - `install.sh`, AUR, PyPI, **AppImage**, Flatpak, Snap,
|
||||
`.deb` / `.rpm`
|
||||
(Store channels plus GitHub `.snap` sideload when Store review is pending)
|
||||
9. `### Verifying what you downloaded` (required, and easy to lose). `release.yml`
|
||||
generates it, with `sha256sum -c --ignore-missing SHA256SUMS` and
|
||||
`gh attestation verify`. A hand-written body replaces the generated one, so carry
|
||||
this block over deliberately. v0.16.2 published a checksum manifest and build
|
||||
provenance and mentioned neither, so nothing a user reads told them either existed
|
||||
10. Footer compare link: `https://github.com/VocaHQ/vocalinux/compare/vPREV...vX.Y.Z`
|
||||
|
||||
#### Include / exclude
|
||||
|
||||
- **Include:** user-visible features, install/packaging changes, desktop reliability fixes, docs that change user instructions.
|
||||
- **Exclude or demote:** Dependabot-only bumps, CI matrix tweaks, agent-env docs, pure refactors - short “CI / maintenance” subsection at most.
|
||||
|
||||
#### Attribution and voice
|
||||
|
||||
- Feature/fix bullets: `(#N by @author; fixes #M reported by @reporter)` when known.
|
||||
- Practical, specific, Linux-native. Name the symptom users hit.
|
||||
- Avoid promotional filler (“seamless”, “pivotal”, “game-changer”, fake significance).
|
||||
|
||||
#### Website changelog vs GitHub Release
|
||||
|
||||
- **Website** (`web/src/app/changelog/page.tsx`): 3-10 concise user-facing bullets for the new entry.
|
||||
- **GitHub Release**: fuller narrative + install block + thanks. Draft in the release-prep **PR body**; paste/edit onto the release after the tag workflow runs (workflow install stub + generated notes are a starting point only).
|
||||
|
||||
#### Minor vs patch (reminder)
|
||||
|
||||
- **Minor** (e.g. `0.15.0`): rewrite README / UPDATE “What’s New” for the new series; full website changelog entry; AppStream release note summarizes the series.
|
||||
- **Patch** (e.g. `0.15.1`): keep series feature table; add “Bug fixes in this patch” only; website changelog lists delta only.
|
||||
|
||||
#### Draft delivery
|
||||
|
||||
- Release-prep PRs should include a `## Draft GitHub Release Notes` section in the PR description for review before tag.
|
||||
- Do not tag from the prep branch alone; tag after merge to `main`.
|
||||
|
||||
### Step 3: Update Documentation
|
||||
|
||||
#### 3.1 Update `README.md`
|
||||
|
||||
**README current-release blurb:**
|
||||
Keep a short one-line pointer to the new tag and [docs/UPDATE.md](UPDATE.md). Do not paste the full release notes into the README.
|
||||
|
||||
**Install commands:**
|
||||
Keep install examples on `main/install.sh` (download-then-run preferred; installer resolves latest release tag):
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
#### 3.2 Update `docs/INSTALL.md`
|
||||
|
||||
Confirm install examples point to `main/install.sh` and not release-tag raw URLs.
|
||||
|
||||
#### 3.3 Update `docs/UPDATE.md`
|
||||
|
||||
Add a new "What's New" section at the top:
|
||||
|
||||
```markdown
|
||||
## What's New in v0.5.0-beta
|
||||
|
||||
- Feature 1
|
||||
- Feature 2
|
||||
- Bug fix 1
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.5.0-beta).
|
||||
|
||||
---
|
||||
|
||||
## Previous Versions
|
||||
|
||||
### v0.4.1-alpha
|
||||
...
|
||||
```
|
||||
|
||||
#### 3.4 Update `SECURITY.md`
|
||||
|
||||
Update the supported versions table:
|
||||
|
||||
```markdown
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.5.x | :white_check_mark: |
|
||||
| 0.4.x | :x: |
|
||||
| < 0.4 | :x: |
|
||||
```
|
||||
|
||||
### Step 4: Update Website
|
||||
|
||||
#### 4.1 Update `web/src/app/page.tsx`
|
||||
|
||||
Update the schema.org softwareVersion (around line 68):
|
||||
|
||||
```typescript
|
||||
"softwareVersion": "vX.Y.Z-PHASE",
|
||||
```
|
||||
|
||||
Update the version badge in the header (around line 293):
|
||||
|
||||
```tsx
|
||||
vX.Y.Z Beta
|
||||
```
|
||||
|
||||
#### 4.2 Update `web/src/app/changelog/page.tsx`
|
||||
|
||||
Add new release entry to the `releases` array at the top of the file.
|
||||
|
||||
#### 4.3 Update `web/package.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "vocalinux-website",
|
||||
"version": "0.5.0"
|
||||
}
|
||||
```
|
||||
|
||||
Also align `web/package-lock.json` top-level `version` fields with `web/package.json`.
|
||||
|
||||
### Step 5: Verify Everything Works
|
||||
|
||||
Run the full verification suite. Install `just` from
|
||||
https://just.systems or the distro package `just`.
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
just test
|
||||
|
||||
# Run linting
|
||||
just lint
|
||||
|
||||
# Run type checking
|
||||
just typecheck
|
||||
|
||||
# Build package
|
||||
just build
|
||||
|
||||
# Website build
|
||||
cd web && npm run build && cd ..
|
||||
|
||||
# Install script sanity checks (optional but recommended)
|
||||
bash -n install.sh
|
||||
./install.sh --help | grep -- --tag
|
||||
```
|
||||
|
||||
### Step 6: Create Release Branch and PR
|
||||
|
||||
```bash
|
||||
# Create branch
|
||||
git checkout -b release/v0.5.0-beta
|
||||
|
||||
# Stage all changes
|
||||
git add -A
|
||||
|
||||
# Commit with conventional commit format
|
||||
git commit -m "chore(release): prepare v0.5.0-beta
|
||||
|
||||
- Update version from 0.4.1-alpha to 0.5.0-beta
|
||||
- Update status badges from Alpha to Beta
|
||||
- Update documentation version references
|
||||
- Update website schema and badges
|
||||
- Update pyproject.toml classifiers
|
||||
- Update SECURITY.md supported versions table"
|
||||
|
||||
# Push branch
|
||||
git push origin release/v0.5.0-beta
|
||||
|
||||
# Create PR (use GitHub CLI or web interface)
|
||||
gh pr create --title "chore(release): prepare v0.5.0-beta" \
|
||||
--body "This PR prepares the repository for the v0.5.0-beta release.
|
||||
|
||||
## Changes
|
||||
- Bumped version to 0.5.0-beta
|
||||
- Updated status badges from Alpha to Beta
|
||||
- Updated all documentation version references
|
||||
- Updated website version info
|
||||
- Updated SECURITY.md supported versions
|
||||
|
||||
## Checklist
|
||||
- [x] All tests passing
|
||||
- [x] Linting clean
|
||||
- [x] Type checking clean
|
||||
- [x] Package builds successfully"
|
||||
```
|
||||
|
||||
### Step 7: Create and Push Tag (After PR Merge)
|
||||
|
||||
Once the PR is merged to main:
|
||||
|
||||
```bash
|
||||
# Checkout main
|
||||
git checkout main
|
||||
git pull origin main
|
||||
|
||||
# Create annotated tag
|
||||
git tag -a v0.5.0-beta -m "Vocalinux Beta Release 0.5.0
|
||||
|
||||
Key changes since 0.4.1-alpha:
|
||||
- Feature 1
|
||||
- Feature 2
|
||||
- Bug fix 1
|
||||
|
||||
Full changelog: https://github.com/VocaHQ/vocalinux/releases"
|
||||
|
||||
# Push tag
|
||||
git push origin v0.5.0-beta
|
||||
```
|
||||
|
||||
### Step 8: Monitor Release
|
||||
|
||||
After pushing the tag, the GitHub Actions workflow will automatically:
|
||||
|
||||
1. Build the Python package (wheel and sdist) - **once**, with `SOURCE_DATE_EPOCH`
|
||||
pinned to the tagged commit. Every later job downloads that artifact instead of
|
||||
rebuilding, so the wheel on PyPI is byte-for-byte the wheel on the release
|
||||
2. Build and attach AppImages for x86_64 and aarch64, both from that same wheel
|
||||
3. Create a GitHub Release with auto-generated notes
|
||||
4. Attach `SHA256SUMS` covering every GitHub asset (wheel, sdist, both AppImages,
|
||||
both Flatpaks, the amd64 snap, the `.deb` and `.rpm` for both arches) and
|
||||
generate build provenance from that
|
||||
manifest (runs after the aarch64 AppImage, both Flatpaks, and the snap land,
|
||||
so a partial manifest never gets published)
|
||||
5. Publish to PyPI via trusted publishing
|
||||
6. Publish the AUR package (when the `AUR_SSH_PRIVATE_KEY` secret is configured)
|
||||
7. Publish the signed self-hosted Flatpak remote to `VocaHQ/vocalinux-flatpak`
|
||||
(stable tags only, once the GitHub Release exists, when
|
||||
`FLATPAK_GPG_PRIVATE_KEY` + `FLATPAK_REPO_TOKEN` are configured — see
|
||||
docs/FLATPAK_REMOTE.md)
|
||||
8. Deploy the website to vocalinux.com
|
||||
9. Build the amd64 snap from locked Python exports and run the installed-artifact
|
||||
gate described in [SNAP.md](SNAP.md), then attach it to the GitHub Release and
|
||||
try Snap Store
|
||||
`edge`/`candidate`. Store human review (for example a super-privileged
|
||||
`allow-installation` plug) must not block the GitHub `.snap`. `stable` does not auto-release (#783):
|
||||
after candidate QA, dispatch `snap-promote.yml`, which releases the
|
||||
candidate revision to `latest/stable`
|
||||
10. Mark as pre-release if version contains alpha/beta/rc
|
||||
|
||||
Monitor at: https://github.com/VocaHQ/vocalinux/actions
|
||||
|
||||
### Step 9: Post-Release Tasks
|
||||
|
||||
- [ ] Verify GitHub Release was created correctly
|
||||
- [ ] Verify `SHA256SUMS` is attached and lists every GitHub asset (wheel, sdist,
|
||||
both AppImages, both Flatpaks, the amd64 snap, the `.deb` and `.rpm` for
|
||||
both arches) - the release notes tell users to run `sha256sum -c`
|
||||
against it
|
||||
- [ ] If the Store holds the snap for human review, confirm the GitHub `.snap`
|
||||
is still attached and the notes document `snap install --dangerous`
|
||||
- [ ] After candidate QA (install, tray, mic, model download, typing into a real
|
||||
app), promote the snap to stable:
|
||||
`gh workflow run snap-promote.yml -f tag=vX.Y.Z` - it fails unless
|
||||
`latest/candidate` carries a revision whose version matches the tag. An
|
||||
optional `snap-stable` environment with required reviewers adds a second
|
||||
approval gate on the dispatch
|
||||
- [ ] Verify provenance: `gh attestation verify <artifact> --repo VocaHQ/vocalinux`
|
||||
- [ ] Verify PyPI package was published (if applicable), and that its wheel sha256
|
||||
matches the line for that wheel in `SHA256SUMS`
|
||||
- [ ] Verify website was deployed (check vocalinux.com)
|
||||
- [ ] If the Flatpak remote is configured, verify it picked up the tag:
|
||||
`flatpak remote-info vocahq com.vocalinux.Vocalinux` (docs/FLATPAK_REMOTE.md)
|
||||
- [ ] Announce on social media/communities
|
||||
- [ ] Update any pinned issues or discussions
|
||||
|
||||
## Emergency Hotfix Process
|
||||
|
||||
For critical bugs in a released version:
|
||||
|
||||
```bash
|
||||
# Create hotfix branch from the tag
|
||||
git checkout -b hotfix/v0.5.1-beta v0.5.0-beta
|
||||
|
||||
# Make fix, commit, push
|
||||
git add -A
|
||||
git commit -m "fix: critical bug description"
|
||||
git push origin hotfix/v0.5.1-beta
|
||||
|
||||
# Create PR targeting main
|
||||
# After merge, tag new version
|
||||
git tag -a v0.5.1-beta -m "Hotfix release v0.5.1-beta"
|
||||
git push origin v0.5.1-beta
|
||||
```
|
||||
|
||||
## Version History
|
||||
|
||||
| Version | Date | Phase | Notes |
|
||||
|---------|------|-------|-------|
|
||||
| 0.2.0-alpha | 2024 | Alpha | Initial alpha |
|
||||
| 0.3.0-alpha | 2024 | Alpha | - |
|
||||
| 0.4.0-alpha | 2024 | Alpha | Multi-language support |
|
||||
| 0.4.1-alpha | 2024 | Alpha | Language selector UI |
|
||||
| 0.5.0-beta | 2025 | Beta | First beta release |
|
||||
| 0.6.0-beta | 2026-02-11 | Beta | Web SEO, mobile responsiveness, improved Fedora support |
|
||||
| 0.6.1-beta | 2026-02-12 | Beta | Device handling improvements |
|
||||
| 0.6.2-beta | 2026-02-17 | Beta | Bug fixes |
|
||||
| 0.6.3-beta | 2026-02-19 | Beta | GPU detection improvements |
|
||||
| 0.7.0-beta | 2026 | Beta | Autostart, tabbed settings, Intel GPU support, single instance |
|
||||
| 0.8.0-beta | 2026-03-01 | Beta | Push-to-talk mode, optional voice commands, input/audio compatibility fixes |
|
||||
| 0.9.0-beta | 2026-03-14 | Beta | Left/right modifier keys, sound effects toggle, Wayland clipboard fallback, leading-space fix |
|
||||
| 0.10.0-beta | 2026-03-25 | Beta | Keyboard/audio reliability hardening, IBus/tray stability fixes, CI + test coverage improvements |
|
||||
| 0.10.1-beta | 2026-03-27 | Beta | Stability patch: tray resource bundling, engine-switch segfault prevention, settings close action, XKB layout preservation |
|
||||
| 0.10.2-beta | 2026-04-08 | Beta | Non-ASCII text injection, IBus Wayland detection, Pop!_OS deps, code quality refactor |
|
||||
| 0.11.0-beta | 2026-05-30 | Beta | Advanced Settings tab, IBus/recognition hardening, installer fixes, distro compatibility |
|
||||
| 0.12.0-beta | 2026-06-07 | Beta | Remote API engine, Silero VAD, threading/IBus hardening, settings and installer fixes |
|
||||
| 0.13.0-beta | 2026-06-30 | Beta | Guided whisper.cpp model variants, Wayland text-injection reliability, hotplug keyboard support, dictation spacing fix, website docs refresh |
|
||||
| 0.14.0-beta | 2026-07-13 | Beta | Configurable modifier+key hotkeys, FunASR/SenseVoice remote-API support, GNOME/KDE Wayland IBus reliability fixes, audio crash fix, hybrid-CPU efficiency fix |
|
||||
| 0.14.1 | 2026-07-17 | Stable | Flatpak packaging, AUR package, layout-aware hotkeys, installer/text-injection fixes |
|
||||
| 0.14.2 | 2026-07-17 | Stable | IBus engine launch + FocusIn gate; settings tabs scroll to fit monitor |
|
||||
| 0.15.0 | 2026-07-28 | Stable | Searchable settings + sidebar dictation footer, AppImage, expanded languages, dictation polish, auto-pause/keepalive, Vulkan device selection, ibus-wayland, Bluetooth mic + shortcut UI fixes |
|
||||
| 0.16.0 | 2026-08-23 | Stable | Update checker + tray notify, Right Alt PTT default (new installs), searchable language list, delete unused models, Voca tone picker (family preview WAVs), About page, AGPL-3.0, family mic icons, installer/just/uv pinning, Test Dictation missing-model message, IBus/audio/clipboard/GPU/AppImage reliability, vocalinux.com family workbench restyle |
|
||||
| 0.17.0 | 2026-09-16 | Stable | Faster Whisper + Parakeet engines, Speech Model simple setup, first-run system language, Snap with ydotool/uinput, Flatpak bundles on the GitHub Release, XWayland/layout paste and settings/audio fixes |
|
||||
| 0.18.0 | 2026-10-02 | Stable | Dictation Pad, evdev hotkey suppression, PipeWire capture + system audio, RemoteDesktop portal injection, per-language shortcuts + tray history, TinyDiarize file transcription, D-Bus activation, custom dictionary, postprocessing hook, floating overlay, audio ducking, AUR -bin + self-hosted Flatpak remote + snap-promote |
|
||||
| 0.18.1 | 2026-10-08 | Stable | Settings Proxy page, opt-in JSONL transcript persistence, .deb/.rpm release packages, slimmer tray menu, dictation-pad Wayland ghost fix, evdev keyboard-discovery tightening, KWin 6 case fix, staged model picker |
|
||||
| 0.18.5 | 2026-10-27 | Stable | Patch: racing stop can no longer leave the mic recording, stalled-mic reads cannot hang Stop, keyboards survive suspend and the GNOME lock screen, Wayland dialogs stay on their own workspace, Ctrl+wheel zoom restored, installer upgrade mode keeps existing config, paste copies marked sensitive on wl-copy 2.2+, AUR source gate on attested sdists |
|
||||
| 0.16.2 | 2026-09-05 | Stable | Patch: KDE leftover IBus skip, Wayland/IBus shortcuts via wtype/ydotool, BackSpace delete that, installer glslc on Fedora/Arch, nightly version stamp, release integrity pins, AUR PKGBUILD CI gate, distro CI/docs drift, Gateway Beta on site |
|
||||
| 0.16.1 | 2026-08-30 | Stable | Patch: per-engine model at startup, leftover tray idle, terminal Ctrl+Shift+V paste, GNOME XWayland layout after IBus, Python 3.11 floor + verified downloads, AppImage glibc that boots on Debian 12, Settings/About polish |
|
||||
|
||||
## Questions?
|
||||
|
||||
If you're unsure about any step:
|
||||
1. Check previous releases for examples
|
||||
2. Review the GitHub Actions workflows in `.github/workflows/`
|
||||
3. Ask in the project's discussions
|
||||
|
||||
---
|
||||
|
||||
**Note**: This document should be updated when the release process changes.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Snap build inputs and verification
|
||||
|
||||
The supported Snap build is **amd64, core24 (Ubuntu 24.04 / Python 3.12),
|
||||
strict confinement, GNOME extension**. whisper.cpp is built for the portable
|
||||
CPU baseline, not Vulkan/CUDA. Optional local engines are not bundled.
|
||||
User installation and interface connections are documented in
|
||||
[INSTALL.md](INSTALL.md#snap-ubuntu-snap-store).
|
||||
|
||||
## Python inputs
|
||||
|
||||
`uv.lock` owns Python versions. The Snap reuses these generated exports:
|
||||
|
||||
- `requirements/installer-build.txt`: the complete hash-pinned build toolchain,
|
||||
installed wheel-only into a temporary, isolated build virtualenv;
|
||||
- `requirements/runtime.txt`: the runtime pins, platform markers and SHA-256
|
||||
hashes, already excluding PyGObject.
|
||||
|
||||
`snap/local/build.py` replaces the Python plugin's implicit resolution. A distro
|
||||
`ensurepip` seeds the build environment offline; its first network operation
|
||||
installs the locked toolchain with `--require-hashes --no-deps`. Runtime
|
||||
dependencies use the same flags plus `--no-build-isolation`. Native builds find
|
||||
the locked CMake/Ninja on PATH. pywhispercpp always builds from its pinned sdist,
|
||||
without a wheel cache, with the portable `GGML_*` CPU options in the recipe.
|
||||
|
||||
The project installs with `--no-deps --no-build-isolation --no-index`. Neither
|
||||
`pyproject.toml` nor its dependency metadata is patched. PyGObject/GTK come from
|
||||
the GNOME platform, not pip. The packaged virtualenv contains no pip or build
|
||||
toolchain. Its launchers are relocatable and prioritize the locked Python
|
||||
packages over incidental copies in the GNOME platform.
|
||||
|
||||
The build audits build-tool and installed runtime versions against the active
|
||||
export pins and records expected runtime versions and both export digests in
|
||||
`usr/share/vocalinux/python-inputs.json` inside the snap. Missing or wrong-version
|
||||
build tools fail the build. For the packaged runtime, extra and duplicate
|
||||
Python distributions are rejected as well.
|
||||
|
||||
Regenerate exports with the repository's `just lock` workflow, not by editing
|
||||
them or adding independent pins to `snapcraft.yaml`. `just export-check` checks
|
||||
them against `uv.lock` in CI.
|
||||
|
||||
## Build and artifact gate
|
||||
|
||||
On a Linux machine with Snapcraft and LXD or Multipass:
|
||||
|
||||
```bash
|
||||
snapcraft pack
|
||||
```
|
||||
|
||||
On a **disposable Ubuntu host with snapd**, inspect the resulting artifact:
|
||||
|
||||
```bash
|
||||
bash snap/local/smoke-test.sh ./vocalinux_<version>_amd64.snap
|
||||
```
|
||||
|
||||
Replace `<version>` with the version that was built. The script refuses to overwrite an
|
||||
existing Vocalinux snap. It installs the supplied file with `--dangerous`,
|
||||
runs the actual application launcher with `--version`, then enters the GNOME
|
||||
command-chain environment to audit Python versions and import the native,
|
||||
GTK, recognition and text-injection modules. It leaves the installation in
|
||||
place for inspection; use a disposable host, not your normal Vocalinux install.
|
||||
|
||||
`unified-pipeline.yml` builds and runs this gate on relevant Python/Snap PRs and
|
||||
main pushes, including recipe-only changes. `release.yml` runs it before the
|
||||
snap artifact can be attached or sent to the Store. Both use the same pinned
|
||||
builder action and Ubuntu 24.04 runner. PR checks need no Store credentials and
|
||||
never publish. Historical-tag backfills retain the tagged recipe's behavior.
|
||||
|
||||
## Deliberate limits
|
||||
|
||||
- This pins Python downloads and build tools, **not every native input**.
|
||||
Ubuntu packages are controlled by the core24/Ubuntu archive policy; the
|
||||
GNOME SDK/platform, Snapcraft and base snaps follow their upstream channels.
|
||||
Their exact revisions and native package versions remain visible in the
|
||||
Snapcraft build records. They are not an immutable snapshot owned by our
|
||||
Python lock.
|
||||
- This is not a claim of byte-for-byte reproducible `.snap` archives. There is
|
||||
no independent Snap rebuild comparison, and native inputs can change.
|
||||
- The smoke imports real modules under confinement but does not download a
|
||||
model, run inference, capture audio, test shortcuts, or type into an app.
|
||||
Candidate desktop QA and promotion to stable remain separate operations;
|
||||
this gate does not trigger `snap-promote.yml`.
|
||||
@@ -0,0 +1,175 @@
|
||||
# Troubleshooting
|
||||
|
||||
Common install and runtime problems. Install overview: [INSTALL.md](INSTALL.md). Support channels: [SUPPORT.md](../SUPPORT.md).
|
||||
|
||||
Always try once with debug logs:
|
||||
|
||||
```bash
|
||||
vocalinux --debug
|
||||
```
|
||||
|
||||
## Command not found: `vocalinux`
|
||||
|
||||
```bash
|
||||
# Official install wrappers
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
vocalinux
|
||||
|
||||
# Or run the venv binary
|
||||
~/.local/share/vocalinux/venv/bin/vocalinux
|
||||
|
||||
# Source checkout
|
||||
source venv/bin/activate
|
||||
vocalinux
|
||||
```
|
||||
|
||||
## No audio / microphone not working
|
||||
|
||||
1. Check system sound settings and mute state
|
||||
2. List capture devices: `arecord -l`
|
||||
3. Run `vocalinux --debug` and confirm the selected device
|
||||
4. Reset a bad device index: set `audio.device_index` to `null` in `~/.config/vocalinux/config.json`
|
||||
5. Bluetooth mics: try a wired device to isolate SCO capture issues
|
||||
|
||||
### Microphone Stalled
|
||||
|
||||
A **Microphone Stalled** notification means the selected input stopped delivering
|
||||
audio. Vocalinux stops the failed dictation attempt.
|
||||
|
||||
Open **Settings → Audio**. Use **Microphone Test → Test** to record two seconds and
|
||||
check the audio level, or select a different **Input Device**, then retry
|
||||
dictation. **Test Dictation** is a separate speech-recognition test. See
|
||||
[Audio input](USER_GUIDE.md#audio-input) for explicit microphone selection and
|
||||
**System Default** behavior.
|
||||
|
||||
## GTK / AppIndicator / `No module named gi`
|
||||
|
||||
Recreate the venv with system site packages:
|
||||
|
||||
```bash
|
||||
sudo apt install python3-gi python3-gi-cairo # Debian/Ubuntu example
|
||||
# tray: gir1.2-ayatanaappindicator3-0.1 or gir1.2-appindicator3-0.1
|
||||
|
||||
deactivate 2>/dev/null || true
|
||||
rm -rf venv
|
||||
/usr/bin/python3 -m venv venv --system-site-packages
|
||||
source venv/bin/activate
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
On GNOME, enable the AppIndicator extension if the tray icon never appears:
|
||||
|
||||
```bash
|
||||
# Debian/Ubuntu
|
||||
sudo apt install gnome-shell-extension-appindicator
|
||||
# Fedora
|
||||
sudo dnf install gnome-shell-extension-appindicator
|
||||
# Arch
|
||||
sudo pacman -S gnome-shell-extension-appindicator
|
||||
|
||||
gnome-extensions enable appindicatorsupport@rgcjonas.gmail.com
|
||||
# log out/in if needed
|
||||
```
|
||||
|
||||
Refresh icons:
|
||||
|
||||
```bash
|
||||
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor
|
||||
vocalinux --debug
|
||||
```
|
||||
|
||||
## Text not injected into apps
|
||||
|
||||
**X11:**
|
||||
|
||||
```bash
|
||||
sudo apt install xdotool # or distro equivalent
|
||||
xdotool type "hello"
|
||||
```
|
||||
|
||||
**Wayland:**
|
||||
|
||||
```bash
|
||||
sudo apt install wtype wl-clipboard xclip xsel
|
||||
wtype "hello"
|
||||
printf "bonjour" | xsel --clipboard --input
|
||||
```
|
||||
|
||||
**KDE Plasma Wayland:** `wtype` may fail if the compositor does not expose a virtual keyboard to normal clients. Prefer **System Settings → Keyboard → Virtual Keyboard → IBus Wayland**, then restart Vocalinux (or log out/in).
|
||||
|
||||
Install IBus if needed:
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt install ibus
|
||||
# Fedora
|
||||
sudo dnf install ibus
|
||||
# Arch
|
||||
sudo pacman -S ibus
|
||||
```
|
||||
|
||||
Compositor-specific notes: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
|
||||
|
||||
## Model download fails
|
||||
|
||||
Models download on first use. Manual VOSK example:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.local/share/vocalinux/models
|
||||
cd ~/.local/share/vocalinux/models
|
||||
wget https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip
|
||||
unzip vosk-model-small-en-us-0.15.zip
|
||||
```
|
||||
|
||||
More VOSK models: https://alphacephei.com/vosk/models
|
||||
whisper.cpp models are managed from Settings or first-run download.
|
||||
|
||||
## `libwhisper.so` / pywhispercpp load errors
|
||||
|
||||
```bash
|
||||
# Unresolved libs
|
||||
ldd $(find ~/.local/share/vocalinux/venv -name '*.so' -path '*/pywhispercpp*' 2>/dev/null | head -1) | grep 'not found'
|
||||
|
||||
# Rebuild whisper.cpp bindings via installer
|
||||
./install.sh --auto --rebuild-whispercpp
|
||||
|
||||
# Or switch to VOSK temporarily
|
||||
vocalinux --engine vosk
|
||||
```
|
||||
|
||||
## Old process still running after update
|
||||
|
||||
Stop via the tray, or use the lock-file PID (do **not** use `pkill -f vocalinux`; it can kill editors and shells):
|
||||
|
||||
```bash
|
||||
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux/instance.lock")"
|
||||
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux-ibus/engine.pid")"
|
||||
vocalinux
|
||||
```
|
||||
|
||||
## Clean reinstall
|
||||
|
||||
```bash
|
||||
./uninstall.sh --keep-config --keep-data
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
## Distro PyGObject not importable in the venv
|
||||
|
||||
The distro `python3-gi` / `python3-gobject` package is installed, but `venv/` was built by a different Python than the one it targets. Current `install.sh` ignores an activated virtualenv and rebuilds a mismatched `venv/`. Otherwise:
|
||||
|
||||
```bash
|
||||
deactivate 2>/dev/null || true
|
||||
rm -rf venv
|
||||
./install.sh
|
||||
```
|
||||
|
||||
On systems with several system interpreters: `SYSTEM_PYTHON=/usr/bin/python3.12 ./install.sh`.
|
||||
|
||||
## Still stuck
|
||||
|
||||
- [SUPPORT.md](../SUPPORT.md)
|
||||
- [GitHub Issues](https://github.com/VocaHQ/vocalinux/issues)
|
||||
- [Discussions](https://github.com/VocaHQ/vocalinux/discussions)
|
||||
- [Discord](https://discord.gg/t6muquAJbm)
|
||||
@@ -0,0 +1,486 @@
|
||||
# Updating Vocalinux
|
||||
|
||||
How to upgrade an existing install, plus release notes for the current series.
|
||||
|
||||
## Quick update
|
||||
|
||||
Vocalinux checks GitHub Releases in the background about every six hours (and shortly after startup). When a newer build is on your selected channel, the tray menu gains an **Update Available...** entry and Settings -> About shows a green **New** badge; open that page for release notes and download links. Updates are not installed automatically. Re-run the installer (or your package manager) as below.
|
||||
|
||||
### Official installer
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
The installer detects a running instance, updates in place, preserves configuration and models, and pulls new dependencies (including neural VAD when available).
|
||||
|
||||
On an existing install (a virtual environment plus `~/.config/vocalinux/config.json`), the installer reports the saved configuration and defaults to **Upgrade (keep current settings)**: the configured engine stays selected, `config.json` is never rewritten, the virtual environment is reused, downloaded models are kept, and pywhispercpp is rebuilt only when this release pins a new version or GPU support is missing. Pick the interactive or automatic modes instead if you want to reconfigure the install.
|
||||
|
||||
For a scripted, non-interactive upgrade:
|
||||
|
||||
```bash
|
||||
bash /tmp/vl.sh --upgrade
|
||||
```
|
||||
|
||||
`--upgrade` on a machine with no existing install falls back to a normal automatic installation.
|
||||
|
||||
### Installed from source
|
||||
|
||||
```bash
|
||||
cd vocalinux
|
||||
git fetch origin
|
||||
git checkout v0.18.5
|
||||
./install.sh
|
||||
```
|
||||
|
||||
Latest development tree:
|
||||
|
||||
```bash
|
||||
cd vocalinux
|
||||
git pull origin main
|
||||
./install.sh
|
||||
```
|
||||
|
||||
### Other install methods
|
||||
|
||||
| Method | Upgrade |
|
||||
|--------|---------|
|
||||
| AUR | `yay -S vocalinux` (or your AUR helper) |
|
||||
| AppImage | Download the new file from [Releases](https://github.com/VocaHQ/vocalinux/releases) |
|
||||
| Snap | Store: `sudo snap refresh vocalinux` (`--edge` until stable is promoted). The recipe ships no `uinput` plug (the Store denied the grant); Wayland typing uses the RemoteDesktop portal. The GitHub `vocalinux_0.18.2_amd64.snap` still declares `uinput` for KDE users who want ydotool (`sudo snap install --dangerous`, then `sudo snap connect vocalinux:uinput`). |
|
||||
| Flatpak (release bundle) | Install the new `.flatpak` from Releases; bundles do not auto-update |
|
||||
| PyPI | Reinstall in the same venv after system packages are current |
|
||||
|
||||
### Check your version
|
||||
|
||||
```bash
|
||||
vocalinux --version
|
||||
# or
|
||||
python3 -c "import vocalinux; print(vocalinux.version.__version__)"
|
||||
```
|
||||
|
||||
### Update problems
|
||||
|
||||
Clean reinstall (keeps config and models by default):
|
||||
|
||||
```bash
|
||||
# Source checkout
|
||||
./uninstall.sh --keep-config --keep-data
|
||||
|
||||
# Curl install (safe to run from any directory)
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/uninstall.sh -o /tmp/vul.sh
|
||||
bash /tmp/vul.sh --keep-config --keep-data
|
||||
|
||||
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh -o /tmp/vl.sh
|
||||
bash /tmp/vl.sh
|
||||
```
|
||||
|
||||
If an old process is stuck, stop via the tray or the PID in the instance lock file (do not use `pkill -f vocalinux`; it can kill unrelated processes):
|
||||
|
||||
```bash
|
||||
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux/instance.lock")"
|
||||
# If you use IBus injection:
|
||||
kill "$(tr -d '[:space:]' < "${XDG_DATA_HOME:-$HOME/.local/share}/vocalinux-ibus/engine.pid")"
|
||||
vocalinux
|
||||
```
|
||||
|
||||
Missing system packages: see [INSTALL.md](INSTALL.md) or [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.18.5
|
||||
|
||||
0.18.5 is a **patch** on the stable line. Default engine is still whisper.cpp. It closes the reports filed after 0.18.4: a stop pressed while a recording is starting can no longer leave the microphone recording forever, microphones that stall mid-read can no longer wedge dictation, keyboards survive suspend and the GNOME lock screen, Ctrl+mouse-wheel zoom works again, and the installer learns an upgrade mode that keeps your settings.
|
||||
|
||||
### 0.18.5 highlights
|
||||
|
||||
| Fix | Description |
|
||||
|---------|-------------|
|
||||
| **A racing stop always wins** | A stop arriving while a recording is still starting is no longer overwritten by the start, so the microphone can never keep recording with no way to halt it (#1023 by @aagprojectsteam-max; fixes #1022 reported by @aagprojectsteam-max) |
|
||||
| **Stalled microphones cannot hang Stop** | Capture reads happen outside the buffer lock, so a mic that stalls mid-read (a USB or Bluetooth hiccup, or the audio server reconfiguring the device) no longer leaves dictation stuck in PROCESSING (#1023; supersedes the approach in #974 by @neuroborus) |
|
||||
| **Keyboards survive suspend and lock** | The evdev forwarder releases its EVIOCGRAB when forwarding cannot run, so keyboards no longer go dead at the GNOME lock screen after a suspend/resume (#1025; fixes #1021 reported by @iholder101) |
|
||||
| **Dialogs stay on their own workspace** | Dictation Pad, Settings and other standalone windows no longer bind to other windows on Wayland, so opening Settings no longer summons or minimizes the Dictation Pad with it (#1024; fixes #984 reported by @hopsayer) |
|
||||
| **Ctrl+mouse-wheel zoom works** | Ctrl key events pass through for applications again, so holding Ctrl and scrolling zooms in Firefox and elsewhere even with a double-tap Ctrl shortcut configured (#967 by @loject; fixes #950 reported by @loject) |
|
||||
| **Upgrade mode in the installer** | `install.sh` on an existing install offers and defaults to an upgrade that keeps your configuration and models, and `bash /tmp/vl.sh --upgrade` runs it non-interactively (#1026; fixes #1009 reported by @plaffitt) |
|
||||
|
||||
### Also in v0.18.5
|
||||
|
||||
- Paste-injection copies are marked sensitive (`wl-copy --sensitive`) on wl-clipboard 2.2+, so clipboard managers that honor the hint, such as Klipper or cliphist, keep dictated text out of their history; the xclip/xsel path and older wl-copy have no such hint (#956 by @Nosion)
|
||||
- AUR source publication is gated on attested release sdists: the recipe is prepared only from the canonical sdist whose checksum and build provenance verify against this repository's release workflow (#1020 by @sesav)
|
||||
- The tray prefers libayatana-appindicator-glib when it is available (#1019; fixes #1013 reported by @jo-so)
|
||||
- The Snap package lists PulseAudio microphones and explains that its whisper.cpp build is CPU-only (#1018; fixes #1011 reported by @cmcclung-ANGENG)
|
||||
- The Wayland fallback overlay stays alive when the dock closes it, covering the leftover case from 0.18.4 (#1017; fixes #1010 reported by @lavoie005)
|
||||
- uv pins are aligned across CI and the release workflows (#1016 by @sesav), release build tooling is pinned with a reproducible-wheel gate (#945 by @sesav), the supported uv range is widened with Fedora/AppImage build hardening (#952 by @sesav), and Dependabot bumps cover pip and GitHub Actions plus flagged vulnerable dependencies (#1014, #1015, #1008 by @Mr-Sunglasses)
|
||||
|
||||
AppImage, Flatpak, and Snap still ship whisper.cpp only.
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.5).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.18.4
|
||||
|
||||
0.18.4 is a **patch** on the stable line. Default engine is still whisper.cpp. It closes the reports filed after 0.18.3: long dictations keep all their audio, model downloads are always your decision, Test Dictation and the Dictation Pad stop competing for text, and GPU and thread selection match what whisper.cpp actually runs on.
|
||||
|
||||
### 0.18.4 highlights
|
||||
|
||||
| Fix | Description |
|
||||
|---------|-------------|
|
||||
| **Long dictations kept whole** | Push-to-talk recordings past the buffer cap are queued for transcription in segments, so a 44.1 kHz mic no longer loses everything after about two minutes (#976 by @dishanood; fixes #975 reported by @dishanood) |
|
||||
| **Explicit model downloads** | Settings never schedules a download on its own. Every download asks first with its size, Cancel cancels the whole change without freezing the dialog, picking a model keeps your language settings, and [docs/MODEL_SELECTION.md](MODEL_SELECTION.md) has a hardware to model guide (#1006; fixes #979, #980, #981, #982, #985, #988 reported by @hopsayer) |
|
||||
| **Test Dictation and the Dictation Pad** | Test Dictation always shows its own result, and "Dictate into Dictation Pad" now lives in Settings > Dictation next to an Open Dictation Pad button (#1005; fixes #983, #986 reported by @hopsayer) |
|
||||
| **GPU picker and CPU threads** | The GPU list follows ggml's own device enumeration, the log reports the backend actually in use, and CPU runs size threads from your core count instead of 2 (#1001; fixes #987, #990 reported by @hopsayer) |
|
||||
| **Cancel a transcription** | Press the recording hotkey again, use the tray item, or click Cancel in Test Dictation to drop a slow transcription. Nothing is typed or added to history (#1004; fixes #991 reported by @hopsayer) |
|
||||
| **Slovenian** | `sl` is a supported language in Settings and in language shortcuts (#995; fixes #970 reported by @samodadela) |
|
||||
|
||||
### Also in v0.18.4
|
||||
|
||||
- Keyboards whose evdev node also reports pointer axes, such as the Logitech K860, are monitored again without being grabbed, so `right_alt` and other hotkeys fire (#978 by @ikarius; fixes #953 reported by @dherdt)
|
||||
- The Flatpak bundles onnxruntime, so Silero VAD works there instead of falling back to amplitude VAD (#1002; fixes #969 reported by @samodadela)
|
||||
- The Flatpak uses the X11 hotkey listener on native X11 sessions, so it no longer needs `--device=all` there (#997; fixes #971 reported by @samodadela)
|
||||
- RemoteDesktop portal requests each get a unique handle token, which fixes the missing GNOME consent dialog and the 15 second timeout (#996; fixes #993 reported by @hal2100)
|
||||
- XWayland apps that are not connected to IBus, such as SoftMaker TextMaker, receive text through xdotool (#1003; fixes #972 reported by @kdseattlewa)
|
||||
- On GNOME Wayland the dictation overlay is mapped at startup, so the first recording no longer steals focus from the app you are typing into (#998; fixes #992 reported by @lavoie005)
|
||||
- `install.sh --engine=parakeet` installs a working Parakeet engine again (#1000; fixes #973 reported by @Ma6nus)
|
||||
- Update checks follow the build channel, so stable installs only hear about stable releases, and Settings can turn them off (#999; fixes #977 reported by @hopsayer)
|
||||
- Faster Settings, typing and dictation, plus mypy as a CI gate (#968)
|
||||
|
||||
AppImage, Flatpak, and Snap still ship whisper.cpp only.
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.4).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.18.3
|
||||
|
||||
0.18.3 is a **patch** on the stable line. Default engine is still whisper.cpp. This one is all fixes: "new line" and "new paragraph" finally insert real line breaks, hotkeys come back on GNOME Shell X11, packaged builds stop crashing on older CPUs, and the Snap package can publish again now that the denied `uinput` plug is gone.
|
||||
|
||||
### 0.18.3 highlights
|
||||
|
||||
| Fix | Description |
|
||||
|---------|-------------|
|
||||
| **Real line breaks** | "new line" and "new paragraph" insert an actual newline standalone or mid-utterance, and the stray punctuation they used to leave behind is gone (#958, #962; fixes #955 reported by @rastarr) |
|
||||
| **GNOME X11 hotkeys** | Push-to-talk and toggle shortcuts work on gnome-shell X11 sessions again; the app now prefers the evdev backend there (#963; fixes #954 reported by @jepst) |
|
||||
| **Layout restore on quit** | Quitting no longer collapses a multi-layout keyboard map (us,de staying us,de) because the IBus engine restore is skipped when a real engine is already active (#963) |
|
||||
| **Older CPUs unblocked** | Snap, Flatpak, AppImage and the .deb/.rpm builds now compile the bundled pywhispercpp at the true x86-64 baseline, ending the SIGILL crash on pre-Haswell processors (#959; fixes #957 reported by @bucketsofmail) |
|
||||
| **Snap can publish** | The `uinput` plug the Snap Store denied is removed, so new revisions clear automatic review again; Wayland typing uses the RemoteDesktop portal (#960) |
|
||||
|
||||
### Also in v0.18.3
|
||||
|
||||
- The Flatpak remote publish warns on the release run when its secrets are not configured, instead of skipping silently for tags (#961; fixes #951 reported by @andreacasini)
|
||||
- README gains a badge row for every install format plus a Nix flake section (#949)
|
||||
- Transcribe File's modal model-download dialog now closes itself once TinyDiarize lands, releasing its grab so the transcript's Copy and Save As buttons are clickable (#965; found during release e2e testing)
|
||||
|
||||
AppImage, Flatpak, and Snap still ship whisper.cpp only.
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.3).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.18.2
|
||||
|
||||
0.18.2 is a **patch** on the stable line. Default engine is still whisper.cpp. The headline is a livelier dictation overlay plus a round of fixes: the overlay orb now reacts to live microphone level, Nix users get a flake package with NixOS and Home Manager modules and Vulkan GPU inference, and the dictation shortcut can no longer strand a key when you are typing while the app starts.
|
||||
|
||||
### 0.18.2 highlights
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Live mic orb** | Dictation overlay orb pulses and ripples with your real audio level instead of sitting static (#940) |
|
||||
| **Nix packaging** | Flake package plus NixOS and Home Manager modules (#936), and Vulkan GPU inference for pywhispercpp on Nix (#942) |
|
||||
| **Safer startup grab** | A keyboard with a held key or queued key events is left ungrabbed at startup, so typing during launch cannot stick a key on the desktop (#941) |
|
||||
| **Older CPU fix** | Bundled pywhispercpp builds no longer use -march=native, so AppImage and Flatpak stop crashing on CPUs without the build host's instruction set (#939) |
|
||||
| **Piped installer** | `curl \| bash` keeps the script on stdin and prompts via /dev/tty, so interactive prompts work mid-pipe (#935) |
|
||||
|
||||
### Also in v0.18.2
|
||||
|
||||
- Installer package map covers cairo headers on openSUSE, Void, Solus and Alpine (#937)
|
||||
- evdev monitors remapper virtual keyboards ungrabbed so remappers like keyd keep working (#932)
|
||||
- The install section on vocalinux.com showcases the .deb, .rpm, Snap, Flatpak and AUR packages (#929)
|
||||
- The remote `curl | bash` install path is gated end to end in CI (#898)
|
||||
|
||||
AppImage, Flatpak, and Snap still ship whisper.cpp only.
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.2).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.18.1
|
||||
|
||||
0.18.1 is a **patch** on the stable line. Default engine is still whisper.cpp. This one is a reliability release: most of it is fixes, and the new features are plumbing you will notice only when you need it. Settings gains a Proxy page so model downloads and update checks work behind SOCKS5 and HTTP proxies, and an opt-in switch that persists transcripts to disk so a failed injection stops meaning a lost sentence. Releases now attach native .deb and .rpm packages, and the tray menu drops Start on Login and About (both already lived in Settings).
|
||||
|
||||
### 0.18.1 highlights
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Proxy settings** | New Settings -> Proxy page: off, system, or manual SOCKS5/HTTP CONNECT with optional auth; covers every model download and the update checker (#909, fixes #655) |
|
||||
| **Transcript persistence** | Opt-in JSONL history on disk; a transcript survives restarts and failed injections (#907, fixes #758) |
|
||||
| **Native packages** | Thin .deb and .rpm for Debian/Ubuntu and Fedora, x86_64 and aarch64, attached to the GitHub Release (#913, step 1 of #600) |
|
||||
| **Slimmer tray menu** | Start on Login and About removed from the tray; both already live in Settings (#905, fixes #654) |
|
||||
| **Staged model picker** | Speech Model Advanced pickers no longer start a download per click; changes stage until you confirm Download (#908, fixes #894) |
|
||||
| **Wayland pad fix** | Dictation Pad no longer ghosts away after sitting idle under a Wayland compositor (#912, fixes #896) |
|
||||
|
||||
### Also in v0.18.1
|
||||
|
||||
- Startup reuses an on-disk same-size whisper.cpp weight instead of re-resolving or re-downloading it (#923, fixes #916 reported by @blacxsnow)
|
||||
- Text injection ends option parsing before typed text, so a chunk starting with `-` no longer fails as an unrecognized option and truncates the dictation (#922, fixes #921)
|
||||
- KDE Plasma 6 Wayland: KWin VirtualKeyboard detection fixed, so dictated letter case stops scrambling (#919, fixes #911 reported by @blackde5ert)
|
||||
- evdev keyboard discovery tightened: pointer-motion devices, multitouch-only touchpads, and devices without a real keyboard key are no longer grabbed as keyboards, so hotkey enablement stops breaking Logitech mice and Goodix touchpads (#902, #917, #918, fixes #900 reported by @brainygamer, #914 reported by @pylame22, #915 reported by @uncletoxa)
|
||||
- Test Dictation transcription readout moved above its controls in the sidebar footer (#904, fixes #677 reported by @hopsayer)
|
||||
- `uninstall.sh` no longer deletes files in the directory you ran it from (#901, fixes #897 reported by @SilverChatte)
|
||||
- Settings > Advanced Initial Prompt accepts typed input again (clicks were being stolen by the enclosing row), and transcript and log saves no longer write a doubled `.txt.txt` name (#927)
|
||||
- Packaging: `.deb` declares `python3-socks` and `.rpm` declares `python3-pysocks` for SOCKS5 proxy support (#920)
|
||||
- CI: snap attach uses `--repo`, checksums still publish when an asset attach fails, the Vulkan pywhispercpp build is reused across runs, and the remote `curl | bash` install path is gated end to end (#899, #903, #906)
|
||||
|
||||
AppImage, Flatpak, and Snap still ship whisper.cpp only.
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.1).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.18.0
|
||||
|
||||
0.18.0 is a **minor** on the stable line. Default engine is still whisper.cpp. The headline fix is a grab of the dictation hotkey so the shortcut stops leaking into the app under it. Alongside it is a set of Wayland-native paths: an in-app Dictation Pad that keeps text off the fragile injection routes entirely, PipeWire capture (microphone and system audio), and a RemoteDesktop portal injection backend. Dictation gains per-language shortcuts, a tray history menu, a floating overlay, and audio ducking. Long-requested contributor work lands here too: D-Bus activation for compositor global shortcuts, bilingual language candidates, a postprocessing script hook, a custom dictionary with corrections, and file transcription with speaker labels.
|
||||
|
||||
### 0.18 series highlights
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Dictation Pad** | In-app window that receives dictation; you copy text out by hand, so Wayland injection quirks cannot touch it (#887, fixes #726) |
|
||||
| **Hotkey suppression** | evdev grabs the dictation shortcut and forwards everything else through a uinput clone; the key no longer types into the focused app (#873, #893, fixes #871) |
|
||||
| **PipeWire capture** | Mic and system-audio sources through the native PipeWire path, not just PortAudio (#889, #883, fixes #751, #760) |
|
||||
| **RemoteDesktop injection** | Wayland text injection through the RemoteDesktop portal, no ydotoold needed (#885, fixes #750) |
|
||||
| **Per-language shortcuts + history** | A dictation shortcut per language, layout-follow while dictating, and recent dictations in the tray menu (#880, #837, #487, fixes #805, #821) |
|
||||
| **File transcription with speakers** | `--transcribe-file` with TinyDiarize per-speaker labels, plus a transcript viewer (#884, fixes #756) |
|
||||
| **D-Bus activation** | Opt-in D-Bus methods so compositor global shortcuts (and scripts) can start dictation (#568, fixes #761) |
|
||||
| **Custom dictionary** | Terms bias plus transcript corrections from one file (#890) |
|
||||
|
||||
### Also in v0.18.0
|
||||
|
||||
- Postprocessing script hook pipes transcriptions through a user command (#479 by @karottenreibe)
|
||||
- Bilingual dictation: configurable second-language Whisper candidates, with deferred settings edits (#424 by @juanfradb)
|
||||
- Optional verified Orukeet model for the Parakeet engine (#840 by @Nathan-Roll1)
|
||||
- Keep recording while an idle-unloaded model reloads instead of dropping the utterance (#851 by @mre31)
|
||||
- Floating glowing dictation overlay and lowering of other audio while dictating (#516, #861)
|
||||
- `config.json` can pin the text-injection backend (#649 by @HashimAbdulaziz, fixes #476 reported by @waldemar-p)
|
||||
- Alt+Shift and Win+Space layout switching keeps working on GNOME Wayland (#876, fixes #848 reported by @hopsayer)
|
||||
- Shortcut recorder learns unmapped F19/F24 and XF86-aliased F13-F23 (#844, fixes #843 reported by @bisgardo)
|
||||
- Vosk refuses to load a model that would exceed available memory instead of tripping the OOM killer (#850 by @AmirF194, fixes #676 reported by @hopsayer)
|
||||
- IBus guard no longer flips GNOME/X11 to a US layout (#827 by @AmirF194)
|
||||
- Model downloads cancel cleanly even when the fetch stalls, and the download dialog shows verifying instead of a stalled 100% (#888, #864 by @guilhermefeitosa66, fixes #679, #863)
|
||||
- Settings: scrollable category list, Dictation Tone grayed while sound effects are off, Test Dictation textbox artifact and missing transcription fixed, speech-model follow-ups (#886, #877, #853, #836, fixes #678, #849, #847, #720, #834)
|
||||
- Update checker falls back when GitHub API rate-limits instead of erroring (#846, fixes #845 reported by @lmstud)
|
||||
- Audio: stop passing an explicit index when zero devices enumerate; View Logs closes via the titlebar X (#891, #892)
|
||||
- Snap gains `hardware-observe` so hotkeys can read input devices (#858, fixes #857 reported by @RhysU)
|
||||
- Installer installs hash-pinned dependencies and build tools, and is split into sourced modules with a generated distro package map (#856, #862, #872 by @sesav)
|
||||
- AUR `vocalinux-bin` ships the AppImage with per-arch digests; releases publish a signed self-hosted Flatpak OSTree remote; a snap-promote workflow gates stable promotion (#879, #875, #881, fixes #817, #785, #783)
|
||||
- VocaGateway can run locally from Settings → Advanced (podman-first) (#774)
|
||||
- Dependency advisories cleared and workflow tokens scoped to repository reads (#869, #865, #866 by @Mr-Sunglasses, #870)
|
||||
- Settings dialog consolidated: guard flags and widget construction in one place each (#878, fixes #793)
|
||||
|
||||
AppImage, Flatpak, and Snap still ship whisper.cpp plus the same engine matrix as 0.17.
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.18.0).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.17.0
|
||||
|
||||
0.17.0 is a **minor** on the stable line. Default engine is still whisper.cpp. This release adds two optional local engines (Faster Whisper and Parakeet), a simpler Speech Model page, Snap packaging with native Wayland typing, and Flatpak bundles built by the release workflow. It also fixes XWayland/layout paste, a KDE xdotool crash, push-to-talk tray redraw, clipped start/stop cues, HDA analog mics that abort when opened below native channel count, native GTK installs that ignored OS dark/light, and English-only models that hid every other language.
|
||||
|
||||
### 0.17 series highlights
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Faster Whisper** | Optional CTranslate2 / INT8 Whisper on CPU (`--engine=faster_whisper`) (#543) |
|
||||
| **Parakeet** | Optional Parakeet TDT 0.6B via sherpa-onnx; default v3-european bundle (`--engine=parakeet`) (#802) |
|
||||
| **Speech Model simple setup** | Language + speed/accuracy first; engine/size under Advanced (#801) |
|
||||
| **First-run language** | Seeds from keyboard layout / locale; saved choice is left alone (#796) |
|
||||
| **Searchable open picker** | Language list filters while open (#798) |
|
||||
| **Localized punctuation commands** | it/fr/de/es/pt/nl/pl/ru; English phrases still work (#642) |
|
||||
| **Bare F-keys** | F1–F24 are valid push-to-talk shortcuts (#815) |
|
||||
| **Snap** | Store listing, ydotool + `uinput` for native Wayland. The Store later denied the `uinput` grant, so the plug was dropped and Wayland typing moved to the RemoteDesktop portal (#519, #823, #822) |
|
||||
| **Flatpak on the tag** | Workflow attaches `.flatpak` assets and checksums them (#786) |
|
||||
|
||||
### Also in v0.17.0
|
||||
|
||||
- Recommended model is a button that sets size and specialization together, and will not ignore a suitable file already on disk (#797)
|
||||
- XWayland xdotool fallback pastes via clipboard so missing-layout characters are not garbled (#680)
|
||||
- Clipboard paste uses the key that types **v** on the current layout (#788)
|
||||
- Timed-out ydotool paste releases Ctrl (#675)
|
||||
- Read `WM_CLASS` with `xprop` instead of crashing `xdotool getwindowclassname` on KDE Plasma Wayland (#807)
|
||||
- Applying an already-downloaded model no longer freezes Settings (#790)
|
||||
- Selected language picks the whisper.cpp variant (English → `.en`). Picking another language, or auto-detect, switches off `.en` / `.en-q*` instead of hiding the rest of the list (#795, #780, #826)
|
||||
- Speech Model labels are nouns (Language, Other languages, Speed vs accuracy). Unused downloads is a sibling expander of Advanced, not nested inside it (#826)
|
||||
- About family grid includes VocaWin (#826)
|
||||
- Push-to-talk tray icon turns red on every hold (#809)
|
||||
- Sink-wake no longer clips start/stop cues (#804)
|
||||
- Open 3-8 channel HDA analog mics at native layout instead of forcing 2ch/48kHz, so PortAudio no longer aborts after read() (`free(): corrupted unsorted chunks`); capture is downmixed to mono for engines (#829, fixes #813)
|
||||
- Native GTK installs (AUR / install.sh) follow OS dark/light via the appearance portal then gsettings; skipped when `GTK_THEME` is set so AppImage and user overrides stay in charge (#830, fixes #816)
|
||||
- Parakeet keeps recognizing after a decode error (#803)
|
||||
- Flatpak/AUR deps derived from `uv.lock` (#819)
|
||||
- Hash-pinned exports for VOSK, Parakeet, and Faster Whisper extras so `install.sh` no longer installs those unpinned; extras are version-capped (#828)
|
||||
- `just verify-release` checks the published GitHub Release (#791)
|
||||
- Distro matrix runs `install.sh` (#810)
|
||||
- `install.sh` Faster Whisper box is CPU CTranslate2 / INT8, not NVIDIA CUDA. The whisper.cpp GPU step does not install the CUDA toolkit; Vulkan is first, CUDA only if a toolkit is already on the machine (#826)
|
||||
|
||||
AppImage, Flatpak and Snap remain whisper.cpp only. Faster Whisper and Parakeet are optional extras on `install.sh` / source installs.
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.17.0).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.16.2
|
||||
|
||||
0.16.2 is a **stability patch** on the 0.16 series. The feature set is the same as 0.16.x. This release fixes KDE leftover IBus so dictation types into real apps, Wayland and IBus keyboard shortcuts through wtype/ydotool, real BackSpace for "delete that", Fedora/Arch installer glslc packages, nightly version stamping, and release integrity pins. CI now gates AUR PKGBUILD builds and the distros the docs promise.
|
||||
|
||||
### 0.16 series highlights
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Update checker** | Settings → About checks stable/nightly; tray shows Update Available for newer GitHub releases (#631, #645) |
|
||||
| **Right Alt PTT default** | New installs default to hold Right Alt (push-to-talk); existing configs keep their shortcut (#648) |
|
||||
| **Searchable languages** | Type to filter the Speech Model language list (#672) |
|
||||
| **Delete unused models** | Remove leftover downloaded speech models from Settings (#671) |
|
||||
| **AGPL-3.0** | License aligned with other VocaHQ projects (#660) |
|
||||
| **Family mic icons** | App icon, tray states, and site favicons use the shared Voca family mic (#704) |
|
||||
| **Tone picker** | Settings → Audio: Lift, Flick, Ember, Step, Voca, Soft, Chirp, Scale, Drop, Glass, Off, plus Preview. New installs default to Voca. Catalog uses family preview WAVs (#707, #708) |
|
||||
| **Installer** | Justfile, uv lockfiles, distro python3-gi required (no pip sdist of PyGObject). Epic #701 still open (#700, #705, #706) |
|
||||
|
||||
### Bug fixes in v0.16.2
|
||||
|
||||
- **KDE inject**: skip leftover IBus when it is not the session IM so dictation types into Kate, browsers, and terminals (#753 by @jatinkrmalik, fixes #752 by @justTravis)
|
||||
- **Wayland shortcuts**: wtype and ydotool deliver real chords instead of refusing or silently doing nothing (#715 by @eiseleb47)
|
||||
- **IBus shortcuts**: route X11_IBUS through xdotool and WAYLAND_IBUS through wtype/ydotool (#716 by @eiseleb47)
|
||||
- **Delete that**: send real BackSpace key events instead of U+0008 text (#714 by @eiseleb47)
|
||||
- **Installer**: Fedora and Arch need glslc/shaderc packages, not glslang (#763 by @jatinkrmalik, see #604)
|
||||
- **Nightly**: stamp `version.py` before `python -m build` so wheel metadata matches the filename (#762 by @sesav)
|
||||
- **Release integrity**: checksums, signatures, and pinned builders for release artifacts (#759 by @sesav, epic #701 phase 5)
|
||||
- **CI**: gate AUR PKGBUILD builds on every PR (#772 by @sesav)
|
||||
- **CI / docs**: test the distros the docs promise and fix docs drift (#773 by @sesav)
|
||||
- **Site**: VocaGateway family card is Beta; README logo, badges, and privacy copy (#765 by @jatinkrmalik, #764)
|
||||
- **Snap**: v0.16.2 `latest/edge` (rev 7) has no `uinput` plug. `sudo snap connect vocalinux:uinput` errors with `snap "vocalinux" has no plug named "uinput"`. Dictation only reaches XWayland apps. (v0.17.0+ added the plug, but the Store denied it, so later revisions drop it again and type via the RemoteDesktop portal.) (#823)
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.16.2).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.16.1
|
||||
|
||||
0.16.1 is a **stability patch** on the 0.16 series. The feature set is the same as 0.16.x. This release fixes wrong-model startup, leftover tray state after toggle stop, paste into terminals, GNOME XWayland layout after inject, and AppImages that needed a glibc newer than Debian 12. The installer now requires Python 3.11 and verifies model downloads.
|
||||
|
||||
### 0.16 series highlights
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Update checker** | Settings → About checks stable/nightly; tray shows Update Available for newer GitHub releases (#631, #645) |
|
||||
| **Right Alt PTT default** | New installs default to hold Right Alt (push-to-talk); existing configs keep their shortcut (#648) |
|
||||
| **Searchable languages** | Type to filter the Speech Model language list (#672) |
|
||||
| **Delete unused models** | Remove leftover downloaded speech models from Settings (#671) |
|
||||
| **AGPL-3.0** | License aligned with other VocaHQ projects (#660) |
|
||||
| **Family mic icons** | App icon, tray states, and site favicons use the shared Voca family mic (#704) |
|
||||
| **Tone picker** | Settings → Audio: Lift, Flick, Ember, Step, Voca, Soft, Chirp, Scale, Drop, Glass, Off, plus Preview. New installs default to Voca. Catalog uses family preview WAVs (#707, #708) |
|
||||
| **Installer** | Justfile, uv lockfiles, distro python3-gi required (no pip sdist of PyGObject). Epic #701 still open (#700, #705, #706) |
|
||||
|
||||
### Bug fixes in v0.16.1
|
||||
|
||||
- **Startup**: resolve model size per engine instead of the leftover generic `model_size` key, so a VOSK save does not make whisper.cpp look for a missing medium model (#684 by @kacperpaczos, fixes #681)
|
||||
- **Settings**: save the model only after the engine loaded it, so a cancelled or failed download does not leave config pointing at a file that is not on disk (#685 by @kacperpaczos)
|
||||
- **Settings**: unused downloads list sized to its real rows so leftover models are not clipped (#686 by @kacperpaczos, fixes #683)
|
||||
- **Config**: one ConfigManager for the process so Settings writes are not overwritten by a stale cache (#691 by @kacperpaczos, fixes #689)
|
||||
- **Tray**: stay idle after leftover transcription on toggle stop (#741)
|
||||
- **Tray**: the missing-model notification can download the recommended model (#687 by @kacperpaczos)
|
||||
- **Injection**: Ctrl+Shift+V when pasting into terminals, so Ctrl+V is not treated as verbatim insert (#734)
|
||||
- **IBus**: sync the XWayland layout from GNOME after scoped inject (#742)
|
||||
- **Installer**: survive a release without a checksum manifest; stop inventing GPUs (#736 by @sesav)
|
||||
- **Installer**: leftover engine repair, just `--no-sync`, ggml verify from #713 (#732)
|
||||
- **AppImage**: build against a glibc floor Debian 12 can run; boot tests on six distros (#743, #744 by @sesav)
|
||||
- **Installer**: Python 3.11 floor, uv tooling, verified model downloads (epic #701 phases 2.5 and 5) (#713 by @sesav)
|
||||
- **Settings / About**: even dropdowns, quieter About, family platform marks (#754)
|
||||
- **AUR**: `python -m build --no-isolation` works with Arch extra setuptools 84 (was capped at `<82`, AUR comment by simona). Skip `context_params` on AUR pywhispercpp 1.4.x so startup no longer dies with `whisper_full_params` (AUR comments by avocadoboat, Masalababa; GitHub #625)
|
||||
- **Docs**: canonical VocaHQ Discord invite; VocaWin is unsigned beta; screenshots page says v0.16; README family/on-device copy (#749, #733, #735, #737)
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.16.1).
|
||||
|
||||
---
|
||||
|
||||
## What's New in v0.16.0
|
||||
|
||||
0.16.0 is a **minor** release on the stable line. It adds an in-app update checker with tray notifications, defaults new installs to hold Right Alt push-to-talk, makes the language picker searchable, lets you delete unused downloaded models, and adds a family dictation tone picker. The license is AGPL-3.0. The installer is hardened (Justfile, uv lockfiles, distro python3-gi). The app icon, tray states, and site favicons use the shared Voca family mic.
|
||||
|
||||
### Highlights
|
||||
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Update checker** | Settings → About checks stable/nightly; tray shows Update Available for newer GitHub releases (#631, #645) |
|
||||
| **Right Alt PTT default** | New installs default to hold Right Alt (push-to-talk); existing configs keep their shortcut (#648) |
|
||||
| **Searchable languages** | Type to filter the Speech Model language list (#672) |
|
||||
| **Delete unused models** | Remove leftover downloaded speech models from Settings (#671) |
|
||||
| **AGPL-3.0** | License aligned with other VocaHQ projects (#660) |
|
||||
| **Family mic icons** | App icon, tray states, and site favicons use the shared Voca family mic (#704) |
|
||||
| **Tone picker** | Settings → Audio: Lift, Flick, Ember, Step, Voca, Soft, Chirp, Scale, Drop, Glass, Off, plus Preview. New installs default to Voca. Catalog uses family preview WAVs (#707, #708) |
|
||||
| **Installer** | Justfile, uv lockfiles, distro python3-gi required (no pip sdist of PyGObject). Epic #701 still open (#700, #705, #706) |
|
||||
|
||||
### New Features
|
||||
|
||||
- **In-app update checker**: Settings → About with stable/nightly channels (#631)
|
||||
- **Update notifications**: Tray menu Update Available entry and About badge when a newer release exists (#645)
|
||||
- **Right Alt push-to-talk default**: New installs only; existing configs are unchanged (#648)
|
||||
- **Searchable language combobox**: Filter the long language list by name or code (#672, fixes #652)
|
||||
- **Delete unused models**: Remove leftover downloaded speech models from Settings (#671, fixes #650)
|
||||
- **Disable missing-tray warning**: Settings toggle for desktops that false-positive the tray check (#628, fixes #620)
|
||||
- **Family mic icons**: App icon, tray states, and site favicons use the shared Voca family mic instead of the old Linux rounded-rect (#704)
|
||||
- **Family dictation tone picker**: Settings → Audio dropdown (Lift, Flick, Ember, Step, Voca, Soft, Chirp, Scale, Drop, Glass, Off) plus Preview. New installs and unknown saved names default to Voca. A saved catalog id, including Off, is left alone. Enable remains the master mute; Off skips start/stop only (#707)
|
||||
- **About page**: Settings → About groups this app, VocaHQ family sites, and talk-to-us (GitHub issues, Discord, X, email) (#718)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **IBus**: Require a restorable engine for scoped injection (#623); restore engine after `register_component` teardown (#643, fixes #558); restore XKB layout after scoped injection on X11 (#665, fixes #664)
|
||||
- **Injection**: Stop typing `test` during the wtype probe (#627, fixes #622)
|
||||
- **whisper.cpp**: Skip unsupported `context_params` on pywhispercpp 1.4 (#626, fixes #625); use CUDA device 0 when CUDA-backed (#636); honor bundled GPU libs and skip software Vulkan devices (#674)
|
||||
- **Audio**: Filter unsafe virtual capture devices (#629, fixes #624); open stereo mics at native channel count (#673, fixes #666); catalog tones are the family preview WAVs, not the synthesized #707 files. `generate_sounds.py` does not clobber catalog ids (#708)
|
||||
- **Tray / Settings**: Prefer Ayatana AppIndicator on KDE (#621); reuse Settings/Logs windows (#669, fixes #653); separate Close from Test Dictation (#670, fixes #651)
|
||||
- **Settings**: Test Dictation no longer reports no speech when recognition never started (missing model / auto-pause / live engine out of sync) (#702)
|
||||
- **Clipboard**: Restore after ydotool clipboard-paste (#588); text-only reads and safer overlapping restore (#646)
|
||||
- **AppImage**: Ship transitive GI typelibs for non-Debian hosts (also hotfixed onto the v0.15.0 AppImages on 2026-08-03) (#637); pin pywhispercpp to the version `install.sh` declares so a newer PyPI wheel cannot break the Vulkan rebuild (#718)
|
||||
- **Installer**: Distro python3-gi is required; pip no longer builds PyGObject from sdist. Unset `XDG_SESSION_TYPE` / `XDG_CURRENT_DESKTOP` no longer crash under `set -u` (#706)
|
||||
- **Installer / downloads / tests**: Gate `util-linux-extra` to Ubuntu 24.04+ (#635, fixes #526); report failed model downloads (#690); stop the suite from overwriting real `config.json` (#694)
|
||||
|
||||
### Docs / maintenance
|
||||
|
||||
- Website screenshot refresh for v0.15 (#630)
|
||||
- Prefer Ayatana AppIndicator in Fedora/Arch packaging hints (#638)
|
||||
- CUDA device 0 note for dual NVIDIA (#644)
|
||||
- Discord and VocaHQ README shields; VocaHQ URL migration; VocaGateway rename (#695, #696, #697)
|
||||
- Discord invite and X handle point at VocaHQ (#722)
|
||||
- vocalinux.com restyled to the Voca family workbench; Open Graph card uses the flat Tux (#728, #729)
|
||||
- Website copy drops the stale 100% offline claim and marks VocaWin as alpha on the site (#717)
|
||||
- Codeberg mirror tag force-push (#633)
|
||||
- Installer hardening, Justfile in place of Makefile, and uv lockfiles with pinned build inputs. Epic #701 remains open (#700, #705 by @sesav)
|
||||
|
||||
See the [full changelog](https://github.com/VocaHQ/vocalinux/releases/tag/v0.16.0).
|
||||
|
||||
---
|
||||
|
||||
## Older releases
|
||||
|
||||
Notes for v0.15.0 and earlier live on GitHub Releases:
|
||||
|
||||
- [v0.15.0](https://github.com/VocaHQ/vocalinux/releases/tag/v0.15.0)
|
||||
- [v0.14.2](https://github.com/VocaHQ/vocalinux/releases/tag/v0.14.2)
|
||||
- [v0.14.1](https://github.com/VocaHQ/vocalinux/releases/tag/v0.14.1)
|
||||
- [v0.14.0-beta](https://github.com/VocaHQ/vocalinux/releases/tag/v0.14.0-beta)
|
||||
|
||||
Full history: https://github.com/VocaHQ/vocalinux/releases
|
||||
|
||||
---
|
||||
|
||||
## Need help?
|
||||
|
||||
- [Installation guide](INSTALL.md)
|
||||
- [Troubleshooting](TROUBLESHOOTING.md)
|
||||
- [User guide](USER_GUIDE.md)
|
||||
- [Support](../SUPPORT.md)
|
||||
- [Report issues](https://github.com/VocaHQ/vocalinux/issues)
|
||||
- [Discussions](https://github.com/VocaHQ/vocalinux/discussions)
|
||||
- [Discord](https://discord.gg/t6muquAJbm)
|
||||
@@ -0,0 +1,371 @@
|
||||
# User guide
|
||||
|
||||
How to use Vocalinux day to day. Install first: [INSTALL.md](INSTALL.md).
|
||||
|
||||
## Getting started
|
||||
|
||||
1. Launch Vocalinux (`vocalinux` or the application menu)
|
||||
2. Find the microphone icon in the system tray
|
||||
3. Start dictation with the tray menu or your keyboard shortcut
|
||||
4. Speak into the focused application; text is injected when an utterance completes
|
||||
5. Stop by releasing the key (push-to-talk, default on new installs) or with the same shortcut (toggle)
|
||||
|
||||
### Start on login
|
||||
|
||||
Enable **Start on Login** from the first-run dialog, tray menu, or Settings. Vocalinux writes an XDG autostart entry (`~/.config/autostart/vocalinux.desktop`) and starts as a normal user app (`--start-minimized`). It does not create a systemd service.
|
||||
|
||||
Works on common desktop environments (GNOME, KDE, Xfce, Cinnamon, MATE, LXQt). Minimal window-manager sessions may need their own autostart helper.
|
||||
|
||||
### Status icons
|
||||
|
||||
| Icon state | Meaning |
|
||||
|------------|---------|
|
||||
| Gray (off) | Inactive |
|
||||
| Blue (on) | Listening |
|
||||
| Orange | Processing speech |
|
||||
|
||||
### Dictation formatting
|
||||
|
||||
Vocalinux capitalizes the start of dictation and letters after `.`, `!`, or `?`. Each completed utterance leaves a trailing space so the next session does not glue onto the previous sentence.
|
||||
|
||||
### Dictating into terminals
|
||||
|
||||
When Vocalinux injects through the clipboard (the usual Wayland / ydotool path), it sends **Ctrl+V** in ordinary text fields and **Ctrl+Shift+V** in terminal emulator windows. Auto-detect works on X11 and on Hyprland, Sway, and niri. On GNOME or KDE Wayland, set **Settings → Dictation → Clipboard Paste Shortcut** to **Ctrl+Shift+V**.
|
||||
|
||||
On non-US layouts such as German Neo, that chord uses the key that types **v** on the active layout (not physical KEY_V). Nested terminal panels inside an IDE are often invisible to window-class detection. If paste lands as a literal `^V` or does nothing, open **Settings → Dictation → Clipboard Paste Shortcut** and choose **Ctrl+Shift+V**.
|
||||
|
||||
On X11, **Paste long dictations** opts in to clipboard-pasting dictations of 30 or more characters instead of typing them key by key. It is off by default. Vocalinux restores the previous clipboard contents after pasting unless **Copy to Clipboard** is enabled. If the clipboard contains an image or other non-text content, Vocalinux types the dictation and leaves that content alone.
|
||||
|
||||
The clipboard copy behind these pastes is temporary: your previous clipboard comes back right after. When the copy goes through `wl-copy` 2.2 or newer, it is also marked sensitive (`wl-copy --sensitive`), and clipboard managers that honor that hint, such as Klipper or cliphist, keep it out of their history. Older `wl-copy` builds and X11 or XWayland pastes (`xclip`/`xsel`) have no such hint, so there the dictated text can still show up in history. With **Settings → Dictation → Copy to Clipboard** on, the dictated text is an ordinary copy and stays in history.
|
||||
|
||||
**Other audio.** Settings → Audio → Other audio can lower speakers and headphones while the microphone is open, then put that volume back. It stays off until you turn it on. Level while dictating is a percent of the current volume (0 is silent). Quitting mid-dictation puts the volume back; if the app crashes first, the next launch does.
|
||||
|
||||
## Audio input
|
||||
|
||||
Open **Settings → Audio → Input Device** to select a specific microphone or choose
|
||||
**System Default**. A valid explicit microphone selection uses that device and
|
||||
bypasses the System Default preference below.
|
||||
|
||||
With **System Default**, Vocalinux leaves valid default or virtual inputs under
|
||||
the audio system's control rather than pinning a hardware device.
|
||||
|
||||
On ALSA only, if PortAudio substitutes arbitrary hardware for the default input,
|
||||
Vocalinux prefers an input-capable `pulse` PCM on the same host API to follow the
|
||||
microphone selected in desktop sound settings. If no suitable `pulse` PCM exists,
|
||||
it keeps PortAudio's fallback device and logs a warning.
|
||||
|
||||
## Shortcuts
|
||||
|
||||
Configure under **Settings → Shortcuts**:
|
||||
|
||||
| Mode | Behavior |
|
||||
|------|----------|
|
||||
| **Push-to-talk** (default on new installs) | Hold Right Alt (Option on Mac-layout keyboards) while speaking; release to stop |
|
||||
| **Toggle** | Double-tap the configured shortcut key to start/stop |
|
||||
|
||||
Existing configs keep their saved shortcut. Left/right modifier keys and custom modifier+key combos (for example `Alt+R`) are supported.
|
||||
|
||||
Enable **Pass Shortcut Keys to Applications** under **Settings → Dictation → Keyboard Shortcuts** to keep modifier actions such as Ctrl+mouse-wheel zoom working. Dictation still detects the configured shortcut, but the shortcut keys will also reach the foreground app, which may respond to them. This is off by default.
|
||||
|
||||
## Voice commands
|
||||
|
||||
Optional spoken commands for punctuation and editing (can be disabled in Settings).
|
||||
English phrases always work. With a non-English recognition language, matching
|
||||
punctuation and line-break phrases in that language are also recognized
|
||||
(Italian *virgola* / *punto*, French *virgule* / *point*, and similar).
|
||||
|
||||
| Command | Action |
|
||||
|---------|--------|
|
||||
| "new line" / "new paragraph" | Line break |
|
||||
| "period" / "full stop" / "dot" | `.` |
|
||||
| "comma" | `,` |
|
||||
| "question mark" | `?` |
|
||||
| "exclamation point" / "exclamation mark" | `!` |
|
||||
| "semicolon" | `;` |
|
||||
| "colon" | `:` |
|
||||
| "delete that" / "scratch that" | Delete last sentence |
|
||||
| "capitalize" / "uppercase" | Capitalize next word |
|
||||
| "all caps" | Next word in ALL CAPS |
|
||||
|
||||
Editing and formatting action phrases (`delete that`, `undo`, `capitalize`, and similar)
|
||||
are currently English-only.
|
||||
|
||||
## Engines and models
|
||||
|
||||
Open **Settings → Speech Model**. The page starts with a simple setup (language and speed/accuracy). Expand **Advanced** for engine, model size, and specialization. Sidebar search (Ctrl+F) works across pages.
|
||||
|
||||
### Engines
|
||||
|
||||
| Engine | Best for | GPU | Footprint |
|
||||
|--------|----------|-----|-----------|
|
||||
| **whisper.cpp** (default) | Most users | Vulkan (AMD, Intel, NVIDIA) | ~74MB default model |
|
||||
| **Whisper** (OpenAI) | PyTorch/CUDA workflows | NVIDIA/CUDA | Large (PyTorch stack) |
|
||||
| **Faster Whisper** | CPU Whisper (CTranslate2 / INT8) | Optional CUDA | Similar model sizes to Whisper |
|
||||
| **VOSK** | Low RAM / older machines | CPU | ~40MB |
|
||||
| **Parakeet** | CPU dictation; 25 European languages | CPU | ~639MB v3-european |
|
||||
| **Remote API** | Offload to a server | N/A (server-side) | Opt-in; see [HTTP_REMOTE.md](HTTP_REMOTE.md) |
|
||||
|
||||
Parakeet runs NVIDIA NeMo ASR models through sherpa-onnx. The default bundle is **v3-european** (25 European languages). **v2-english** is English-only. Parakeet ignores the catalog language picker (language is treated as auto).
|
||||
|
||||
### Language
|
||||
|
||||
Pick the language you dictate in from **Language**, or leave it on auto-detect.
|
||||
|
||||
If you work in more than one language and switch keyboard layouts to do it, turn
|
||||
on **Follow keyboard layout** instead. Vocalinux then reads your active layout at
|
||||
the start of every dictation and uses the matching language, so switching layout
|
||||
switches dictation language with it. The Language picker greys out while this is
|
||||
on and shows what your current layout resolves to; turning it off pins that
|
||||
language.
|
||||
|
||||
Available for whisper.cpp, Whisper, Faster Whisper, and Remote API. VOSK loads a
|
||||
separate model per language, so following a layout would mean a model reload on
|
||||
the hotkey; Parakeet does not use the language picker at all. Active-layout
|
||||
detection uses GNOME's input-source settings; on other desktops it falls back to
|
||||
the configured primary layout.
|
||||
|
||||
### Activation via a KDE Plasma global shortcut
|
||||
|
||||
Instead of the built-in hotkey listener, you can let your desktop's global
|
||||
shortcut system trigger Vocalinux. On Wayland the built-in listener reads
|
||||
`/dev/input` (requiring membership in the `input` group and effectively acting
|
||||
as a system-wide key reader). Delegating activation to the compositor avoids
|
||||
this entirely: no `/dev/input` access and no `input` group needed just to
|
||||
start/stop dictation. Text injection is unaffected.
|
||||
|
||||
Enable it in Vocalinux:
|
||||
|
||||
1. Open **Settings → Shortcuts** (the Keyboard Shortcuts group on the Dictation page)
|
||||
2. Turn on **External Activation (Desktop Shortcut)**
|
||||
|
||||
The change applies immediately; you do not need to restart. The built-in key
|
||||
listener stops, and a running instance exposes a D-Bus service on the session
|
||||
bus (`com.vocalinux.Vocalinux`). The CLI can forward commands to it:
|
||||
|
||||
```bash
|
||||
vocalinux --toggle # start if idle, stop if active
|
||||
vocalinux --start # start voice typing
|
||||
vocalinux --stop # stop voice typing
|
||||
```
|
||||
|
||||
Then bind a compositor shortcut to `vocalinux --toggle` on a native install.
|
||||
For Flatpak, bind the `gdbus` command in
|
||||
[Running without device access](../packaging/flatpak/README.md#running-without-device-access)
|
||||
instead, because `vocalinux --toggle` is not on the host PATH. A desktop
|
||||
shortcut only sends the key press, so it can toggle dictation but cannot
|
||||
support push-to-talk because it never sees the release. On KDE Plasma:
|
||||
|
||||
1. Open **System Settings -> Keyboard -> Shortcuts -> Add New -> Command or Script**
|
||||
(older Plasma: **System Settings -> Shortcuts -> Custom Shortcuts -> Edit ->
|
||||
New -> Global Shortcut -> Command/URL**).
|
||||
|
||||
2. Bind a key combination of your choice to the command `vocalinux --toggle`
|
||||
for a native install. For Flatpak, use the D-Bus command linked above.
|
||||
|
||||
Now your chosen key combination toggles dictation, handled by the compositor
|
||||
rather than by Vocalinux reading the keyboard directly. This works the same way
|
||||
on other compositors that support binding a key to a command (e.g. GNOME custom
|
||||
shortcuts, Sway/Hyprland `bindsym`/`bind`).
|
||||
|
||||
As an advanced alternative, you can set the same option in
|
||||
`~/.config/vocalinux/config.json` under `shortcuts`:
|
||||
|
||||
```json
|
||||
"shortcuts": {
|
||||
"disable_internal_hotkey": true
|
||||
}
|
||||
```
|
||||
|
||||
Quit Vocalinux before editing that file so the running app cannot overwrite
|
||||
the edit from its cached config. Start Vocalinux again after saving.
|
||||
|
||||
### Model size (whisper.cpp / Whisper)
|
||||
|
||||
| Size | Approx. size | Tradeoff |
|
||||
|------|--------------|----------|
|
||||
| tiny | ~74MB | Fastest; real-time friendly |
|
||||
| base | ~141MB | Balance of speed and accuracy |
|
||||
| small | ~465MB | Better accuracy |
|
||||
| medium | ~1.5GB | High accuracy |
|
||||
| large | ~3.0GB | Best accuracy; heavier |
|
||||
|
||||
For whisper.cpp, also pick a **Specialization**: standard multilingual, English-only, quantized (lower memory), Turbo, or legacy large. English-only specializations limit the language selector to English. Exact IDs (for example `medium.en-q5_0`, `large-v3-turbo`) work with `--model`.
|
||||
|
||||
### Removing unused models
|
||||
|
||||
If leftover files are on disk that are not the model currently selected, **Unused downloads** appears under the model info card. Expand it to delete leftovers one at a time. Confirming removes those files from `~/.local/share/vocalinux`. Packaged system-wide VOSK models are left alone.
|
||||
|
||||
### GPU
|
||||
|
||||
whisper.cpp prefers Vulkan when the bundled pywhispercpp libraries include it, then CUDA, then CPU. Host tools such as `vulkaninfo` only describe the machine. The engine follows the libraries actually loaded. On multi-GPU machines a discrete Vulkan device is preferred; override under **Settings → Performance → Vulkan GPU**. Check logs with `vocalinux --debug`.
|
||||
|
||||
Pip wheels of pywhispercpp are often CUDA builds. In that case Vocalinux uses CUDA device 0. `install.sh` rebuilds pywhispercpp with Vulkan or CUDA when it can.
|
||||
|
||||
### Auto-pause and keep-alive
|
||||
|
||||
Under Settings:
|
||||
|
||||
- **Auto-pause apps**: unload the model while listed apps run
|
||||
- **Model keep-alive**: unload after idle timeout to free GPU/CPU
|
||||
|
||||
In **Settings → Performance → Unload When Idle**, enable **Record while model
|
||||
reloads** to speak as soon as you press the dictation shortcut. Audio stays in
|
||||
memory while the model loads, then joins the rest of the recording for
|
||||
transcription. Releasing the shortcut before loading finishes still submits the
|
||||
recorded speech. Wait for that transcription to finish before starting another
|
||||
recording. This option is off by default.
|
||||
|
||||
## Tips for better recognition
|
||||
|
||||
1. Use a decent microphone and reduce background noise when you can
|
||||
2. Speak clearly at a natural pace
|
||||
3. Prefer `tiny`/`base` for snappy dictation; larger models when accuracy matters more than latency
|
||||
4. English-only or quantized specializations help when they match your use case
|
||||
5. Confirm Vulkan/CUDA in debug logs if transcription is slower than expected
|
||||
|
||||
## CLI
|
||||
|
||||
```bash
|
||||
vocalinux --help
|
||||
vocalinux --version
|
||||
vocalinux --debug
|
||||
vocalinux --engine whisper_cpp
|
||||
vocalinux --engine faster_whisper
|
||||
vocalinux --engine parakeet
|
||||
vocalinux --model medium.en-q5_0
|
||||
vocalinux --wayland
|
||||
vocalinux --start-minimized
|
||||
vocalinux --transcribe-file meeting.wav # diarized transcript on stdout, then exits
|
||||
```
|
||||
|
||||
## Custom Dictionary Support
|
||||
|
||||
Open **Settings → Custom Dictionary** to configure two separate capabilities:
|
||||
|
||||
- **Custom terms** bias recognition toward product names, people, and jargon.
|
||||
They are read from `~/.config/vocalinux/dictionary.txt` by default, as UTF-8
|
||||
with one term per line. Blank lines and `#` comments are allowed, so the same
|
||||
file remains friendly to an accessibility scanner. Use the add/remove editor
|
||||
or choose a different readable terms file with the file picker.
|
||||
- **Transcript corrections** replace a known misheard word or phrase after
|
||||
transcription, for example `super base` with `Supabase`. Corrections are
|
||||
stored separately in `~/.config/vocalinux/custom-dictionary-corrections.json`.
|
||||
|
||||
VocaLinux re-reads both files before each completed dictation segment, so an
|
||||
external edit applies to the next segment without restarting the app. Vocabulary
|
||||
bias works with Whisper, whisper.cpp, and Faster Whisper. Corrections work with
|
||||
every engine, including VOSK, Parakeet, and the configured remote API.
|
||||
|
||||
Corrections run before voice-command interpretation. This can prevent a
|
||||
command-like misrecognition from acting, but avoid replacements that create a
|
||||
voice command unless that is intentional. Correction replacements are not
|
||||
automatically added to recognition bias.
|
||||
|
||||
For a one-session terms override, start Vocalinux with:
|
||||
|
||||
```bash
|
||||
vocalinux --dictionary-file /path/to/dictionary.txt
|
||||
```
|
||||
|
||||
This temporarily enables terms from that file without changing saved settings;
|
||||
the Custom terms controls are disabled for the session. It does not disable
|
||||
transcript corrections.
|
||||
|
||||
`--transcribe-file` uses the TinyDiarize model (`small.en-tdrz`) and needs it downloaded first — the tray "Transcribe Audio File…" entry fetches it on demand.
|
||||
|
||||
### Post-Processing
|
||||
|
||||
Vocalinux can pipe each transcription result through a user-defined script before injecting it into your application. This lets you apply custom transformations — for example, grammar correction, abbreviation expansion, or domain-specific formatting.
|
||||
|
||||
**To configure:**
|
||||
1. Open Settings from the tray icon menu (right-click)
|
||||
2. Go to the **Post-Processing** tab
|
||||
3. Enter the path to your script, or click **Browse…** to select it
|
||||
4. Leave the field empty to disable post-processing
|
||||
|
||||
**Script contract:**
|
||||
- The script receives the transcription on **stdin**
|
||||
- It must write the replacement text to **stdout**
|
||||
- stdout is injected verbatim — trailing newlines are preserved (e.g. paragraph breaks), except a single trailing newline that line-oriented tools like `echo` add when the transcription had none
|
||||
- A non-zero exit code or a script that times out (10 s) causes the original text to be used unchanged
|
||||
- Scripts run on a dedicated worker so a slow script cannot interrupt dictation
|
||||
|
||||
**Example** — a shell script that uppercases everything:
|
||||
```bash
|
||||
#!/bin/bash
|
||||
tr '[:lower:]' '[:upper:]'
|
||||
```
|
||||
Make the script executable (`chmod +x`) before setting the path in Vocalinux.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
```bash
|
||||
vocalinux --debug
|
||||
```
|
||||
|
||||
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for tray, audio, injection, and model issues. Distro notes: [DISTRO_COMPATIBILITY.md](DISTRO_COMPATIBILITY.md). Updates: [UPDATE.md](UPDATE.md). Help channels: [SUPPORT.md](../SUPPORT.md).
|
||||
|
||||
### Text injection backend
|
||||
|
||||
Vocalinux types your dictated text using one of several backends. It picks one
|
||||
automatically, and on most desktops the automatic choice is correct.
|
||||
|
||||
Autodetection can be wrong, though, and it fails in a way that is easy to
|
||||
misread: on a compositor that does not relay IBus commits to native Wayland
|
||||
applications, IBus reports the text as delivered while nothing appears. If
|
||||
dictation works in some windows (typically XWayland ones, like a browser) but
|
||||
silently does nothing in others, that is the symptom.
|
||||
|
||||
Pin the backend explicitly in `~/.config/vocalinux/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"text_injection": {
|
||||
"backend": "wtype"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Value | Backend |
|
||||
|---|---|
|
||||
| `auto` | Autodetect (default; autodetection may select IBus) |
|
||||
| `ibus` | IBus input method; on Wayland, bypasses compositor checks and may silently do nothing in native Wayland apps |
|
||||
| `portal` | RemoteDesktop portal (Wayland; the sandboxed path, asks for permission once, works under Flatpak and Snap) |
|
||||
| `wtype` | wtype virtual keyboard (Wayland) |
|
||||
| `ydotool` | ydotool uinput (Wayland; needs `ydotoold`) |
|
||||
| `xdotool` | xdotool (X11). On Wayland it only turns IBus off -- the Wayland tool is still picked automatically |
|
||||
|
||||
The setting takes effect on the next start. `auto` leaves normal autodetection
|
||||
in place and may select IBus. An explicit non-IBus pin (`portal`, `wtype`,
|
||||
`ydotool`, or `xdotool`) skips IBus selection.
|
||||
|
||||
On Wayland, when IBus is not selected, autodetection tries the RemoteDesktop
|
||||
portal first -- it is the only injection path Wayland officially supports and
|
||||
it needs no uinput device or helper daemon -- then `ydotool`, `wtype`, and
|
||||
finally `xdotool` under XWayland.
|
||||
|
||||
On X11 the injection tool is `xdotool` regardless of which non-`ibus` value you
|
||||
pin, so `xdotool` is the name to use there when IBus is unreliable in a
|
||||
particular application. Pinning `ibus` keeps the IBus path; pinning anything
|
||||
else turns it off.
|
||||
|
||||
To try a backend for a single run without changing the saved setting, set
|
||||
`VOCALINUX_FORCE_BACKEND`, which overrides the config value. Set it to `auto`
|
||||
to ignore a saved pin for that run:
|
||||
|
||||
```bash
|
||||
VOCALINUX_FORCE_BACKEND=wtype vocalinux --debug
|
||||
```
|
||||
|
||||
The setting and environment override are read at startup, so restart Vocalinux
|
||||
after editing `config.json`. The startup log first records a backend pin request;
|
||||
it does not prove the backend was available or that text reached the focused
|
||||
application. Later logs identify a fallback when a pin was not applied.
|
||||
|
||||
If a pinned tool is unavailable, Vocalinux warns and continues with its normal
|
||||
fallback selection. `portal` needs a desktop implementing the
|
||||
`org.freedesktop.portal.RemoteDesktop` interface (GNOME and KDE Plasma do;
|
||||
most wlroots compositors do not). `ydotool` also needs a usable `/dev/uinput`
|
||||
and a working `ydotoold` setup. `xdotool` types into X11/XWayland windows,
|
||||
not native Wayland windows. A live test in the target application is still the
|
||||
final confirmation that text is delivered.
|
||||
@@ -0,0 +1,51 @@
|
||||
# Domain Docs
|
||||
|
||||
How the engineering skills should consume this repo's domain documentation when exploring the codebase.
|
||||
|
||||
## Before exploring, read these
|
||||
|
||||
- **`GLOSSARY.md`** at the repo root, or
|
||||
- **`GLOSSARY-MAP.md`** at the repo root if it exists: it points at one `GLOSSARY.md` per context. Read each one relevant to the topic.
|
||||
- **`docs/adr/`**: read ADRs that touch the area you're about to work in. In multi-context repos, also check `src/<context>/docs/adr/` for context-scoped decisions.
|
||||
|
||||
If any of these files don't exist, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The `/domain-modeling` skill (reached via `/grill-with-docs` and `/improve-codebase-architecture`) creates them lazily when terms or decisions actually get resolved.
|
||||
|
||||
## File structure
|
||||
|
||||
Single-context repo (most repos):
|
||||
|
||||
```
|
||||
/
|
||||
├── GLOSSARY.md
|
||||
├── docs/adr/
|
||||
│ ├── 0001-event-sourced-orders.md
|
||||
│ └── 0002-postgres-for-write-model.md
|
||||
└── src/
|
||||
```
|
||||
|
||||
Multi-context repo (presence of `GLOSSARY-MAP.md` at the root):
|
||||
|
||||
```
|
||||
/
|
||||
├── GLOSSARY-MAP.md
|
||||
├── docs/adr/ ← system-wide decisions
|
||||
└── src/
|
||||
├── ordering/
|
||||
│ ├── GLOSSARY.md
|
||||
│ └── docs/adr/ ← context-specific decisions
|
||||
└── billing/
|
||||
├── GLOSSARY.md
|
||||
└── docs/adr/
|
||||
```
|
||||
|
||||
## Use the glossary's vocabulary
|
||||
|
||||
When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `GLOSSARY.md`. Don't drift to synonyms the glossary explicitly avoids.
|
||||
|
||||
If the concept you need isn't in the glossary yet, that's a signal: either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/domain-modeling`).
|
||||
|
||||
## Flag ADR conflicts
|
||||
|
||||
If your output contradicts an existing ADR, surface it explicitly rather than silently overriding:
|
||||
|
||||
> _Contradicts ADR-0007 (event-sourced orders), but worth reopening because…_
|
||||
@@ -0,0 +1,40 @@
|
||||
# Issue tracker: Gitea
|
||||
|
||||
Issues and specs for this repo live in Gitea at `https://git.bongbetic.com/xavierk/voculinux`. Use the `tea` CLI for all operations.
|
||||
|
||||
Run `tea logins list` first. If no login exists for `git.bongbetic.com`, add one with `tea logins add`. When working outside a checkout whose remote points at Gitea, pass `--repo xavierk/voculinux --login <name>` explicitly.
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Create an issue**: `tea issues create --repo xavierk/voculinux --title "..." --description "..."`. Use `--description-file -` with a heredoc for multi-line bodies. Add `--labels "..."` to triage at creation.
|
||||
- **Read an issue**: `tea issues <index> --repo xavierk/voculinux --fields index,title,state,author,labels,assignees,milestone,body,comments`.
|
||||
- **List issues**: `tea issues list --repo xavierk/voculinux --state open --fields index,title,state,author,labels --limit 30`, with `--labels`, `--author`, `--assignee`, or `--keyword` filters. Use `-o json` for machine-readable output.
|
||||
- **Comment on an issue**: `tea comments add <index> "..." --repo xavierk/voculinux`.
|
||||
- **Apply / remove labels**: `tea issues edit <index> --repo xavierk/voculinux --add-labels "..."` / `--remove-labels "..."`.
|
||||
- **Close**: `tea issues close <index> --repo xavierk/voculinux`. Reopen with `tea issues reopen <index>`.
|
||||
- **Manage labels**: `tea labels list --repo xavierk/voculinux`. Create missing triage labels with `tea labels create`.
|
||||
|
||||
## Pull requests as a triage surface
|
||||
|
||||
**PRs as a request surface: no.**
|
||||
|
||||
When set to `yes`, PRs run through the same labels and states as issues, using the `tea pulls` equivalents.
|
||||
|
||||
## When a skill says "publish to the issue tracker"
|
||||
|
||||
Create a Gitea issue with `tea issues create`.
|
||||
|
||||
## When a skill says "fetch the relevant ticket"
|
||||
|
||||
Read it as in **Read an issue** above.
|
||||
|
||||
## Wayfinding operations
|
||||
|
||||
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
|
||||
|
||||
- **Map**: a single issue labelled `wayfinder:map`, holding the Notes / Decisions-so-far / Fog body.
|
||||
- **Child ticket**: an issue with `Part of #<map-index>` at the top of its body. Labels: `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`). Once claimed, assign it to the driving dev with `tea issues edit <index> --add-assignees <user>`.
|
||||
- **Blocking**: a `Blocked by: #<n>, #<n>` line at the top of the child body. A ticket is unblocked when every blocker is closed.
|
||||
- **Frontier query**: list the map's open children, drop any with an open blocker or an assignee; first in map order wins.
|
||||
- **Claim**: `tea issues edit <n> --add-assignees <user>`, the session's first write.
|
||||
- **Resolve**: `tea comments add <n> "<answer>"`, then `tea issues close <n>`, then append a context pointer to the map's Decisions-so-far.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Triage Labels
|
||||
|
||||
The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker.
|
||||
|
||||
| Label in mattpocock/skills | Label in our tracker | Meaning |
|
||||
| -------------------------- | -------------------- | ---------------------------------------- |
|
||||
| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue |
|
||||
| `needs-info` | `needs-info` | Waiting on reporter for more information |
|
||||
| `ready-for-agent` | `ready-for-agent` | Fully specified, ready for an AFK agent |
|
||||
| `ready-for-human` | `ready-for-human` | Requires human implementation |
|
||||
| `wontfix` | `wontfix` | Will not be actioned |
|
||||
|
||||
When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table.
|
||||
|
||||
Edit the "Label in our tracker" column to match whatever vocabulary you actually use.
|
||||
@@ -0,0 +1,56 @@
|
||||
# Performance benchmarks
|
||||
|
||||
Before and after numbers for the performance pass in
|
||||
[#968](https://github.com/VocaHQ/vocalinux/pull/968). "main" is the code before
|
||||
that PR. All runs used the same box: 8 vCPU Intel Xeon Platinum 8559C, Python
|
||||
3.13, pywhispercpp 1.5.1, X11.
|
||||
|
||||
## Settings first open
|
||||
|
||||

|
||||
|
||||
The Settings dialog used to import every installed engine package (Vosk,
|
||||
OpenAI Whisper, faster-whisper) just to see whether it was installed. With all
|
||||
optional engines installed, the first open took 1.38 s and the process kept an
|
||||
extra 606 MB for the rest of its life. Probing with `importlib.util.find_spec`
|
||||
brings that down to 214 ms and 50 MB.
|
||||
|
||||
## Text injection on X11
|
||||
|
||||

|
||||
|
||||
Measured by injecting text into KWrite through `TextInjector.inject_text`,
|
||||
mean of 3 runs. Dropping the 0.1 s sleep after every 20 characters saves
|
||||
about 2 s per 420 characters. Turning on Settings > "Paste long dictations"
|
||||
sends text of 30 or more characters through the clipboard, which takes about
|
||||
40 ms at any length; the previous clipboard content is restored afterwards.
|
||||
Typing speed itself is set by xdotool's per-key delay, so absolute typed
|
||||
times vary by machine.
|
||||
|
||||
## whisper.cpp after a GPU init failure
|
||||
|
||||

|
||||
|
||||
When Vulkan or CUDA fails to initialise, the CPU fallback used to keep the
|
||||
GPU thread count (cores / 4, so 2 here) instead of the CPU policy
|
||||
(cores - 2, capped at 8, so 6 here). Times are for an 11 s clip.
|
||||
|
||||
## Silence timeout
|
||||
|
||||

|
||||
|
||||
200 LibriSpeech dev-clean utterances (5 per speaker, 26 min of audio) were
|
||||
replayed through the same segmentation `_record_audio` uses: 1024-sample
|
||||
chunks, Silero VAD at the default sensitivity, and a split whenever silence
|
||||
exceeds the timeout. Below 1.2 s some sentences get cut in two at a natural
|
||||
pause; at 1.2 s none were. The default is now 1.2 s instead of 2.0 s, so each
|
||||
dictation finishes 0.8 s sooner. Read speech pauses less than live dictation,
|
||||
so raise the timeout in Settings if you pause mid-sentence to think.
|
||||
|
||||
## Where the time goes
|
||||
|
||||
On an 11 s utterance with the tiny model, the Python code around the
|
||||
transcription took 0.3 ms of a 389 ms call; the rest is native whisper.cpp.
|
||||
A standalone `whisper-cli` built from the same whisper.cpp commit was no
|
||||
faster, so rewriting the app in another language would not speed up
|
||||
transcription.
|
||||
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 339 KiB |
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1791456040,
|
||||
"narHash": "sha256-H83yz/do+hjOO0uujHyH8RgtIQP2v7Mw+cLwcZK/xKc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e7439b6b14ad3cc35d05608ebca9bce01a25f5f8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
description = "Vocalinux — free, offline voice dictation for Linux";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ self, nixpkgs }:
|
||||
let
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
];
|
||||
forAllSystems = nixpkgs.lib.genAttrs systems;
|
||||
in
|
||||
{
|
||||
packages = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
vocalinux = pkgs.python3Packages.callPackage ./packaging/nix/package.nix {
|
||||
pywhispercpp = pkgs.python3Packages.callPackage ./packaging/nix/pywhispercpp.nix { };
|
||||
src = self;
|
||||
};
|
||||
default = self.packages.${system}.vocalinux;
|
||||
}
|
||||
);
|
||||
|
||||
apps = forAllSystems (system: {
|
||||
vocalinux = {
|
||||
type = "app";
|
||||
program = "${self.packages.${system}.vocalinux}/bin/vocalinux";
|
||||
};
|
||||
default = self.apps.${system}.vocalinux;
|
||||
});
|
||||
|
||||
overlays.default = final: prev: {
|
||||
vocalinux = self.packages.${prev.stdenv.hostPlatform.system}.vocalinux;
|
||||
};
|
||||
|
||||
nixosModules.vocalinux =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
imports = [ ./packaging/nix/module.nix ];
|
||||
programs.vocalinux.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.vocalinux;
|
||||
};
|
||||
nixosModules.default = self.nixosModules.vocalinux;
|
||||
|
||||
homeManagerModules.vocalinux =
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
imports = [ ./packaging/nix/home-manager.nix ];
|
||||
programs.vocalinux.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.vocalinux;
|
||||
};
|
||||
homeManagerModules.default = self.homeManagerModules.vocalinux;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
# Sourced by install.sh after it has resolved the local or tagged repository.
|
||||
# Keep this file declarative: function definitions only, with no top-level actions.
|
||||
|
||||
# Function to install desktop entry with error handling
|
||||
install_desktop_entry() {
|
||||
print_info "Installing desktop entry..."
|
||||
|
||||
# Check if desktop entry file exists
|
||||
if [ ! -f "vocalinux.desktop" ]; then
|
||||
print_error "Desktop entry file not found: vocalinux.desktop"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create desktop directory if it doesn't exist
|
||||
mkdir -p "$DESKTOP_DIR" || {
|
||||
print_error "Failed to create desktop directory: $DESKTOP_DIR"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy desktop entry
|
||||
cp vocalinux.desktop "$DESKTOP_DIR/" || {
|
||||
print_error "Failed to copy desktop entry to $DESKTOP_DIR"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Update the desktop entry to use the wrapper script with GI_TYPELIB_PATH
|
||||
WRAPPER_SCRIPT="$HOME/.local/bin/vocalinux-gui"
|
||||
if [ ! -f "$WRAPPER_SCRIPT" ]; then
|
||||
print_warning "Wrapper script not found at $WRAPPER_SCRIPT"
|
||||
print_warning "Desktop entry may not work correctly"
|
||||
else
|
||||
# Update Exec line to include GI_TYPELIB_PATH for PyGObject
|
||||
# Use the detected path for cross-distro compatibility
|
||||
sed -i "s|^Exec=vocalinux|Exec=env GI_TYPELIB_PATH=$GI_TYPELIB_DETECTED $WRAPPER_SCRIPT|" "$DESKTOP_DIR/vocalinux.desktop" || {
|
||||
print_warning "Failed to update desktop entry path"
|
||||
}
|
||||
print_info "Updated desktop entry to use wrapper script with GI_TYPELIB_PATH"
|
||||
fi
|
||||
|
||||
# Make desktop entry executable
|
||||
chmod +x "$DESKTOP_DIR/vocalinux.desktop" || {
|
||||
print_warning "Failed to make desktop entry executable"
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to install icons with error handling
|
||||
install_icons() {
|
||||
print_info "Installing application icons..."
|
||||
|
||||
# Create icon directory if it doesn't exist
|
||||
mkdir -p "$ICON_DIR" || {
|
||||
print_error "Failed to create icon directory: $ICON_DIR"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if icons directory exists
|
||||
if [ ! -d "resources/icons/scalable" ]; then
|
||||
print_warning "Custom icons not found in resources/icons/scalable directory"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# List of icons to install
|
||||
local ICONS=(
|
||||
"vocalinux.svg"
|
||||
"vocalinux-microphone.svg"
|
||||
"vocalinux-microphone-off.svg"
|
||||
"vocalinux-microphone-process.svg"
|
||||
)
|
||||
|
||||
# Install each icon
|
||||
local INSTALLED_COUNT=0
|
||||
for icon in "${ICONS[@]}"; do
|
||||
if [ -f "resources/icons/scalable/$icon" ]; then
|
||||
cp "resources/icons/scalable/$icon" "$ICON_DIR/" || {
|
||||
print_warning "Failed to copy icon: $icon"
|
||||
continue
|
||||
}
|
||||
((INSTALLED_COUNT++))
|
||||
else
|
||||
print_warning "Icon not found: resources/icons/scalable/$icon"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$INSTALLED_COUNT" -eq "${#ICONS[@]}" ]; then
|
||||
print_success "Installed all custom Vocalinux icons"
|
||||
return 0
|
||||
elif [ "$INSTALLED_COUNT" -gt 0 ]; then
|
||||
print_warning "Installed $INSTALLED_COUNT/${#ICONS[@]} custom Vocalinux icons"
|
||||
return 0
|
||||
else
|
||||
print_error "Failed to install any icons"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to update icon cache and desktop database
|
||||
update_icon_cache() {
|
||||
print_info "Updating icon cache..."
|
||||
|
||||
# Check if gtk-update-icon-cache command exists
|
||||
if command_exists gtk-update-icon-cache; then
|
||||
gtk-update-icon-cache -f -t "${XDG_DATA_HOME:-$HOME/.local/share}/icons/hicolor" 2>/dev/null || {
|
||||
print_warning "Failed to update icon cache"
|
||||
}
|
||||
else
|
||||
print_warning "gtk-update-icon-cache command not found, skipping icon cache update"
|
||||
fi
|
||||
|
||||
# Update desktop database so the app appears in application menus immediately
|
||||
print_info "Updating desktop database..."
|
||||
if command_exists update-desktop-database; then
|
||||
update-desktop-database "${XDG_DATA_HOME:-$HOME/.local/share}/applications" 2>/dev/null || {
|
||||
print_warning "Failed to update desktop database"
|
||||
}
|
||||
else
|
||||
print_warning "update-desktop-database command not found - app may not appear in menu until next login"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install resources (icons, sounds) to the virtual environment
|
||||
# so the resource_manager can find them at runtime
|
||||
install_resources_to_venv() {
|
||||
print_info "Installing resources to virtual environment..."
|
||||
|
||||
# Target directory: $VENV_DIR/share/vocalinux/resources
|
||||
local VENV_RESOURCES_DIR="$VENV_DIR/share/vocalinux/resources"
|
||||
|
||||
# Create directories
|
||||
mkdir -p "$VENV_RESOURCES_DIR/icons/scalable" || {
|
||||
print_warning "Failed to create venv resources directory"
|
||||
return 1
|
||||
}
|
||||
mkdir -p "$VENV_RESOURCES_DIR/sounds" || {
|
||||
print_warning "Failed to create venv sounds directory"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy icons if available
|
||||
if [ -d "resources/icons/scalable" ]; then
|
||||
cp resources/icons/scalable/*.svg "$VENV_RESOURCES_DIR/icons/scalable/" 2>/dev/null || {
|
||||
print_warning "Failed to copy icons to venv resources"
|
||||
}
|
||||
fi
|
||||
|
||||
# Copy sounds if available
|
||||
if [ -d "resources/sounds" ]; then
|
||||
cp resources/sounds/*.wav "$VENV_RESOURCES_DIR/sounds/" 2>/dev/null || {
|
||||
print_warning "Failed to copy sounds to venv resources"
|
||||
}
|
||||
fi
|
||||
|
||||
# Verify
|
||||
local ICON_COUNT=$(ls "$VENV_RESOURCES_DIR/icons/scalable/"*.svg 2>/dev/null | wc -l)
|
||||
local SOUND_COUNT=$(ls "$VENV_RESOURCES_DIR/sounds/"*.wav 2>/dev/null | wc -l)
|
||||
|
||||
if [ "$ICON_COUNT" -gt 0 ] && [ "$SOUND_COUNT" -gt 0 ]; then
|
||||
print_success "Installed resources to venv ($ICON_COUNT icons, $SOUND_COUNT sounds)"
|
||||
else
|
||||
print_warning "Some resources may be missing from venv ($ICON_COUNT icons, $SOUND_COUNT sounds)"
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
#!/bin/bash
|
||||
# Sourced by install.sh after it has resolved the local or tagged repository.
|
||||
# Keep this file declarative: function definitions only, with no top-level actions.
|
||||
|
||||
# Print section header for interactive mode
|
||||
clear_screen() {
|
||||
if [ -t 1 ] && command -v clear >/dev/null 2>&1 && [ -n "${TERM:-}" ]; then
|
||||
clear >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
print_header() {
|
||||
local title="$1"
|
||||
echo ""
|
||||
echo "============================================================"
|
||||
echo " $title"
|
||||
echo "============================================================"
|
||||
}
|
||||
|
||||
# Function to run interactive guided installation
|
||||
run_interactive_install() {
|
||||
clear_screen
|
||||
cat << "EOF"
|
||||
|
||||
Interactive Installation Guide
|
||||
===============================
|
||||
|
||||
EOF
|
||||
|
||||
echo "Welcome! This guided installation will help you set up Vocalinux"
|
||||
echo "with the best options for your system."
|
||||
echo ""
|
||||
echo "Local engines (whisper.cpp, Whisper, Faster Whisper, VOSK) process audio on-device after you download a model."
|
||||
echo "Optional Remote API is off unless you choose it; then audio goes only to the server you configure."
|
||||
echo ""
|
||||
|
||||
# An existing install is an upgrade by default: keep the saved configuration
|
||||
# and update in place instead of redoing first-time setup. Choosing the full
|
||||
# guided setup continues below and can re-point the engine deliberately.
|
||||
if [[ "${EXISTING_INSTALL:-no}" == "yes" ]]; then
|
||||
echo "An existing Vocalinux installation was detected:"
|
||||
echo " Configuration: $CONFIG_DIR/config.json (kept unchanged by an upgrade)"
|
||||
echo " Virtual env: $VENV_DIR (reused by an upgrade)"
|
||||
echo ""
|
||||
echo " 1. Upgrade (keep current settings) - update Vocalinux only"
|
||||
echo " 2. Full guided setup - choose engine, backend, and model options"
|
||||
echo ""
|
||||
|
||||
read_prompt -p "Choose [1-2] (default: 1): " UPGRADE_CHOICE
|
||||
UPGRADE_CHOICE=${UPGRADE_CHOICE:-1}
|
||||
|
||||
if [[ "$UPGRADE_CHOICE" != "2" ]]; then
|
||||
UPGRADE_MODE="yes"
|
||||
INTERACTIVE_MODE="no"
|
||||
NON_INTERACTIVE="yes"
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Step 1: Detect and display system info
|
||||
print_header "Step 1: Your System"
|
||||
echo "Detected: $DISTRO_NAME $DISTRO_VERSION"
|
||||
|
||||
# Get hardware recommendation
|
||||
local RECOMMENDATION=$(get_engine_recommendation)
|
||||
local RECOMMENDED_ENGINE=$(echo "$RECOMMENDATION" | cut -d':' -f1)
|
||||
local RECOMMENDED_ICON=$(echo "$RECOMMENDATION" | cut -d':' -f2)
|
||||
local RECOMMENDED_REASON=$(echo "$RECOMMENDATION" | cut -d':' -f3-)
|
||||
|
||||
echo "Hardware: $RECOMMENDED_REASON"
|
||||
echo ""
|
||||
|
||||
# Step 2: Choose speech recognition engine
|
||||
print_header "Step 2: Choose Speech Recognition Engine"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 1. WHISPER.CPP * RECOMMENDED │"
|
||||
echo " │ • Local default engine; CUDA, Vulkan, or CPU │"
|
||||
echo " │ • Supports NVIDIA (CUDA), AMD, Intel (Vulkan) │"
|
||||
echo " │ • CPU-only mode available for older systems │"
|
||||
echo " │ • Models: tiny (39MB) to large (1.5GB) │"
|
||||
echo " │ • ~33 languages plus Auto-detect │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 2. WHISPER (OpenAI) │"
|
||||
echo " │ • PyTorch-based, high accuracy │"
|
||||
echo " │ • Only supports NVIDIA GPUs (CUDA) │"
|
||||
echo " │ • Larger download (~2GB with CUDA) │"
|
||||
echo " │ • Good for development/research │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 3. VOSK │"
|
||||
echo " │ • Lightweight and fast │"
|
||||
echo " │ • Works on older/low-RAM systems │"
|
||||
echo " │ • ~40MB download │"
|
||||
echo " │ • Good for basic dictation needs │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 4. FASTER-WHISPER │"
|
||||
echo " │ • Optional CTranslate2 Whisper backend │"
|
||||
echo " │ • Fast on CPU with INT8 quantization │"
|
||||
echo " │ • Checksum-verified Hugging Face models │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 5. REMOTE API (ADVANCED) │"
|
||||
echo " │ • Offload processing to a GPU server on your network │"
|
||||
echo " │ • Ideal for laptops without GPU │"
|
||||
echo " │ • Supports whisper.cpp server & OpenAI-compatible APIs │"
|
||||
echo " │ • Minimal local resources needed │"
|
||||
echo " │ • Requires a remote server to be running │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
|
||||
# Show recommendation
|
||||
case "$RECOMMENDED_ENGINE" in
|
||||
whisper_cpp)
|
||||
echo " → Recommendation: whisper.cpp (recommended for your hardware)"
|
||||
DEFAULT_CHOICE="1"
|
||||
;;
|
||||
vosk)
|
||||
echo " → Recommendation: VOSK (lightweight option for your system)"
|
||||
DEFAULT_CHOICE="3"
|
||||
;;
|
||||
*)
|
||||
echo " → Recommendation: whisper.cpp (recommended default)"
|
||||
DEFAULT_CHOICE="1"
|
||||
;;
|
||||
esac
|
||||
echo ""
|
||||
|
||||
read_prompt -p "Choose engine [1-5] (default: $DEFAULT_CHOICE): " ENGINE_CHOICE
|
||||
ENGINE_CHOICE=${ENGINE_CHOICE:-$DEFAULT_CHOICE}
|
||||
|
||||
case "$ENGINE_CHOICE" in
|
||||
1)
|
||||
SELECTED_ENGINE="whisper_cpp"
|
||||
ENGINE_DISPLAY="Whisper.cpp (Recommended)"
|
||||
;;
|
||||
2)
|
||||
SELECTED_ENGINE="whisper"
|
||||
ENGINE_DISPLAY="Whisper (OpenAI)"
|
||||
;;
|
||||
3)
|
||||
SELECTED_ENGINE="vosk"
|
||||
ENGINE_DISPLAY="VOSK (Lightweight)"
|
||||
;;
|
||||
4)
|
||||
SELECTED_ENGINE="faster_whisper"
|
||||
ENGINE_DISPLAY="Faster-Whisper"
|
||||
;;
|
||||
5)
|
||||
SELECTED_ENGINE="remote_api"
|
||||
ENGINE_DISPLAY="Remote API"
|
||||
;;
|
||||
*)
|
||||
SELECTED_ENGINE="whisper_cpp"
|
||||
ENGINE_DISPLAY="Whisper.cpp (Recommended)"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Step 3: Whisper.cpp backend selection (if whisper.cpp chosen)
|
||||
if [[ "$SELECTED_ENGINE" == "whisper_cpp" ]]; then
|
||||
print_header "Step 3: Choose Whisper.cpp Backend"
|
||||
echo ""
|
||||
|
||||
# Detect available backends
|
||||
local BACKEND_INFO=$(detect_whispercpp_backends)
|
||||
local RECOMMENDED_BACKEND=$(echo "$BACKEND_INFO" | cut -d':' -f1)
|
||||
local RECOMMENDED_REASON=$(echo "$BACKEND_INFO" | cut -d':' -f2)
|
||||
local CAN_BUILD_GPU=$(echo "$BACKEND_INFO" | cut -d':' -f3)
|
||||
local HAS_VULKAN=$(echo "$BACKEND_INFO" | cut -d':' -f4)
|
||||
local HAS_NVIDIA=$(echo "$BACKEND_INFO" | cut -d':' -f5)
|
||||
local HAS_VULKAN_DEV=$(echo "$BACKEND_INFO" | cut -d':' -f6)
|
||||
local HAS_CUDA_DEV=$(echo "$BACKEND_INFO" | cut -d':' -f7)
|
||||
local VULKAN_COMPAT=$(echo "$BACKEND_INFO" | cut -d':' -f8)
|
||||
local VULKAN_COMPAT_REASON=$(echo "$BACKEND_INFO" | cut -d':' -f9)
|
||||
|
||||
# Show warning for incompatible GPUs
|
||||
if [[ "$VULKAN_COMPAT" == "incompatible" ]]; then
|
||||
echo ""
|
||||
print_warning "═══════════════════════════════════════════════════════════════"
|
||||
print_warning " ⚠️ INCOMPATIBLE GPU DETECTED"
|
||||
print_warning "═══════════════════════════════════════════════════════════════"
|
||||
print_warning ""
|
||||
print_warning " Your GPU: $VULKAN_COMPAT_REASON"
|
||||
print_warning ""
|
||||
print_warning " This Intel GPU lacks VK_KHR_16bit_storage support, which is"
|
||||
print_warning " required for whisper.cpp Vulkan acceleration."
|
||||
print_warning ""
|
||||
print_warning " The CPU backend will be used instead, which is still fast!"
|
||||
print_warning ""
|
||||
print_warning "═══════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "Whisper.cpp can use different backends for speech recognition:"
|
||||
echo ""
|
||||
|
||||
if [[ "$CAN_BUILD_GPU" == "true" ]]; then
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 1. GPU (Vulkan/CUDA) * RECOMMENDED │"
|
||||
echo " │ • Fastest performance with GPU acceleration │"
|
||||
printf " │ • %-*s│\n" 54 "$RECOMMENDED_REASON"
|
||||
echo " │ • Requires building from source (takes ~2-5 min) │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 2. CPU (Pre-built) │"
|
||||
echo " │ • Works on all systems │"
|
||||
echo " │ • Faster installation (no compilation) │"
|
||||
echo " │ • Good performance on modern CPUs │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " → Recommendation: GPU backend for best performance"
|
||||
local DEFAULT_BACKEND="1"
|
||||
else
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 1. GPU (Vulkan/CUDA) │"
|
||||
echo " │ • ⚠️ GPU libraries not detected │"
|
||||
echo " │ • Requires: libvulkan-dev, glslc/glslang-tools (Vulkan) │"
|
||||
echo " │ or: CUDA toolkit (NVIDIA) │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
echo " ┌─────────────────────────────────────────────────────────────┐"
|
||||
echo " │ 2. CPU (Pre-built) * RECOMMENDED │"
|
||||
echo " │ • Works on all systems │"
|
||||
echo " │ • Fast installation (no compilation) │"
|
||||
echo " │ • Good performance on modern CPUs │"
|
||||
echo " └─────────────────────────────────────────────────────────────┘"
|
||||
echo ""
|
||||
|
||||
if [[ "$HAS_VULKAN" == "yes" && "$HAS_VULKAN_DEV" != "true" ]]; then
|
||||
echo " 💡 Tip: Install 'libvulkan-dev' and a shader compiler for GPU support:"
|
||||
echo " sudo apt install libvulkan-dev glslc 2>/dev/null || sudo apt install libvulkan-dev glslang-tools"
|
||||
echo ""
|
||||
elif [[ "$HAS_NVIDIA" == "yes" && "$HAS_CUDA_DEV" != "true" ]]; then
|
||||
echo " 💡 Tip: Install CUDA toolkit for NVIDIA GPU support:"
|
||||
echo " https://developer.nvidia.com/cuda-downloads"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo " → Recommendation: CPU backend (GPU libraries not detected)"
|
||||
local DEFAULT_BACKEND="2"
|
||||
fi
|
||||
|
||||
read_prompt -p "Choose backend [1-2] (default: $DEFAULT_BACKEND): " BACKEND_CHOICE
|
||||
BACKEND_CHOICE=${BACKEND_CHOICE:-$DEFAULT_BACKEND}
|
||||
|
||||
if [[ "$BACKEND_CHOICE" == "1" ]]; then
|
||||
WHISPERCPP_BACKEND="gpu"
|
||||
BACKEND_DISPLAY="GPU (Vulkan/CUDA)"
|
||||
else
|
||||
WHISPERCPP_BACKEND="cpu"
|
||||
BACKEND_DISPLAY="CPU (Pre-built)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Step 3 for Remote API: Configure server URL
|
||||
if [[ "$SELECTED_ENGINE" == "remote_api" ]]; then
|
||||
print_header "Step 3: Configure Remote Server"
|
||||
echo ""
|
||||
print_info "You need a speech recognition server running on your local network."
|
||||
echo ""
|
||||
echo " Supported servers:"
|
||||
echo " • whisper.cpp server: ./server -m model.bin --host 0.0.0.0 --port 8080"
|
||||
echo " • LocalAI: docker run -p 8080:8080 localai/localai"
|
||||
echo " • Faster Whisper: faster-whisper-server --host 0.0.0.0 --port 8080"
|
||||
echo " • Any OpenAI-compatible speech API"
|
||||
echo ""
|
||||
read_prompt -p "Enter remote server URL (or leave blank to set later): " REMOTE_API_URL_INPUT
|
||||
if [ -n "$REMOTE_API_URL_INPUT" ]; then
|
||||
REMOTE_API_URL="$REMOTE_API_URL_INPUT"
|
||||
REMOTE_DISPLAY="$REMOTE_API_URL"
|
||||
else
|
||||
REMOTE_API_URL=""
|
||||
REMOTE_DISPLAY="(configure later in Settings)"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Step 4: Model download preference (skip for remote_api)
|
||||
if [[ "$SELECTED_ENGINE" != "remote_api" ]]; then
|
||||
print_header "Step 4: Model Download"
|
||||
echo ""
|
||||
echo "Speech recognition models can be downloaded now or later."
|
||||
echo ""
|
||||
echo " 1. Download now (recommended)"
|
||||
echo " • Faster first run - ready to use immediately"
|
||||
echo " • Offline capable right after install"
|
||||
echo ""
|
||||
echo " 2. Download later"
|
||||
echo " • Smaller initial install"
|
||||
echo " • Models download automatically on first use"
|
||||
echo ""
|
||||
|
||||
read_prompt -p "Download models now? [1-2] (default: 1): " MODELS_CHOICE
|
||||
MODELS_CHOICE=${MODELS_CHOICE:-1}
|
||||
|
||||
if [[ "$MODELS_CHOICE" == "2" ]]; then
|
||||
SKIP_MODELS="yes"
|
||||
MODELS_DISPLAY="Download on first use"
|
||||
else
|
||||
MODELS_DISPLAY="Download now (recommended)"
|
||||
fi
|
||||
else
|
||||
# Remote API: No need to download model
|
||||
SKIP_MODELS="yes"
|
||||
MODELS_DISPLAY="Not needed (remote processing)"
|
||||
fi
|
||||
|
||||
# Summary
|
||||
print_header "Installation Summary"
|
||||
echo ""
|
||||
echo " Speech Engine: $ENGINE_DISPLAY"
|
||||
if [[ "$SELECTED_ENGINE" == "whisper_cpp" ]]; then
|
||||
echo " Backend: ${BACKEND_DISPLAY:-CPU (Pre-built)}"
|
||||
if [[ "${WHISPERCPP_BACKEND}" == "gpu" ]]; then
|
||||
echo " Note: GPU build will compile from source (2-5 minutes)"
|
||||
fi
|
||||
fi
|
||||
if [[ "$SELECTED_ENGINE" == "remote_api" ]]; then
|
||||
echo " Remote Server: $REMOTE_DISPLAY"
|
||||
fi
|
||||
echo " Models: $MODELS_DISPLAY"
|
||||
echo " Install Location: ${INSTALL_DIR:-\$HOME/.local/share/vocalinux}"
|
||||
echo ""
|
||||
read_prompt -p "Press Enter to continue with installation, or Ctrl+C to cancel..."
|
||||
echo ""
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
#!/bin/bash
|
||||
# Sourced by install.sh after it has resolved the local or tagged repository.
|
||||
# Keep this file declarative: function definitions only, with no top-level actions.
|
||||
|
||||
# Model integrity verification
|
||||
#
|
||||
# Models are 40MB-2GB downloads that end up being loaded by native code, so no
|
||||
# model is installed without matching a digest pinned in this repository.
|
||||
# src/vocalinux/utils/model_checksums.txt is the same manifest the application
|
||||
# uses at runtime; it is regenerated by scripts/generate-model-checksums.py.
|
||||
#
|
||||
# A model that cannot be verified is deleted and the function returns 1, which
|
||||
# callers already treat as "leave it for first run" rather than aborting the
|
||||
# install. The app re-downloads and re-verifies it later.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Print the digest of $1 using algorithm $2, trying the tools most likely present.
|
||||
compute_file_digest() {
|
||||
local file="$1" algo="$2"
|
||||
|
||||
case "$algo" in
|
||||
sha256)
|
||||
if command_exists sha256sum; then sha256sum "$file" | cut -d' ' -f1
|
||||
elif command_exists shasum; then shasum -a 256 "$file" | cut -d' ' -f1
|
||||
elif command_exists openssl; then openssl dgst -sha256 "$file" | awk '{print $NF}'
|
||||
else return 1; fi
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Compare $1 against algorithm $2 and digest $3. $4 labels the file in messages.
|
||||
verify_digest() {
|
||||
local file="$1" algo="$2" expected="$3" label="$4" actual
|
||||
|
||||
if ! actual=$(compute_file_digest "$file" "$algo") || [ -z "$actual" ]; then
|
||||
print_error "Cannot compute the $algo digest of $label: no sha256sum, shasum or openssl found."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$actual" != "$expected" ]; then
|
||||
print_error "$label failed $algo verification."
|
||||
print_error " expected: $expected"
|
||||
print_error " actual: $actual"
|
||||
print_error "The file does not match the digest pinned in this release."
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_success "$label verified ($algo)"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Verify $1 against the manifest entry named $2 (defaults to $1's basename).
|
||||
verify_model_checksum() {
|
||||
local file="$1"
|
||||
local key="${2:-$(basename "$file")}"
|
||||
local algo expected size actual_size
|
||||
|
||||
if [ ! -f "$MODEL_CHECKSUMS_FILE" ]; then
|
||||
print_error "Checksum manifest not found at $MODEL_CHECKSUMS_FILE."
|
||||
print_error "Cannot verify $key; refusing to install an unverified model."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Manifest columns: filename algorithm digest size-in-bytes
|
||||
algo=$(awk -v k="$key" '$1==k {print $2; exit}' "$MODEL_CHECKSUMS_FILE")
|
||||
expected=$(awk -v k="$key" '$1==k {print $3; exit}' "$MODEL_CHECKSUMS_FILE")
|
||||
size=$(awk -v k="$key" '$1==k {print $4; exit}' "$MODEL_CHECKSUMS_FILE")
|
||||
|
||||
if [ -z "$algo" ] || [ -z "$expected" ]; then
|
||||
print_error "No checksum is pinned for $key in $MODEL_CHECKSUMS_FILE."
|
||||
print_error "Regenerate it with scripts/generate-model-checksums.py."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Size first: it is free, and it reports a truncated download as truncation
|
||||
# rather than as a digest mismatch that reads like tampering.
|
||||
if [ -n "$size" ] && [ "$size" != "0" ]; then
|
||||
actual_size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || echo "")
|
||||
if [ -n "$actual_size" ] && [ "$actual_size" != "$size" ]; then
|
||||
print_error "$key is $actual_size bytes, expected $size (truncated download?)."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
verify_digest "$file" "$algo" "$expected" "$key"
|
||||
}
|
||||
|
||||
# Verify an OpenAI Whisper checkpoint against the sha256 embedded in its own URL
|
||||
# (they publish each file under a path segment that is its digest).
|
||||
verify_openai_model_checksum() {
|
||||
local file="$1" url="$2" label="$3" expected
|
||||
|
||||
expected=$(printf '%s\n' "$url" | grep -oE '/[0-9a-f]{64}/' | tr -d '/' | head -n1)
|
||||
if [ -z "$expected" ]; then
|
||||
print_error "$url carries no sha256 path segment; refusing to install an unverified model."
|
||||
return 1
|
||||
fi
|
||||
|
||||
verify_digest "$file" "sha256" "$expected" "$label"
|
||||
}
|
||||
|
||||
# Download $1 to $2, preferring wget and falling back to curl. $3 labels the
|
||||
# model in error messages. Leaves no partial file behind on failure.
|
||||
download_model_file() {
|
||||
local url="$1" dest="$2" label="$3"
|
||||
|
||||
if command_exists wget; then
|
||||
if ! wget --progress=bar:force:noscroll --tries=3 --timeout=60 -O "$dest" "$url" 2>&1; then
|
||||
print_error "Failed to download $label with wget"
|
||||
rm -f "$dest"
|
||||
return 1
|
||||
fi
|
||||
elif command_exists curl; then
|
||||
# -f: fail on HTTP errors instead of saving the error page as the model
|
||||
if ! curl -fL --progress-bar --retry 3 --retry-delay 2 -o "$dest" "$url"; then
|
||||
print_error "Failed to download $label with curl"
|
||||
rm -f "$dest"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
print_error "Neither wget nor curl is available to download $label"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -s "$dest" ]; then
|
||||
print_error "Downloaded $label is empty or missing"
|
||||
rm -f "$dest"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Print the digest pinned for manifest entry $1, or nothing when unpinned.
|
||||
pinned_digest_for() {
|
||||
[ -f "$MODEL_CHECKSUMS_FILE" ] || return 1
|
||||
awk -v k="$1" '$1==k {print $3; exit}' "$MODEL_CHECKSUMS_FILE"
|
||||
}
|
||||
|
||||
# The Hugging Face commit the whisper.cpp digests were taken at.
|
||||
whispercpp_pinned_revision() {
|
||||
[ -f "$MODEL_CHECKSUMS_FILE" ] || return 1
|
||||
awk '/^#[[:space:]]*whispercpp-revision:/ {print $3; exit}' "$MODEL_CHECKSUMS_FILE"
|
||||
}
|
||||
|
||||
# False when the cloned release predates the manifest. That app has no runtime
|
||||
# verification either, so refusing to pre-download would protect nothing.
|
||||
model_verification_available() {
|
||||
[ -f "$MODEL_CHECKSUMS_FILE" ]
|
||||
}
|
||||
|
||||
# Function to download and install Whisper tiny model
|
||||
install_whisper_model() {
|
||||
print_info "Installing Whisper tiny model (~75MB)..."
|
||||
|
||||
# Create whisper models directory
|
||||
local WHISPER_DIR="$DATA_DIR/models/whisper"
|
||||
mkdir -p "$WHISPER_DIR"
|
||||
|
||||
# Whisper tiny model URL and path
|
||||
local TINY_MODEL_URL="https://openaipublic.azureedge.net/main/whisper/models/65147644a518d12f04e32d6f3b26facc3f8dd46e5390956a9424a650c0ce22b9/tiny.pt"
|
||||
local TINY_MODEL_PATH="$WHISPER_DIR/tiny.pt"
|
||||
|
||||
# An existing file is not a verified file: it may predate checksum
|
||||
# verification, or have been replaced since. Hash it before trusting it,
|
||||
# and re-download rather than keep something that does not match.
|
||||
if [ -f "$TINY_MODEL_PATH" ]; then
|
||||
if verify_openai_model_checksum "$TINY_MODEL_PATH" "$TINY_MODEL_URL" "Whisper tiny model"; then
|
||||
print_info "Whisper tiny model already exists at $TINY_MODEL_PATH"
|
||||
return 0
|
||||
fi
|
||||
print_warning "The existing Whisper tiny model does not match its pinned digest; replacing it."
|
||||
rm -f "$TINY_MODEL_PATH"
|
||||
fi
|
||||
|
||||
# Check internet connectivity
|
||||
if ! command -v wget >/dev/null 2>&1 && ! command -v curl >/dev/null 2>&1; then
|
||||
print_warning "Neither wget nor curl found. Cannot download Whisper model."
|
||||
print_warning "Model will be downloaded on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test internet connectivity (HTTP probes; ICMP ping is often blocked)
|
||||
if ! check_connectivity; then
|
||||
print_warning "No internet connection detected (HTTP probes to pypi.org/api.github.com/huggingface.co failed)."
|
||||
print_warning "Whisper model will be downloaded on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Downloading Whisper tiny model..."
|
||||
print_info "This may take a few minutes depending on your internet connection."
|
||||
|
||||
local TEMP_FILE="$VOCALINUX_TMP_DIR/tiny.pt"
|
||||
|
||||
if ! download_model_file "$TINY_MODEL_URL" "$TEMP_FILE" "Whisper model"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify before the file reaches its final location, so a failed download is
|
||||
# never installed. (The "already exists" path above hashes what it finds.)
|
||||
if ! verify_openai_model_checksum "$TEMP_FILE" "$TINY_MODEL_URL" "Whisper tiny model"; then
|
||||
rm -f "$TEMP_FILE"
|
||||
print_warning "Whisper model will be downloaded and verified on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Move to final location
|
||||
mv "$TEMP_FILE" "$TINY_MODEL_PATH"
|
||||
|
||||
# Verify the model file
|
||||
if [ -f "$TINY_MODEL_PATH" ]; then
|
||||
local MODEL_SIZE=$(du -h "$TINY_MODEL_PATH" | cut -f1)
|
||||
print_success "Whisper tiny model installed successfully ($MODEL_SIZE)"
|
||||
|
||||
# Create a marker file to indicate this model was pre-installed
|
||||
echo "$(date)" > "$WHISPER_DIR/.vocalinux_preinstalled"
|
||||
|
||||
return 0
|
||||
else
|
||||
print_error "Whisper model installation failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to download and install VOSK models
|
||||
install_vosk_models() {
|
||||
print_info "Installing VOSK speech recognition models..."
|
||||
|
||||
# Create models directory
|
||||
local MODELS_DIR="$DATA_DIR/models"
|
||||
mkdir -p "$MODELS_DIR"
|
||||
|
||||
# Define model information
|
||||
local SMALL_MODEL_URL="https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip"
|
||||
local SMALL_MODEL_NAME="vosk-model-small-en-us-0.15"
|
||||
local SMALL_MODEL_PATH="$MODELS_DIR/$SMALL_MODEL_NAME"
|
||||
|
||||
local SMALL_MODEL_ARCHIVE="$SMALL_MODEL_NAME.zip"
|
||||
# The extracted tree has no digest of its own — the pin covers the zip, which
|
||||
# is deleted after unpacking. So whoever unpacks it records the verified zip
|
||||
# digest in a stamp (here, and in the app's own downloader), and the directory
|
||||
# is trusted only while that stamp matches what we pin today.
|
||||
local SMALL_MODEL_STAMP="$SMALL_MODEL_PATH/.vocalinux_verified"
|
||||
local EXPECTED_ZIP_DIGEST
|
||||
EXPECTED_ZIP_DIGEST=$(pinned_digest_for "$SMALL_MODEL_ARCHIVE" || true)
|
||||
if [ -d "$SMALL_MODEL_PATH" ]; then
|
||||
if [ -n "$EXPECTED_ZIP_DIGEST" ] && [ -f "$SMALL_MODEL_STAMP" ] &&
|
||||
[ "$(cat "$SMALL_MODEL_STAMP" 2>/dev/null)" = "$EXPECTED_ZIP_DIGEST" ]; then
|
||||
print_info "Small VOSK model already exists at $SMALL_MODEL_PATH (verified)"
|
||||
return 0
|
||||
fi
|
||||
# Unverified is not the same as known-bad, and this runs on every install:
|
||||
# a tree unpacked before stamps existed, or by the app itself, simply has
|
||||
# no stamp. Deleting it here would trade a working model for no model
|
||||
# whenever the download, unzip or network that follows fails. Fetch and
|
||||
# verify the replacement first; the swap below is what removes this tree.
|
||||
print_warning "The existing VOSK model carries no matching verification stamp; re-downloading it."
|
||||
fi
|
||||
|
||||
# Refuse before spending the download, not after verification rejects it.
|
||||
if [ -z "$EXPECTED_ZIP_DIGEST" ]; then
|
||||
print_error "No checksum is pinned for $SMALL_MODEL_ARCHIVE in $MODEL_CHECKSUMS_FILE."
|
||||
print_warning "VOSK model will be downloaded and verified on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check internet connectivity
|
||||
if ! command -v wget >/dev/null 2>&1 && ! command -v curl >/dev/null 2>&1; then
|
||||
print_warning "Neither wget nor curl found. Cannot download VOSK models."
|
||||
print_warning "Models will be downloaded on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test internet connectivity (HTTP probes; ICMP ping is often blocked)
|
||||
if ! check_connectivity; then
|
||||
print_warning "No internet connection detected (HTTP probes to pypi.org/api.github.com/huggingface.co failed)."
|
||||
print_warning "VOSK models will be downloaded on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Downloading small VOSK model (approximately 40MB)..."
|
||||
print_info "This may take a few minutes depending on your internet connection."
|
||||
|
||||
local TEMP_ZIP="$VOCALINUX_TMP_DIR/$(basename $SMALL_MODEL_URL)"
|
||||
|
||||
if ! download_model_file "$SMALL_MODEL_URL" "$TEMP_ZIP" "VOSK model"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify before extracting: a zip that fails its pinned digest must not get
|
||||
# as far as writing files into the models directory.
|
||||
if ! verify_model_checksum "$TEMP_ZIP"; then
|
||||
rm -f "$TEMP_ZIP"
|
||||
print_warning "VOSK model will be downloaded and verified on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Extracting VOSK model..."
|
||||
|
||||
if ! command -v unzip >/dev/null 2>&1; then
|
||||
print_error "unzip command not found. Cannot extract VOSK model."
|
||||
rm -f "$TEMP_ZIP"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Unpack beside the model rather than over it: any model already installed
|
||||
# stays usable until a complete, verified replacement exists, and staging in
|
||||
# MODELS_DIR keeps the swap a same-filesystem rename.
|
||||
local STAGING_DIR="$MODELS_DIR/.vosk-staging.$$"
|
||||
# A run killed mid-swap leaves its scratch directories behind; they are named
|
||||
# so they can be recognised and are of no use to a later run.
|
||||
find "$MODELS_DIR" -maxdepth 1 -type d \
|
||||
\( -name '.vosk-staging.*' -o -name '.*.replaced.*' \) \
|
||||
-exec rm -rf {} + 2>/dev/null || true
|
||||
if ! mkdir -p "$STAGING_DIR"; then
|
||||
print_error "Failed to create a staging directory under $MODELS_DIR"
|
||||
rm -f "$TEMP_ZIP"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! unzip -q "$TEMP_ZIP" -d "$STAGING_DIR"; then
|
||||
print_error "Failed to extract VOSK model"
|
||||
rm -f "$TEMP_ZIP"
|
||||
rm -rf "$STAGING_DIR"
|
||||
return 1
|
||||
fi
|
||||
rm -f "$TEMP_ZIP"
|
||||
|
||||
if [ ! -d "$STAGING_DIR/$SMALL_MODEL_NAME" ]; then
|
||||
print_error "VOSK model extraction failed - $SMALL_MODEL_NAME not found in the archive"
|
||||
rm -rf "$STAGING_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
chmod -R 755 "$STAGING_DIR/$SMALL_MODEL_NAME"
|
||||
echo "$(date)" > "$STAGING_DIR/$SMALL_MODEL_NAME/.vocalinux_preinstalled"
|
||||
|
||||
# Record the digest this tree was extracted from, so a later run can tell a
|
||||
# verified model from one that merely exists. Written before the swap: an
|
||||
# unstamped tree is one this function would download all over again.
|
||||
if [ -z "$EXPECTED_ZIP_DIGEST" ] ||
|
||||
! printf '%s\n' "$EXPECTED_ZIP_DIGEST" > "$STAGING_DIR/$SMALL_MODEL_NAME/.vocalinux_verified"; then
|
||||
print_error "Could not record the verified digest for $SMALL_MODEL_NAME"
|
||||
rm -rf "$STAGING_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Swap. The old tree is moved aside rather than deleted, so a failed rename
|
||||
# can put it back.
|
||||
local REPLACED_DIR="$MODELS_DIR/.$SMALL_MODEL_NAME.replaced.$$"
|
||||
if [ -d "$SMALL_MODEL_PATH" ] && ! mv "$SMALL_MODEL_PATH" "$REPLACED_DIR"; then
|
||||
print_error "Could not move the existing VOSK model aside; keeping it"
|
||||
rm -rf "$STAGING_DIR"
|
||||
return 1
|
||||
fi
|
||||
if ! mv "$STAGING_DIR/$SMALL_MODEL_NAME" "$SMALL_MODEL_PATH"; then
|
||||
print_error "Failed to install the verified VOSK model"
|
||||
if [ -d "$REPLACED_DIR" ]; then
|
||||
mv "$REPLACED_DIR" "$SMALL_MODEL_PATH"
|
||||
fi
|
||||
rm -rf "$STAGING_DIR"
|
||||
return 1
|
||||
fi
|
||||
rm -rf "$REPLACED_DIR" "$STAGING_DIR"
|
||||
|
||||
print_success "VOSK small model installed successfully at $SMALL_MODEL_PATH"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to download and install whisper.cpp tiny model
|
||||
install_whispercpp_model() {
|
||||
print_info "Installing whisper.cpp tiny model (~39MB)..."
|
||||
|
||||
# Create whisper.cpp models directory
|
||||
local WHISPERCPP_DIR="$DATA_DIR/models/whispercpp"
|
||||
mkdir -p "$WHISPERCPP_DIR"
|
||||
|
||||
# whisper.cpp tiny model URL and path. The Hugging Face revision is pinned to
|
||||
# the one the digests in model_checksums.txt were taken at, so upstream
|
||||
# replacing ggml-tiny.bin cannot turn every install into a checksum failure.
|
||||
local WHISPERCPP_REVISION
|
||||
WHISPERCPP_REVISION=$(whispercpp_pinned_revision)
|
||||
if [ -z "$WHISPERCPP_REVISION" ]; then
|
||||
print_error "No whisper.cpp revision is pinned in $MODEL_CHECKSUMS_FILE."
|
||||
print_warning "whisper.cpp model will be downloaded and verified on first application run."
|
||||
return 1
|
||||
fi
|
||||
local TINY_MODEL_URL="https://huggingface.co/ggerganov/whisper.cpp/resolve/$WHISPERCPP_REVISION/ggml-tiny.bin"
|
||||
local TINY_MODEL_PATH="$WHISPERCPP_DIR/ggml-tiny.bin"
|
||||
|
||||
# An existing file is not a verified file: it may predate checksum
|
||||
# verification, or have been replaced since. Hash it before trusting it,
|
||||
# and re-download rather than keep something that does not match.
|
||||
if [ -f "$TINY_MODEL_PATH" ]; then
|
||||
if verify_model_checksum "$TINY_MODEL_PATH" "ggml-tiny.bin"; then
|
||||
print_info "whisper.cpp tiny model already exists at $TINY_MODEL_PATH"
|
||||
return 0
|
||||
fi
|
||||
print_warning "The existing whisper.cpp tiny model does not match its pinned digest; replacing it."
|
||||
rm -f "$TINY_MODEL_PATH"
|
||||
fi
|
||||
|
||||
# Check internet connectivity
|
||||
if ! command -v wget >/dev/null 2>&1 && ! command -v curl >/dev/null 2>&1; then
|
||||
print_warning "Neither wget nor curl found. Cannot download whisper.cpp model."
|
||||
print_warning "Model will be downloaded on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test internet connectivity (HTTP probes; ICMP ping is often blocked)
|
||||
if ! check_connectivity; then
|
||||
print_warning "No internet connection detected (HTTP probes to pypi.org/api.github.com/huggingface.co failed)."
|
||||
print_warning "whisper.cpp model will be downloaded on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Downloading whisper.cpp tiny model..."
|
||||
print_info "This may take a few minutes depending on your internet connection."
|
||||
|
||||
local TEMP_FILE="$VOCALINUX_TMP_DIR/ggml-tiny.bin"
|
||||
|
||||
if ! download_model_file "$TINY_MODEL_URL" "$TEMP_FILE" "whisper.cpp model"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify before the file reaches its final location, so a failed download is
|
||||
# never installed. (The "already exists" path above hashes what it finds.)
|
||||
if ! verify_model_checksum "$TEMP_FILE" "ggml-tiny.bin"; then
|
||||
rm -f "$TEMP_FILE"
|
||||
print_warning "whisper.cpp model will be downloaded and verified on first application run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Move to final location
|
||||
mv "$TEMP_FILE" "$TINY_MODEL_PATH"
|
||||
|
||||
# Verify the model file
|
||||
if [ -f "$TINY_MODEL_PATH" ]; then
|
||||
local MODEL_SIZE=$(du -h "$TINY_MODEL_PATH" | cut -f1)
|
||||
print_success "whisper.cpp tiny model installed successfully ($MODEL_SIZE)"
|
||||
|
||||
# Create a marker file to indicate this model was pre-installed
|
||||
echo "$(date)" > "$WHISPERCPP_DIR/.vocalinux_preinstalled"
|
||||
|
||||
return 0
|
||||
else
|
||||
print_error "whisper.cpp model installation failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
# Generated by scripts/generate_distro_package_map.py -- do not edit.
|
||||
# Regenerate with `just distro-packages` after editing
|
||||
# scripts/distro-package-map.yaml.
|
||||
|
||||
DEBIAN_13_PLUS_PROBE_PACKAGE=libgirepository-2.0-dev
|
||||
|
||||
load_distro_package_map() {
|
||||
local package_map_key="$1"
|
||||
|
||||
SYSTEM_PACKAGES=()
|
||||
APPINDICATOR_PACKAGES=()
|
||||
GI_DEVELOPMENT_PACKAGES=()
|
||||
OPTIONAL_SYSTEM_PACKAGES=()
|
||||
PYTHON_PIP_SUFFIX=""
|
||||
PYTHON_GOBJECT_SUFFIX=""
|
||||
PYTHON_GOBJECT_CAIRO_SUFFIX=""
|
||||
PYTHON_DEVEL_SUFFIX=""
|
||||
PYTHON_VIRTUALENV_SUFFIX=""
|
||||
PYTHON_VENV_SUFFIX=""
|
||||
SHADER_COMPILER_PACKAGES=()
|
||||
VULKAN_PACKAGES=()
|
||||
XDOTOOL_PACKAGES=()
|
||||
WTYPE_PACKAGES=()
|
||||
YDOTOOL_PACKAGES=()
|
||||
|
||||
case "$package_map_key" in
|
||||
ubuntu)
|
||||
SYSTEM_PACKAGES=(python3-pip python3-gi python3-gi-cairo gir1.2-gtk-3.0 gir1.2-ibus-1.0 libcairo2-dev cmake python3-dev build-essential portaudio19-dev python3-venv pkg-config wget curl unzip vulkan-tools libvulkan-dev xclip xsel wl-clipboard libssl-dev autoconf automake libtool patchelf)
|
||||
APPINDICATOR_PACKAGES=(gir1.2-appindicator3-0.1 gir1.2-ayatanaappindicator3-0.1)
|
||||
GI_DEVELOPMENT_PACKAGES=(libgirepository-2.0-dev libgirepository1.0-dev)
|
||||
OPTIONAL_SYSTEM_PACKAGES=(util-linux-extra)
|
||||
SHADER_COMPILER_PACKAGES=(glslc glslang-tools)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
debian_12)
|
||||
SYSTEM_PACKAGES=(python3-pip python3-gi python3-gi-cairo gir1.2-gtk-3.0 gir1.2-ibus-1.0 libcairo2-dev cmake python3-dev build-essential portaudio19-dev python3-venv pkg-config wget curl unzip vulkan-tools libvulkan-dev xclip xsel wl-clipboard libssl-dev autoconf automake libtool patchelf libgirepository1.0-dev gir1.2-ayatanaappindicator3-0.1)
|
||||
OPTIONAL_SYSTEM_PACKAGES=(util-linux-extra)
|
||||
SHADER_COMPILER_PACKAGES=(glslc glslang-tools)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
debian_13_plus)
|
||||
SYSTEM_PACKAGES=(python3-pip python3-gi python3-gi-cairo gir1.2-gtk-3.0 gir1.2-ibus-1.0 libcairo2-dev cmake python3-dev build-essential portaudio19-dev python3-venv pkg-config wget curl unzip vulkan-tools libvulkan-dev xclip xsel wl-clipboard libssl-dev autoconf automake libtool patchelf libgirepository-2.0-dev gir1.2-ayatanaappindicator3-0.1)
|
||||
OPTIONAL_SYSTEM_PACKAGES=(util-linux-extra)
|
||||
SHADER_COMPILER_PACKAGES=(glslc glslang-tools)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
fedora)
|
||||
SYSTEM_PACKAGES=(python3-pip python3-gobject gtk3 ibus-devel gobject-introspection-devel python3-devel portaudio-devel cairo-devel python3-virtualenv pkg-config cmake gcc-c++ make wget curl unzip vulkan-tools vulkan-loader-devel glslc patchelf xclip xsel wl-clipboard)
|
||||
APPINDICATOR_PACKAGES=(libayatana-appindicator-gtk3 libappindicator-gtk3)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
arch)
|
||||
SYSTEM_PACKAGES=(python-pip python-gobject gtk3 ibus gobject-introspection python-cairo portaudio python-virtualenv pkg-config cmake wget curl unzip base-devel vulkan-tools vulkan-headers shaderc patchelf xclip xsel wl-clipboard)
|
||||
APPINDICATOR_PACKAGES=(libayatana-appindicator libappindicator-gtk3)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
suse)
|
||||
SYSTEM_PACKAGES=(gtk3 ibus typelib-1_0-IBus-1_0 gobject-introspection-devel portaudio-devel cairo-devel pkg-config cmake gcc gcc-c++ make wget curl unzip xclip xsel wl-clipboard typelib-1_0-Notify-0_7 libnotify4 patchelf)
|
||||
APPINDICATOR_PACKAGES=(typelib-1_0-AyatanaAppIndicator3-0_1 typelib-1_0-AppIndicator3-0_1 typelib-1_0-AyatanaAppIndicator-0_1 libayatana-appindicator3-1 libappindicator3-1 libappindicator-gtk3)
|
||||
SHADER_COMPILER_PACKAGES=(shaderc glslang-devel glslang)
|
||||
VULKAN_PACKAGES=(vulkan-tools vulkan-devel)
|
||||
PYTHON_DEVEL_SUFFIX=devel
|
||||
PYTHON_GOBJECT_SUFFIX=gobject
|
||||
PYTHON_GOBJECT_CAIRO_SUFFIX=gobject-cairo
|
||||
PYTHON_PIP_SUFFIX=pip
|
||||
PYTHON_VENV_SUFFIX=venv
|
||||
PYTHON_VIRTUALENV_SUFFIX=virtualenv
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
gentoo)
|
||||
SYSTEM_PACKAGES=(dev-python/pygobject:3 x11-libs/gtk+:3 dev-libs/libayatana-appindicator media-libs/portaudio dev-lang/python:3.11 pkgconf cmake media-libs/shaderc dev-util/patchelf x11-misc/xclip x11-misc/xsel gui-apps/wl-clipboard)
|
||||
XDOTOOL_PACKAGES=(x11-misc/xdotool)
|
||||
WTYPE_PACKAGES=(x11-misc/wtype)
|
||||
YDOTOOL_PACKAGES=(app-misc/ydotool)
|
||||
;;
|
||||
|
||||
alpine)
|
||||
SYSTEM_PACKAGES=(py3-gobject3 py3-pip gtk+3.0 py3-cairo portaudio-dev cairo-dev py3-virtualenv pkgconf cmake build-base wget curl unzip shaderc patchelf vulkan-tools xclip xsel wl-clipboard)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
void)
|
||||
SYSTEM_PACKAGES=(python3-pip python3-gobject gtk+3 libappindicator-gtk3 gobject-introspection portaudio-devel cairo-devel python3-devel pkg-config cmake base-devel wget curl unzip shaderc patchelf Vulkan-Tools xclip xsel wl-clipboard)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
solus)
|
||||
SYSTEM_PACKAGES=(python3-pip python3-gobject gtk3 libappindicator gobject-introspection-devel portaudio-devel cairo-devel python3-virtualenv pkg-config cmake gcc g++ make wget curl unzip shaderc patchelf vulkan-tools xclip xsel wl-clipboard)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
mageia)
|
||||
SYSTEM_PACKAGES=(python3-pip python3-gobject gtk3 ibus-devel gobject-introspection-devel python3-devel portaudio-devel cairo-devel python3-virtualenv pkg-config cmake gcc-c++ make wget curl unzip vulkan-tools vulkan-loader-devel glslc patchelf xclip xsel wl-clipboard)
|
||||
XDOTOOL_PACKAGES=(xdotool)
|
||||
WTYPE_PACKAGES=(wtype)
|
||||
YDOTOOL_PACKAGES=(ydotool)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown distro package map key: $package_map_key" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -0,0 +1,888 @@
|
||||
#!/bin/bash
|
||||
# Sourced by install.sh after it has resolved the local or tagged repository.
|
||||
# Keep this file declarative: function definitions only, with no top-level actions.
|
||||
|
||||
# Function to check if a command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to check if a package is installed (for apt-based systems)
|
||||
apt_package_installed() {
|
||||
dpkg -s "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to check if a package is installed (for dnf-based systems)
|
||||
dnf_package_installed() {
|
||||
rpm -q "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Function to check if a package is installed (for pacman-based systems)
|
||||
pacman_package_installed() {
|
||||
pacman -Q "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Install an AppIndicator/StatusNotifierItem provider, preferring the
|
||||
# actively maintained Ayatana fork over the legacy Canonical package
|
||||
# (unmaintained since ~2013). The legacy package can install and import
|
||||
# without error yet silently fail to register a tray icon with KDE's
|
||||
# StatusNotifierWatcher, leaving no icon and no logged error. $1 is the
|
||||
# package-manager install command (e.g. "sudo dnf install -y"), $2/$3 are
|
||||
# the Ayatana/legacy package names for that package manager, $4 is the
|
||||
# "is this package installed" checker function name.
|
||||
install_preferred_appindicator() {
|
||||
local install_cmd="$1"
|
||||
local ayatana_pkg="$2"
|
||||
local legacy_pkg="$3"
|
||||
local checker="$4"
|
||||
|
||||
if "$checker" "$ayatana_pkg"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if $install_cmd "$ayatana_pkg" 2>/dev/null; then
|
||||
print_info "Installed $ayatana_pkg (Ayatana AppIndicator; required for a working KDE tray icon)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if "$checker" "$legacy_pkg"; then
|
||||
print_info "$ayatana_pkg not available; $legacy_pkg is already installed but may not show a tray icon on KDE Plasma"
|
||||
return 0
|
||||
fi
|
||||
|
||||
print_info "$ayatana_pkg not available, falling back to $legacy_pkg (may not show a tray icon on KDE Plasma)..."
|
||||
if $install_cmd "$legacy_pkg"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
print_error "Failed to install an AppIndicator package (tried $ayatana_pkg and $legacy_pkg)"
|
||||
return 1
|
||||
}
|
||||
|
||||
suse_python_package_prefix() {
|
||||
python3 -c 'import sys; print(f"python{sys.version_info.major}{sys.version_info.minor}")' 2>/dev/null || echo "python3"
|
||||
}
|
||||
|
||||
suse_python_package_candidates() {
|
||||
local suffix="$1"
|
||||
local PY_PREFIX
|
||||
PY_PREFIX=$(suse_python_package_prefix)
|
||||
|
||||
if [[ "$PY_PREFIX" != "python3" ]]; then
|
||||
echo "${PY_PREFIX}-${suffix} python3-${suffix}"
|
||||
else
|
||||
echo "python3-${suffix}"
|
||||
fi
|
||||
}
|
||||
|
||||
suse_package_installed() {
|
||||
rpm -q "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
suse_install_first_available() {
|
||||
local DESCRIPTION="$1"
|
||||
shift
|
||||
|
||||
local PKG
|
||||
for PKG in "$@"; do
|
||||
[ -z "$PKG" ] && continue
|
||||
|
||||
if suse_package_installed "$PKG"; then
|
||||
print_info "$DESCRIPTION is already installed ($PKG)."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if sudo zypper install -y "$PKG" 2>/dev/null; then
|
||||
print_success "Installed $DESCRIPTION ($PKG)."
|
||||
return 0
|
||||
fi
|
||||
|
||||
print_info "$DESCRIPTION package '$PKG' not available, trying next option..."
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
suse_appindicator_gi_available() {
|
||||
python3 - <<'PY' >/dev/null 2>&1
|
||||
import importlib
|
||||
import gi
|
||||
|
||||
for namespace in ("AppIndicator3", "AyatanaAppIndicator3", "AyatanaAppindicator3"):
|
||||
try:
|
||||
gi.require_version(namespace, "0.1")
|
||||
importlib.import_module(f"gi.repository.{namespace}")
|
||||
raise SystemExit(0)
|
||||
except (ImportError, ValueError):
|
||||
pass
|
||||
|
||||
raise SystemExit(1)
|
||||
PY
|
||||
}
|
||||
|
||||
suse_install_appindicator_runtime() {
|
||||
if suse_appindicator_gi_available; then
|
||||
print_info "AppIndicator/Ayatana GI namespace is already available."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local PKG
|
||||
for PKG in "${APPINDICATOR_PACKAGES[@]}"; do
|
||||
if suse_package_installed "$PKG"; then
|
||||
print_info "AppIndicator/Ayatana package is already installed ($PKG); verifying GI namespace..."
|
||||
elif sudo zypper install -y "$PKG" 2>/dev/null; then
|
||||
print_success "Installed AppIndicator/Ayatana package ($PKG)."
|
||||
# Refresh the shared-library cache so the GI typelib is discoverable
|
||||
sudo ldconfig 2>/dev/null || true
|
||||
else
|
||||
print_info "AppIndicator/Ayatana package '$PKG' not available, trying next option..."
|
||||
continue
|
||||
fi
|
||||
|
||||
if suse_appindicator_gi_available; then
|
||||
print_success "AppIndicator/Ayatana GI namespace is available."
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
suse_shader_compiler_available() {
|
||||
command_exists glslc || command_exists glslangValidator
|
||||
}
|
||||
|
||||
resolve_debian_package_map_key() {
|
||||
local DEBIAN_MAJOR="${DISTRO_VERSION%%.*}"
|
||||
|
||||
# Only Debian's own VERSION_ID identifies a Debian release. Derivatives
|
||||
# often use an unrelated product version, so select their compatible map
|
||||
# by probing the package inventory instead.
|
||||
if [[ "$DISTRO_ID" == "debian" && "$DEBIAN_MAJOR" =~ ^[0-9]+$ ]]; then
|
||||
if [ "$DEBIAN_MAJOR" -lt 12 ]; then
|
||||
print_error "Debian 12 or newer is required (detected Debian $DEBIAN_MAJOR)." >&2
|
||||
return "$EXIT_MISSING_DEPS"
|
||||
elif [ "$DEBIAN_MAJOR" -ge 13 ]; then
|
||||
echo "debian_13_plus"
|
||||
else
|
||||
echo "debian_12"
|
||||
fi
|
||||
else
|
||||
# A missing cache is not evidence of an older Debian base. Refresh
|
||||
# before probing; keep command substitution's stdout for the key only.
|
||||
sudo apt update >&2 || {
|
||||
print_error "Failed to refresh package indexes for Debian base detection." >&2
|
||||
return "$EXIT_NETWORK"
|
||||
}
|
||||
if apt-cache show "$DEBIAN_13_PLUS_PROBE_PACKAGE" &>/dev/null 2>&1; then
|
||||
echo "debian_13_plus"
|
||||
else
|
||||
echo "debian_12"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install system dependencies based on the detected distribution
|
||||
install_system_dependencies() {
|
||||
print_info "Installing system dependencies..."
|
||||
|
||||
local PACKAGE_MAP_KEY="$DISTRO_FAMILY"
|
||||
if [[ "$DISTRO_FAMILY" == "debian" ]]; then
|
||||
PACKAGE_MAP_KEY=$(resolve_debian_package_map_key) || exit "$?"
|
||||
fi
|
||||
case "$PACKAGE_MAP_KEY" in
|
||||
ubuntu|debian_12|debian_13_plus|fedora|arch|suse|gentoo|alpine|void|solus|mageia)
|
||||
load_distro_package_map "$PACKAGE_MAP_KEY" || exit "$EXIT_MISSING_DEPS"
|
||||
;;
|
||||
esac
|
||||
|
||||
# GObject Introspection / GLib headers for building PyGObject and friends.
|
||||
# Prefer libgirepository-2.0-dev when available (Ubuntu 24.04+, Pop!_OS Cosmic+,
|
||||
# Debian 13+). When both 1.0 and 2.0 packages exist, install both: 2.0 provides
|
||||
# the modern GLib GI headers that pip builds need, while 1.0 still pulls
|
||||
# gobject-introspection tooling. Older distros that only ship 1.0 keep that.
|
||||
# See #571 (installer previously kept 1.0 whenever apt-cache still listed it).
|
||||
if [[ "$DISTRO_FAMILY" == "ubuntu" ]]; then
|
||||
local GI_DEV_PACKAGE
|
||||
local GI_DEV_FOUND="no"
|
||||
for GI_DEV_PACKAGE in "${GI_DEVELOPMENT_PACKAGES[@]}"; do
|
||||
if apt-cache show "$GI_DEV_PACKAGE" &>/dev/null 2>&1; then
|
||||
SYSTEM_PACKAGES+=("$GI_DEV_PACKAGE")
|
||||
GI_DEV_FOUND="yes"
|
||||
fi
|
||||
done
|
||||
if [[ "$GI_DEV_FOUND" == "no" ]]; then
|
||||
SYSTEM_PACKAGES+=("${GI_DEVELOPMENT_PACKAGES[1]}")
|
||||
fi
|
||||
SYSTEM_PACKAGES+=("${APPINDICATOR_PACKAGES[0]}")
|
||||
fi
|
||||
|
||||
if [[ "$DISTRO_FAMILY" == "ubuntu" || "$DISTRO_FAMILY" == "debian" ]]; then
|
||||
local SHADER_PACKAGE="${SHADER_COMPILER_PACKAGES[1]}"
|
||||
local SHADER_CANDIDATE
|
||||
for SHADER_CANDIDATE in "${SHADER_COMPILER_PACKAGES[@]}"; do
|
||||
if apt-cache show "$SHADER_CANDIDATE" &>/dev/null 2>&1; then
|
||||
SHADER_PACKAGE="$SHADER_CANDIDATE"
|
||||
break
|
||||
fi
|
||||
done
|
||||
SYSTEM_PACKAGES+=("$SHADER_PACKAGE")
|
||||
|
||||
local OPTIONAL_PACKAGE
|
||||
for OPTIONAL_PACKAGE in "${OPTIONAL_SYSTEM_PACKAGES[@]}"; do
|
||||
if apt-cache show "$OPTIONAL_PACKAGE" &>/dev/null 2>&1; then
|
||||
SYSTEM_PACKAGES+=("$OPTIONAL_PACKAGE")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
local MISSING_PACKAGES=""
|
||||
local INSTALL_CMD=""
|
||||
local UPDATE_CMD=""
|
||||
|
||||
case "$DISTRO_FAMILY" in
|
||||
ubuntu|debian)
|
||||
# Check for missing packages
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
if ! apt_package_installed "$pkg"; then
|
||||
MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_PACKAGES" ]; then
|
||||
print_info "Installing missing packages:$MISSING_PACKAGES"
|
||||
sudo apt update || { print_error "Failed to update package lists"; exit "$EXIT_NETWORK"; }
|
||||
|
||||
# Handle appindicator package for Ubuntu (old package deprecated in newer releases)
|
||||
if [[ "$DISTRO_FAMILY" == "ubuntu" ]] && echo "$MISSING_PACKAGES" | grep -q "${APPINDICATOR_PACKAGES[0]}"; then
|
||||
FILTERED_PACKAGES=$(echo "$MISSING_PACKAGES" | sed "s/${APPINDICATOR_PACKAGES[0]}//" | xargs)
|
||||
|
||||
if ! DEBIAN_FRONTEND=noninteractive sudo apt install -y "${APPINDICATOR_PACKAGES[0]}" 2>/dev/null; then
|
||||
print_info "${APPINDICATOR_PACKAGES[0]} not available, trying ${APPINDICATOR_PACKAGES[1]}..."
|
||||
if ! DEBIAN_FRONTEND=noninteractive sudo apt install -y "${APPINDICATOR_PACKAGES[1]}"; then
|
||||
print_error "Failed to install appindicator package (tried both ${APPINDICATOR_PACKAGES[*]})"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
print_info "Successfully installed ${APPINDICATOR_PACKAGES[1]} (modern replacement)"
|
||||
fi
|
||||
|
||||
if [ -n "$FILTERED_PACKAGES" ]; then
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt install -y $FILTERED_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
fi
|
||||
else
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt install -y $MISSING_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
fi
|
||||
else
|
||||
print_info "All required packages are already installed."
|
||||
fi
|
||||
;;
|
||||
|
||||
fedora)
|
||||
# For Fedora/RHEL-based systems
|
||||
if command_exists dnf; then
|
||||
INSTALL_CMD="sudo dnf install -y"
|
||||
UPDATE_CMD="sudo dnf check-update"
|
||||
elif command_exists yum; then
|
||||
INSTALL_CMD="sudo yum install -y"
|
||||
UPDATE_CMD="sudo yum check-update"
|
||||
else
|
||||
print_error "No supported package manager found (dnf/yum)"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
# Check for missing packages
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
if ! dnf_package_installed "$pkg"; then
|
||||
MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_PACKAGES" ]; then
|
||||
print_info "Installing missing packages:$MISSING_PACKAGES"
|
||||
$UPDATE_CMD || true # dnf check-update returns 100 if updates available
|
||||
$INSTALL_CMD $MISSING_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
else
|
||||
print_info "All required packages are already installed."
|
||||
fi
|
||||
|
||||
install_preferred_appindicator "$INSTALL_CMD" "${APPINDICATOR_PACKAGES[0]}" "${APPINDICATOR_PACKAGES[1]}" dnf_package_installed || exit "$EXIT_MISSING_DEPS"
|
||||
;;
|
||||
|
||||
arch)
|
||||
# For Arch-based systems
|
||||
if ! command_exists pacman; then
|
||||
print_error "Pacman package manager not found"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
# Check for missing packages
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
if ! pacman_package_installed "$pkg"; then
|
||||
MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_PACKAGES" ]; then
|
||||
print_info "Installing missing packages:$MISSING_PACKAGES"
|
||||
sudo pacman -Sy
|
||||
sudo pacman -S --noconfirm $MISSING_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
else
|
||||
print_info "All required packages are already installed."
|
||||
fi
|
||||
|
||||
install_preferred_appindicator "sudo pacman -S --noconfirm" "${APPINDICATOR_PACKAGES[0]}" "${APPINDICATOR_PACKAGES[1]}" pacman_package_installed || exit "$EXIT_MISSING_DEPS"
|
||||
;;
|
||||
|
||||
suse)
|
||||
# For openSUSE
|
||||
if ! command_exists zypper; then
|
||||
print_error "Zypper package manager not found"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
sudo zypper refresh || true
|
||||
|
||||
if [[ "${SELECTED_ENGINE:-whisper_cpp}" == "whisper_cpp" && "${WHISPERCPP_BACKEND:-}" != "cpu" ]]; then
|
||||
SYSTEM_PACKAGES+=("${VULKAN_PACKAGES[@]}")
|
||||
fi
|
||||
|
||||
local MISSING_ZYPPER_PACKAGES=()
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
if ! suse_package_installed "$pkg"; then
|
||||
MISSING_ZYPPER_PACKAGES+=("$pkg")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${#MISSING_ZYPPER_PACKAGES[@]}" -gt 0 ]; then
|
||||
print_info "Installing missing packages: ${MISSING_ZYPPER_PACKAGES[*]}"
|
||||
sudo zypper install -y "${MISSING_ZYPPER_PACKAGES[@]}" || {
|
||||
print_error "Failed to install openSUSE base dependencies"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
}
|
||||
else
|
||||
print_info "All base openSUSE packages are already installed."
|
||||
fi
|
||||
|
||||
local PY_PIP_CANDIDATES=()
|
||||
local PY_GOBJECT_CANDIDATES=()
|
||||
local PY_GOBJECT_CAIRO_CANDIDATES=()
|
||||
local PY_DEVEL_CANDIDATES=()
|
||||
local PY_VIRTUALENV_CANDIDATES=()
|
||||
local PY_VENV_CANDIDATES=()
|
||||
|
||||
read -r -a PY_PIP_CANDIDATES <<< "$(suse_python_package_candidates "$PYTHON_PIP_SUFFIX")"
|
||||
read -r -a PY_GOBJECT_CANDIDATES <<< "$(suse_python_package_candidates "$PYTHON_GOBJECT_SUFFIX")"
|
||||
read -r -a PY_GOBJECT_CAIRO_CANDIDATES <<< "$(suse_python_package_candidates "$PYTHON_GOBJECT_CAIRO_SUFFIX")"
|
||||
read -r -a PY_DEVEL_CANDIDATES <<< "$(suse_python_package_candidates "$PYTHON_DEVEL_SUFFIX")"
|
||||
read -r -a PY_VIRTUALENV_CANDIDATES <<< "$(suse_python_package_candidates "$PYTHON_VIRTUALENV_SUFFIX")"
|
||||
read -r -a PY_VENV_CANDIDATES <<< "$(suse_python_package_candidates "$PYTHON_VENV_SUFFIX")"
|
||||
|
||||
print_info "Resolving openSUSE Python packages for $(suse_python_package_prefix)..."
|
||||
|
||||
if ! suse_install_first_available "Python pip" "${PY_PIP_CANDIDATES[@]}"; then
|
||||
print_error "Failed to install Python pip package (tried: ${PY_PIP_CANDIDATES[*]})"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
if ! suse_install_first_available "PyGObject bindings" "${PY_GOBJECT_CANDIDATES[@]}"; then
|
||||
print_error "Failed to install PyGObject package (tried: ${PY_GOBJECT_CANDIDATES[*]})"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
if ! suse_install_first_available "PyGObject Cairo bindings" "${PY_GOBJECT_CAIRO_CANDIDATES[@]}"; then
|
||||
print_error "Failed to install PyGObject Cairo package (tried: ${PY_GOBJECT_CAIRO_CANDIDATES[*]})"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
if ! suse_install_first_available "Python development headers" "${PY_DEVEL_CANDIDATES[@]}"; then
|
||||
print_error "Failed to install Python development headers (tried: ${PY_DEVEL_CANDIDATES[*]})"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
if ! suse_install_first_available "Python virtualenv/venv" "${PY_VIRTUALENV_CANDIDATES[@]}" "${PY_VENV_CANDIDATES[@]}"; then
|
||||
print_warning "Python virtualenv/venv package was not found (tried: ${PY_VIRTUALENV_CANDIDATES[*]} ${PY_VENV_CANDIDATES[*]})"
|
||||
print_warning "Continuing because python3 -m venv may still be available."
|
||||
fi
|
||||
|
||||
if ! suse_install_appindicator_runtime; then
|
||||
print_error "Failed to install a working AppIndicator/Ayatana GI runtime on openSUSE."
|
||||
print_error "Try manually: sudo zypper install ${APPINDICATOR_PACKAGES[0]} ${APPINDICATOR_PACKAGES[3]}"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
if [[ "${SELECTED_ENGINE:-whisper_cpp}" == "whisper_cpp" && "${WHISPERCPP_BACKEND:-}" != "cpu" ]]; then
|
||||
if ! suse_shader_compiler_available; then
|
||||
if ! suse_install_first_available "Vulkan shader compiler" "${SHADER_COMPILER_PACKAGES[@]}"; then
|
||||
print_warning "No Vulkan shader compiler found - whisper.cpp Vulkan build may fail"
|
||||
print_warning "Install shaderc manually for glslc support if you want GPU acceleration."
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! suse_shader_compiler_available; then
|
||||
print_warning "glslc/glslangValidator is still unavailable; CPU fallback will be used if Vulkan build fails."
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
gentoo)
|
||||
# For Gentoo Linux
|
||||
if ! command_exists emerge; then
|
||||
print_error "Emerge package manager not found"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
print_info "Gentoo detected. Installing dependencies..."
|
||||
print_warning "Gentoo uses emerge. This may take longer as packages are compiled from source."
|
||||
|
||||
# Check for missing packages
|
||||
MISSING_PACKAGES=""
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
# Gentoo uses qlist to check if packages are installed
|
||||
if ! qlist -I "$pkg" >/dev/null 2>&1; then
|
||||
MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_PACKAGES" ]; then
|
||||
print_info "Installing packages:$MISSING_PACKAGES"
|
||||
# Update Portage tree first
|
||||
sudo emerge --sync || { print_error "Failed to sync Portage tree"; exit "$EXIT_NETWORK"; }
|
||||
# Install missing packages
|
||||
sudo emerge $MISSING_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
else
|
||||
print_info "All required packages are already installed."
|
||||
fi
|
||||
;;
|
||||
|
||||
alpine)
|
||||
# For Alpine Linux
|
||||
if ! command_exists apk; then
|
||||
print_error "Apk package manager not found"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
print_info "Alpine Linux detected."
|
||||
print_warning "Alpine uses musl libc. Some Python packages may not have pre-built wheels."
|
||||
|
||||
# Check for missing packages
|
||||
MISSING_PACKAGES=""
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
if ! apk info -e "$pkg" >/dev/null 2>&1; then
|
||||
MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_PACKAGES" ]; then
|
||||
print_info "Installing packages:$MISSING_PACKAGES"
|
||||
sudo apk update || { print_error "Failed to update package indexes"; exit "$EXIT_NETWORK"; }
|
||||
sudo apk add $MISSING_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
else
|
||||
print_info "All required packages are already installed."
|
||||
fi
|
||||
;;
|
||||
|
||||
void)
|
||||
# For Void Linux
|
||||
if ! command_exists xbps; then
|
||||
print_error "Xbps package manager not found"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
print_info "Void Linux detected."
|
||||
|
||||
# Check for missing packages
|
||||
MISSING_PACKAGES=""
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
if ! xbps-query "$pkg" >/dev/null 2>&1; then
|
||||
MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_PACKAGES" ]; then
|
||||
print_info "Installing packages:$MISSING_PACKAGES"
|
||||
sudo xbps-install -Sy $MISSING_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
else
|
||||
print_info "All required packages are already installed."
|
||||
fi
|
||||
;;
|
||||
|
||||
solus)
|
||||
# For Solus
|
||||
if ! command_exists eopkg; then
|
||||
print_error "Eopkg package manager not found"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
print_info "Solus detected."
|
||||
|
||||
# Check for missing packages
|
||||
MISSING_PACKAGES=""
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
if ! eopkg list-installed | grep -qw "$pkg"; then
|
||||
MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_PACKAGES" ]; then
|
||||
print_info "Installing packages:$MISSING_PACKAGES"
|
||||
sudo eopkg install $MISSING_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
else
|
||||
print_info "All required packages are already installed."
|
||||
fi
|
||||
;;
|
||||
|
||||
mageia)
|
||||
# For Mageia
|
||||
if command_exists dnf; then
|
||||
INSTALL_CMD="sudo dnf install -y"
|
||||
UPDATE_CMD="sudo dnf check-update"
|
||||
elif command_exists urpmi; then
|
||||
INSTALL_CMD="sudo urpmi --force"
|
||||
UPDATE_CMD="sudo urpmi.update -a"
|
||||
else
|
||||
print_error "No supported package manager found (dnf/urpmi)"
|
||||
exit "$EXIT_MISSING_DEPS"
|
||||
fi
|
||||
|
||||
# Use similar packages to Fedora/RHEL
|
||||
for pkg in "${SYSTEM_PACKAGES[@]}"; do
|
||||
# Mageia uses rpm like Fedora
|
||||
if ! rpm -q "$pkg" >/dev/null 2>&1; then
|
||||
MISSING_PACKAGES="$MISSING_PACKAGES $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_PACKAGES" ]; then
|
||||
print_info "Installing missing packages:$MISSING_PACKAGES"
|
||||
$UPDATE_CMD 2>/dev/null || true
|
||||
$INSTALL_CMD $MISSING_PACKAGES || { print_error "Failed to install dependencies"; exit "$EXIT_MISSING_DEPS"; }
|
||||
else
|
||||
print_info "All required packages are already installed."
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
print_error "Unsupported distribution family: $DISTRO_FAMILY"
|
||||
print_info ""
|
||||
print_info "Your distribution ($DISTRO_NAME) is not officially supported."
|
||||
print_info "However, you can still install Vocalinux manually:"
|
||||
print_info ""
|
||||
print_info "1. Run the dependency checker:"
|
||||
print_info " bash scripts/check-system-deps.sh"
|
||||
print_info ""
|
||||
print_info "2. Install missing dependencies using your package manager"
|
||||
print_info ""
|
||||
print_info "3. Run the installer with --skip-system-deps:"
|
||||
print_info " ./install.sh --skip-system-deps"
|
||||
print_info ""
|
||||
print_info "4. Or install from source in a virtual environment:"
|
||||
print_info " /usr/bin/python3 -m venv --system-site-packages venv"
|
||||
print_info " source venv/bin/activate"
|
||||
print_info " pip install -e .[whisper,vad]"
|
||||
print_info ""
|
||||
print_info "For more information, see the project wiki:"
|
||||
print_info " https://github.com/VocaHQ/vocalinux/wiki"
|
||||
print_info ""
|
||||
if [[ "$NON_INTERACTIVE" != "yes" ]]; then
|
||||
read_prompt -p "Continue anyway? (y/n) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit "$EXIT_USER_ABORT"
|
||||
fi
|
||||
else
|
||||
print_info "Non-interactive mode: continuing (dependencies may be missing)..."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Function to detect and install text input tools
|
||||
install_text_input_tools() {
|
||||
if [[ "$SKIP_SYSTEM_DEPS" == "yes" ]]; then
|
||||
print_warning "Skipping text input tool installation (--skip-system-deps specified)."
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Unsupported distros can continue past install_system_dependencies in
|
||||
# non-interactive mode, but they have no generated package inventory.
|
||||
if [[ -z "${XDOTOOL_PACKAGES+x}" ]]; then
|
||||
print_warning "No text input package map is available for $DISTRO_NAME."
|
||||
print_warning "Install xdotool or wtype manually for your display server."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local XDOTOOL_PKG="${XDOTOOL_PACKAGES[0]}"
|
||||
local WTYPE_PKG="${WTYPE_PACKAGES[0]}"
|
||||
local YDOTOOL_PKG="${YDOTOOL_PACKAGES[0]}"
|
||||
|
||||
# Detect session type more robustly
|
||||
local SESSION_TYPE="unknown"
|
||||
|
||||
# Check XDG_SESSION_TYPE first. These are often unset without a login
|
||||
# session even when DISPLAY is set; ${var:-} keeps set -u from aborting.
|
||||
if [ -n "${XDG_SESSION_TYPE:-}" ]; then
|
||||
SESSION_TYPE="${XDG_SESSION_TYPE:-}"
|
||||
# Check for Wayland-specific environment variables
|
||||
elif [ -n "${WAYLAND_DISPLAY:-}" ]; then
|
||||
SESSION_TYPE="wayland"
|
||||
# Check if X server is running
|
||||
elif [ -n "${DISPLAY:-}" ] && command_exists xset && xset q &>/dev/null; then
|
||||
SESSION_TYPE="x11"
|
||||
# Check loginctl if available
|
||||
elif command_exists loginctl; then
|
||||
SESSION_TYPE=$(loginctl show-session $(loginctl | grep $(whoami) | awk '{print $1}') -p Type | cut -d= -f2 || true)
|
||||
fi
|
||||
|
||||
print_info "Detected session type: $SESSION_TYPE"
|
||||
if [[ "$SESSION_TYPE" == "wayland" ]] && is_kde_plasma_session; then
|
||||
print_kde_wayland_ibus_hint
|
||||
fi
|
||||
|
||||
# Install appropriate tools based on session type and distribution
|
||||
case "$SESSION_TYPE" in
|
||||
wayland)
|
||||
print_info "Installing Wayland text input tools..."
|
||||
case "$DISTRO_FAMILY" in
|
||||
ubuntu|debian)
|
||||
if ! apt_package_installed "$WTYPE_PKG"; then
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt install -y "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "wtype is already installed."
|
||||
fi
|
||||
;;
|
||||
fedora)
|
||||
if command_exists dnf && ! dnf_package_installed "$WTYPE_PKG"; then
|
||||
sudo dnf install -y "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
elif command_exists yum && ! rpm -q "$WTYPE_PKG" &>/dev/null; then
|
||||
sudo yum install -y "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "wtype is already installed."
|
||||
fi
|
||||
;;
|
||||
arch)
|
||||
if ! pacman_package_installed "$WTYPE_PKG"; then
|
||||
sudo pacman -S --noconfirm "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "wtype is already installed."
|
||||
fi
|
||||
;;
|
||||
suse)
|
||||
sudo zypper install -y "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
;;
|
||||
gentoo)
|
||||
if ! qlist -I "$WTYPE_PKG" >/dev/null 2>&1; then
|
||||
sudo emerge "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "wtype is already installed."
|
||||
fi
|
||||
;;
|
||||
alpine)
|
||||
if ! apk info -e "$WTYPE_PKG" >/dev/null 2>&1; then
|
||||
sudo apk add "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "wtype is already installed."
|
||||
fi
|
||||
;;
|
||||
void)
|
||||
if ! xbps-query "$WTYPE_PKG" >/dev/null 2>&1; then
|
||||
sudo xbps-install -Sy "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "wtype is already installed."
|
||||
fi
|
||||
;;
|
||||
solus)
|
||||
if ! eopkg list-installed | grep -qw "$WTYPE_PKG"; then
|
||||
sudo eopkg install "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "wtype is already installed."
|
||||
fi
|
||||
;;
|
||||
mageia)
|
||||
if command_exists dnf && ! rpm -q "$WTYPE_PKG" >/dev/null 2>&1; then
|
||||
sudo dnf install -y "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
elif command_exists urpmi && ! rpm -q "$WTYPE_PKG" >/dev/null 2>&1; then
|
||||
sudo urpmi -y "$WTYPE_PKG" || { print_warning "Failed to install wtype. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "wtype is already installed."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
print_warning "Unsupported distribution for Wayland text input tools."
|
||||
print_warning "Please install 'wtype' manually for Wayland text input support."
|
||||
;;
|
||||
esac
|
||||
|
||||
# Try to install ydotool as additional fallback for Wayland
|
||||
# ydotool works better with some compositors (like GNOME) where wtype may fail
|
||||
print_info "Attempting to install ydotool for better Wayland compatibility..."
|
||||
case "$DISTRO_FAMILY" in
|
||||
ubuntu|debian)
|
||||
if ! apt_package_installed "$YDOTOOL_PKG"; then
|
||||
if ! DEBIAN_FRONTEND=noninteractive sudo apt install -y "$YDOTOOL_PKG" 2>/dev/null; then
|
||||
if [[ "$DISTRO_FAMILY" == "debian" ]]; then
|
||||
print_warning "ydotool is not packaged in Debian's standard repos."
|
||||
print_info "For full Wayland input support, you can compile ydotool from source:"
|
||||
print_info " sudo apt install -y git cmake libevdev-dev"
|
||||
print_info " git clone https://github.com/ReimuNotMoe/ydotool.git /tmp/ydotool"
|
||||
print_info " cmake -S /tmp/ydotool -B /tmp/ydotool/build && sudo cmake --build /tmp/ydotool/build --target install"
|
||||
print_info " sudo systemctl enable --now ydotoold"
|
||||
print_info "Alternatively, wtype (already installed) will handle most Wayland compositors."
|
||||
else
|
||||
print_info "ydotool not available in repos (optional)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
fedora)
|
||||
if command_exists dnf; then
|
||||
sudo dnf install -y "$YDOTOOL_PKG" 2>/dev/null || print_info "ydotool not available in repos (optional)"
|
||||
fi
|
||||
;;
|
||||
arch)
|
||||
if ! pacman_package_installed "$YDOTOOL_PKG"; then
|
||||
sudo pacman -S --noconfirm "$YDOTOOL_PKG" 2>/dev/null || print_info "ydotool not available in repos (optional)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Add user to input group for ydotool/dotool support
|
||||
if ! groups | grep -q '\binput\b'; then
|
||||
print_info "Adding $USER to 'input' group for text injection..."
|
||||
sudo usermod -aG input "$USER" || print_warning "Failed to add user to input group"
|
||||
print_warning "You will need to LOG OUT and back in for text injection to work with ydotool/dotool"
|
||||
fi
|
||||
|
||||
# Install udev rule for ydotool/dotool — and for the evdev
|
||||
# backend's uinput clone, which opens /dev/uinput O_RDWR, so the
|
||||
# rule needs 0660 (0620 is write-only). Appending (not overwriting)
|
||||
# preserves any rules the user already keeps in this file; when an
|
||||
# older MODE=0620 line is present our later line still wins.
|
||||
UINPUT_UDEV_RULE='KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"'
|
||||
if ! grep -qxF "$UINPUT_UDEV_RULE" /etc/udev/rules.d/80-dotool.rules 2>/dev/null; then
|
||||
print_info "Installing udev rule for input device access..."
|
||||
printf '\n%s\n' "$UINPUT_UDEV_RULE" \
|
||||
| sudo tee -a /etc/udev/rules.d/80-dotool.rules >/dev/null 2>&1 || print_warning "Failed to install udev rule"
|
||||
sudo udevadm control --reload 2>/dev/null || true
|
||||
sudo udevadm trigger 2>/dev/null || true
|
||||
fi
|
||||
;;
|
||||
|
||||
x11|"")
|
||||
print_info "Installing X11 text input tools..."
|
||||
case "$DISTRO_FAMILY" in
|
||||
ubuntu|debian)
|
||||
if ! apt_package_installed "$XDOTOOL_PKG"; then
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt install -y "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "xdotool is already installed."
|
||||
fi
|
||||
;;
|
||||
fedora)
|
||||
if command_exists dnf && ! dnf_package_installed "$XDOTOOL_PKG"; then
|
||||
sudo dnf install -y "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
elif command_exists yum && ! rpm -q "$XDOTOOL_PKG" &>/dev/null; then
|
||||
sudo yum install -y "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "xdotool is already installed."
|
||||
fi
|
||||
;;
|
||||
arch)
|
||||
if ! pacman_package_installed "$XDOTOOL_PKG"; then
|
||||
sudo pacman -S --noconfirm "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "xdotool is already installed."
|
||||
fi
|
||||
;;
|
||||
suse)
|
||||
sudo zypper install -y "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
;;
|
||||
gentoo)
|
||||
if ! qlist -I "$XDOTOOL_PKG" >/dev/null 2>&1; then
|
||||
sudo emerge "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "xdotool is already installed."
|
||||
fi
|
||||
;;
|
||||
alpine)
|
||||
if ! apk info -e "$XDOTOOL_PKG" >/dev/null 2>&1; then
|
||||
sudo apk add "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "xdotool is already installed."
|
||||
fi
|
||||
;;
|
||||
void)
|
||||
if ! xbps-query "$XDOTOOL_PKG" >/dev/null 2>&1; then
|
||||
sudo xbps-install -Sy "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "xdotool is already installed."
|
||||
fi
|
||||
;;
|
||||
solus)
|
||||
if ! eopkg list-installed | grep -qw "$XDOTOOL_PKG"; then
|
||||
sudo eopkg install "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "xdotool is already installed."
|
||||
fi
|
||||
;;
|
||||
mageia)
|
||||
if command_exists dnf && ! rpm -q "$XDOTOOL_PKG" >/dev/null 2>&1; then
|
||||
sudo dnf install -y "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
elif command_exists urpmi && ! rpm -q "$XDOTOOL_PKG" >/dev/null 2>&1; then
|
||||
sudo urpmi -y "$XDOTOOL_PKG" || { print_warning "Failed to install xdotool. Text injection may not work properly."; }
|
||||
else
|
||||
print_info "xdotool is already installed."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
print_warning "Unsupported distribution for X11 text input tools."
|
||||
print_warning "Please install 'xdotool' manually for X11 text input support."
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
*)
|
||||
print_warning "Unknown session type: $SESSION_TYPE"
|
||||
print_warning "Installing both Wayland and X11 text input tools for compatibility..."
|
||||
|
||||
# Install both tools based on distribution
|
||||
case "$DISTRO_FAMILY" in
|
||||
ubuntu|debian)
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt install -y "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
;;
|
||||
fedora|mageia)
|
||||
if command_exists dnf; then
|
||||
sudo dnf install -y "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
elif command_exists yum; then
|
||||
sudo yum install -y "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
fi
|
||||
# Mageia also supports urpmi
|
||||
if [[ "$DISTRO_FAMILY" == "mageia" ]] && command_exists urpmi; then
|
||||
sudo urpmi -y "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
fi
|
||||
;;
|
||||
arch)
|
||||
sudo pacman -S --noconfirm "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
;;
|
||||
suse)
|
||||
sudo zypper install -y "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
;;
|
||||
gentoo)
|
||||
sudo emerge "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
;;
|
||||
alpine)
|
||||
sudo apk add "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
;;
|
||||
void)
|
||||
sudo xbps-install -Sy "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
;;
|
||||
solus)
|
||||
sudo eopkg install "$XDOTOOL_PKG" "$WTYPE_PKG" || { print_warning "Failed to install text input tools. Text injection may not work properly."; }
|
||||
;;
|
||||
*)
|
||||
print_warning "Unsupported distribution for text input tools."
|
||||
print_warning "Please install 'xdotool' and 'wtype' manually for text input support."
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
# Vocalinux justfile
|
||||
# Convenient commands for development
|
||||
# Run `just` to list all recipes. Python tooling runs through `uv run` against
|
||||
# .venv/ — run `just deps` after cloning (requires uv).
|
||||
#
|
||||
# Two environments, deliberately separate:
|
||||
# .venv/ dev tooling, built by uv from .python-version (3.13). `just deps`
|
||||
# builds PyGObject from the lock and needs libgirepository-2.0-dev
|
||||
# (Ubuntu 24.04+) or glib2-devel (Fedora 40+), plus cairo-gobject
|
||||
# headers on Fedora. Debian 12 cannot build 3.56; use `just install-dev`.
|
||||
# venv/ what `just install` creates, always from the system Python so the
|
||||
# distro PyGObject package is importable.
|
||||
# install.sh ignores an activated .venv and rebuilds
|
||||
# venv/ if another interpreter created it, so `just install` is safe to
|
||||
# run from any shell. Override with SYSTEM_PYTHON=/usr/bin/python3.12.
|
||||
|
||||
# Extras and groups installed by `just deps`. `uv sync` prunes whatever the flags
|
||||
# do not name — omitting `--group lint` really does uninstall the linters.
|
||||
# Recipes that run tools use `uv run --no-sync` so they do not undo `just deps-all`
|
||||
# (whisper/vosk/docs). They depend on `_tooling` for the same reason: with nothing
|
||||
# left to create .venv/, `uv run --no-sync` on a fresh clone leaves an empty one
|
||||
# behind and fails with `Failed to spawn: pytest`. CI lints with `--only-group lint`
|
||||
# instead: that skips the project, whose pyaudio/PyGObject need system headers a
|
||||
# lint runner has no reason to install.
|
||||
DEV_EXTRAS := "--extra dev --extra vad --group lint"
|
||||
|
||||
# List available recipes
|
||||
default:
|
||||
@just --list
|
||||
|
||||
# Fail before `uv sync` when the headers pyaudio, pycairo and PyGObject need are
|
||||
# absent. Without this, the first error is a C compiler traceback from inside a
|
||||
# dependency build, which reads as a uv problem rather than a distro package.
|
||||
# PyGObject/pycairo checks apply only on Linux, matching the dependency marker.
|
||||
# An existing .venv/ with the platform's native packages skips the header check.
|
||||
[no-exit-message]
|
||||
[private]
|
||||
_check_build_deps:
|
||||
@python3 scripts/check_build_deps.py
|
||||
|
||||
# Create .venv/ and keep it matching the lock. --inexact is what makes this safe
|
||||
# to run ahead of every recipe: a plain `uv sync` removes extraneous packages, so
|
||||
# it would uninstall whatever `just deps-all` installed — the very thing the
|
||||
# --no-sync flags below exist to prevent. `version` skips this; it reads one
|
||||
# string out of version.py and needs a bare interpreter, not a sync.
|
||||
[private]
|
||||
_tooling: _check_build_deps
|
||||
uv sync --inexact {{DEV_EXTRAS}}
|
||||
|
||||
# Install Vocalinux
|
||||
install:
|
||||
./install.sh
|
||||
|
||||
# Install in development mode
|
||||
install-dev:
|
||||
./install.sh --dev
|
||||
|
||||
# Install development dependencies into .venv/ (dev + vad extras)
|
||||
deps: _check_build_deps
|
||||
uv sync {{DEV_EXTRAS}}
|
||||
|
||||
# Install every optional extra — whisper/vosk engines and docs (CUDA torch, multi-GB)
|
||||
deps-all: _check_build_deps
|
||||
uv sync --all-extras --group lint
|
||||
|
||||
# Run test suite
|
||||
test: _tooling
|
||||
@echo "Running tests..."
|
||||
uv run --no-sync pytest -v
|
||||
|
||||
# Run tests with coverage
|
||||
test-cov: _tooling
|
||||
@echo "Running tests with coverage..."
|
||||
uv run --no-sync pytest --cov=src --cov-report=html --cov-report=term
|
||||
@echo "Coverage report generated in htmlcov/"
|
||||
|
||||
# Run linters (flake8, black, isort)
|
||||
lint: _tooling
|
||||
@echo "Running flake8..."
|
||||
uv run --no-sync flake8 src/ tests/ snap/local/ --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
@echo "Checking black formatting..."
|
||||
uv run --no-sync black --check --diff src/ tests/ snap/local/
|
||||
@echo "Checking isort..."
|
||||
uv run --no-sync isort --check-only --diff --profile black src/ tests/ snap/local/
|
||||
|
||||
# Auto-format code (black + isort)
|
||||
format: _tooling
|
||||
@echo "Formatting with black..."
|
||||
uv run --no-sync black src/ tests/ snap/local/
|
||||
@echo "Sorting imports with isort..."
|
||||
uv run --no-sync isort --profile black src/ tests/ snap/local/
|
||||
|
||||
# Run type checking (mypy)
|
||||
typecheck: _tooling
|
||||
@echo "Running mypy..."
|
||||
uv run --locked --no-sync --only-group lint mypy src/
|
||||
|
||||
# Build distribution packages
|
||||
build:
|
||||
@echo "Building distribution packages..."
|
||||
uv build
|
||||
@echo "Built packages in dist/"
|
||||
|
||||
# Building on the host instead ships the host's glibc and GTK, which is how the
|
||||
# published AppImage ended up unable to start on Debian 12 or Ubuntu 22.04.
|
||||
#
|
||||
# Build the AppImage as CI does, in the pinned base image (needs docker)
|
||||
appimage: build
|
||||
bash packaging/appimage/docker-build.sh dist/*.whl "$(grep -oP '__version__\s*=\s*"\K[^"]+' src/vocalinux/version.py)" dist
|
||||
|
||||
# Start the built AppImage in a distro container, as the CI matrix does. Pick a
|
||||
# distro older than the build image to test the glibc floor, or newer to test
|
||||
# that the bundle does not break the host binaries it spawns.
|
||||
#
|
||||
# Boot the built AppImage on a distro, e.g. `just appimage-boot fedora:42`
|
||||
appimage-boot distro="debian:12":
|
||||
docker run --rm -v "$PWD/dist:/dist:ro" -v "$PWD/packaging/appimage:/pk:ro" {{distro}} bash /pk/boot-test.sh "/dist/$(basename "$(ls dist/*.AppImage)")"
|
||||
|
||||
# Build the .deb and .rpm in the pinned container, as release.yml does (needs
|
||||
# docker). Thin packages: the distro supplies Python, GTK and the typelibs;
|
||||
# only pywhispercpp and pynput are vendored.
|
||||
native-packages: build
|
||||
bash packaging/native/docker-build.sh dist/*.whl "$(grep -oP '__version__\s*=\s*"\K[^"]+' src/vocalinux/version.py)" dist
|
||||
|
||||
# Install the built package in a matching distro container, as the CI matrix
|
||||
# does: debian:12 / ubuntu:24.04 exercise the .deb, fedora:42 the .rpm.
|
||||
native-smoke distro="debian:12":
|
||||
docker run --rm -v "$PWD/dist:/out:ro" -v "$PWD/packaging/native:/pk:ro" {{distro}} bash /pk/smoke-test.sh
|
||||
|
||||
# Build the canonical sdist, prepare an explicitly unattested local PKGBUILD,
|
||||
# then build/install it unchanged on current Arch (needs uv and docker).
|
||||
# Keep distributions and diagnostics away from other packaging commands' outputs.
|
||||
aur-gate:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
WORK="$(mktemp -d)"
|
||||
cleanup() {
|
||||
local status=$?
|
||||
if [ "$status" -eq 0 ]; then
|
||||
rm -rf "$WORK"
|
||||
else
|
||||
echo "AUR gate failed; diagnostics retained in $WORK" >&2
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
python3 scripts/build_reproducible_wheel.py --python "${PYTHON:-python3}" \
|
||||
--output "$WORK/dist" --diagnostics "$WORK/diagnostics"
|
||||
uv venv --no-config --python "${PYTHON:-python3}" "$WORK/venv"
|
||||
uv pip install --no-config --python "$WORK/venv/bin/python" \
|
||||
--require-hashes --no-deps --only-binary=:all: -r requirements/release-build.txt
|
||||
"$WORK/venv/bin/python" scripts/prepare_aur_source.py \
|
||||
--local-unattested --sdist "$WORK"/dist/vocalinux-*.tar.gz --output "$WORK/source"
|
||||
docker run --rm -v "$PWD:/repo:ro" -v "$WORK/source:/aur-source:ro" \
|
||||
-e AUR_SOURCE=/aur-source archlinux:latest bash /repo/packaging/aur/build-test.sh
|
||||
|
||||
# Run install.sh unattended in a distro container, as the CI gate does. Answers
|
||||
# "does this commit install" (needs docker).
|
||||
#
|
||||
# The tree is taken via git archive of HEAD and extracted inside the container,
|
||||
# so the venv local mode creates lands in the container's copy rather than in
|
||||
# your working tree. Mount the common gitdir as well for linked worktrees.
|
||||
#
|
||||
# Usage: `just install-gate` for debian:12, or `just install-gate fedora:42`
|
||||
install-gate distro="debian:12":
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
COMMON="$(cd "$(git rev-parse --git-common-dir)" && pwd)"
|
||||
ARGS=(--rm -v "$PWD:$PWD:ro" -e REPO="$PWD")
|
||||
if [ "$COMMON" != "$PWD/.git" ]; then
|
||||
ARGS+=(-v "$COMMON:$COMMON:ro")
|
||||
fi
|
||||
docker run "${ARGS[@]}" {{distro}} bash "$PWD/scripts/install-test.sh"
|
||||
|
||||
# Run install.sh's remote path end to end in a distro container, as the CI gate
|
||||
# does: bootstrap outside a checkout, tag selection, clone/fetch of a mirror
|
||||
# published from HEAD, handoff to the tagged installer. Answers "does the
|
||||
# public curl|bash path install this commit" (needs docker). Same worktree
|
||||
# handling as install-gate above.
|
||||
#
|
||||
# Usage: `just remote-install-gate` for debian:12, or `just remote-install-gate fedora:42`
|
||||
remote-install-gate distro="debian:12":
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
COMMON="$(cd "$(git rev-parse --git-common-dir)" && pwd)"
|
||||
ARGS=(--rm -v "$PWD:$PWD:ro" -e REPO="$PWD")
|
||||
if [ "$COMMON" != "$PWD/.git" ]; then
|
||||
ARGS+=(-v "$COMMON:$COMMON:ro")
|
||||
fi
|
||||
docker run "${ARGS[@]}" {{distro}} bash "$PWD/scripts/install-remote-test.sh"
|
||||
|
||||
# Check that a published release verifies as published: manifest, provenance,
|
||||
# notes and PyPI digests. Needs gh, downloads nothing.
|
||||
# Usage: `just verify-release` for the latest, or `just verify-release v0.17.0`
|
||||
verify-release tag="":
|
||||
python3 scripts/verify_release.py {{tag}}
|
||||
|
||||
# Build in two clean environments, compare wheels, then stage canonical dist/.
|
||||
# PYTHON selects the build interpreter (CI uses the supported floor, 3.11).
|
||||
reproducible-wheel:
|
||||
python3 scripts/build_reproducible_wheel.py --python "${PYTHON:-python3}"
|
||||
|
||||
# Regenerate uv.lock and the hash-pinned requirements/* exports.
|
||||
# Bump the torch +cpu pin in requirements/whisper.in when you want a newer
|
||||
# CPU build. OpenAI Whisper does not use torchaudio, whose CPU index can lag.
|
||||
lock:
|
||||
uv lock
|
||||
uv export --only-group release-build --no-emit-project -o requirements/release-build.txt
|
||||
uv export --only-group installer-build --no-emit-project -o requirements/installer-build.txt
|
||||
uv export --no-dev --no-emit-project --no-emit-package pygobject -o requirements/runtime.txt
|
||||
uv export --no-dev --extra vad --no-emit-project --no-emit-package pygobject -o requirements/vad.txt
|
||||
# One export per selectable engine. install.sh installs each of these as an
|
||||
# extra, so an extra without an export is an install path with nothing
|
||||
# pinned: that is how parakeet, faster-whisper and vosk reached users.
|
||||
# tests/test_dependency_exports.py enumerates the extras and fails when one
|
||||
# has no export, rather than trusting this list to stay complete.
|
||||
uv export --no-dev --extra vosk --no-emit-project --no-emit-package pygobject -o requirements/vosk.txt
|
||||
uv export --no-dev --extra parakeet --no-emit-project --no-emit-package pygobject -o requirements/parakeet.txt
|
||||
uv export --no-dev --extra faster-whisper --no-emit-project --no-emit-package pygobject -o requirements/faster-whisper.txt
|
||||
# --group lint too: the linters live in a dependency group, not in the dev
|
||||
# extra, so exporting the extra alone produced a file that reproduced
|
||||
# neither `just deps` nor what CI lints with.
|
||||
uv export --extra dev --group lint --no-emit-project --no-emit-package pygobject -o requirements/dev.txt
|
||||
uv pip compile requirements/whisper.in --generate-hashes --emit-index-url \
|
||||
--index-url https://pypi.org/simple \
|
||||
--extra-index-url https://download.pytorch.org/whl/cpu \
|
||||
--index-strategy unsafe-best-match --universal --python-version 3.11 \
|
||||
-c requirements/runtime.txt -c requirements/installer-build.txt -o requirements/whisper.txt
|
||||
# Compiled rather than exported: what the AppImage bundles on top of the
|
||||
# lock, and what builds it, are pinned away from uv.lock on purpose --
|
||||
# see requirements/appimage.in. --universal so one file covers both arches.
|
||||
uv pip compile requirements/appimage.in --universal --no-deps --generate-hashes \
|
||||
-o requirements/appimage.txt
|
||||
uv pip compile requirements/appimage-tools.in --universal --no-deps --generate-hashes \
|
||||
-o requirements/appimage-tools.txt
|
||||
# The Flatpak is a fourth copy of the dependency set, and it drifted ten
|
||||
# packages behind before anything compared it to source. Regenerate it here
|
||||
# so a lock refresh cannot leave it behind again.
|
||||
just flatpak-deps
|
||||
|
||||
# Fail if uv.lock is stale relative to pyproject.toml
|
||||
lock-check:
|
||||
uv lock --check
|
||||
|
||||
# Fail if any requirements/* export is behind uv.lock. Reads the `uv export`
|
||||
# lines out of `lock` above and re-runs them, rather than keeping a second copy
|
||||
# of that list. Offline: `uv export` reads the lock, so this needs no network.
|
||||
export-check:
|
||||
python3 scripts/check_exports.py
|
||||
|
||||
# Regenerate the shell package inventory consumed by install.sh. The committed
|
||||
# output keeps the runtime installer independent of a YAML parser.
|
||||
distro-packages: _tooling
|
||||
uv run --no-sync python scripts/generate_distro_package_map.py
|
||||
|
||||
# Fail if install.d/package_map.sh is behind its YAML source.
|
||||
distro-packages-check: _tooling
|
||||
uv run --no-sync python scripts/generate_distro_package_map.py --check
|
||||
|
||||
# The export pins names, versions and digests; this looks up the URL that serves
|
||||
# those bytes, so it needs PyPI. tests/test_flatpak_packaging.py checks the same
|
||||
# invariant offline, which is what CI gates on.
|
||||
# Point the Flatpak's dependency manifest at what uv.lock resolved.
|
||||
flatpak-deps: _tooling
|
||||
uv run --no-sync python scripts/sync_flatpak_deps.py
|
||||
|
||||
# Fail if the Flatpak manifest is behind requirements/vad.txt (runtime + [vad]).
|
||||
flatpak-deps-check: _tooling
|
||||
uv run --no-sync python scripts/sync_flatpak_deps.py --check
|
||||
|
||||
# Refresh the pinned model digests. whisper.cpp digests come from Hugging Face
|
||||
# `lfs` metadata and cost no bandwidth; VOSK is pinned by the bytes we fetch, so
|
||||
# every zip not already in the manifest is downloaded. A first run, or any run
|
||||
# with --refresh, pulls ~21.9GB and takes ~30 minutes.
|
||||
# Run after adding a model to vosk_model_info.py, whispercpp_model_info.py,
|
||||
# parakeet_model_info.py or faster_whisper_model_info.py.
|
||||
model-checksums: _tooling
|
||||
uv run --no-sync python scripts/generate-model-checksums.py
|
||||
|
||||
# Remove build artifacts
|
||||
clean:
|
||||
@echo "Cleaning build artifacts..."
|
||||
rm -rf build/
|
||||
rm -rf dist/
|
||||
rm -rf *.egg-info
|
||||
rm -rf src/*.egg-info
|
||||
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
||||
find . -type f -name "*.pyc" -delete
|
||||
find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true
|
||||
find . -type d -name ".mypy_cache" -exec rm -rf {} + 2>/dev/null || true
|
||||
rm -rf htmlcov/
|
||||
rm -f .coverage
|
||||
rm -f coverage.xml
|
||||
@echo "Clean complete"
|
||||
|
||||
# Run the installed application
|
||||
run:
|
||||
vocalinux
|
||||
|
||||
# Run the installed application with debug logging
|
||||
run-debug:
|
||||
vocalinux --debug
|
||||
|
||||
# Run from source
|
||||
run-source: _tooling
|
||||
uv run --no-sync python -m vocalinux.main
|
||||
|
||||
# Run from source with debug logging
|
||||
run-source-debug: _tooling
|
||||
uv run --no-sync python -m vocalinux.main --debug
|
||||
|
||||
# Run pre-commit hooks on all files
|
||||
pre-commit: _tooling
|
||||
uv run --no-sync pre-commit run --all-files
|
||||
|
||||
# Print the current version
|
||||
version:
|
||||
@uv run --no-sync python -c "from src.vocalinux.version import __version__; print(__version__)"
|
||||
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env bash
|
||||
# Start the finished AppImage in a distro container and check it comes up.
|
||||
#
|
||||
# Usage: boot-test.sh <path-to-appimage>
|
||||
#
|
||||
# The build host cannot catch what this catches: its libraries match what it
|
||||
# bundled. Both #743 regressions reached a user for that reason — one when the
|
||||
# bundle loaded a GI library the host also had (libibus), one when the app
|
||||
# handed its own library path to a host binary (ibus). Old distros prove the
|
||||
# glibc floor; new ones prove the bundle does not poison what it shells out to.
|
||||
set -euo pipefail
|
||||
|
||||
APPIMAGE="$(readlink -f "${1:?usage: boot-test.sh <path-to-appimage>}")"
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
|
||||
WORKDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORKDIR"' EXIT
|
||||
export XDG_CONFIG_HOME="$WORKDIR/config" XDG_DATA_HOME="$WORKDIR/data" \
|
||||
XDG_CACHE_HOME="$WORKDIR/cache" HOME="$WORKDIR"
|
||||
mkdir -p "$XDG_CONFIG_HOME" "$XDG_DATA_HOME" "$XDG_CACHE_HOME"
|
||||
|
||||
. /etc/os-release
|
||||
DISTRO="$PRETTY_NAME"
|
||||
echo "== $DISTRO (glibc $(ldd --version | head -1 | grep -oE '[0-9]+\.[0-9]+$')) =="
|
||||
|
||||
# Xvfb and a session bus for the tray, a GLib CLI to prove host binaries still
|
||||
# run, the distro's GTK 3 runtime, and xdotool. The last two are not the AppImage
|
||||
# failing
|
||||
# to be self-contained: the AppImage excludelist deliberately leaves libX11,
|
||||
# libharfbuzz and friends to the host, because bundling them breaks more than it
|
||||
# fixes, and xdotool is a documented host prerequisite for every install path
|
||||
# except the Flatpak. Any desktop has them; a bare container does not.
|
||||
echo "== Installing test prerequisites =="
|
||||
case "${ID}${ID_LIKE:+ $ID_LIKE}" in
|
||||
*debian*|ubuntu*)
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq --no-install-recommends \
|
||||
xvfb xauth dbus-x11 libglib2.0-bin ca-certificates libgtk-3-0 xdotool >/dev/null
|
||||
;;
|
||||
*fedora*|*rhel*)
|
||||
dnf install -y -q xorg-x11-server-Xvfb xorg-x11-xauth dbus-x11 glib2 gtk3 xdotool >/dev/null
|
||||
;;
|
||||
*arch*)
|
||||
pacman -Sy --noconfirm --quiet xorg-server-xvfb xorg-xauth dbus glib2 gtk3 xdotool >/dev/null
|
||||
;;
|
||||
*suse*)
|
||||
# openSUSE splits these differently: xvfb-run ships on its own, the session
|
||||
# bus is in dbus-1-daemon, and the GTK 3 runtime is libgtk-3-0.
|
||||
zypper -n -q in xorg-x11-server-Xvfb xvfb-run xauth dbus-1-daemon \
|
||||
glib2-tools libgtk-3-0 xdotool >/dev/null
|
||||
;;
|
||||
*)
|
||||
echo "No package recipe for '$ID'; add one to boot-test.sh" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "== It runs at all =="
|
||||
"$APPIMAGE" --version || fail "the AppImage does not start on $DISTRO"
|
||||
|
||||
# Unpack once so the checks below can use the bundle's own interpreter.
|
||||
cd "$WORKDIR"
|
||||
"$APPIMAGE" --appimage-extract >/dev/null
|
||||
BUNDLE="$WORKDIR/squashfs-root"
|
||||
bundle_python() {
|
||||
APPDIR="$BUNDLE" \
|
||||
PYTHONHOME="$BUNDLE/usr" \
|
||||
PYTHONPATH="$BUNDLE/usr/lib/python3:$BUNDLE/usr/lib/python3/site-packages" \
|
||||
GI_TYPELIB_PATH="$BUNDLE/usr/lib/girepository-1.0" \
|
||||
LD_LIBRARY_PATH="$BUNDLE/usr/lib" \
|
||||
"$BUNDLE/usr/bin/python3" "$@"
|
||||
}
|
||||
|
||||
echo "== Its GI stack is the bundled one =="
|
||||
# A typelib whose library is missing loads the host's copy against the bundle's
|
||||
# older GLib. That is how libibus turned IBus.Engine into a 'void' GType.
|
||||
bundle_python - <<'PY' || fail "the bundled GI stack does not load"
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version("IBus", "1.0")
|
||||
from gi.repository import Gtk, IBus # noqa: F401
|
||||
|
||||
if IBus.Engine.__gtype__.name in ("void", "invalid"):
|
||||
raise SystemExit("IBus typelib loaded but its library did not")
|
||||
|
||||
from vocalinux.text_injection import text_injector # noqa: F401
|
||||
from vocalinux import gateway_embed # noqa: F401
|
||||
|
||||
print(" Gtk 3.0, IBus, text_injection and gateway_embed all import")
|
||||
PY
|
||||
|
||||
echo "== Host binaries still run when the app spawns them =="
|
||||
# The bundle's LD_LIBRARY_PATH reaches every child process, so a host tool built
|
||||
# against a newer GLib dies before it does anything: `ibus` exited with
|
||||
# `undefined symbol: g_free_sized` and dictated text reached no window.
|
||||
bundle_python - <<'PY' || fail "a host binary cannot run from inside the bundle"
|
||||
import subprocess
|
||||
|
||||
from vocalinux.utils.host_process import host_env
|
||||
|
||||
PROBE = ["gsettings", "--version"]
|
||||
inherited = subprocess.run(PROBE, capture_output=True, text=True)
|
||||
sanitized = subprocess.run(PROBE, capture_output=True, text=True, env=host_env())
|
||||
if sanitized.returncode != 0:
|
||||
raise SystemExit(f"gsettings failed with a sanitized environment: {sanitized.stderr.strip()}")
|
||||
if inherited.returncode != 0:
|
||||
print(" host GLib is newer than the bundle's; host_env() is what keeps it working")
|
||||
print(f" gsettings {sanitized.stdout.strip()} runs")
|
||||
PY
|
||||
|
||||
echo "== It reaches the tray =="
|
||||
LOG="$WORKDIR/boot.log"
|
||||
set +e
|
||||
timeout -s TERM 40 xvfb-run -a dbus-run-session -- \
|
||||
"$APPIMAGE" --debug --start-minimized >"$LOG" 2>&1
|
||||
status=$?
|
||||
set -e
|
||||
# 124 is the timeout we asked for: the app is a tray application, so staying up
|
||||
# until killed is the pass condition, not an early exit.
|
||||
if [ "$status" -ne 124 ] && [ "$status" -ne 0 ] && [ "$status" -ne 143 ]; then
|
||||
echo "--- last 30 lines ---" >&2
|
||||
tail -n 30 "$LOG" >&2
|
||||
fail "the app exited with $status instead of running"
|
||||
fi
|
||||
|
||||
grep -q "Initializing Vocalinux" "$LOG" || {
|
||||
tail -n 30 "$LOG" >&2
|
||||
fail "startup never reached component initialisation"
|
||||
}
|
||||
grep -q "Initializing system tray indicator" "$LOG" || {
|
||||
tail -n 30 "$LOG" >&2
|
||||
fail "startup never reached the tray indicator"
|
||||
}
|
||||
if grep -q "Failed to create AppIndicator" "$LOG"; then
|
||||
tail -n 30 "$LOG" >&2
|
||||
fail "the tray indicator could not be created"
|
||||
fi
|
||||
# A traceback before the tray is a failed startup. One after it is the noise
|
||||
# pynput's X listener makes when we TERM the app under Xvfb, so it is reported
|
||||
# rather than fatal — the process staying up to the timeout is the real signal.
|
||||
startup="$WORKDIR/startup.log"
|
||||
sed -n '1,/Initializing system tray indicator/p' "$LOG" > "$startup"
|
||||
if grep -q "^Traceback" "$startup"; then
|
||||
grep -A 15 "^Traceback" "$startup" | head -n 20 >&2
|
||||
fail "startup raised an exception"
|
||||
fi
|
||||
if grep -q "^Traceback" "$LOG"; then
|
||||
echo " note: traceback on the shutdown path, after the tray came up" >&2
|
||||
fi
|
||||
|
||||
echo "PASS: $DISTRO"
|
||||
@@ -0,0 +1,802 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build a relocatable AppImage for Vocalinux, natively for whichever
|
||||
# architecture this script runs on (x86_64 or aarch64) - no cross-compiling.
|
||||
#
|
||||
# Usage: build.sh <path-to-wheel> <version> [output-dir]
|
||||
#
|
||||
# Bundles a managed CPython (python-build-standalone, fetched by uv, relocated
|
||||
# via PYTHONHOME rather than a venv since venvs hard-code absolute paths) plus
|
||||
# PyGObject/GTK3/AppIndicator/IBus GObject-Introspection typelibs, since
|
||||
# those are needed by `gi.repository` at runtime and linuxdeploy-plugin-gtk
|
||||
# does not bundle them (it targets native C GTK apps, which don't need
|
||||
# introspection data).
|
||||
#
|
||||
# Downloads are pinned in packaging/appimage/tool_checksums.txt; packages come
|
||||
# from the hash-pinned requirements/*.txt exports.
|
||||
#
|
||||
# Run it inside the base image those pins name (container-build.sh does), or the
|
||||
# AppImage inherits this host's glibc and GTK: built on Ubuntu 24.04 it starts on
|
||||
# neither Debian 12, Ubuntu 22.04 nor RHEL 9.
|
||||
#
|
||||
# ponytail: text-injection CLI tools (xdotool/wtype/ydotool) are not
|
||||
# bundled, same runtime prerequisite as the PyPI install path documented
|
||||
# in docs/INSTALL.md. Add bundling if users hit missing-binary complaints.
|
||||
#
|
||||
# GPU: pip wheels of pywhispercpp are CPU-only. This script rebuilds
|
||||
# pywhispercpp from source with GGML_VULKAN=1 when Vulkan headers and a
|
||||
# shader compiler are on the build host. The AppImage uses the host Vulkan
|
||||
# loader/ICDs at runtime (do not bundle NVIDIA/AMD driver ICDs).
|
||||
# Set VOCALINUX_APPIMAGE_REQUIRE_VULKAN=1 in CI so a failed rebuild fails
|
||||
# the job instead of shipping a CPU-only image. Set
|
||||
# VOCALINUX_APPIMAGE_SKIP_VULKAN=1 to force the CPU wheel.
|
||||
# A build that produced libggml-vulkan.so is kept in VOCALINUX_APPIMAGE_CACHE
|
||||
# and reused while the base image, tool_checksums.txt, and the pywhispercpp
|
||||
# pin are unchanged. A CPU-only build is not cached.
|
||||
set -euo pipefail
|
||||
|
||||
WHEEL="$1"
|
||||
VERSION="$2"
|
||||
OUTDIR="${3:-dist}"
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
# shellcheck source=native-cache.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/native-cache.sh"
|
||||
|
||||
# Same pywhispercpp release install.sh pins. Read from there rather than repeated
|
||||
# here: unpinned, this build picks up whatever PyPI published today, which is how
|
||||
# a 1.5.1 released mid-PR broke the Vulkan rebuild.
|
||||
PYWHISPERCPP_VERSION="$(sed -n 's/^PYWHISPERCPP_VERSION="\([^"]*\)"/\1/p' "$REPO_ROOT/install.sh" | head -n1)"
|
||||
if [ -z "$PYWHISPERCPP_VERSION" ]; then
|
||||
echo "Could not read PYWHISPERCPP_VERSION from install.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
# The bundle and the Vulkan rebuild install the same pinned sdist. Two pins that
|
||||
# disagree would ship one whisper build and link against another.
|
||||
LOCKED_PYWHISPERCPP="$(awk -F'==' '/^pywhispercpp==/ {print $2; exit}' \
|
||||
"$REPO_ROOT/requirements/vad.txt" | tr -d ' \\')"
|
||||
if [ "$LOCKED_PYWHISPERCPP" != "$PYWHISPERCPP_VERSION" ]; then
|
||||
echo "pywhispercpp is pinned twice and the pins disagree:" >&2
|
||||
echo " install.sh: $PYWHISPERCPP_VERSION" >&2
|
||||
echo " requirements/vad.txt: $LOCKED_PYWHISPERCPP" >&2
|
||||
echo "Change pyproject.toml and run 'just lock', or fix install.sh." >&2
|
||||
exit 1
|
||||
fi
|
||||
ARCH="$(uname -m)"
|
||||
|
||||
case "$ARCH" in
|
||||
x86_64|aarch64) ;;
|
||||
*) echo "Unsupported architecture: $ARCH (need x86_64 or aarch64)" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
# Every download below is looked up here first, so a moved upstream asset fails
|
||||
# the build instead of quietly changing what ships.
|
||||
PINS="$REPO_ROOT/packaging/appimage/tool_checksums.txt"
|
||||
|
||||
pin_field() {
|
||||
local name="$1" field="$2" value
|
||||
value="$(awk -v k="$name" -v f="$field" '$1==k {print $f; exit}' "$PINS")"
|
||||
if [ -z "$value" ]; then
|
||||
echo "No pin named '$name' in $PINS" >&2
|
||||
exit 1
|
||||
fi
|
||||
printf '%s\n' "$value"
|
||||
}
|
||||
|
||||
# Default --retry skips TLS RST (curl 35). GitHub release assets flake that way.
|
||||
curl_retry() {
|
||||
curl --retry 5 --retry-all-errors --retry-delay 2 --fail --silent --show-error --location "$@"
|
||||
}
|
||||
|
||||
# Download the pin named $1 to $2, and refuse to go on unless it hashes right.
|
||||
fetch_pinned() {
|
||||
local name="$1" dest="$2" url expected actual
|
||||
url="$(pin_field "$name" 4)"
|
||||
expected="$(pin_field "$name" 3)"
|
||||
curl_retry -o "$dest" "$url"
|
||||
actual="$(sha256sum "$dest" | cut -d' ' -f1)"
|
||||
if [ "$actual" != "$expected" ]; then
|
||||
echo "Checksum mismatch for $name" >&2
|
||||
echo " url: $url" >&2
|
||||
echo " expected: $expected" >&2
|
||||
echo " actual: $actual" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Checkout of a pinned git tree, shared by the two things that need one.
|
||||
checkout_pinned() {
|
||||
local name="$1" dest="$2" commit
|
||||
commit="$(pin_field "$name" 3)"
|
||||
mkdir -p "$dest"
|
||||
git -C "$dest" init -q
|
||||
git -C "$dest" remote add origin "$(pin_field "$name" 4)"
|
||||
git -C "$dest" fetch -q --depth 1 origin "$commit"
|
||||
git -C "$dest" checkout -q FETCH_HEAD
|
||||
}
|
||||
|
||||
# Seed typelibs Vocalinux imports directly, plus transitive GIR deps that Gtk
|
||||
# and AppIndicator require (xlib, Dbusmenu, …). Without those, GI falls back to
|
||||
# the builder's baked-in path (/usr/lib/x86_64-linux-gnu/girepository-1.0), which
|
||||
# does not exist on Fedora/openSUSE/Arch — startup then reports "missing GTK3".
|
||||
TYPELIBS=(
|
||||
Gtk-3.0 Gdk-3.0 GdkX11-3.0 GdkPixbuf-2.0 GLib-2.0 GObject-2.0 Gio-2.0
|
||||
GModule-2.0 Pango-1.0 PangoCairo-1.0 cairo-1.0 HarfBuzz-0.0 Atk-1.0
|
||||
freetype2-2.0 fontconfig-2.0 xlib-2.0
|
||||
AyatanaAppIndicator3-0.1 AyatanaAppindicator3-0.1 AppIndicator3-0.1
|
||||
Dbusmenu-0.4 Notify-0.7 IBus-1.0 Rsvg-2.0 GtkLayerShell-0.1
|
||||
)
|
||||
|
||||
# Runtime only needs one tray stack (same order as tray_indicator.py). Prefer
|
||||
# Ayatana; accept the rare lowercase typelib; legacy AppIndicator3 last.
|
||||
INDICATOR_TYPELIBS=(
|
||||
AyatanaAppIndicator3-0.1 AyatanaAppindicator3-0.1 AppIndicator3-0.1
|
||||
)
|
||||
|
||||
# Soft dependencies the app itself falls back from: dictation_overlay.py uses a
|
||||
# plain GTK window when layer shell is absent, so these are copied when found
|
||||
# but must never block a direct build on a host without them.
|
||||
OPTIONAL_TYPELIBS=(
|
||||
GtkLayerShell-0.1
|
||||
)
|
||||
|
||||
# Shared libs loaded via GI at runtime (not linked into python3), so
|
||||
# linuxdeploy will not discover them from -e python3 alone.
|
||||
# verify_typelib_libraries below fails the build when one is missing.
|
||||
GI_RUNTIME_LIBS=(
|
||||
libappindicator3.so.1
|
||||
libayatana-appindicator3.so.1
|
||||
libdbusmenu-glib.so.4
|
||||
libdbusmenu-gtk3.so.4
|
||||
libnotify.so.4
|
||||
libibus-1.0.so.5
|
||||
libgtk-layer-shell.so.0
|
||||
# Nothing imports PangoXft, but linuxdeploy keeps its typelib, and a typelib
|
||||
# without its library is the trap that cost us IBus. 30 KB is cheaper than an
|
||||
# exception to the rule.
|
||||
libpangoxft-1.0.so.0
|
||||
)
|
||||
|
||||
# Named by a bundled typelib but on the AppImage excludelist, so the host's copy
|
||||
# is the right one. Anything else missing is a bug, not a policy.
|
||||
HOST_PROVIDED_LIBS=(
|
||||
libharfbuzz.so.0
|
||||
libharfbuzz-gobject.so.0
|
||||
# Layer shell is optional end to end (see OPTIONAL_TYPELIBS): when its
|
||||
# library cannot be bundled, the host's copy is the right one — the app
|
||||
# falls back to a plain GTK window when no host copy exists either.
|
||||
libgtk-layer-shell.so.0
|
||||
)
|
||||
|
||||
# On the excludelist, but something we bundle links them, so the host cannot be
|
||||
# asked for them: libgcrypt is bundled and needs libgpg-error, and a host
|
||||
# without it — a Fedora container, any minimal system — cannot load our GTK at
|
||||
# all ("Failed to load shared library 'libgtk-3.so.0'").
|
||||
BUNDLED_DEPENDENCY_LIBS=(
|
||||
libgpg-error.so.0
|
||||
)
|
||||
|
||||
WORKDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORKDIR"' EXIT
|
||||
APPDIR="$WORKDIR/AppDir"
|
||||
TOOLDIR="$WORKDIR/tools"
|
||||
mkdir -p "$APPDIR/usr/bin" "$APPDIR/usr/lib" "$TOOLDIR" "$OUTDIR"
|
||||
|
||||
# Nested AppImages need extract-and-run on hosts without usable FUSE.
|
||||
export APPIMAGE_EXTRACT_AND_RUN="${APPIMAGE_EXTRACT_AND_RUN:-1}"
|
||||
|
||||
# Warn rather than refuse: the script still has to run by hand when debugging.
|
||||
expected_base="$(pin_field base-image 4)"
|
||||
actual_base="$(. /etc/os-release 2>/dev/null && echo "$ID:$VERSION_ID")"
|
||||
if [ "$actual_base" != "$expected_base" ]; then
|
||||
echo "Warning: building on ${actual_base:-an unknown host}, not the pinned $expected_base." >&2
|
||||
echo " This AppImage will inherit this host's glibc and GTK. Use docker-build.sh." >&2
|
||||
fi
|
||||
|
||||
echo "== Fetching pinned AppImage tooling ($ARCH) =="
|
||||
fetch_pinned "linuxdeploy-$ARCH" "$TOOLDIR/linuxdeploy"
|
||||
fetch_pinned "linuxdeploy-plugin-gtk" "$TOOLDIR/linuxdeploy-plugin-gtk.sh"
|
||||
fetch_pinned "appimagetool-$ARCH" "$TOOLDIR/appimagetool"
|
||||
chmod +x "$TOOLDIR/linuxdeploy" "$TOOLDIR/linuxdeploy-plugin-gtk.sh" "$TOOLDIR/appimagetool"
|
||||
|
||||
echo "== Fetching pinned uv =="
|
||||
# Only if it is the pinned version: uv picks the interpreter build and resolves
|
||||
# the wheels, so a different uv is a different AppImage.
|
||||
UV_VERSION="$(pin_field "uv-$ARCH" 4 | sed 's|.*/download/\([^/]*\)/.*|\1|')"
|
||||
if command -v uv >/dev/null 2>&1 && [ "$(uv --version | awk '{print $2}')" = "$UV_VERSION" ]; then
|
||||
UV="$(command -v uv)"
|
||||
else
|
||||
fetch_pinned "uv-$ARCH" "$TOOLDIR/uv.tar.gz"
|
||||
tar xzf "$TOOLDIR/uv.tar.gz" -C "$TOOLDIR"
|
||||
UV="$TOOLDIR/uv-${ARCH}-unknown-linux-gnu/uv"
|
||||
fi
|
||||
echo " uv $UV_VERSION ($UV)"
|
||||
|
||||
echo "== Bundling managed CPython =="
|
||||
# python-build-standalone, not the host's interpreter: deterministic, and it
|
||||
# needs glibc 2.17, so the base image alone decides the floor.
|
||||
CPYTHON_VERSION="$(pin_field cpython 3)"
|
||||
export UV_PYTHON_INSTALL_DIR="$WORKDIR/pyroot"
|
||||
"$UV" python install "$CPYTHON_VERSION"
|
||||
PY_BIN="$("$UV" python find "$CPYTHON_VERSION")"
|
||||
PY_PREFIX="$(cd "$(dirname "$PY_BIN")/.." && pwd)"
|
||||
PY_VER="${CPYTHON_VERSION%.*}"
|
||||
echo " CPython $CPYTHON_VERSION from $PY_PREFIX"
|
||||
cp -a "$PY_PREFIX/bin" "$PY_PREFIX/lib" "$APPDIR/usr/"
|
||||
# Drop what nothing imports. tkinter goes with its extension module and the
|
||||
# Tcl/Tk runtime: a stray _tkinter.so stops linuxdeploy dead on libtcl9.0.so.
|
||||
rm -rf "$APPDIR/usr/lib/python${PY_VER}/test" \
|
||||
"$APPDIR/usr/lib/python${PY_VER}/idlelib" \
|
||||
"$APPDIR/usr/lib/python${PY_VER}/tkinter" \
|
||||
"$APPDIR/usr/lib/python${PY_VER}/lib2to3" \
|
||||
"$APPDIR/usr/lib/python${PY_VER}/lib-dynload/_tkinter"*.so \
|
||||
"$APPDIR/usr/lib/python${PY_VER}/config-${PY_VER}"*
|
||||
rm -rf "$APPDIR/usr/lib"/libtcl*.so "$APPDIR/usr/lib"/tcl9* "$APPDIR/usr/lib"/tk9* \
|
||||
"$APPDIR/usr/lib"/itcl* "$APPDIR/usr/lib"/thread3*
|
||||
rm -f "$APPDIR/usr/lib"/libpython*.a
|
||||
find "$APPDIR/usr/lib/python${PY_VER}" -name '__pycache__' -type d -prune -exec rm -rf {} + 2>/dev/null || true
|
||||
rm -rf "${APPDIR:?}/usr/lib/python${PY_VER}/site-packages"/*
|
||||
|
||||
# Everything lands in the bundle prefix, built against the managed interpreter
|
||||
# so the extension modules match the one that will run them.
|
||||
uv_install() {
|
||||
"$UV" pip install --python "$PY_BIN" --prefix "$APPDIR/usr" "$@"
|
||||
}
|
||||
|
||||
echo "== Installing Vocalinux + runtime deps into the bundle =="
|
||||
# From the lock, not from whatever PyPI serves today. vad.txt is a superset of
|
||||
# runtime.txt (a test keeps it that way, so this is one resolution rather than
|
||||
# two); appimage.txt adds the PyGObject the exports leave out. The wheel is last
|
||||
# with --no-deps: re-resolving its deps would walk back out of the lock.
|
||||
uv_install --require-hashes -r "$REPO_ROOT/requirements/vad.txt"
|
||||
# --no-deps: PyGObject declares pycairo, which vad.txt already installed, and
|
||||
# --require-hashes would stop on a requirement appimage.txt does not carry.
|
||||
uv_install --require-hashes --no-deps -r "$REPO_ROOT/requirements/appimage.txt"
|
||||
uv_install --no-deps "$WHEEL"
|
||||
|
||||
echo "== Adding desktop entry + icon =="
|
||||
install -Dm644 "$REPO_ROOT/vocalinux.desktop" "$APPDIR/usr/share/applications/vocalinux.desktop"
|
||||
# AppImage desktop integration expects Exec=AppRun; set WM class for the tray app.
|
||||
sed -i \
|
||||
-e 's|^Exec=.*|Exec=AppRun|' \
|
||||
-e '/^StartupWMClass=/d' \
|
||||
"$APPDIR/usr/share/applications/vocalinux.desktop"
|
||||
printf 'StartupWMClass=vocalinux\n' >> "$APPDIR/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 "$REPO_ROOT/resources/icons/scalable/vocalinux.svg" \
|
||||
"$APPDIR/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
|
||||
copy_typelibs() {
|
||||
local dest="$1"
|
||||
local require_all="${2:-0}"
|
||||
mkdir -p "$dest"
|
||||
local typelib found missing=() indicator_found=0
|
||||
for typelib in "${TYPELIBS[@]}"; do
|
||||
found="$(find /usr/lib /usr/lib64 -name "${typelib}.typelib" 2>/dev/null | head -1 || true)"
|
||||
if [ -n "$found" ]; then
|
||||
cp "$found" "$dest/"
|
||||
case " ${INDICATOR_TYPELIBS[*]} " in
|
||||
*" ${typelib} "*) indicator_found=1 ;;
|
||||
esac
|
||||
else
|
||||
missing+=("$typelib")
|
||||
fi
|
||||
done
|
||||
|
||||
# Tray indicator typelibs are alternates; drop them from the hard-fail list
|
||||
# when at least one copied successfully. Optional typelibs never hard-fail.
|
||||
local hard_missing=()
|
||||
for typelib in "${missing[@]}"; do
|
||||
case " ${INDICATOR_TYPELIBS[*]} " in
|
||||
*" ${typelib} "*)
|
||||
if [ "$indicator_found" -eq 0 ]; then
|
||||
hard_missing+=("$typelib")
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case " ${OPTIONAL_TYPELIBS[*]} " in
|
||||
*" ${typelib} "*) ;;
|
||||
*) hard_missing+=("$typelib") ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$require_all" = "1" ] && [ "${#hard_missing[@]}" -gt 0 ]; then
|
||||
echo "Missing required typelibs on the build host:" >&2
|
||||
printf ' - %s\n' "${hard_missing[@]}" >&2
|
||||
if [ "$indicator_found" -eq 0 ]; then
|
||||
echo "Need at least one of: ${INDICATOR_TYPELIBS[*]}" >&2
|
||||
fi
|
||||
echo "Install the matching gir1.2-* packages and retry." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "${#missing[@]}" -gt 0 ]; then
|
||||
echo "Warning: typelibs not found on build host (optional/alternate): ${missing[*]}" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
copy_gi_runtime_libs() {
|
||||
local dest="$1"
|
||||
shift
|
||||
mkdir -p "$dest"
|
||||
local lib found
|
||||
for lib in "$@"; do
|
||||
found="$(find /usr/lib /usr/lib64 -name "$lib" 2>/dev/null | head -1 || true)"
|
||||
if [ -n "$found" ]; then
|
||||
cp -aL "$found" "$dest/"
|
||||
# Prefer versioned real files so linuxdeploy can resolve the SONAME.
|
||||
if [ -L "$found" ]; then
|
||||
real="$(readlink -f "$found")"
|
||||
cp -aL "$real" "$dest/" 2>/dev/null || true
|
||||
fi
|
||||
echo " bundled $lib from $found"
|
||||
else
|
||||
echo "Warning: $lib not found on build host (tray/notify may need host libs)" >&2
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
has_vulkan_build_deps() {
|
||||
if [ -f /usr/include/vulkan/vulkan.h ] || pkg-config --exists vulkan 2>/dev/null; then
|
||||
:
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
command -v g++ >/dev/null 2>&1 || command -v clang++ >/dev/null 2>&1 || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# Pinned wheels, not the image's cmake 3.22.1 — exactly shaderc's floor. Stay on
|
||||
# cmake 3.x: 4.0 rejects the `VERSION 3.4...3.18` pywhispercpp declares.
|
||||
ensure_build_tools() {
|
||||
if [ -n "${BUILD_TOOLS_READY:-}" ]; then
|
||||
return 0
|
||||
fi
|
||||
echo "== Installing pinned build tools (cmake, ninja) =="
|
||||
# A venv, not --prefix: the console scripts import their own package, which a
|
||||
# prefix install leaves on no interpreter's path.
|
||||
"$UV" venv --python "$PY_BIN" "$TOOLDIR/buildtools" >/dev/null
|
||||
"$UV" pip install --python "$TOOLDIR/buildtools" \
|
||||
--require-hashes -r "$REPO_ROOT/requirements/appimage-tools.txt"
|
||||
export PATH="$TOOLDIR/buildtools/bin:$PATH"
|
||||
BUILD_TOOLS_READY=1
|
||||
echo " $(cmake --version | head -1), ninja $(ninja --version)"
|
||||
}
|
||||
|
||||
# ggml demands glslc (`find_package(Vulkan COMPONENTS glslc REQUIRED)`) and the
|
||||
# base image packages none, so build it from the pinned shaderc commit — ~4 min
|
||||
# on a runner, and CI caches it in VOCALINUX_APPIMAGE_CACHE since the commit is
|
||||
# its only input.
|
||||
ensure_glslc() {
|
||||
if command -v glslc >/dev/null 2>&1; then
|
||||
echo " glslc: $(command -v glslc)"
|
||||
return 0
|
||||
fi
|
||||
local commit cache_dir src
|
||||
commit="$(pin_field shaderc 3)"
|
||||
cache_dir="${VOCALINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/vocalinux-appimage}/glslc-${commit}-${ARCH}"
|
||||
if [ ! -x "$cache_dir/glslc" ]; then
|
||||
echo "== Building glslc from shaderc ${commit:0:12} (this image packages none) =="
|
||||
ensure_build_tools
|
||||
src="$WORKDIR/shaderc"
|
||||
checkout_pinned shaderc "$src"
|
||||
# DEPS pins glslang, SPIRV-Tools and SPIRV-Headers by commit; git-sync-deps
|
||||
# checks out exactly those, so the pinned commit fixes the whole tree.
|
||||
(cd "$src" && ./utils/git-sync-deps)
|
||||
cmake -S "$src" -B "$src/build" -G Ninja -DCMAKE_BUILD_TYPE=Release \
|
||||
-DSHADERC_SKIP_TESTS=ON -DSHADERC_SKIP_EXAMPLES=ON \
|
||||
-DSHADERC_SKIP_COPYRIGHT_CHECK=ON -DSPIRV_SKIP_TESTS=ON \
|
||||
-DSPIRV_SKIP_EXECUTABLES=ON >"$WORKDIR/shaderc-cmake.log" 2>&1 || {
|
||||
tail -n 30 "$WORKDIR/shaderc-cmake.log" >&2; return 1; }
|
||||
cmake --build "$src/build" --target glslc_exe \
|
||||
-j"${CMAKE_BUILD_PARALLEL_LEVEL:-$(nproc)}" >"$WORKDIR/shaderc-build.log" 2>&1 || {
|
||||
tail -n 30 "$WORKDIR/shaderc-build.log" >&2; return 1; }
|
||||
mkdir -p "$cache_dir"
|
||||
install -m755 "$src/build/glslc/glslc" "$cache_dir/glslc"
|
||||
fi
|
||||
export PATH="$cache_dir:$PATH"
|
||||
echo " glslc: $("$cache_dir/glslc" --version | head -1)"
|
||||
}
|
||||
|
||||
# The base image's headers are too old for ggml (see the pin). Only the compile
|
||||
# sees these: the bundle carries no loader, the host's is used.
|
||||
ensure_vulkan_headers() {
|
||||
VULKAN_INCLUDE_DIR="$WORKDIR/vulkan-headers/include"
|
||||
if [ ! -d "$VULKAN_INCLUDE_DIR" ]; then
|
||||
echo "== Fetching pinned Vulkan headers =="
|
||||
checkout_pinned vulkan-headers "$WORKDIR/vulkan-headers"
|
||||
fi
|
||||
echo " $(sed -n 's/.*VK_HEADER_VERSION \([0-9]*\).*/vulkan headers 1.x.\1/p' \
|
||||
"$VULKAN_INCLUDE_DIR/vulkan/vulkan_core.h" | head -1)"
|
||||
}
|
||||
|
||||
remove_appdir_pywhispercpp() {
|
||||
find "$APPDIR/usr" -depth \( \
|
||||
-name 'pywhispercpp' -o \
|
||||
-name 'pywhispercpp.libs' -o \
|
||||
-name 'pywhispercpp-*.dist-info' -o \
|
||||
-name '_pywhispercpp*' \
|
||||
\) -exec rm -rf {} + 2>/dev/null || true
|
||||
}
|
||||
|
||||
copy_whisper_native_libs_to_usr_lib() {
|
||||
mkdir -p "$APPDIR/usr/lib"
|
||||
local lib
|
||||
while IFS= read -r lib; do
|
||||
[ -n "$lib" ] || continue
|
||||
cp -aL "$lib" "$APPDIR/usr/lib/" 2>/dev/null || cp -a "$lib" "$APPDIR/usr/lib/"
|
||||
echo " staged $(basename "$lib") -> usr/lib"
|
||||
done < <(find "$APPDIR/usr" \( -name 'libggml*.so*' -o -name 'libwhisper.so*' \) ! -path '*/usr/lib/*' 2>/dev/null || true)
|
||||
}
|
||||
|
||||
# ggml's instruction-set floor for every CPU-side pywhispercpp build this
|
||||
# script ships; CMAKE_ARGS inlines it below so the native-cache id keeps
|
||||
# hashing it. GGML_NATIVE is ggml's default and compiles libggml-cpu with
|
||||
# -march=native, tuned to whichever runner the build lands on: a runner with
|
||||
# AVX-512 ships a libggml-cpu.so that dies with SIGILL on any CPU without it
|
||||
# (#938), and the native cache then serves the same binary to every later
|
||||
# build. GGML_NATIVE=OFF alone is not the portable baseline either — while
|
||||
# the native default is on, ggml turns every GGML_* SIMD option on and still
|
||||
# compiles -mavx2 -mfma, dying the same way on pre-Haswell CPUs (#957). Each
|
||||
# option is pinned off for the plain x86-64 baseline; the Vulkan path is
|
||||
# unaffected because its shaders run on the GPU.
|
||||
PORTABLE_GGML_CMAKE_ARGS="-DGGML_NATIVE=OFF -DGGML_SSE42=OFF -DGGML_AVX=OFF -DGGML_AVX2=OFF -DGGML_BMI2=OFF -DGGML_FMA=OFF -DGGML_F16C=OFF"
|
||||
|
||||
# Reinstall the same pinned sdist the bundle already carries, hashes and all:
|
||||
# a source build is still a download, and this one ends up in ctypes.cdll.
|
||||
# GGML_VULKAN=1 in the caller's env selects the Vulkan build; without it the
|
||||
# compile is CPU-only and any -DVulkan_INCLUDE_DIR is dead.
|
||||
_install_pinned_pywhispercpp() {
|
||||
local pip_log="$1"
|
||||
awk '/^pywhispercpp==/ {found=1; print; next}
|
||||
found && /^[[:space:]]/ {print; next}
|
||||
found {exit}' "$REPO_ROOT/requirements/vad.txt" > "$WORKDIR/pywhispercpp.txt"
|
||||
# Hosts that default cc/c++ to clang (this Cloud Agent image) fail the
|
||||
# CMAKE C++ compiler test: clang does not search gcc's libstdc++ path.
|
||||
CC="${CC:-gcc}" CXX="${CXX:-g++}" \
|
||||
GGML_VULKAN="${GGML_VULKAN:-0}" \
|
||||
CMAKE_ARGS="-DCMAKE_INSTALL_RPATH=\$ORIGIN -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON $PORTABLE_GGML_CMAKE_ARGS${VULKAN_INCLUDE_DIR:+ -DVulkan_INCLUDE_DIR=$VULKAN_INCLUDE_DIR}" \
|
||||
uv_install --verbose --require-hashes --no-deps \
|
||||
--reinstall-package pywhispercpp --no-binary pywhispercpp \
|
||||
-r "$WORKDIR/pywhispercpp.txt" >"$pip_log" 2>&1
|
||||
}
|
||||
|
||||
# CPU-only fallback for the Vulkan path. The PyPI wheel the bundle started
|
||||
# with is the same AVX2+FMA build the SIGILL reports come from, so keeping it
|
||||
# is no fallback at all on pre-Haswell CPUs — rebuild the sdist at the
|
||||
# baseline instead.
|
||||
_compile_pywhispercpp_baseline() {
|
||||
local pip_log="$WORKDIR/pywhispercpp-baseline.log"
|
||||
export CMAKE_BUILD_PARALLEL_LEVEL="${CMAKE_BUILD_PARALLEL_LEVEL:-$(nproc)}"
|
||||
ensure_build_tools
|
||||
echo "== Rebuilding pywhispercpp at the portable CPU baseline =="
|
||||
remove_appdir_pywhispercpp
|
||||
if ! _install_pinned_pywhispercpp "$pip_log"; then
|
||||
# The wheel is already gone, so "continue" would ship an AppImage with
|
||||
# no speech engine at all; fail the build instead.
|
||||
echo "Baseline pywhispercpp rebuild failed; refusing to ship without the speech engine." >&2
|
||||
tail -n 40 "$pip_log" 2>/dev/null | sed 's/^/ /' >&2 || true
|
||||
return 1
|
||||
fi
|
||||
copy_whisper_native_libs_to_usr_lib
|
||||
}
|
||||
|
||||
# The miss path of rebuild_pywhispercpp_vulkan. require_vulkan, cache_dir, and
|
||||
# site are locals of that caller; bash shows them to this function.
|
||||
_compile_pywhispercpp_vulkan() {
|
||||
local vk_lib
|
||||
if ! has_vulkan_build_deps; then
|
||||
echo "Vulkan build deps missing (libvulkan-dev plus a C++ compiler)." >&2
|
||||
if [ "$require_vulkan" = "1" ]; then
|
||||
echo "VOCALINUX_APPIMAGE_REQUIRE_VULKAN=1: refusing to ship a CPU-only AppImage." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Warning: AppImage will use a CPU-only baseline pywhispercpp build." >&2
|
||||
_compile_pywhispercpp_baseline || return 1
|
||||
return 0
|
||||
fi
|
||||
|
||||
ensure_build_tools
|
||||
ensure_vulkan_headers
|
||||
if ! ensure_glslc; then
|
||||
echo "Could not provide glslc; ggml cannot compile its Vulkan shaders." >&2
|
||||
if [ "$require_vulkan" = "1" ]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "Warning: continuing with a CPU-only baseline pywhispercpp build." >&2
|
||||
_compile_pywhispercpp_baseline || return 1
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "== Rebuilding pywhispercpp with Vulkan =="
|
||||
remove_appdir_pywhispercpp
|
||||
local pip_log="$WORKDIR/pywhispercpp-vulkan.log"
|
||||
export CMAKE_BUILD_PARALLEL_LEVEL="${CMAKE_BUILD_PARALLEL_LEVEL:-$(nproc)}"
|
||||
if ! GGML_VULKAN=1 _install_pinned_pywhispercpp "$pip_log"; then
|
||||
# The tail is the Python traceback wrapping the build and says nothing about
|
||||
# the compile, so lead with the compiler's own errors.
|
||||
echo "pywhispercpp Vulkan rebuild failed." >&2
|
||||
grep -E "error:|FAILED:|CMake Error" "$pip_log" 2>/dev/null \
|
||||
| head -n 20 | sed 's/^/ /' >&2 || true
|
||||
echo " --- last 40 log lines ---" >&2
|
||||
tail -n 40 "$pip_log" 2>/dev/null | sed 's/^/ /' >&2 || true
|
||||
if [ "$require_vulkan" = "1" ]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "Warning: continuing with a CPU-only baseline pywhispercpp build." >&2
|
||||
_compile_pywhispercpp_baseline || return 1
|
||||
return 0
|
||||
fi
|
||||
|
||||
vk_lib="$(find "$APPDIR/usr" -name 'libggml-vulkan.so*' 2>/dev/null | head -1 || true)"
|
||||
if [ -z "$vk_lib" ]; then
|
||||
echo "Vulkan rebuild did not produce libggml-vulkan.so." >&2
|
||||
if [ "$require_vulkan" = "1" ]; then
|
||||
tail -n 80 "$pip_log" 2>/dev/null | sed 's/^/ /' >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
# The GGML_VULKAN=1 compile is already the portable baseline even when no
|
||||
# Vulkan library comes out of it, so this build is safe to keep.
|
||||
echo "Warning: AppImage will use CPU-only baseline pywhispercpp." >&2
|
||||
copy_whisper_native_libs_to_usr_lib
|
||||
return 0
|
||||
fi
|
||||
echo " found $vk_lib"
|
||||
copy_whisper_native_libs_to_usr_lib
|
||||
if ! pywhispercpp_cache_publish "$site" "$cache_dir"; then
|
||||
echo "Warning: Vulkan build succeeded but was not cached for the next run." >&2
|
||||
fi
|
||||
}
|
||||
|
||||
rebuild_pywhispercpp_vulkan() {
|
||||
local require_vulkan="${VOCALINUX_APPIMAGE_REQUIRE_VULKAN:-0}"
|
||||
if [ "${VOCALINUX_APPIMAGE_SKIP_VULKAN:-0}" = "1" ]; then
|
||||
echo "== Skipping pywhispercpp Vulkan rebuild (VOCALINUX_APPIMAGE_SKIP_VULKAN=1) =="
|
||||
return 0
|
||||
fi
|
||||
|
||||
# The Vocalinux wheel was installed above and is not part of this cache.
|
||||
# A hit still replaces the CPU pywhispercpp wheel the lock just installed,
|
||||
# and it does not run _compile_pywhispercpp_vulkan.
|
||||
local cache_dir site
|
||||
cache_dir="$(pywhispercpp_native_cache_dir "$ARCH")"
|
||||
site="$APPDIR/usr/lib/python${PY_VER}/site-packages"
|
||||
pywhispercpp_restore_or_run "$cache_dir" "$site" copy_whisper_native_libs_to_usr_lib \
|
||||
_compile_pywhispercpp_vulkan
|
||||
}
|
||||
|
||||
echo "== Copying GObject-Introspection typelibs (not handled by linuxdeploy-plugin-gtk) =="
|
||||
copy_typelibs "$APPDIR/usr/lib/girepository-1.0" 0
|
||||
|
||||
echo "== Copying GI runtime shared libraries (AppIndicator/Notify) =="
|
||||
copy_gi_runtime_libs "$APPDIR/usr/lib" \
|
||||
"${GI_RUNTIME_LIBS[@]}" "${BUNDLED_DEPENDENCY_LIBS[@]}"
|
||||
|
||||
echo "== Writing AppRun =="
|
||||
cat > "$APPDIR/AppRun" << 'APPRUN'
|
||||
#!/usr/bin/env bash
|
||||
HERE="$(dirname "$(readlink -f "${0}")")"
|
||||
export PYTHONHOME="$HERE/usr"
|
||||
export PYTHONPATH="$HERE/usr/lib/python3:$HERE/usr/lib/python3/site-packages"
|
||||
export GI_TYPELIB_PATH="$HERE/usr/lib/girepository-1.0"
|
||||
export LD_LIBRARY_PATH="$HERE/usr/lib:${LD_LIBRARY_PATH:-}"
|
||||
export XDG_DATA_DIRS="$HERE/usr/share:${XDG_DATA_DIRS:-/usr/share}"
|
||||
exec "$HERE/usr/bin/python3" -m vocalinux.main "$@"
|
||||
APPRUN
|
||||
# PYTHONPATH above uses a version-agnostic symlink so AppRun doesn't need
|
||||
# to know the exact interpreter minor version at runtime.
|
||||
ln -sfn "python${PY_VER}" "$APPDIR/usr/lib/python3"
|
||||
chmod +x "$APPDIR/AppRun"
|
||||
|
||||
rebuild_pywhispercpp_vulkan
|
||||
|
||||
echo "== Running linuxdeploy (resolves the shared-library closure + GTK theming) =="
|
||||
export DEPLOY_GTK_VERSION=3
|
||||
"$TOOLDIR/linuxdeploy" --appdir "$APPDIR" \
|
||||
--plugin gtk \
|
||||
-e "$APPDIR/usr/bin/python3" \
|
||||
-d "$APPDIR/usr/share/applications/vocalinux.desktop" \
|
||||
-i "$APPDIR/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
|
||||
# The plugin can change the bundle after PyGObject was installed. Check the
|
||||
# package and the version-agnostic Python path that AppRun and the GI smoke use
|
||||
# before entering a new mount/user namespace; a missing module there is not a
|
||||
# missing python3-gi package on the builder's host.
|
||||
echo "== Checking bundled PyGObject after linuxdeploy =="
|
||||
GI_SITE="$APPDIR/usr/lib/python${PY_VER}/site-packages"
|
||||
if [ ! -f "$GI_SITE/gi/__init__.py" ]; then
|
||||
echo "PyGObject is missing from $GI_SITE after linuxdeploy." >&2
|
||||
echo "Check the earlier uv install of requirements/appimage.txt." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ -d "$APPDIR/usr/lib/python3" ] && [ ! -L "$APPDIR/usr/lib/python3" ]; then
|
||||
echo "Expected usr/lib/python3 to be a symlink to python${PY_VER}, not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
# Restore this link if linuxdeploy replaced it; a broken alias hides gi even
|
||||
# though its versioned site-packages directory is present in the bundle.
|
||||
ln -sfn "python${PY_VER}" "$APPDIR/usr/lib/python3"
|
||||
if ! PYTHONHOME="$APPDIR/usr" \
|
||||
PYTHONPATH="$APPDIR/usr/lib/python3:$APPDIR/usr/lib/python3/site-packages" \
|
||||
LD_LIBRARY_PATH="$APPDIR/usr/lib" \
|
||||
"$APPDIR/usr/bin/python3" -c 'import gi; print(" gi:", gi.__file__)'; then
|
||||
echo "The bundled Python cannot import gi before the isolated smoke test." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# linuxdeploy copies the host's full typelib set; keep those extras (transitive
|
||||
# GIR deps vary by distro) and re-assert our required seed on top.
|
||||
echo "== Ensuring required typelibs are present (keeping linuxdeploy extras) =="
|
||||
copy_typelibs "$APPDIR/usr/lib/girepository-1.0" 1
|
||||
|
||||
# GI loads a typelib's library by name, so a typelib bundled without it pulls in
|
||||
# the host's copy against the bundled GLib. IBus shipped that way and died on
|
||||
# hosts with GLib 2.76+ (`undefined symbol: g_task_set_static_name`). The build
|
||||
# host cannot notice — its libraries match what it bundled.
|
||||
echo "== Checking every bundled typelib has its library =="
|
||||
verify_typelib_libraries() {
|
||||
"$APPDIR/usr/bin/python3" - "$APPDIR" "${HOST_PROVIDED_LIBS[*]}" <<'PY'
|
||||
import pathlib
|
||||
import struct
|
||||
import sys
|
||||
|
||||
appdir = pathlib.Path(sys.argv[1])
|
||||
host_provided = set(sys.argv[2].split())
|
||||
typelib_dir = appdir / "usr" / "lib" / "girepository-1.0"
|
||||
lib_dir = appdir / "usr" / "lib"
|
||||
|
||||
# Typelib header layout: 16-byte magic, then fixed fields; shared_library is a
|
||||
# uint32 offset at byte 52 into a comma-separated, NUL-terminated string.
|
||||
MAGIC = b"GOBJ\nMETADATA\r\n\x1a"
|
||||
SHARED_LIBRARY_OFFSET = 52
|
||||
|
||||
|
||||
def shared_libraries(path):
|
||||
blob = path.read_bytes()
|
||||
if not blob.startswith(MAGIC):
|
||||
return []
|
||||
offset = struct.unpack_from("<I", blob, SHARED_LIBRARY_OFFSET)[0]
|
||||
if not offset:
|
||||
return []
|
||||
return [name for name in blob[offset : blob.index(b"\x00", offset)].decode().split(",") if name]
|
||||
|
||||
|
||||
# Every typelib that ships, not only the seeded ones: linuxdeploy keeps the
|
||||
# host's extras, and an extra loads the host's library just as readily.
|
||||
checked, missing = 0, []
|
||||
for typelib in sorted(typelib_dir.glob("*.typelib")):
|
||||
namespace = typelib.stem
|
||||
checked += 1
|
||||
for library in shared_libraries(typelib):
|
||||
if library in host_provided or (lib_dir / library).exists():
|
||||
continue
|
||||
missing.append(f"{namespace}.typelib needs {library}")
|
||||
|
||||
if missing:
|
||||
print("Typelibs bundled without the library they load:", file=sys.stderr)
|
||||
for line in missing:
|
||||
print(f" - {line}", file=sys.stderr)
|
||||
print("GI would load the host's copy against the bundled GLib.", file=sys.stderr)
|
||||
print("Add it to GI_RUNTIME_LIBS, or to HOST_PROVIDED_LIBS if the", file=sys.stderr)
|
||||
print("AppImage excludelist says it has to come from the host.", file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
|
||||
print(f" {checked} typelibs checked, every library present")
|
||||
PY
|
||||
}
|
||||
verify_typelib_libraries
|
||||
|
||||
echo "== Patching linuxdeploy GTK AppRun hook (Wayland-friendly GDK backend) =="
|
||||
GTK_HOOK="$APPDIR/apprun-hooks/linuxdeploy-plugin-gtk.sh"
|
||||
if [ -f "$GTK_HOOK" ]; then
|
||||
# Upstream forces GDK_BACKEND=x11 even on Wayland, which breaks hover/focus
|
||||
# for GTK widgets under Plasma (XWayland). Prefer native Wayland unless the
|
||||
# user opts into X11 via VOCALINUX_FORCE_X11=1.
|
||||
"$APPDIR/usr/bin/python3" - "$GTK_HOOK" <<'PY'
|
||||
import pathlib, re, sys
|
||||
path = pathlib.Path(sys.argv[1])
|
||||
text = path.read_text()
|
||||
replacement = (
|
||||
'# Prefer Wayland when available; force X11 only when requested.\n'
|
||||
'if [ "${VOCALINUX_FORCE_X11:-0}" = "1" ]; then\n'
|
||||
' export GDK_BACKEND=x11\n'
|
||||
'elif [ -n "${WAYLAND_DISPLAY:-}" ] || [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then\n'
|
||||
' export GDK_BACKEND=wayland\n'
|
||||
'else\n'
|
||||
' export GDK_BACKEND=x11\n'
|
||||
'fi'
|
||||
)
|
||||
new, n = re.subn(
|
||||
r'^[ \t]*export GDK_BACKEND=x11[^\n]*$',
|
||||
replacement,
|
||||
text,
|
||||
count=1,
|
||||
flags=re.M,
|
||||
)
|
||||
if n != 1:
|
||||
raise SystemExit(f"failed to patch GDK_BACKEND in {path} (matches={n})")
|
||||
path.write_text(new)
|
||||
print(f"Patched {path}")
|
||||
PY
|
||||
else
|
||||
echo "Warning: GTK AppRun hook not found at $GTK_HOOK" >&2
|
||||
fi
|
||||
|
||||
echo "== Smoke-testing GI imports without host typelibs =="
|
||||
# Catch the openSUSE/Fedora class of failure before packaging: Gtk needs xlib
|
||||
# (and friends) from the bundle when the host GI search path is not Debian's.
|
||||
smoke_gi_imports() {
|
||||
local appdir="$1"
|
||||
unshare --user --mount --map-root-user bash -c "
|
||||
set -euo pipefail
|
||||
mkdir -p /tmp/vocalinux-empty-gi
|
||||
for d in /usr/lib/x86_64-linux-gnu/girepository-1.0 \
|
||||
/usr/lib/aarch64-linux-gnu/girepository-1.0 \
|
||||
/usr/lib/girepository-1.0 \
|
||||
/usr/lib64/girepository-1.0; do
|
||||
if [ -d \"\$d\" ]; then
|
||||
mount --bind /tmp/vocalinux-empty-gi \"\$d\"
|
||||
fi
|
||||
done
|
||||
export PYTHONHOME='$appdir/usr'
|
||||
export PYTHONPATH='$appdir/usr/lib/python3:$appdir/usr/lib/python3/site-packages'
|
||||
export GI_TYPELIB_PATH='$appdir/usr/lib/girepository-1.0'
|
||||
export LD_LIBRARY_PATH='$appdir/usr/lib'
|
||||
'$appdir/usr/bin/python3' - <<'PY'
|
||||
try:
|
||||
import gi
|
||||
except ModuleNotFoundError:
|
||||
import os
|
||||
import pathlib
|
||||
import stat
|
||||
import sys
|
||||
|
||||
print('Bundled gi is not importable inside the isolated smoke test.', file=sys.stderr)
|
||||
print(f' python: {sys.executable}, uid: {os.geteuid()}', file=sys.stderr)
|
||||
print(' PYTHONHOME:', os.environ.get('PYTHONHOME'), file=sys.stderr)
|
||||
print(' PYTHONPATH:', os.environ.get('PYTHONPATH'), file=sys.stderr)
|
||||
print(f' sys.path: {sys.path}', file=sys.stderr)
|
||||
lib = pathlib.Path(sys.prefix) / 'lib'
|
||||
versioned = lib / f'python{sys.version_info.major}.{sys.version_info.minor}'
|
||||
for candidate in (lib / 'python3', versioned / 'site-packages' / 'gi',
|
||||
lib / 'python3' / 'site-packages' / 'gi'):
|
||||
try:
|
||||
details = candidate.stat()
|
||||
except OSError as exc:
|
||||
print(f' {candidate}: {exc}', file=sys.stderr)
|
||||
else:
|
||||
print(f' {candidate}: mode={stat.S_IMODE(details.st_mode):o}, '
|
||||
f'uid={details.st_uid}, accessible={os.access(candidate, os.R_OK | os.X_OK)}',
|
||||
file=sys.stderr)
|
||||
raise
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk # noqa: F401
|
||||
try:
|
||||
gi.require_version('AyatanaAppIndicator3', '0.1')
|
||||
from gi.repository import AyatanaAppIndicator3 # noqa: F401
|
||||
except (ImportError, ValueError):
|
||||
try:
|
||||
gi.require_version('AyatanaAppindicator3', '0.1')
|
||||
from gi.repository import AyatanaAppindicator3 # noqa: F401
|
||||
except (ImportError, ValueError):
|
||||
gi.require_version('AppIndicator3', '0.1')
|
||||
from gi.repository import AppIndicator3 # noqa: F401
|
||||
# ibus_engine.py subclasses IBus.Engine at import time; a failed libibus load
|
||||
# leaves a stub whose GType is 'void', so check the type, not just the import.
|
||||
gi.require_version('IBus', '1.0')
|
||||
from gi.repository import IBus
|
||||
if IBus.Engine.__gtype__.name in ('void', 'invalid'):
|
||||
raise SystemExit('IBus typelib loaded but libibus did not')
|
||||
print('GI smoke OK')
|
||||
PY
|
||||
"
|
||||
}
|
||||
|
||||
if command -v unshare >/dev/null 2>&1 && unshare --user --mount --map-root-user true 2>/dev/null; then
|
||||
smoke_gi_imports "$APPDIR"
|
||||
else
|
||||
echo "Warning: unshare unavailable; skipping isolated GI smoke test" >&2
|
||||
fi
|
||||
|
||||
echo "== Packaging AppImage =="
|
||||
OUTPUT="$OUTDIR/Vocalinux-${VERSION}-${ARCH}.AppImage"
|
||||
ARCH="$ARCH" "$TOOLDIR/appimagetool" "$APPDIR" "$OUTPUT"
|
||||
echo "Built $OUTPUT"
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install what build.sh needs on a bare base image, then run it.
|
||||
#
|
||||
# The AppImage inherits the glibc and the GTK stack of whatever host builds it,
|
||||
# so the host is a pinned input like any other: `base-image` in
|
||||
# tool_checksums.txt. This script is the part that runs inside that image; the
|
||||
# way in is docker-build.sh, which both CI and `just appimage` call:
|
||||
#
|
||||
# bash packaging/appimage/docker-build.sh dist/vocalinux-0.16.0-py3-none-any.whl 0.16.0 dist
|
||||
#
|
||||
# Only the interpreter and the Python packages are pinned by digest; these apt
|
||||
# packages are whatever the pinned image resolves to. That is the trade the base
|
||||
# image makes: its archive is frozen enough for this to be stable, and pinning
|
||||
# every .deb would cost more than it protects.
|
||||
set -euo pipefail
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq --no-install-recommends \
|
||||
ca-certificates curl git xz-utils file squashfs-tools desktop-file-utils \
|
||||
build-essential pkg-config python3 \
|
||||
libcairo2-dev libgirepository1.0-dev portaudio19-dev \
|
||||
libgtk-3-0 gir1.2-gtk-3.0 \
|
||||
gir1.2-ayatanaappindicator3-0.1 libayatana-appindicator3-1 \
|
||||
gir1.2-notify-0.7 libnotify4 \
|
||||
gir1.2-dbusmenu-glib-0.4 libdbusmenu-gtk3-4 \
|
||||
gir1.2-ibus-1.0 gir1.2-rsvg-2.0 librsvg2-common \
|
||||
gir1.2-gtklayershell-0.1 libgtk-layer-shell0 \
|
||||
libvulkan-dev
|
||||
|
||||
bash "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/build.sh" "$@"
|
||||
|
||||
# A container builds as root, so everything it wrote is root-owned. Hand the
|
||||
# results back to whoever started it (docker-build.sh passes its own ids).
|
||||
if [ -n "${HOST_UID:-}" ]; then
|
||||
chown -R "${HOST_UID}:${HOST_GID:-$HOST_UID}" "${3:-dist}" \
|
||||
"${VOCALINUX_APPIMAGE_CACHE:-/cache}" 2>/dev/null || true
|
||||
fi
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the AppImage build inside the pinned base image.
|
||||
#
|
||||
# Usage: docker-build.sh <path-to-wheel> <version> [output-dir]
|
||||
#
|
||||
# This is what CI calls and what you should call locally, so that what you get
|
||||
# is what CI gets: the base image decides the glibc floor and the GTK version
|
||||
# the AppImage links against, and building on the host instead means shipping
|
||||
# whatever that host happens to run.
|
||||
#
|
||||
# Honours VOCALINUX_APPIMAGE_REQUIRE_VULKAN / _SKIP_VULKAN like build.sh, and
|
||||
# keeps glslc and the pywhispercpp Vulkan build in VOCALINUX_APPIMAGE_CACHE
|
||||
# (~/.cache/vocalinux-appimage by default) so the next build reuses them.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/../.." && pwd)"
|
||||
IMAGE="$(awk '$1=="base-image" {print $3}' "$REPO_ROOT/packaging/appimage/tool_checksums.txt")"
|
||||
if [ -z "$IMAGE" ]; then
|
||||
echo "No base-image pin in packaging/appimage/tool_checksums.txt" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CACHE="${VOCALINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/vocalinux-appimage}"
|
||||
mkdir -p "$CACHE"
|
||||
|
||||
# The wheel and output dir are given as host paths; the repo is mounted at the
|
||||
# same place it lives, so relative arguments keep working inside.
|
||||
# seccomp=unconfined only to allow unshare: without it build.sh's isolated GI
|
||||
# smoke test silently skips, which is how #585 shipped.
|
||||
exec docker run --rm \
|
||||
--security-opt seccomp=unconfined \
|
||||
-v "$REPO_ROOT:$REPO_ROOT" -w "$REPO_ROOT" \
|
||||
-v "$CACHE:/cache" \
|
||||
-e VOCALINUX_APPIMAGE_CACHE=/cache \
|
||||
-e VOCALINUX_APPIMAGE_REQUIRE_VULKAN \
|
||||
-e VOCALINUX_APPIMAGE_SKIP_VULKAN \
|
||||
-e CMAKE_BUILD_PARALLEL_LEVEL \
|
||||
-e HOST_UID="$(id -u)" \
|
||||
-e HOST_GID="$(id -g)" \
|
||||
"$IMAGE" bash packaging/appimage/container-build.sh "$@"
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
# Id for the reusable pywhispercpp Vulkan build.
|
||||
#
|
||||
# That compile depends on the base image (glibc, and the toolchain apt installs
|
||||
# from it), every pin in tool_checksums.txt, the cmake/ninja pins in
|
||||
# requirements/appimage-tools.txt, the Vulkan flags in build.sh, and the
|
||||
# pywhispercpp sdist install.sh names. It does not depend on the rest of the
|
||||
# Vocalinux sources, so this id ignores the git commit and the Actions run id
|
||||
# on purpose: putting either in the cache key would rebuild on every push.
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo="$(cd "$here/../.." && pwd)"
|
||||
pins="${VOCALINUX_PINS:-$repo/packaging/appimage/tool_checksums.txt}"
|
||||
install_sh="${VOCALINUX_INSTALL_SH:-$repo/install.sh}"
|
||||
tools="${VOCALINUX_APPIMAGE_TOOLS:-$repo/requirements/appimage-tools.txt}"
|
||||
build_sh="${VOCALINUX_BUILD_SH:-$repo/packaging/appimage/build.sh}"
|
||||
|
||||
base="$(awk '$1=="base-image" {print $3; exit}' "$pins")"
|
||||
if [ -z "$base" ]; then
|
||||
echo "No base-image pin in $pins" >&2
|
||||
exit 1
|
||||
fi
|
||||
pywhispercpp="$(sed -n 's/^PYWHISPERCPP_VERSION="\([^"]*\)"/\1/p' "$install_sh" | head -n1)"
|
||||
if [ -z "$pywhispercpp" ]; then
|
||||
echo "Could not read PYWHISPERCPP_VERSION from $install_sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "$tools" ]; then
|
||||
echo "No AppImage build-tool pins at $tools" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Cache revision for the native flags. Hashing those lines, not all of
|
||||
# build.sh, misses the cache when the compile changes and hits when a comment
|
||||
# elsewhere in the script changes.
|
||||
flags="$(awk '/GGML_VULKAN=1/ || /CMAKE_ARGS=/ { print }' "$build_sh")"
|
||||
if ! printf '%s\n' "$flags" | grep -q 'GGML_VULKAN=1'; then
|
||||
echo "Could not read the Vulkan compile flags from $build_sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! printf '%s\n' "$flags" | grep -q 'CMAKE_ARGS='; then
|
||||
echo "Could not read CMAKE_ARGS from $build_sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
pins_hash="$(sha256sum "$pins" | awk '{print $1}')"
|
||||
tools_hash="$(sha256sum "$tools" | awk '{print $1}')"
|
||||
printf '%s\n%s\n%s\n%s\n%s\n' \
|
||||
"$base" "$pins_hash" "$pywhispercpp" "$tools_hash" "$flags" \
|
||||
| sha256sum | awk '{print $1}'
|
||||
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env bash
|
||||
# Reuse a pywhispercpp build that already contains libggml-vulkan.so.
|
||||
#
|
||||
# Sourced by build.sh. A tree without that library is a CPU wheel, and caching
|
||||
# one would ship it to the next run that asked for Vulkan.
|
||||
#
|
||||
# The directory name is the id from native-cache-id.sh plus the architecture.
|
||||
# The .so is not portable across either.
|
||||
|
||||
_NATIVE_CACHE_HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
pywhispercpp_native_cache_dir() {
|
||||
local arch="$1"
|
||||
local root id
|
||||
root="${VOCALINUX_APPIMAGE_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/vocalinux-appimage}"
|
||||
id="$(bash "$_NATIVE_CACHE_HERE/native-cache-id.sh")"
|
||||
printf '%s\n' "$root/pywhispercpp-vulkan-${arch}-${id}"
|
||||
}
|
||||
|
||||
pywhispercpp_cache_has_vulkan() {
|
||||
local dir="$1"
|
||||
local found
|
||||
[ -d "$dir" ] || return 1
|
||||
found="$(find "$dir" -name 'libggml-vulkan.so*' -print -quit)"
|
||||
[ -n "$found" ]
|
||||
}
|
||||
|
||||
# Copy the pywhispercpp install out of a site-packages directory.
|
||||
# Leaves the rest of the prefix (Vocalinux, numpy, …) where it is.
|
||||
pywhispercpp_cache_publish() {
|
||||
local site="$1" dest="$2"
|
||||
local parent staging pattern backup
|
||||
# Called from `if !`, which disables set -e for this whole function.
|
||||
# A failing cp has to return on its own, or a short write becomes the cache.
|
||||
parent="$(dirname "$dest")"
|
||||
mkdir -p "$parent" || return 1
|
||||
staging="$(mktemp -d "$parent/.pywhispercpp-staging-XXXXXX")" || return 1
|
||||
for pattern in \
|
||||
"$site/pywhispercpp" \
|
||||
"$site"/pywhispercpp-*.dist-info \
|
||||
"$site"/pywhispercpp.libs \
|
||||
"$site"/_pywhispercpp* \
|
||||
"$site"/libggml*.so* \
|
||||
"$site"/libwhisper.so*
|
||||
do
|
||||
[ -e "$pattern" ] || [ -L "$pattern" ] || continue
|
||||
if ! cp -a "$pattern" "$staging/"; then
|
||||
rm -rf "$staging"
|
||||
echo "Failed to copy $(basename "$pattern") into the pywhispercpp cache." >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
if ! pywhispercpp_cache_has_vulkan "$staging"; then
|
||||
rm -rf "$staging"
|
||||
echo "Refusing to cache a pywhispercpp build with no libggml-vulkan.so" >&2
|
||||
return 1
|
||||
fi
|
||||
backup="${dest}.replacing"
|
||||
rm -rf "$backup"
|
||||
if [ -e "$dest" ]; then
|
||||
if ! mv "$dest" "$backup"; then
|
||||
rm -rf "$staging"
|
||||
echo "Failed to move the previous pywhispercpp cache aside." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
if ! mv "$staging" "$dest"; then
|
||||
echo "Failed to publish the pywhispercpp cache." >&2
|
||||
if [ -e "$backup" ] && ! mv "$backup" "$dest"; then
|
||||
echo "Also failed to restore the previous pywhispercpp cache." >&2
|
||||
fi
|
||||
rm -rf "$staging"
|
||||
return 1
|
||||
fi
|
||||
rm -rf "$backup"
|
||||
}
|
||||
|
||||
# Replace whatever pywhispercpp the prefix just installed (the CPU wheel) with
|
||||
# the cached Vulkan build. Other packages in site-packages stay.
|
||||
pywhispercpp_cache_restore() {
|
||||
local src="$1" site="$2"
|
||||
if ! pywhispercpp_cache_has_vulkan "$src"; then
|
||||
echo "Cached pywhispercpp tree has no libggml-vulkan.so" >&2
|
||||
return 1
|
||||
fi
|
||||
mkdir -p "$site" || return 1
|
||||
find "$site" -depth \( \
|
||||
-name 'pywhispercpp' -o \
|
||||
-name 'pywhispercpp.libs' -o \
|
||||
-name 'pywhispercpp-*.dist-info' -o \
|
||||
-name '_pywhispercpp*' -o \
|
||||
-name 'libggml*.so*' -o \
|
||||
-name 'libwhisper.so*' \
|
||||
\) -exec rm -rf {} + 2>/dev/null || true
|
||||
if ! cp -a "$src"/. "$site/"; then
|
||||
echo "Restoring the cached pywhispercpp tree failed." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 0 when the cached tree is in place. 1 when the caller has to compile.
|
||||
pywhispercpp_try_restore() {
|
||||
local cache_dir="$1"
|
||||
local site="$2"
|
||||
local vk_lib
|
||||
if ! pywhispercpp_cache_has_vulkan "$cache_dir"; then
|
||||
return 1
|
||||
fi
|
||||
echo "== Reusing pywhispercpp Vulkan build (${cache_dir##*/}) =="
|
||||
if pywhispercpp_cache_restore "$cache_dir" "$site"; then
|
||||
vk_lib="$(find "$site" -name 'libggml-vulkan.so*' -print -quit 2>/dev/null || true)"
|
||||
if [ -n "$vk_lib" ]; then
|
||||
echo " found $vk_lib"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
echo "Cached Vulkan build could not be restored; compiling again." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# $1 cache dir, $2 site-packages, $3 command to run on a hit, then the compile
|
||||
# command. A hit does not run the compile command.
|
||||
pywhispercpp_restore_or_run() {
|
||||
local cache_dir="$1"
|
||||
local site="$2"
|
||||
local on_reuse="$3"
|
||||
shift 3
|
||||
if pywhispercpp_try_restore "$cache_dir" "$site"; then
|
||||
"$on_reuse"
|
||||
return $?
|
||||
fi
|
||||
if [ "$#" -eq 0 ]; then
|
||||
echo "No compile command given for the pywhispercpp Vulkan build." >&2
|
||||
return 1
|
||||
fi
|
||||
"$@"
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
# Pinned build inputs for packaging/appimage/build.sh.
|
||||
#
|
||||
# Everything the AppImage build downloads is pinned and verified here. Before
|
||||
# this file the build pulled linuxdeploy and appimagetool from their
|
||||
# `continuous` tags and the GTK plugin from `master`, so two builds of the same
|
||||
# commit could differ, and nothing would notice a replaced asset.
|
||||
#
|
||||
# Columns: name, kind, value, source — parseable by awk, like
|
||||
# src/vocalinux/utils/model_checksums.txt.
|
||||
#
|
||||
# sha256 the file downloaded from <source> must hash to <value>
|
||||
# git clone <source>, check out commit <value> (a commit is its own digest)
|
||||
# docker build inside image <value>; <source> records the tag it came from
|
||||
# version handed to uv, which pins and verifies the download itself
|
||||
#
|
||||
# To bump one: change the version in its <source> URL, download it, and replace
|
||||
# <value> with `sha256sum` of what you got. The base image digest comes from
|
||||
# `docker buildx imagetools inspect ubuntu:22.04` (use the index digest, not a
|
||||
# per-architecture one — the same line has to work on x86_64 and aarch64).
|
||||
#
|
||||
# The base image is old on purpose: the AppImage inherits the glibc of whatever
|
||||
# built it, and Ubuntu 22.04's 2.35 is below Debian 12, Fedora, Arch and
|
||||
# Tumbleweed. Raising it silently drops distros. See docs/INSTALL.md.
|
||||
|
||||
base-image docker docker.io/library/ubuntu@sha256:2edbbc5dc405e9612ba3584ce95480277e3eb374407b5505fe26f17df77c7dbc ubuntu:22.04
|
||||
cpython version 3.12.14 python-build-standalone, installed by uv
|
||||
|
||||
uv-x86_64 sha256 68a509da24b06b4223a1c0175fb5eb5bc79342b76cbeff0cfe51ac3f5b17b6b2 https://github.com/astral-sh/uv/releases/download/0.12.5/uv-x86_64-unknown-linux-gnu.tar.gz
|
||||
uv-aarch64 sha256 9bf43b4d1a07665bf64d4c4e710930b382321a785e0eb10aac07f46471f86a31 https://github.com/astral-sh/uv/releases/download/0.12.5/uv-aarch64-unknown-linux-gnu.tar.gz
|
||||
|
||||
linuxdeploy-x86_64 sha256 c20cd71e3a4e3b80c3483cef793cda3f4e990aca14014d23c544ca3ce1270b4d https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20251107-1/linuxdeploy-x86_64.AppImage
|
||||
linuxdeploy-aarch64 sha256 620095110d693282b8ebeb244a95b5e911cf8f65f76c88b4b47d16ae6346fcff https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20251107-1/linuxdeploy-aarch64.AppImage
|
||||
appimagetool-x86_64 sha256 ed4ce84f0d9caff66f50bcca6ff6f35aae54ce8135408b3fa33abfc3cb384eb0 https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-x86_64.AppImage
|
||||
appimagetool-aarch64 sha256 f0837e7448a0c1e4e650a93bb3e85802546e60654ef287576f46c71c126a9158 https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-aarch64.AppImage
|
||||
linuxdeploy-plugin-gtk sha256 b0f4cbc684a0103a9651f0955b635eaea0096b3a66c0f5a2c2aa337960375171 https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/7a3fbc31a9e5075073ff8790f26effbac5f84453/linuxdeploy-plugin-gtk.sh
|
||||
|
||||
# ggml compiles its Vulkan shaders with glslc, which Ubuntu 22.04 does not
|
||||
# package at all (24.04 does). Built from source when the build host has none;
|
||||
# see ensure_glslc in build.sh.
|
||||
shaderc git 2c8cae778eec0283b44acbe7ed1a386865d78799 https://github.com/google/shaderc.git
|
||||
|
||||
# The base image's Vulkan headers are 1.3.204, from February 2022. ggml wants
|
||||
# VK_KHR_cooperative_matrix, VK_KHR_shader_bfloat16 and VK_NV_cooperative_matrix2,
|
||||
# so it does not compile against them. Headers decide only what the build sees:
|
||||
# at run time the AppImage uses the host's loader and driver, and that ABI is
|
||||
# stable. Tag vulkan-sdk-1.4.357.0.
|
||||
vulkan-headers git e3b1eec08173d6b825cd3ac88c885a63b621504a https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
@@ -0,0 +1,230 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build a prepared, checksum-pinned AUR source package on current Arch.
|
||||
#
|
||||
# Usage (first prepare build/aur-source with scripts/prepare_aur_source.py):
|
||||
# docker run --rm -v "$PWD:/repo:ro" archlinux:latest \
|
||||
# bash /repo/packaging/aur/build-test.sh
|
||||
# or: just aur-gate
|
||||
#
|
||||
# This is the gate #757 needed: Arch extra moved to setuptools 84 while
|
||||
# build-system.requires still capped it below 82, so the PKGBUILD's
|
||||
# --no-isolation build broke for AUR users — and nothing ever ran makepkg on
|
||||
# the PKGBUILD before a tag published it.
|
||||
# Both PR and release gates consume the canonical sdist and fully prepared
|
||||
# PKGBUILD without rewriting source=, versions or checksums. PR fixtures are
|
||||
# explicitly unattested; the release job verifies published bytes and provenance
|
||||
# before running this gate. AUR_SOURCE_ONLY=1 leaves the existing -bin smoke out;
|
||||
# AUR_FETCH_SOURCE=1 makes makepkg download the real published source URL afresh.
|
||||
#
|
||||
# Not this gate's, despite reaching Arch users: #736 came through install.sh,
|
||||
# not through this package. The AUR build of v0.16.0 was intact, because the
|
||||
# tree it built carried neither model_checksums.txt nor the code reading it.
|
||||
# Closing that one takes a build gate for install.sh, not for this package.
|
||||
#
|
||||
# Deliberately archlinux:latest, unpinned: the AUR is a rolling channel and
|
||||
# #757 was Arch moving under us. A pinned image would test a world that no
|
||||
# longer exists.
|
||||
#
|
||||
# Two depends cannot come from the repos: python-pywhispercpp is a virtual
|
||||
# name that the AUR -cpu/-cuda/-rocm backends provide (#579), and
|
||||
# python-pynput lives in the AUR itself. A stub package with provides=()
|
||||
# satisfies them so makepkg verifies the full depends set; for the import
|
||||
# smoke they are pip-installed from the hash-pinned requirements/runtime.txt,
|
||||
# so the smoke runs the versions we pin, not whatever AUR ships — that drift
|
||||
# (AUR -cpu is still 1.4.x) is a monitoring job, not this gate.
|
||||
#
|
||||
# What the smoke therefore does NOT prove: that depends=() is complete. This
|
||||
# container carries base-devel and python-pip with their own closures, and the
|
||||
# two names above arrive via pip --no-deps, so a missing *direct* dependency
|
||||
# still passes. Transitive ones are the provider's to declare — the backend
|
||||
# providing python-pywhispercpp declares python-platformdirs itself.
|
||||
set -euo pipefail
|
||||
|
||||
REPO="${REPO:-/repo}"
|
||||
PKGDIR="${AUR_SOURCE:-$REPO/build/aur-source}"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Retry: a mirror going mid-transaction slow leaves half the cache and a
|
||||
# clean database, so re-running the same transaction resumes rather than
|
||||
# restarts.
|
||||
pacman_retry() {
|
||||
local attempt
|
||||
for attempt in 1 2 3; do
|
||||
pacman "$@" && return 0
|
||||
echo " pacman failed (attempt $attempt); retrying" >&2
|
||||
sleep 5
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
. /etc/os-release
|
||||
[ "$ID" = "arch" ] || fail "this gate runs on Arch Linux (got '$ID')"
|
||||
|
||||
[ -f "$PKGDIR/PKGBUILD" ] || fail "$PKGDIR/PKGBUILD not found"
|
||||
|
||||
# Upgrade before installing anything. archlinux:latest lags the mirrors, so
|
||||
# -Sy alone would put fresh packages on a stale base — the partial upgrade
|
||||
# Arch warns about, and a breakage this gate would be causing rather than
|
||||
# detecting. It is also what "Arch as it is today" has to mean here.
|
||||
pacman_retry -Syu --noconfirm >/dev/null
|
||||
|
||||
# Sourcing gives us pkgname, _tag and the depends/makedepends arrays the same
|
||||
# way makepkg itself reads them.
|
||||
# shellcheck source=/dev/null
|
||||
source "$PKGDIR/PKGBUILD"
|
||||
|
||||
echo "== Arch, $(date -u +%F) =="
|
||||
echo " building ${pkgname} ${pkgver}-${pkgrel} (tagged _tag=${_tag})"
|
||||
pacman -Q python python-setuptools 2>/dev/null || true
|
||||
|
||||
echo "== Install depends and makedepends from the repos =="
|
||||
# AUR-resolved depends (see header): satisfied by the stub below, not pacman.
|
||||
AUR_RESOLVED="python-pywhispercpp python-pynput"
|
||||
repo_deps=()
|
||||
for dep in "${depends[@]}" "${makedepends[@]}"; do
|
||||
case " $AUR_RESOLVED " in
|
||||
*" $dep "*) ;;
|
||||
*) repo_deps+=("$dep") ;;
|
||||
esac
|
||||
done
|
||||
# --needed keeps this idempotent; an unknown name here is a gate failure in
|
||||
# its own right: it means the PKGBUILD depends on something Arch does not
|
||||
# package (how a python-pywhispercpp-cpu rename would go unnoticed again).
|
||||
# base-devel is the documented prerequisite for building any AUR package
|
||||
# (fakeroot, debugedit and friends); makepkg aborts without it.
|
||||
pacman_retry -S --needed --noconfirm --asdeps base-devel namcap python-pip curl \
|
||||
"${repo_deps[@]}" >/dev/null
|
||||
|
||||
WORKDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORKDIR"' EXIT
|
||||
|
||||
echo "== Satisfy the AUR-resolved depends for dependency resolution =="
|
||||
# makepkg verifies every depends entry against the local pacman database.
|
||||
# Without this stub it would fail on the two names no repo can provide.
|
||||
STUB="$WORKDIR/stub"
|
||||
mkdir -p "$STUB"
|
||||
cat >"$STUB/PKGBUILD" <<EOF
|
||||
pkgname=vocalinux-gate-stub
|
||||
pkgver=1
|
||||
pkgrel=1
|
||||
pkgdesc="Satisfies the AUR-resolved depends of the vocalinux build gate"
|
||||
arch=('any')
|
||||
provides=('python-pywhispercpp' 'python-pynput')
|
||||
EOF
|
||||
|
||||
echo "== Copy the prepared PKGBUILD and original sdist without rewriting =="
|
||||
BUILD="$WORKDIR/pkg"
|
||||
mkdir -p "$BUILD"
|
||||
# makepkg consumes the cached archive under the same filename as source= and
|
||||
# still verifies its real checksum. No SKIP or --skipchecksums for source builds.
|
||||
cp "$PKGDIR/PKGBUILD" "$BUILD/PKGBUILD"
|
||||
if [ "${AUR_FETCH_SOURCE:-0}" = 1 ]; then
|
||||
echo " release gate: makepkg must download the published source URL afresh"
|
||||
else
|
||||
cp "$PKGDIR/${pkgname}-${_version}.tar.gz" "$BUILD/"
|
||||
fi
|
||||
|
||||
# makepkg refuses to run as root; a build user is the container-standard fix.
|
||||
useradd -m builder
|
||||
chown -R builder "$WORKDIR"
|
||||
|
||||
(
|
||||
cd "$STUB"
|
||||
runuser -u builder -- makepkg -f --noconfirm >/dev/null
|
||||
pacman -U --noconfirm ./*.pkg.tar.* >/dev/null
|
||||
)
|
||||
|
||||
echo "== makepkg =="
|
||||
(
|
||||
cd "$BUILD"
|
||||
# No -s and no --nodeps: depends were installed above, the stub satisfies
|
||||
# the AUR-resolved two, so makepkg's own verification is part of the gate.
|
||||
runuser -u builder -- makepkg -f --noconfirm
|
||||
)
|
||||
|
||||
echo "== namcap =="
|
||||
check_namcap() {
|
||||
local target="$1" out
|
||||
out="$(namcap "$target" 2>&1 || true)"
|
||||
echo "$out" | sed 's/^/ /'
|
||||
if echo "$out" | grep -q ' E: '; then
|
||||
fail "namcap reports errors on $target"
|
||||
fi
|
||||
}
|
||||
check_namcap "$BUILD/PKGBUILD"
|
||||
check_namcap "$BUILD"/*.pkg.tar.*
|
||||
|
||||
echo "== Install the package and smoke it =="
|
||||
# The two AUR-resolved deps as importable modules, at the versions we pin.
|
||||
awk '/^(pywhispercpp|pynput)==/{p=1} p{print; if ($0 !~ /\\$/) p=0}' \
|
||||
"$REPO/requirements/runtime.txt" >"$WORKDIR/pinned.txt"
|
||||
pip install --no-deps --break-system-packages --require-hashes -r "$WORKDIR/pinned.txt" >/dev/null
|
||||
|
||||
pacman -U --noconfirm "$BUILD"/*.pkg.tar.* >/dev/null
|
||||
|
||||
# The console script proves the wheel's entry points landed; the imports walk
|
||||
# every depends entry the package declares (gi/Gtk/AppIndicator, IBus, cairo,
|
||||
# pyaudio, numpy, requests, tqdm, psutil, evdev, xlib, pynput).
|
||||
vocalinux --version
|
||||
python - "$_version" <<'PY' || fail "the installed package does not import or has the wrong version"
|
||||
import sys
|
||||
from importlib.metadata import version
|
||||
|
||||
assert version("vocalinux") == sys.argv[1], "installed distribution version differs from the sdist"
|
||||
|
||||
import vocalinux.main
|
||||
import vocalinux.ui.tray_indicator
|
||||
import vocalinux.speech_recognition.recognition_manager
|
||||
import vocalinux.speech_recognition.command_processor
|
||||
import vocalinux.text_injection.text_injector
|
||||
import vocalinux.text_injection.ibus_engine
|
||||
import vocalinux.ui.keyboard_backends
|
||||
import pywhispercpp.model
|
||||
|
||||
print(" main, tray, recognition, injection and keyboard backends import")
|
||||
PY
|
||||
|
||||
cmp -s "$PKGDIR/PKGBUILD" "$BUILD/PKGBUILD" || fail "the tested PKGBUILD was modified"
|
||||
cmp -s "$PKGDIR/${pkgname}-${_version}.tar.gz" "$BUILD/${pkgname}-${_version}.tar.gz" \
|
||||
|| fail "the tested source archive was modified"
|
||||
echo "PASS: the exact prepared source PKGBUILD builds and installs on current Arch"
|
||||
if [ "${AUR_SOURCE_ONLY:-0}" = 1 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "== Build vocalinux-bin against a stub AppImage =="
|
||||
# The -bin package's arch sources are the published release assets, which do
|
||||
# not exist for an untagged HEAD. A placeholder exercises the same package()
|
||||
# install path on this arch; the pinned sums still describe the real assets,
|
||||
# so this stage skips checksum verification — release.yml's updpkgsums keeps
|
||||
# the published PKGBUILD pinned to the actual files.
|
||||
BINPKGDIR="$REPO/packaging/aur/vocalinux-bin"
|
||||
[ -f "$BINPKGDIR/PKGBUILD" ] || fail "$BINPKGDIR/PKGBUILD not found"
|
||||
# shellcheck source=/dev/null
|
||||
source "$BINPKGDIR/PKGBUILD"
|
||||
echo " building ${pkgname} ${pkgver}-${pkgrel} (tagged _tag=${_tag})"
|
||||
|
||||
pacman_retry -S --needed --noconfirm --asdeps "${depends[@]}" >/dev/null
|
||||
|
||||
# WORKDIR was handed to `builder` before this stage, so create the bin
|
||||
# directory as that user — makepkg writes into it as `builder`.
|
||||
BINBUILD="$WORKDIR/binpkg"
|
||||
runuser -u builder -- mkdir -p "$BINBUILD"
|
||||
cp "$BINPKGDIR/PKGBUILD" "$BINPKGDIR/vocalinux.desktop" \
|
||||
"$BINPKGDIR/vocalinux.svg" "$BINPKGDIR/LICENSE" "$BINBUILD/"
|
||||
CARCH="$(uname -m)"
|
||||
printf 'aur gate stub\n' >"$BINBUILD/Vocalinux-${_tag}-${CARCH}.AppImage"
|
||||
|
||||
(
|
||||
cd "$BINBUILD"
|
||||
runuser -u builder -- makepkg -f --noconfirm --skipchecksums
|
||||
)
|
||||
|
||||
check_namcap "$BINPKGDIR/PKGBUILD"
|
||||
check_namcap "$BINBUILD"/*.pkg.tar.*
|
||||
|
||||
echo "PASS: both PKGBUILDs build on Arch (this commit, not the last tag)"
|
||||
@@ -0,0 +1,661 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
@@ -0,0 +1,61 @@
|
||||
# Maintainer: Jatin K Malik <jatinkrmalik@gmail.com>
|
||||
# Updated by .github/workflows/release.yml on v* tags. Setup: docs/AUR.md
|
||||
|
||||
pkgname=vocalinux-bin
|
||||
# AUR pkgver cannot contain hyphens (v0.14.0-beta -> 0.14.0beta).
|
||||
pkgver=0.17.0
|
||||
_tag=0.17.0
|
||||
pkgrel=1
|
||||
pkgdesc="Free, offline voice dictation for Linux (prebuilt AppImage)"
|
||||
arch=('x86_64' 'aarch64')
|
||||
url="https://github.com/VocaHQ/vocalinux"
|
||||
license=('AGPL-3.0-only')
|
||||
# fuse2: the type-2 AppImage runtime mounts its squashfs through FUSE.
|
||||
# Everything else it needs (CPython, GTK, the whisper.cpp Vulkan build) is
|
||||
# inside the bundle — that is the point of shipping the AppImage.
|
||||
depends=(
|
||||
'fuse2'
|
||||
'hicolor-icon-theme'
|
||||
# The bundled app spawns these host tools for keystroke injection; on X11
|
||||
# without active IBus it requires xdotool and on Wayland a host tool.
|
||||
'xdotool'
|
||||
'wtype'
|
||||
)
|
||||
optdepends=(
|
||||
'vulkan-icd-loader: GPU-accelerated whisper.cpp transcription'
|
||||
'ibus: IBus text injection (preferred on some layouts and compositors)'
|
||||
'xclip: X11 clipboard tools (copy/paste injection fallbacks)'
|
||||
'wl-clipboard: Wayland clipboard (wl-copy/wl-paste) injection fallbacks'
|
||||
'ydotool: uinput keystroke injection fallback'
|
||||
)
|
||||
provides=('vocalinux')
|
||||
conflicts=('vocalinux' 'vocalinux-git')
|
||||
# Stripping would rewrite the runtime header of a self-mounting ELF.
|
||||
options=('!strip')
|
||||
source=(
|
||||
'vocalinux.desktop'
|
||||
'vocalinux.svg'
|
||||
'LICENSE'
|
||||
)
|
||||
source_x86_64=("Vocalinux-${_tag}-x86_64.AppImage::https://github.com/VocaHQ/vocalinux/releases/download/v${_tag}/Vocalinux-${_tag}-x86_64.AppImage")
|
||||
source_aarch64=("Vocalinux-${_tag}-aarch64.AppImage::https://github.com/VocaHQ/vocalinux/releases/download/v${_tag}/Vocalinux-${_tag}-aarch64.AppImage")
|
||||
sha256sums=('837006a9c689146308eae8c57cba1cdcc06673a108e72f39231837c6f63ae487'
|
||||
'128b8939ffc00314a55d0600ab29c6a92dfb116138e088c59579a086616ec8ec'
|
||||
'8486a10c4393cee1c25392769ddd3b2d6c242d6ec7928e1414efff7dfb2f07ef')
|
||||
sha256sums_x86_64=('1a87408bf5bd8f9176c395a4da9ce28c68a1a7585bd67f125ff6037c4328909c')
|
||||
sha256sums_aarch64=('b256fe8577e2733a4da3ae4f9c2b9717f10017ad8328b832070ce04edc996a7d')
|
||||
|
||||
package() {
|
||||
install -Dm755 "Vocalinux-${_tag}-${CARCH}.AppImage" \
|
||||
"${pkgdir}/opt/${pkgname}/Vocalinux-${_tag}-${CARCH}.AppImage"
|
||||
|
||||
install -Dm644 vocalinux.desktop \
|
||||
"${pkgdir}/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 vocalinux.svg \
|
||||
"${pkgdir}/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||
|
||||
install -dm755 "${pkgdir}/usr/bin"
|
||||
ln -s "/opt/${pkgname}/Vocalinux-${_tag}-${CARCH}.AppImage" \
|
||||
"${pkgdir}/usr/bin/vocalinux"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Vocalinux
|
||||
Comment=Seamless voice dictation system for Linux
|
||||
GenericName=Voice Typing
|
||||
Exec=vocalinux
|
||||
Icon=vocalinux
|
||||
Terminal=false
|
||||
Categories=Utility;Accessibility;AudioVideo;
|
||||
Keywords=voice;typing;dictation;speech;recognition;transcription;accessibility;
|
||||
StartupNotify=true
|
||||
X-GNOME-UsesNotifications=true
|
||||
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 460 460" width="460" height="460" role="img" aria-label="Vocalinux">
|
||||
<circle cx="229" cy="231.5" r="221.5" fill="#0F6B57"/>
|
||||
<path d="M 164 127 A 65 65 0 0 1 294 127 L 294 224 A 65 65 0 0 1 164 224 Z" fill="#F2F6F2"/>
|
||||
<path d="M 144.87 202.02 A 87 87 0 1 0 312.13 202.02" fill="none" stroke="#F2F6F2" stroke-width="18" stroke-linecap="round"/>
|
||||
<path d="M 228.5 313 L 228.5 382" fill="none" stroke="#F2F6F2" stroke-width="18" stroke-linecap="round"/>
|
||||
<path d="M 170 382 L 287 382" fill="none" stroke="#F2F6F2" stroke-width="18" stroke-linecap="round"/>
|
||||
<path d="M 123.12 168.78 A 129.0 99.2 0 0 0 123.12 283.22" fill="none" stroke="#F2F6F2" stroke-width="18" stroke-linecap="round"/>
|
||||
<path d="M 333.88 168.78 A 129.0 99.2 0 0 1 333.88 283.22" fill="none" stroke="#F2F6F2" stroke-width="18" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 887 B |
@@ -0,0 +1,82 @@
|
||||
# Maintainer: Jatin K Malik <jatinkrmalik@gmail.com>
|
||||
# Updated by .github/workflows/release.yml on v* tags. Setup: docs/AUR.md
|
||||
|
||||
pkgname=vocalinux
|
||||
# AUR pkgver cannot contain hyphens (v0.14.0-beta -> 0.14.0beta).
|
||||
pkgver=0.18.4
|
||||
_tag=0.18.4
|
||||
# PEP 440-normalized sdist version may differ from a prerelease tag.
|
||||
_version=0.18.4
|
||||
pkgrel=1
|
||||
pkgdesc="Free, offline voice dictation for Linux"
|
||||
arch=('any')
|
||||
url="https://github.com/VocaHQ/vocalinux"
|
||||
license=('AGPL-3.0-only')
|
||||
depends=(
|
||||
'python>=3.11'
|
||||
'python-gobject'
|
||||
'gtk3'
|
||||
'libayatana-appindicator'
|
||||
'ibus'
|
||||
'gobject-introspection'
|
||||
'python-cairo'
|
||||
'python-pynput'
|
||||
'python-pywhispercpp'
|
||||
'python-pyaudio'
|
||||
'portaudio'
|
||||
'python-numpy'
|
||||
'python-requests'
|
||||
'python-pysocks'
|
||||
'python-tqdm'
|
||||
'python-psutil'
|
||||
'python-evdev'
|
||||
'python-xlib'
|
||||
'hicolor-icon-theme'
|
||||
)
|
||||
# --no-isolation uses distro python-setuptools (Arch extra is 84+).
|
||||
# pyproject.toml build-system.requires must accept that version.
|
||||
makedepends=(
|
||||
'python-build'
|
||||
'python-installer'
|
||||
'python-wheel'
|
||||
'python-setuptools'
|
||||
)
|
||||
optdepends=(
|
||||
'python-pywhispercpp-cpu: CPU-only whisper.cpp backend (default provider)'
|
||||
'python-pywhispercpp-cuda: NVIDIA GPU whisper.cpp backend'
|
||||
'python-pywhispercpp-rocm: AMD GPU whisper.cpp backend'
|
||||
'python-onnxruntime: Silero VAD'
|
||||
# One line per selectable engine. Without it the engine is offered in
|
||||
# Settings and fails at import, which is how vosk and whisper shipped too.
|
||||
'python-vosk: Vosk engine'
|
||||
'python-openai-whisper: OpenAI Whisper engine'
|
||||
'python-sherpa-onnx: Parakeet TDT 0.6B engine'
|
||||
'python-faster-whisper: faster-whisper engine'
|
||||
'xdotool: X11 injection fallback'
|
||||
'xclip: X11 clipboard tools (copy/paste injection fallbacks)'
|
||||
'wl-clipboard: Wayland clipboard (wl-copy/wl-paste) injection fallbacks'
|
||||
'wtype: Wayland keystroke injection fallback'
|
||||
'gtk-layer-shell: dictation overlay as a layer surface on KDE and wlroots Wayland'
|
||||
)
|
||||
conflicts=('vocalinux-git')
|
||||
source=("${pkgname}-${_version}.tar.gz::https://github.com/VocaHQ/vocalinux/releases/download/v${_tag}/${pkgname}-${_version}.tar.gz")
|
||||
# Canonical release sdist, also published on PyPI. prepare_aur_source.py verifies
|
||||
# its checksum/provenance before pinning the next version; publication never rehashes.
|
||||
sha256sums=('f14ae90e37b13b86c6aa2153ba5aa8a2aa62d65b93082344695f54807924e243')
|
||||
|
||||
build() {
|
||||
cd "${pkgname}-${_version}"
|
||||
python -m build --wheel --no-isolation
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${pkgname}-${_version}"
|
||||
python -m installer --destdir="${pkgdir}" dist/*.whl
|
||||
|
||||
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
|
||||
install -Dm644 vocalinux.desktop "${pkgdir}/usr/share/applications/vocalinux.desktop"
|
||||
|
||||
for icon in resources/icons/scalable/*.svg; do
|
||||
install -Dm644 "$icon" "${pkgdir}/usr/share/icons/hicolor/scalable/apps/$(basename "$icon")"
|
||||
done
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
# Vocalinux Flatpak Packaging
|
||||
|
||||
Manifest and AppStream metadata for building Vocalinux as a Flatpak.
|
||||
|
||||
## VocaHQ remote (auto-update)
|
||||
|
||||
The recommended install is the self-hosted VocaHQ OSTree remote — the
|
||||
Homebrew-tap analogue — which `release.yml` signs and publishes to
|
||||
`VocaHQ/vocalinux-flatpak` (GitHub Pages) on every stable `v*` tag:
|
||||
|
||||
```bash
|
||||
flatpak install https://vocahq.github.io/vocalinux-flatpak/com.vocalinux.Vocalinux.flatpakref
|
||||
flatpak update # each new release arrives here
|
||||
```
|
||||
|
||||
The `.flatpakref` adds the `vocahq` remote and resolves the GNOME runtime
|
||||
through Flathub via `RuntimeRepo=` — the manual equivalent is `remote-add`
|
||||
for `flathub` then `vocahq`, then `flatpak install vocahq
|
||||
com.vocalinux.Vocalinux`. Only the app is ours; `org.gnome.Platform//50`
|
||||
still comes from Flathub. One-time repo/key setup:
|
||||
[docs/FLATPAK_REMOTE.md](../../docs/FLATPAK_REMOTE.md).
|
||||
|
||||
## GitHub Release bundles
|
||||
|
||||
Each `v*` GitHub Release attaches `Vocalinux-<version>-x86_64.flatpak` and
|
||||
`Vocalinux-<version>-aarch64.flatpak` as a no-remote fallback:
|
||||
|
||||
```bash
|
||||
# once: Flathub remote + GNOME runtime (the app itself is not on Flathub)
|
||||
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install flathub org.gnome.Platform//50
|
||||
|
||||
flatpak install --user ./Vocalinux-<version>-x86_64.flatpak
|
||||
flatpak run com.vocalinux.Vocalinux
|
||||
```
|
||||
|
||||
Bundles do **not** auto-update — the VocaHQ remote above is the path for
|
||||
that. Vocalinux is **not on Flathub** (submission
|
||||
[flathub/flathub#9368](https://github.com/flathub/flathub/pull/9368) closed on
|
||||
policy grounds; we are not re-submitting). Local `flatpak-builder` remains for
|
||||
contributors (below).
|
||||
|
||||
## Current Scope
|
||||
|
||||
The manifest ships the default `whisper_cpp` engine and Silero VAD
|
||||
(`onnxruntime`). VOSK is omitted because the PyPI package is wheel-only (no
|
||||
sdist), so a Flathub-ready VOSK build would need to compile VOSK and its native
|
||||
deps from source.
|
||||
|
||||
Global keyboard shortcuts use **evdev** (`/dev/input`) on Wayland and
|
||||
XWayland. On native X11, they use the X11 **pynput** listener through
|
||||
`--socket=x11`. GNOME X11 prefers evdev and falls back to pynput when
|
||||
`/dev/input` cannot be read.
|
||||
Text injection prefers the **RemoteDesktop portal**
|
||||
(`org.freedesktop.portal.RemoteDesktop` `NotifyKeyboardKeysym` sends keysyms,
|
||||
so non-US layouts work) and falls back to **wl-copy** + **ydotool Ctrl+V**
|
||||
(instant paste into native Wayland apps) when the portal is unavailable.
|
||||
Character-by-character `ydotool type` is only a fallback. `xdotool` remains
|
||||
for pure X11/XWayland clients.
|
||||
|
||||
Permissions: `--socket=wayland` (clipboard), `--socket=x11` (xdotool fallback),
|
||||
`--device=all` (evdev hotkeys + uinput for the ydotool fallback; Flatpak has
|
||||
no narrower uinput flag).
|
||||
|
||||
## Running without device access
|
||||
|
||||
To disable device access while keeping GPU support for Vulkan whisper.cpp, run:
|
||||
|
||||
```bash
|
||||
flatpak override --user --nodevice=all --device=dri com.vocalinux.Vocalinux
|
||||
```
|
||||
|
||||
On native X11, hotkeys still work through the X11 listener, except on GNOME X11,
|
||||
where mutter never passes physical keys to that listener (#954), so it needs
|
||||
`/dev/input` like Wayland. On Wayland, the built-in hotkey needs `/dev/input`: grant `--device=input` on Flatpak 1.15.6 or
|
||||
newer, or `--device=all` on older versions. If `/dev/input` is unavailable,
|
||||
enable **Settings → Shortcuts → External Activation (Desktop Shortcut)** and
|
||||
bind a desktop shortcut to:
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest com.vocalinux.Vocalinux --object-path /com/vocalinux/Vocalinux --method com.vocalinux.Vocalinux.Toggle
|
||||
```
|
||||
|
||||
Use toggle mode for this shortcut. A desktop shortcut only sends a key press,
|
||||
so it cannot support push-to-talk. Running
|
||||
`flatpak run com.vocalinux.Vocalinux --toggle` also works, but starts a sandbox
|
||||
on each press. The host `gdbus` command is immediate and does not start another
|
||||
sandbox.
|
||||
|
||||
Without `/dev/uinput`, the ydotool injection fallback is unavailable. The
|
||||
RemoteDesktop portal and xdotool fallbacks remain available.
|
||||
|
||||
## Local Build
|
||||
|
||||
```bash
|
||||
# one-time runtime/SDK
|
||||
flatpak install flathub org.gnome.Platform//50 org.gnome.Sdk//50
|
||||
|
||||
# from repo root — add flags as needed:
|
||||
# --user --install install for the current user
|
||||
# --repo=repo export a local repo (then bundle or lint)
|
||||
# --compose-url-policy=full --mirror-screenshots-url=https://dl.flathub.org/media
|
||||
flatpak-builder --force-clean build-dir packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
|
||||
flatpak run com.vocalinux.Vocalinux --debug
|
||||
|
||||
# single-file bundle (after a --repo=repo build)
|
||||
flatpak build-bundle repo vocalinux.flatpak com.vocalinux.Vocalinux
|
||||
# elsewhere: flatpak install --user vocalinux.flatpak
|
||||
```
|
||||
|
||||
Lint (needs `org.flatpak.Builder`):
|
||||
|
||||
```bash
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder manifest packaging/flatpak/com.vocalinux.Vocalinux.yml
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder builddir build-dir
|
||||
flatpak run --command=flatpak-builder-lint org.flatpak.Builder repo repo # if you used --repo=repo
|
||||
```
|
||||
|
||||
Prefer `flatpak run` after `--install` for GUI testing. On GNOME runtimes with
|
||||
glycin loaders, `flatpak-builder --run` can fail to load themed SVG icons for an
|
||||
uninstalled stable app ID; it is still fine for non-GUI smokes:
|
||||
|
||||
```bash
|
||||
flatpak-builder --run build-dir packaging/flatpak/com.vocalinux.Vocalinux.yml \
|
||||
python3 -c 'from pywhispercpp.model import Model; print("pywhispercpp ok")'
|
||||
```
|
||||
|
||||
## Python Dependencies
|
||||
|
||||
`python3-dependencies.yaml` is generated from `requirements/vad.txt`, the
|
||||
hash-pinned export `just lock` writes out of `uv.lock`. This includes the
|
||||
runtime dependencies plus the `[vad]` extra. Refresh it whenever the dependency
|
||||
set changes:
|
||||
|
||||
```bash
|
||||
just flatpak-deps # rewrite the manifest (needs PyPI)
|
||||
just flatpak-deps-check # report drift, change nothing
|
||||
```
|
||||
|
||||
`just lock` runs the first of those itself, so a normal dependency change needs
|
||||
no extra step.
|
||||
|
||||
The script resolves each package's URL by looking up the digest uv already
|
||||
recorded, so the bytes this build downloads are the bytes in `uv.lock`, not
|
||||
merely the same version number. It takes a universal wheel where one exists and
|
||||
the sdist otherwise. `onnxruntime` has no sdist, so its CPython-ABI wheel is
|
||||
pinned to GNOME 50's Python version and selected separately for each Flatpak
|
||||
architecture.
|
||||
|
||||
This replaced a `flatpak-pip-generator` invocation whose package list was typed
|
||||
out on the command line. Nothing regenerated it and no test compared it to
|
||||
anything, so it drifted: by 2026-09-10 ten of its fifteen shared packages were
|
||||
behind the lock, `pydub` and `lxml` were still built four months after #705
|
||||
deleted them for having no imports, and pywhispercpp sat at 1.4.1 under the
|
||||
project's own `>=1.5.0`. The project is installed here with
|
||||
`pip3 install --no-deps`, so nothing inside the build could notice.
|
||||
`tests/test_flatpak_packaging.py` is what notices now, and it runs offline.
|
||||
|
||||
Two things in that file are hand-written and the script preserves them, because
|
||||
no generator produces them: pywhispercpp's Vulkan build, which injects a version
|
||||
into `setup.py` (the sdist ships no `version.txt`, `setup()` takes no `version=`
|
||||
argument, and setuptools-scm has no git tree to read in the sandbox), and the
|
||||
symlinking of whisper.cpp's shared libraries onto the loader path.
|
||||
|
||||
`python3-build-dependencies.yaml` is a small hand-maintained helper so
|
||||
`--no-build-isolation` builds can import `mesonpy` before NumPy is built.
|
||||
|
||||
## Channel: VocaHQ remote + GitHub Releases, not Flathub
|
||||
|
||||
Flathub is **not pursued**. The submission,
|
||||
[flathub/flathub#9368](https://github.com/flathub/flathub/pull/9368), was closed
|
||||
on 2026-07-23 on policy grounds. See
|
||||
[#167](https://github.com/VocaHQ/vocalinux/issues/167) for the channel decision,
|
||||
[#784](https://github.com/VocaHQ/vocalinux/issues/784) for release bundles, and
|
||||
[#785](https://github.com/VocaHQ/vocalinux/issues/785) for the self-hosted
|
||||
remote. Do not re-submit. The `vocahq` remote, local builds, and GitHub
|
||||
Release `.flatpak` assets are the supported paths.
|
||||
|
||||
## Manifest Details
|
||||
|
||||
- Runtime / SDK: `org.gnome.Platform//50`, `org.gnome.Sdk//50`
|
||||
- Mic: `--socket=pulseaudio` · GPU: `--device=dri` · models: `--share=network`
|
||||
- Input: `--device=all` for evdev hotkeys on Wayland/XWayland and the ydotool/`uinput` fallback; native X11 hotkeys use pynput through `--socket=x11`
|
||||
- Injection: RemoteDesktop portal first; packaged `wl-copy`, `ydotool`/`ydotoold`, plus `xdotool`/`xsel` fallback
|
||||
- Display: `--socket=wayland` (clipboard) and `--socket=x11` (xdotool fallback)
|
||||
- IBus: `--talk-name=org.freedesktop.IBus`
|
||||
- Tray: `--talk-name=org.kde.StatusNotifierWatcher`
|
||||
|
||||
Config and models use Flatpak XDG dirs under `~/.var/app/com.vocalinux.Vocalinux/`.
|
||||
@@ -0,0 +1,14 @@
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Vocalinux
|
||||
Comment=Free, offline voice dictation for Linux
|
||||
GenericName=Voice Typing
|
||||
Exec=vocalinux
|
||||
Icon=com.vocalinux.Vocalinux
|
||||
Terminal=false
|
||||
Categories=Utility;Accessibility;AudioVideo;
|
||||
Keywords=voice;typing;dictation;speech;recognition;transcription;accessibility;
|
||||
StartupNotify=true
|
||||
StartupWMClass=com.vocalinux.Vocalinux
|
||||
X-GNOME-UsesNotifications=true
|
||||
@@ -0,0 +1,194 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>com.vocalinux.Vocalinux</id>
|
||||
|
||||
<name>Vocalinux</name>
|
||||
<summary>Free, offline voice dictation for Linux</summary>
|
||||
<developer id="com.vocalinux">
|
||||
<name>Jatin K Malik</name>
|
||||
</developer>
|
||||
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>AGPL-3.0-only</project_license>
|
||||
|
||||
<description>
|
||||
<p>
|
||||
Vocalinux is a privacy-first, fully offline voice dictation system for Linux.
|
||||
Speak naturally and your words appear in any application — on X11 or Wayland —
|
||||
using local speech recognition. No cloud, no data leaves your machine.
|
||||
Speech recognition models are downloaded on first run.
|
||||
</p>
|
||||
<p>Features:</p>
|
||||
<ul>
|
||||
<li>Toggle or push-to-talk activation modes</li>
|
||||
<li>Real-time transcription with minimal latency</li>
|
||||
<li>Universal compatibility across all Linux applications</li>
|
||||
<li>100% offline operation for privacy and reliability</li>
|
||||
<li>whisper.cpp by default — high-performance C++ speech recognition</li>
|
||||
<li>Universal GPU support via Vulkan (AMD, Intel, NVIDIA)</li>
|
||||
<li>System tray integration with visual status indicators</li>
|
||||
<li>Start on login support via XDG autostart</li>
|
||||
<li>Pleasant audio feedback with smooth gliding tones</li>
|
||||
<li>Graphical settings dialog for easy configuration</li>
|
||||
</ul>
|
||||
<p>
|
||||
This Flatpak ships the whisper.cpp engine. On a Wayland session, text is
|
||||
injected through XWayland.
|
||||
</p>
|
||||
</description>
|
||||
|
||||
<launchable type="desktop-id">com.vocalinux.Vocalinux.desktop</launchable>
|
||||
|
||||
<categories>
|
||||
<category>Utility</category>
|
||||
<category>Accessibility</category>
|
||||
<category>AudioVideo</category>
|
||||
</categories>
|
||||
|
||||
<keywords>
|
||||
<keyword>voice</keyword>
|
||||
<keyword>typing</keyword>
|
||||
<keyword>dictation</keyword>
|
||||
<keyword>speech</keyword>
|
||||
<keyword>recognition</keyword>
|
||||
<keyword>transcription</keyword>
|
||||
<keyword>accessibility</keyword>
|
||||
</keywords>
|
||||
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Real-time voice-to-text transcription</caption>
|
||||
<image>https://vocalinux.com/screenshots/00-transcription.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Speech engine settings</caption>
|
||||
<image>https://vocalinux.com/screenshots/settings-speech-engine.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>System tray indicator</caption>
|
||||
<image>https://vocalinux.com/screenshots/02-system-tray.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<url type="homepage">https://vocalinux.com</url>
|
||||
<url type="bugtracker">https://github.com/VocaHQ/vocalinux/issues</url>
|
||||
<url type="vcs-browser">https://github.com/VocaHQ/vocalinux</url>
|
||||
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="violence-cartoon">none</content_attribute>
|
||||
<content_attribute id="violence-fantasy">none</content_attribute>
|
||||
<content_attribute id="violence-realistic">none</content_attribute>
|
||||
<content_attribute id="violence-bloodshed">none</content_attribute>
|
||||
<content_attribute id="violence-sexual">none</content_attribute>
|
||||
<content_attribute id="violence-desecration">none</content_attribute>
|
||||
<content_attribute id="violence-slavery">none</content_attribute>
|
||||
<content_attribute id="violence-worship">none</content_attribute>
|
||||
<content_attribute id="drugs-alcohol">none</content_attribute>
|
||||
<content_attribute id="drugs-narcotics">none</content_attribute>
|
||||
<content_attribute id="drugs-tobacco">none</content_attribute>
|
||||
<content_attribute id="sex-nudity">none</content_attribute>
|
||||
<content_attribute id="sex-themes">none</content_attribute>
|
||||
<content_attribute id="sex-homosexuality">none</content_attribute>
|
||||
<content_attribute id="sex-prostitution">none</content_attribute>
|
||||
<content_attribute id="sex-adultery">none</content_attribute>
|
||||
<content_attribute id="sex-appearance">none</content_attribute>
|
||||
<content_attribute id="language-profanity">none</content_attribute>
|
||||
<content_attribute id="language-humor">none</content_attribute>
|
||||
<content_attribute id="language-discrimination">none</content_attribute>
|
||||
<content_attribute id="social-chat">none</content_attribute>
|
||||
<content_attribute id="social-info">none</content_attribute>
|
||||
<content_attribute id="social-audio">none</content_attribute>
|
||||
<content_attribute id="social-location">none</content_attribute>
|
||||
<content_attribute id="social-contacts">none</content_attribute>
|
||||
<content_attribute id="money-purchasing">none</content_attribute>
|
||||
<content_attribute id="money-gambling">none</content_attribute>
|
||||
</content_rating>
|
||||
|
||||
<releases>
|
||||
<release version="0.18.5" date="2026-10-27">
|
||||
<description>
|
||||
<p>Patch: a stop that races a recording start can no longer leave the microphone recording forever, capture reads happen outside the buffer lock so a stalled microphone can no longer hang Stop, keyboards stay alive through suspend and the GNOME lock screen, Dictation Pad and Settings no longer bind to other windows on Wayland, Ctrl+mouse-wheel zoom works again, the installer gains an upgrade mode that keeps your existing configuration, and paste-injection copies are marked sensitive for clipboard history on wl-clipboard 2.2+. This Flatpak still ships whisper.cpp only.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.18.4" date="2026-10-21">
|
||||
<description>
|
||||
<p>Patch: long push-to-talk dictations are transcribed in segments instead of being cut off, model downloads only start after you confirm them and Cancel cancels the whole change, Test Dictation keeps its own result while the Dictation Pad is open, the GPU picker follows ggml's device list and CPU runs use most of your cores, the recording hotkey can cancel a transcription in progress, this Flatpak bundles onnxruntime for Silero VAD and uses the X11 hotkey listener on X11 sessions, RemoteDesktop portal requests no longer collide on GNOME, update checks can be turned off, and Slovenian is supported. This Flatpak still ships whisper.cpp only.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.18.3" date="2026-10-17">
|
||||
<description>
|
||||
<p>Patch: "new line" and "new paragraph" voice commands insert real line breaks standalone and mid-utterance, hotkeys work again on GNOME Shell X11 and quitting no longer collapses multi-layout keyboard maps, the bundled pywhispercpp builds at the portable x86-64 baseline so older CPUs stop crashing, and the Snap recipe drops the `uinput` plug the Store denied so revisions publish again. This Flatpak still ships whisper.cpp only.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.18.2" date="2026-10-12">
|
||||
<description>
|
||||
<p>Patch: the dictation overlay orb pulses and ripples with live microphone level, Nix gets a flake package with NixOS and Home Manager modules plus Vulkan GPU inference, keyboards with a held key or queued key events are left ungrabbed at startup so typing during launch cannot strand a key, bundled pywhispercpp drops -march=native so AppImage and Flatpak stop crashing on older CPUs, and the piped installer prompts via /dev/tty. This Flatpak still ships whisper.cpp only.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.18.1" date="2026-10-08">
|
||||
<description>
|
||||
<p>Patch: Settings Proxy page for model downloads and update checks behind SOCKS5/HTTP proxies, opt-in JSONL transcript persistence so a failed injection no longer loses the text, .deb and .rpm release packages for Debian and Fedora, and a slimmer tray menu with Start on Login and About living in Settings. Dictation pad windows no longer ghost away under Wayland compositors, keyboard discovery stops grabbing mice, touchpads, and power buttons, KDE Plasma 6 Wayland letter case is fixed, and the Speech Model picker stages changes until Download is confirmed instead of starting a fetch per click. This Flatpak still ships whisper.cpp only.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.18.0" date="2026-10-02">
|
||||
<description>
|
||||
<p>Minor: in-app Dictation Pad for Wayland-safe dictation, per-language dictation shortcuts, tray dictation history, file transcription with speaker labels, opt-in D-Bus activation for compositor global shortcuts, custom dictionary with corrections, postprocessing script hook, floating dictation overlay, audio ducking while dictating, and the dictation hotkey grabbed so it stops leaking into the focused app. PipeWire/system-audio capture and the RemoteDesktop portal injection backend are native-install paths; this Flatpak still ships whisper.cpp only.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.17.0" date="2026-09-16">
|
||||
<description>
|
||||
<p>Minor: Faster Whisper and Parakeet local engines, Speech Model simple setup, first-run system language, searchable open language picker, localized punctuation commands, bare function-key push-to-talk, Snap packaging with ydotool/uinput, Flatpak bundles attached by the release workflow, and XWayland/layout paste plus settings/audio fixes (HDA analog mics at native layout, native GTK OS dark/light, English-only models no longer trap other languages). This Flatpak still ships whisper.cpp only.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.16.2" date="2026-09-05">
|
||||
<description>
|
||||
<p>Stability patch: skip leftover IBus on KDE so dictation types into real apps, Wayland/IBus shortcuts via wtype and ydotool, real BackSpace for "delete that", Fedora/Arch installer glslc (not glslang), nightly version stamp before build, release integrity checksums and pinned builders, AUR PKGBUILD CI gate, distro CI plus docs drift fixes, and VocaGateway Beta on the site.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.16.1" date="2026-08-30">
|
||||
<description>
|
||||
<p>Stability patch: per-engine model size at startup, save the model only after it loaded, leftover-download list shows every row, one ConfigManager so Settings writes stick, tray stays idle after leftover transcription and can download the recommended model from the missing-model notification, Ctrl+Shift+V paste in terminals, GNOME XWayland layout after scoped IBus inject, Python 3.11 installer floor with verified model downloads, AppImage glibc that boots on Debian 12, AUR build against Arch extra setuptools 84, skip context_params on AUR pywhispercpp 1.4, and Settings/About layout polish.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.16.0" date="2026-08-23">
|
||||
<description>
|
||||
<p>In-app update checker with tray notifications, hold Right Alt push-to-talk default for new installs, searchable language list, delete unused downloaded speech models, family dictation tone picker (default Voca, family preview WAVs), Settings About page for this app, VocaHQ, and talk to us, AGPL-3.0 relicensing, shared Voca family mic for app/tray/site icons, hardened installer with Justfile and uv lockfiles (distro python3-gi required), Test Dictation missing-model message, and desktop reliability fixes for IBus, audio capture, clipboard restore, GPU/Vulkan selection, and AppImage GI typelibs.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.15.0" date="2026-07-28">
|
||||
<description>
|
||||
<p>Searchable sidebar settings with dictation controls in the sidebar footer, AppImage packages for x86_64 and aarch64, expanded speech-language catalog (including Hungarian), sentence capitalization and trailing spaces for continuous dictation, auto-pause and idle model unload, Vulkan discrete-GPU selection, ibus-wayland support on previously unbridged compositors, Bluetooth mic capture crash fix, custom-shortcut Record/Set restore, and desktop reliability fixes.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.14.2" date="2026-07-17">
|
||||
<description>
|
||||
<p>IBus stability (engine process launch after XDG path import; first-dictation FocusIn gate on GNOME Wayland) and settings dialog tabs that scroll so the window fits the monitor.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.14.1" date="2026-07-16">
|
||||
<description>
|
||||
<p>First Flathub-oriented packaging release: Flatpak with whisper.cpp + Vulkan, wl-copy/ydotool Wayland paste, evdev global hotkeys, AUR package, layout-aware shortcuts, and installer fixes.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.14.0-beta" date="2026-07-14">
|
||||
<description>
|
||||
<p>Vocalinux 0.14.0-beta as Flatpak: whisper.cpp with Vulkan, XDG config/models/logs, XWayland text injection, and system tray integration.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.12.0-beta" date="2026-06-07">
|
||||
<description>
|
||||
<p>First Flatpak release: whisper.cpp engine with Vulkan GPU support, XDG-compliant data paths, and XWayland text injection.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.11.0-beta" date="2026-05-30">
|
||||
<description>
|
||||
<p>Guided whisper.cpp model variants, hotplug keyboard rescanning, and IBus setup refinements.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="0.10.2-beta" date="2026-04-08">
|
||||
<description>
|
||||
<p>Non-ASCII text injection, IBus Wayland detection fixes, Pop!_OS dependency support, and code quality improvements.</p>
|
||||
</description>
|
||||
</release>
|
||||
</releases>
|
||||
</component>
|
||||
@@ -0,0 +1,139 @@
|
||||
app-id: com.vocalinux.Vocalinux
|
||||
branch: stable
|
||||
runtime: org.gnome.Platform
|
||||
runtime-version: "50"
|
||||
sdk: org.gnome.Sdk
|
||||
command: vocalinux
|
||||
|
||||
build-options:
|
||||
env:
|
||||
NO_REPAIR: "1"
|
||||
PYWHISPERCPP_VERSION: "1.5.0"
|
||||
|
||||
finish-args:
|
||||
# Download speech-recognition models on first run.
|
||||
- --share=network
|
||||
# Shared memory for X11 / XWayland.
|
||||
- --share=ipc
|
||||
# X11 for xdotool fallback; Wayland for wl-copy (instant paste into native apps).
|
||||
# Injection prefers the RemoteDesktop portal (DBus, keysyms) and falls back
|
||||
# to ydotool/uinput -- not the Wayland virtual-keyboard protocol.
|
||||
- --socket=x11
|
||||
- --socket=wayland
|
||||
# Microphone capture (works against PulseAudio and PipeWire-pulse).
|
||||
- --socket=pulseaudio
|
||||
# GPU render node for the Vulkan-accelerated whisper.cpp build.
|
||||
- --device=dri
|
||||
# /dev/input for evdev hotkeys on Wayland/XWayland and /dev/uinput for ydotool
|
||||
# injection fallback (Ctrl+V / type) when the RemoteDesktop portal is
|
||||
# unavailable. Flatpak has no narrower flag than "all" for uinput.
|
||||
- --device=all
|
||||
# IBus Unicode injection backend.
|
||||
- --talk-name=org.freedesktop.IBus
|
||||
# Desktop notifications.
|
||||
- --talk-name=org.freedesktop.Notifications
|
||||
# System tray / status-notifier icon.
|
||||
- --talk-name=org.kde.StatusNotifierWatcher
|
||||
- --talk-name=org.gnome.Shell
|
||||
# Find the bundled AppIndicator typelib under /app (searched before the runtime).
|
||||
- --env=GI_TYPELIB_PATH=/app/lib/girepository-1.0
|
||||
|
||||
modules:
|
||||
- name: portaudio
|
||||
buildsystem: cmake-ninja
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
- -DCMAKE_INSTALL_PREFIX=/app
|
||||
- -DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
cleanup:
|
||||
- /include
|
||||
- /lib/cmake
|
||||
- /lib/pkgconfig
|
||||
- "*.a"
|
||||
- "*.la"
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/PortAudio/portaudio/archive/refs/tags/v19.7.0.tar.gz
|
||||
sha256: 5af29ba58bbdbb7bbcefaaecc77ec8fc413f0db6f4c4e286c40c3e1b83174fa0
|
||||
|
||||
- shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json
|
||||
- name: xsel
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- autoreconf -fi
|
||||
- ./configure --prefix=/app
|
||||
- make
|
||||
- make install
|
||||
cleanup:
|
||||
- /share/man
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/kfish/xsel/archive/refs/tags/1.2.1.tar.gz
|
||||
sha256: 18487761f5ca626a036d65ef2db8ad9923bf61685e06e7533676c56d7d60eb14
|
||||
|
||||
- name: xdotool
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- make
|
||||
- make install PREFIX=/app
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/jordansissel/xdotool/archive/refs/tags/v3.20211022.1.tar.gz
|
||||
sha256: 82b15a944a5e82fee15e0f6116bd9f642bc3d0bb6989fc0ca5ad9dfe35de0847
|
||||
|
||||
# Wayland clipboard for bulk paste (wl-copy + ydotool Ctrl+V).
|
||||
- name: wl-clipboard
|
||||
buildsystem: meson
|
||||
config-opts:
|
||||
- -Dfishcompletiondir=no
|
||||
- -Dzshcompletiondir=no
|
||||
cleanup:
|
||||
- /share/man
|
||||
- /share/bash-completion
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/bugaevc/wl-clipboard/archive/refs/tags/v2.2.1.tar.gz
|
||||
sha256: 6eb8081207fb5581d1d82c4bcd9587205a31a3d47bea3ebeb7f41aa1143783eb
|
||||
|
||||
# uinput-based typing / paste chords for native Wayland clients.
|
||||
# Pinned to v1.0.4 (keycode:value key API). Distro 0.1.x uses "ctrl+v" instead;
|
||||
# vocalinux detects the installed CLI at runtime (see TextInjector).
|
||||
- name: ydotool
|
||||
buildsystem: cmake-ninja
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
# CMake 4.x in GNOME SDK rejects projects declaring min < 3.5.
|
||||
- -DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
cleanup:
|
||||
- /share/man
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/ReimuNotMoe/ydotool/archive/refs/tags/v1.0.4.tar.gz
|
||||
sha256: ba075a43aa6ead51940e892ecffa4d0b8b40c241e4e2bc4bd9bd26b61fde23bd
|
||||
x-checker-data:
|
||||
type: anitya
|
||||
project-id: 138160
|
||||
stable-only: true
|
||||
url-template: https://github.com/ReimuNotMoe/ydotool/archive/refs/tags/v$version.tar.gz
|
||||
- type: shell
|
||||
commands:
|
||||
# scdoc is not in the SDK; man pages are not needed in the sandbox.
|
||||
- sed -i '/add_subdirectory(manpage)/d' CMakeLists.txt
|
||||
- sed -i 's/project(ydotool C)/project(ydotool C)\nadd_definitions(-DVERSION=\\"1.0.4\\")/' CMakeLists.txt
|
||||
|
||||
- python3-build-dependencies.yaml
|
||||
- python3-dependencies.yaml
|
||||
|
||||
- name: vocalinux
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --no-deps --no-build-isolation --prefix=/app .
|
||||
- install -Dm644 packaging/flatpak/com.vocalinux.Vocalinux.desktop -t /app/share/applications/
|
||||
- install -Dm644 resources/icons/scalable/vocalinux.svg /app/share/icons/hicolor/scalable/apps/com.vocalinux.Vocalinux.svg
|
||||
- install -Dm644 resources/icons/scalable/vocalinux-microphone-off.svg /app/share/icons/hicolor/scalable/apps/com.vocalinux.Vocalinux-microphone-off.svg
|
||||
- install -Dm644 resources/icons/scalable/vocalinux-microphone.svg /app/share/icons/hicolor/scalable/apps/com.vocalinux.Vocalinux-microphone.svg
|
||||
- install -Dm644 resources/icons/scalable/vocalinux-microphone-process.svg /app/share/icons/hicolor/scalable/apps/com.vocalinux.Vocalinux-microphone-process.svg
|
||||
- install -Dm644 packaging/flatpak/com.vocalinux.Vocalinux.metainfo.xml -t /app/share/metainfo/
|
||||
sources:
|
||||
- type: dir
|
||||
path: ../..
|
||||
@@ -0,0 +1,52 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>VocaHQ Flatpak remote</title>
|
||||
<style>
|
||||
body {
|
||||
max-width: 42rem;
|
||||
margin: 3rem auto;
|
||||
padding: 0 1rem;
|
||||
font-family: system-ui, sans-serif;
|
||||
line-height: 1.6;
|
||||
}
|
||||
code,
|
||||
pre {
|
||||
background: #f2f2f2;
|
||||
border-radius: 4px;
|
||||
}
|
||||
pre {
|
||||
padding: 1rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>VocaHQ Flatpak remote</h1>
|
||||
<p>
|
||||
Self-hosted, signed OSTree repository for
|
||||
<a href="https://vocalinux.com">Vocalinux</a> — published on every stable
|
||||
tagged release, so installs auto-update via <code>flatpak update</code>.
|
||||
</p>
|
||||
<pre><code>flatpak install __FLATPAKREF_URL__</code></pre>
|
||||
<p>
|
||||
The <code>.flatpakref</code> adds the <code>vocahq</code> remote and
|
||||
resolves the GNOME runtime through Flathub in one step. To wire it up by
|
||||
hand instead:
|
||||
</p>
|
||||
<pre><code>flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak remote-add --if-not-exists vocahq __FLATPAKREPO_URL__
|
||||
flatpak install vocahq com.vocalinux.Vocalinux</code></pre>
|
||||
<p>
|
||||
The GNOME runtime still comes from Flathub — the
|
||||
<code>.flatpakref</code> declares <code>RuntimeRepo</code> so flatpak
|
||||
finds it there. Vocalinux itself is not on Flathub.
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://github.com/VocaHQ/vocalinux">Source code</a> ·
|
||||
<a href="__REMOTE_URL__">Repository index</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,11 @@
|
||||
name: python3-build-dependencies
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}" --prefix=${FLATPAK_DEST} meson-python pyproject-metadata
|
||||
sources:
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl
|
||||
sha256: 67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl
|
||||
sha256: 85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096
|
||||
@@ -0,0 +1,216 @@
|
||||
# Generated by scripts/sync_flatpak_deps.py from requirements/vad.txt, the
|
||||
# hash-pinned export `just lock` writes out of uv.lock. Run `just flatpak-deps`
|
||||
# after any dependency change; `just flatpak-deps-check` and
|
||||
# tests/test_flatpak_packaging.py fail when this file falls behind.
|
||||
#
|
||||
# Do not hand-edit the url/sha256 pairs. Every other line is hand-written and
|
||||
# the script preserves it: pywhispercpp needs a Vulkan build, a version
|
||||
# injected into setup.py, and whisper.cpp's shared libraries symlinked onto
|
||||
# the loader path, none of which a generator produces.
|
||||
name: python3-dependencies
|
||||
buildsystem: simple
|
||||
build-commands: []
|
||||
modules:
|
||||
- name: python3-pywhispercpp
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
# The PyPI sdist derives its version from git metadata, which is absent in
|
||||
# the offline Flatpak build, so inject the version explicitly. --no-same-owner
|
||||
# stops GNU tar from trying to restore the archive's uid inside the build
|
||||
# sandbox (where chown to an arbitrary uid is not permitted).
|
||||
- tar --no-same-owner -xzf pywhispercpp-1.5.0.tar.gz
|
||||
# The build runs under --no-build-isolation, where setuptools-scm is absent,
|
||||
# so a replace that matched nothing would not fail -- it would produce a wheel
|
||||
# carrying version 0.0.0. recognition_manager.py reads that metadata and
|
||||
# degrades GPU context_params below the floor in pyproject.toml, silently.
|
||||
# Assert the shape instead.
|
||||
- python3 -c "from pathlib import Path; p = Path('pywhispercpp-1.5.0/setup.py'); s = p.read_text(); n = 'setup(\\n name=\"pywhispercpp\",'; assert n in s, 'pywhispercpp setup.py no longer matches the injection point'; p.write_text(s.replace(n, n + '\\n version=\"1.5.0\",'))"
|
||||
- tar --owner=0 --group=0 -czf pywhispercpp-1.5.0.tar.gz pywhispercpp-1.5.0
|
||||
# GGML_NATIVE is ggml's default and compiles libggml-cpu with
|
||||
# -march=native, so the package inherits whichever instruction set the
|
||||
# Flatpak builder has. An AVX-512 builder ships a binary that SIGILLs on
|
||||
# any CPU without it (#938). GGML_NATIVE=OFF alone is not the portable
|
||||
# baseline either: while the native default is on, ggml turns every
|
||||
# GGML_* SIMD option on and still compiles -mavx2 -mfma, dying the same
|
||||
# way on pre-Haswell CPUs (#957). Each option is pinned off for the
|
||||
# plain x86-64 baseline.
|
||||
- PYWHISPERCPP_VERSION=1.5.0 NO_REPAIR=1 GGML_VULKAN=1 CMAKE_ARGS="-DGGML_NATIVE=OFF -DGGML_SSE42=OFF -DGGML_AVX=OFF -DGGML_AVX2=OFF -DGGML_BMI2=OFF -DGGML_FMA=OFF -DGGML_F16C=OFF" pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "pywhispercpp" --no-build-isolation
|
||||
# whisper.cpp installs its shared libraries next to the extension module.
|
||||
# Symlink them onto the default loader path so the extension resolves them
|
||||
# without a runtime LD_LIBRARY_PATH, regardless of the SDK's Python minor
|
||||
# version or the exact whisper.cpp soname.
|
||||
- |
|
||||
set -eu
|
||||
sitedir="$(find "${FLATPAK_DEST}/lib" -maxdepth 2 -type d -name site-packages | head -n1)"
|
||||
echo "Linking whisper.cpp libraries from: ${sitedir}"
|
||||
find "${sitedir}" -maxdepth 2 \( -name 'libggml*.so*' -o -name 'libwhisper*.so*' \) \
|
||||
-exec ln -sf {} "${FLATPAK_DEST}/lib/" \;
|
||||
ls -l "${FLATPAK_DEST}/lib/" | grep -E 'libggml|libwhisper' || true
|
||||
sources:
|
||||
- &id002
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl
|
||||
sha256: 42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b
|
||||
- &id003
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/cc/61/d01fc49b8dea277640b55a9e15960dbca9fdc8c9fde18e572d39c59f4019/charset_normalizer-3.5.1-py3-none-any.whl
|
||||
sha256: 6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6
|
||||
- &id004
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/57/b0/0e52c878c53f245edd3a11020f20979b3f490f245af532c7cae3027754b5/idna-3.19-py3-none-any.whl
|
||||
sha256: 815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
- &id008
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/9a/80/db0b4559e57ec36362bedbb05530a87fafbcb6067708c946967a41d449e7/numpy-2.5.2.tar.gz
|
||||
sha256: d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/19/a9/c34aebedd3a4c9afe5101b1b8713710b3fec18087c8a36c35d2f909861bd/platformdirs-4.11.3-py3-none-any.whl
|
||||
sha256: 5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/1c/43/8778f0685a4d32d74efdfa78fc5f745ca9998d96f8121dbf7793db2da5d3/pywhispercpp-1.5.0.tar.gz
|
||||
sha256: 5aa54c73ec96617d97aa519dbbf817e44255eddd9bd52ee1243be61028dbd018
|
||||
- &id005
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl
|
||||
sha256: 2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0
|
||||
- &id007
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/f9/1c/01bfd571a64e7f270e6bab5e33777debe0edc56759233ce84f27dec92d14/tqdm-4.70.0-py3-none-any.whl
|
||||
sha256: 7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953
|
||||
- &id006
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl
|
||||
sha256: 0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3
|
||||
- name: python3-pynput
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "pynput" --no-build-isolation
|
||||
sources:
|
||||
- &id001
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/a5/f5/397b61091120a9ca5001041dd7bf76c385b3bfd67a0e5bcb74b852bd22a4/evdev-1.9.3.tar.gz
|
||||
sha256: 2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/6d/98/bbeb760852adb27f166ce1617f0e51aabb15f21b1e60ea703f2aed3c78ac/pynput-1.8.2-py2.py3-none-any.whl
|
||||
sha256: 8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1
|
||||
- &id009
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/fc/b8/ff33610932e0ee81ae7f1269c890f697d56ff74b9f5b2ee5d9b7fa2c5355/python_xlib-0.33-py2.py3-none-any.whl
|
||||
sha256: c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
- &id010
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl
|
||||
sha256: 4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274
|
||||
- name: python3-evdev
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "evdev" --no-build-isolation
|
||||
sources:
|
||||
- *id001
|
||||
- name: python3-requests
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "requests" --no-build-isolation
|
||||
sources:
|
||||
- *id002
|
||||
- *id003
|
||||
- *id004
|
||||
- *id005
|
||||
- *id006
|
||||
- name: python3-pysocks
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "pysocks" --no-build-isolation
|
||||
sources:
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl
|
||||
sha256: 2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5
|
||||
- name: python3-tqdm
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "tqdm" --no-build-isolation
|
||||
sources:
|
||||
- *id007
|
||||
- name: python3-numpy
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "numpy" --no-build-isolation
|
||||
sources:
|
||||
- *id008
|
||||
- name: python3-onnxruntime
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "onnxruntime" --no-build-isolation
|
||||
sources:
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/83/2c/d8eb945d2a372149df9705a8d5c8d7c6c46c987c5446dbcea9e1ea7f6556/onnxruntime-1.29.0-cp313-cp313-manylinux_2_28_x86_64.whl
|
||||
sha256: e2128f31f449e922c62dbe5d8b6b7b079f0bcaf2d56a102fa203cb6e5bb5ab19
|
||||
only-arches: [x86_64]
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/c9/17/b9ad04051a8c4f504852ce0e8e10f9a6b2f1a331eedcdcc503df776dd0ea/onnxruntime-1.29.0-cp313-cp313-manylinux_2_28_aarch64.whl
|
||||
sha256: d67673c5367727860922c5262d724472f1b5539fb7ccf4c81a638f9b71719803
|
||||
only-arches: [aarch64]
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/e8/2d/d2a548598be01649e2d46231d151a6c56d10b964d94043a335ae56ea2d92/flatbuffers-25.12.19-py2.py3-none-any.whl
|
||||
sha256: 7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl
|
||||
sha256: d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/19/c7/5f7c636ec43e0c545e28d1f1db71990108306f7bdcb89f069ba97e428e7f/protobuf-7.35.1-py3-none-any.whl
|
||||
sha256: 4bc97768d8fe4ad6743c8a19403e314511ed9f6d13205b687e52421c023ac1b9
|
||||
- *id008
|
||||
- name: python3-pyaudio
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "pyaudio" --no-build-isolation
|
||||
sources:
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/26/1d/8878c7752febb0f6716a7e1a52cb92ac98871c5aa522cba181878091607c/PyAudio-0.2.14.tar.gz
|
||||
sha256: 78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87
|
||||
- name: python3-python-xlib
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "python-xlib" --no-build-isolation
|
||||
sources:
|
||||
- *id009
|
||||
- *id010
|
||||
- name: python3-psutil
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "psutil" --no-build-isolation
|
||||
sources:
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz
|
||||
sha256: 0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372
|
||||
- name: python3-meson-python
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "meson-python" --no-build-isolation
|
||||
sources:
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl
|
||||
sha256: 67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298
|
||||
- &id011
|
||||
type: file
|
||||
url: https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl
|
||||
sha256: 85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096
|
||||
- name: python3-pyproject-metadata
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} "pyproject-metadata" --no-build-isolation
|
||||
sources:
|
||||
- *id011
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "intltool",
|
||||
"cleanup": [ "*" ],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz",
|
||||
"mirror-urls": [
|
||||
"https://sources.suse.com/SUSE:SLE-15-SP7:Update:BCI/000product/ca527df4d03bf96a67854a8ed2f0c64b/INCLUDED/SUSE:SLE-15-SP6:GA::intltool::45f77273c3f2ef792fa697b444183beb/intltool-0.51.0.tar.gz",
|
||||
"https://mirror-hk.koddos.net/lfs/lfs-packages/12.0/intltool-0.51.0.tar.gz",
|
||||
"https://gstreamer.freedesktop.org/src/mirror/intltool-0.51.0.tar.gz"
|
||||
],
|
||||
"sha256": "67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "intltool-perl5.26-regex-fixes.patch"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
Description: Escape "{", to prevent complaints from perl 5.22 and 5.26
|
||||
Author: Roderich Schupp <roderich.schupp@gmail.com>
|
||||
Author: gregor herrmann <gregoa@debian.org>
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=788705
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=826471
|
||||
Bug-Upstream: https://bugs.launchpad.net/intltool/+bug/1490906
|
||||
|
||||
Index: intltool-0.51.0/intltool-update.in
|
||||
===================================================================
|
||||
--- intltool-0.51.0.orig/intltool-update.in 2017-07-23 17:24:35.113169465 +0200
|
||||
+++ intltool-0.51.0/intltool-update.in 2017-07-23 17:24:35.109169052 +0200
|
||||
@@ -1062,13 +1062,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/)
|
||||
+ if ($str =~ /^(.*)\$\{?([A-Z_]+)}?(.*)$/)
|
||||
{
|
||||
my $rest = $3;
|
||||
my $untouched = $1;
|
||||
my $sub = "";
|
||||
# Ignore recursive definitions of variables
|
||||
- $sub = $varhash{$2} if defined $varhash{$2} and $varhash{$2} !~ /\${?$2}?/;
|
||||
+ $sub = $varhash{$2} if defined $varhash{$2} and $varhash{$2} !~ /\$\{?$2}?/;
|
||||
|
||||
return SubstituteVariable ("$untouched$sub$rest");
|
||||
}
|
||||
@@ -1190,10 +1190,10 @@
|
||||
$name =~ s/\(+$//g;
|
||||
$version =~ s/\(+$//g;
|
||||
|
||||
- $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
|
||||
- $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
|
||||
- $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
|
||||
- $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
|
||||
+ $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\$\{?AC_PACKAGE_NAME}?/);
|
||||
+ $varhash{"PACKAGE"} = $name if (not $name =~ /\$\{?PACKAGE}?/);
|
||||
+ $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\$\{?AC_PACKAGE_VERSION}?/);
|
||||
+ $varhash{"VERSION"} = $version if (not $name =~ /\$\{?VERSION}?/);
|
||||
}
|
||||
|
||||
if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)[,]?([^,\)]+)?/m)
|
||||
@@ -1219,11 +1219,11 @@
|
||||
$version =~ s/\(+$//g;
|
||||
$bugurl =~ s/\(+$//g if (defined $bugurl);
|
||||
|
||||
- $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
|
||||
- $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
|
||||
- $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
|
||||
- $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
|
||||
- $varhash{"PACKAGE_BUGREPORT"} = $bugurl if (defined $bugurl and not $bugurl =~ /\${?\w+}?/);
|
||||
+ $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\$\{?AC_PACKAGE_NAME}?/);
|
||||
+ $varhash{"PACKAGE"} = $name if (not $name =~ /\$\{?PACKAGE}?/);
|
||||
+ $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\$\{?AC_PACKAGE_VERSION}?/);
|
||||
+ $varhash{"VERSION"} = $version if (not $name =~ /\$\{?VERSION}?/);
|
||||
+ $varhash{"PACKAGE_BUGREPORT"} = $bugurl if (defined $bugurl and not $bugurl =~ /\$\{?\w+}?/);
|
||||
}
|
||||
|
||||
# \s makes this not work, why?
|
||||
@@ -0,0 +1,50 @@
|
||||
From 729546c51806a1b3ea6cb6efb7a115b1baa811f1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
|
||||
Date: Mon, 18 Nov 2019 19:58:53 +0100
|
||||
Subject: [PATCH 1/1] Fix HAVE_VALGRIND AM_CONDITIONAL
|
||||
|
||||
The AM_CONDITIONAL should also be run with --disable-tests, otherwise
|
||||
HAVE_VALGRIND is undefined.
|
||||
---
|
||||
configure | 4 ++--
|
||||
configure.ac | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index 831a3bb..8913b9b 100644
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -14801,6 +14801,8 @@ else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
have_valgrind=yes
|
||||
+fi
|
||||
+
|
||||
fi
|
||||
if test "x$have_valgrind" = "xyes"; then
|
||||
HAVE_VALGRIND_TRUE=
|
||||
@@ -14811,8 +14813,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
-fi
|
||||
-
|
||||
|
||||
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index ace54d1..cbd38a6 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -120,8 +120,8 @@ PKG_CHECK_MODULES(DBUSMENUTESTS, json-glib-1.0 >= $JSON_GLIB_REQUIRED_VERSION
|
||||
[have_tests=yes]
|
||||
)
|
||||
PKG_CHECK_MODULES(DBUSMENUTESTSVALGRIND, valgrind, have_valgrind=yes, have_valgrind=no)
|
||||
-AM_CONDITIONAL([HAVE_VALGRIND], [test "x$have_valgrind" = "xyes"])
|
||||
])
|
||||
+AM_CONDITIONAL([HAVE_VALGRIND], [test "x$have_valgrind" = "xyes"])
|
||||
|
||||
AC_SUBST(DBUSMENUTESTS_CFLAGS)
|
||||
AC_SUBST(DBUSMENUTESTS_LIBS)
|
||||
--
|
||||
2.46.2
|
||||
@@ -0,0 +1,43 @@
|
||||
From 8a09e6ad33c58c017c0c8fd756da036fc39428ea Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Koskovich <akoskovich@pm.me>
|
||||
Date: Sun, 29 Sep 2024 13:47:54 -0400
|
||||
Subject: [PATCH 1/1] Make introspection configurable
|
||||
|
||||
---
|
||||
CMakeLists.txt | 1 +
|
||||
src/CMakeLists.txt | 4 ++++
|
||||
2 files changed, 5 insertions(+)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 0e13fcd..f3e9ec0 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -12,6 +12,7 @@ endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
option(ENABLE_TESTS "Enable all tests and checks" OFF)
|
||||
option(ENABLE_COVERAGE "Enable coverage reports (includes enabling all tests and checks)" OFF)
|
||||
option(ENABLE_WERROR "Treat all build warnings as errors" OFF)
|
||||
+option(ENABLE_INTROSPECTION "Enable introspection" ON)
|
||||
|
||||
if(ENABLE_COVERAGE)
|
||||
set(ENABLE_TESTS ON)
|
||||
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
||||
index 5b3638d..aca9481 100644
|
||||
--- a/src/CMakeLists.txt
|
||||
+++ b/src/CMakeLists.txt
|
||||
@@ -108,6 +108,8 @@ install(TARGETS "ayatana-ido3-0.4" LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIB
|
||||
|
||||
# AyatanaIdo3-0.4.gir
|
||||
|
||||
+if (ENABLE_INTROSPECTION)
|
||||
+
|
||||
find_package(GObjectIntrospection REQUIRED QUIET)
|
||||
|
||||
if (INTROSPECTION_FOUND)
|
||||
@@ -183,3 +185,5 @@ if (INTROSPECTION_FOUND)
|
||||
endif ()
|
||||
|
||||
endif ()
|
||||
+
|
||||
+endif ()
|
||||
--
|
||||
2.46.2
|
||||
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"name": "libayatana-appindicator",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig"
|
||||
],
|
||||
"config-opts": [
|
||||
"-DENABLE_BINDINGS_MONO=NO",
|
||||
"-DENABLE_BINDINGS_VALA=NO",
|
||||
"-DENABLE_GTKDOC=NO"
|
||||
],
|
||||
"modules": [
|
||||
"../intltool/intltool-0.51.json",
|
||||
{
|
||||
"name": "libdbusmenu",
|
||||
"buildsystem": "autotools",
|
||||
"build-options": {
|
||||
"cflags": "-Wno-error"
|
||||
},
|
||||
"cleanup": [
|
||||
"*.la",
|
||||
"/include",
|
||||
"/lib/pkgconfig",
|
||||
"/libexec",
|
||||
"/share/doc",
|
||||
"/share/gtk-doc"
|
||||
],
|
||||
"config-opts": [
|
||||
"--with-gtk=3",
|
||||
"--disable-dumper",
|
||||
"--disable-static",
|
||||
"--disable-tests",
|
||||
"--disable-gtk-doc",
|
||||
"--enable-introspection=no",
|
||||
"--disable-vala"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://launchpad.net/libdbusmenu/16.04/16.04.0/+download/libdbusmenu-16.04.0.tar.gz",
|
||||
"mirror-urls": [
|
||||
"https://sources.suse.com/SUSE:SLFO:Main:Build/libdbusmenu/a5b3e4717f09f90f9cd5568a5f933e8d/libdbusmenu-16.04.0.tar.gz",
|
||||
"https://mirror.math.princeton.edu/pub/frugalware/frugalware-2.1/source/xlib/libdbusmenu/libdbusmenu-16.04.0.tar.gz",
|
||||
"https://ftp.fr.openbsd.org/pub/OpenBSD/distfiles/libdbusmenu-16.04.0.tar.gz"
|
||||
],
|
||||
"sha256": "b9cc4a2acd74509435892823607d966d424bd9ad5d0b00938f27240a1bfa878a"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"paths": [
|
||||
"0001-Fix-HAVE_VALGRIND-AM_CONDITIONAL.patch"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ayatana-ido",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig"
|
||||
],
|
||||
"config-opts": [
|
||||
"-DENABLE_INTROSPECTION=OFF"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/AyatanaIndicators/ayatana-ido.git",
|
||||
"tag": "0.10.4",
|
||||
"commit": "f968079b09e2310fefc3fc307359025f1c74b3eb",
|
||||
"x-checker-data": {
|
||||
"type": "git",
|
||||
"tag-pattern": "^([\\d.]+)$"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"paths": [
|
||||
"0001-Make-introspection-configurable.patch"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "libayatana-indicator",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig",
|
||||
"/libexec",
|
||||
"/share"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/AyatanaIndicators/libayatana-indicator.git",
|
||||
"tag": "0.9.4",
|
||||
"commit": "611bb384b73fa6311777ba4c41381a06f5b99dad",
|
||||
"x-checker-data": {
|
||||
"type": "git",
|
||||
"tag-pattern": "^([\\d.]+)$"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/AyatanaIndicators/libayatana-appindicator.git",
|
||||
"tag": "0.5.94",
|
||||
"commit": "31e8bb083b307e1cc96af4874a94707727bd1e79",
|
||||
"x-checker-data": {
|
||||
"type": "git",
|
||||
"tag-pattern": "^([\\d.]+)$"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build vocalinux_<version>_<arch>.deb and vocalinux-<version>.<arch>.rpm.
|
||||
#
|
||||
# Usage: build.sh <path-to-vocalinux-wheel> <version> [output-dir]
|
||||
# version release version, e.g. 0.18.0 or 0.19.0-beta
|
||||
#
|
||||
# CI and releases run this inside docker-build.sh's pinned Debian 12 image;
|
||||
# it works on any host with bash, python3 + pip, curl and tar. The packages
|
||||
# stay thin on purpose (#600): the interpreter, GTK, PyGObject and the gi
|
||||
# typelibs come from the distribution, and so does every Python dependency
|
||||
# the distros package. Only pywhispercpp and pynput are vendored — the first
|
||||
# is unpackaged on both distros and the second is missing from Fedora.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/../.." && pwd)"
|
||||
PINS="$REPO_ROOT/packaging/native/tool_checksums.txt"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
WHEEL="$(readlink -f "${1:?usage: build.sh <wheel> <version> [outdir]}")"
|
||||
RAW_VERSION="${2:?usage: build.sh <wheel> <version> [outdir]}"
|
||||
OUTDIR="$(mkdir -p "${3:-dist}" && cd "${3:-dist}" && pwd)"
|
||||
[ -f "$WHEEL" ] || fail "wheel not found: $WHEEL"
|
||||
|
||||
# Split "0.19.0-beta" into version + prerelease; nfpm renders the prerelease
|
||||
# as a "~beta" suffix, which orders before the stable release in both dpkg
|
||||
# and rpm. An empty prerelease expands to nothing.
|
||||
VERSION="${RAW_VERSION#v}"
|
||||
PRERELEASE=""
|
||||
case "$VERSION" in
|
||||
*-*)
|
||||
PRERELEASE="${VERSION#*-}"
|
||||
VERSION="${VERSION%%-*}"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$(uname -m)" in
|
||||
x86_64) NFPM_PIN="nfpm-x86_64"; NFPM_ARCH="amd64" ;;
|
||||
aarch64|arm64) NFPM_PIN="nfpm-aarch64"; NFPM_ARCH="arm64" ;;
|
||||
*) fail "unsupported architecture $(uname -m)" ;;
|
||||
esac
|
||||
|
||||
TOOLS="$(mktemp -d)"
|
||||
trap 'rm -rf "$TOOLS"' EXIT
|
||||
|
||||
fetch_pinned() {
|
||||
local name="$1" dest="$2" url sum
|
||||
sum="$(awk -v n="$name" '$1==n && $2=="sha256" {print $3}' "$PINS")"
|
||||
url="$(awk -v n="$name" '$1==n && $2=="sha256" {print $4}' "$PINS")"
|
||||
[ -n "$sum" ] && [ -n "$url" ] || fail "no sha256 pin for $name in $PINS"
|
||||
curl -fSL --retry 3 -o "$dest" "$url"
|
||||
echo "$sum $dest" | sha256sum -c - >/dev/null
|
||||
}
|
||||
|
||||
# nfpm is a single static binary inside the release tarball; unpack just it.
|
||||
fetch_pinned "$NFPM_PIN" "$TOOLS/nfpm.tar.gz"
|
||||
tar -xzf "$TOOLS/nfpm.tar.gz" -C "$TOOLS" nfpm
|
||||
NFPM="$TOOLS/nfpm"
|
||||
|
||||
PAYLOAD="$TOOLS/payload"
|
||||
DOC="$TOOLS/pkg-doc"
|
||||
install -d \
|
||||
"$PAYLOAD/usr/lib/vocalinux/app" \
|
||||
"$PAYLOAD/usr/lib/vocalinux/vendor" \
|
||||
"$PAYLOAD/usr/bin" \
|
||||
"$PAYLOAD/usr/share/applications" \
|
||||
"$PAYLOAD/usr/share/icons/hicolor/scalable/apps" \
|
||||
"$DOC"
|
||||
|
||||
# --- application payload ------------------------------------------------
|
||||
# The wheel is a zip; -m zipfile lays out vocalinux/ and its dist-info
|
||||
# exactly where pip --target would, without pip's EXTERNALLY-MANAGED refusal
|
||||
# on Debian 12.
|
||||
python3 -m zipfile -e "$WHEEL" "$PAYLOAD/usr/lib/vocalinux/app/"
|
||||
|
||||
# --- vendored wheels -----------------------------------------------------
|
||||
# Download each supported CPython's pywhispercpp wheel — it has no abi3 tag,
|
||||
# so there is one wheel per interpreter — plus the pure-Python pynput, per
|
||||
# the hashes pinned in requirements/runtime.txt, and merge them flat into
|
||||
# the vendor dir. The extension filenames carry their tag
|
||||
# (_pywhispercpp.cpython-311-*.so next to .cpython-313-*.so) so all four
|
||||
# coexist, and the flat layout reproduces what pip would place in
|
||||
# site-packages, which is what utils/pywhispercpp_loader.py scans for.
|
||||
#
|
||||
# VENDOR_PYS tracks requires-python in pyproject.toml and the CI matrix.
|
||||
VENDOR_PYS="3.11 3.12 3.13 3.14"
|
||||
PINS_VENDOR="$TOOLS/vendor-requirements.txt"
|
||||
awk '/^(pywhispercpp|pynput)==/{p=1} p{print; if ($0 !~ /\\$/) p=0}' \
|
||||
"$REPO_ROOT/requirements/runtime.txt" > "$PINS_VENDOR"
|
||||
grep -q "^pywhispercpp==" "$PINS_VENDOR" || fail "pywhispercpp pin not found in requirements/runtime.txt"
|
||||
grep -q "^pynput==" "$PINS_VENDOR" || fail "pynput pin not found in requirements/runtime.txt"
|
||||
|
||||
for PYV in $VENDOR_PYS; do
|
||||
mkdir -p "$TOOLS/wheels/$PYV"
|
||||
pip3 download --require-hashes --no-deps --only-binary=:all: \
|
||||
--python-version "$PYV" -r "$PINS_VENDOR" -d "$TOOLS/wheels/$PYV" >/dev/null
|
||||
done
|
||||
for VENDOR_WHEEL in "$TOOLS"/wheels/*/*.whl; do
|
||||
python3 -m zipfile -e "$VENDOR_WHEEL" "$PAYLOAD/usr/lib/vocalinux/vendor/"
|
||||
done
|
||||
|
||||
# --- portable libggml-cpu -------------------------------------------------
|
||||
# The pinned pywhispercpp wheels bundle a libggml-cpu compiled for AVX2+FMA,
|
||||
# which dies with SIGILL at model load on pre-Haswell CPUs (#957). Rebuild
|
||||
# the ggml libraries from the same pinned sdist at the plain x86-64 baseline —
|
||||
# GGML_NATIVE=OFF alone still compiles -mavx2 -mfma, because ggml turns every
|
||||
# GGML_* SIMD option on while its native default is on — and swap them into
|
||||
# the vendored copies. libwhisper and the Python extension carry no generated
|
||||
# SIMD, so only the libggml set needs replacing.
|
||||
SDIST_DIR="$TOOLS/pywhispercpp-sdist"
|
||||
mkdir -p "$SDIST_DIR"
|
||||
pip3 download --require-hashes --no-deps --no-binary pywhispercpp \
|
||||
-r "$PINS_VENDOR" -d "$SDIST_DIR" >/dev/null
|
||||
tar -xzf "$SDIST_DIR"/pywhispercpp-*.tar.gz -C "$SDIST_DIR"
|
||||
WHISPER_GGML="$(echo "$SDIST_DIR"/pywhispercpp-*/whisper.cpp/ggml)"
|
||||
[ -d "$WHISPER_GGML" ] || fail "whisper.cpp/ggml missing from pywhispercpp sdist"
|
||||
# ggml.pc.in is generated upstream and absent from the sdist; it only feeds
|
||||
# the standalone install rules this build never runs.
|
||||
touch "$WHISPER_GGML/ggml.pc.in"
|
||||
cmake -S "$WHISPER_GGML" -B "$TOOLS/ggml-build" \
|
||||
-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON \
|
||||
-DGGML_NATIVE=OFF -DGGML_SSE42=OFF -DGGML_AVX=OFF -DGGML_AVX2=OFF \
|
||||
-DGGML_BMI2=OFF -DGGML_FMA=OFF -DGGML_F16C=OFF \
|
||||
-DGGML_BUILD_TESTS=OFF -DGGML_BUILD_EXAMPLES=OFF
|
||||
cmake --build "$TOOLS/ggml-build" --target ggml-cpu -j"$(nproc)"
|
||||
BASELINE_CPU="$(find "$TOOLS/ggml-build" -name 'libggml-cpu.so.*' -type f | sort -V | tail -1)"
|
||||
[ -f "$BASELINE_CPU" ] || fail "baseline libggml-cpu build produced no library"
|
||||
# objdump, not a feature check: the SIGILL is ISA-level, so assert no 256-bit
|
||||
# or FMA instructions survive in the library that ships. No grep -q: under
|
||||
# pipefail an early exit SIGPIPEs objdump and the pipeline reports a miss.
|
||||
if objdump -d "$BASELINE_CPU" | grep -E 'ymm|vfmadd|vfnmadd|vfmsub|vzeroupper' >/dev/null; then
|
||||
fail "baseline libggml-cpu still carries AVX/FMA instructions"
|
||||
fi
|
||||
# The vendored wheel files carry auditwheel-mangled basenames
|
||||
# (libggml-cpu-<hash>.so.0.9.8) that the extension's NEEDED entries point at,
|
||||
# so overwrite the cpu library in place and keep its filename. Only cpu is
|
||||
# swapped: the wheel's other libggml files carry no generated SIMD, and the
|
||||
# mangled core lib doubles as the extension's __cxa_call_terminate provider —
|
||||
# replacing it with a locally built copy drops that export.
|
||||
swapped=0
|
||||
while IFS= read -r vendored; do
|
||||
cp "$BASELINE_CPU" "$vendored"
|
||||
swapped=$((swapped + 1))
|
||||
done < <(find "$PAYLOAD/usr/lib/vocalinux/vendor" -name 'libggml-cpu*.so*')
|
||||
[ "$swapped" -gt 0 ] || fail "found no vendored libggml-cpu to replace"
|
||||
# The baseline library's own NEEDED entries use the unmangled sonames
|
||||
# (libggml-base.so.0, libgomp.so.1), so alias the vendored copies — the same
|
||||
# upstream version, and base/gomp carry no generated SIMD anyway — under
|
||||
# those names inside pywhispercpp.libs.
|
||||
while IFS= read -r libs_dir; do
|
||||
vendored_base="$(find "$libs_dir" -name 'libggml-base*.so*' | head -1)"
|
||||
[ -n "$vendored_base" ] || fail "no vendored libggml-base in $libs_dir"
|
||||
cp "$vendored_base" "$libs_dir/libggml-base.so.0"
|
||||
vendored_gomp="$(find "$libs_dir" -name 'libgomp*.so*' | head -1)"
|
||||
[ -n "$vendored_gomp" ] || fail "no vendored libgomp in $libs_dir"
|
||||
cp "$vendored_gomp" "$libs_dir/libgomp.so.1"
|
||||
done < <(find "$PAYLOAD/usr/lib/vocalinux/vendor" -type d -name 'pywhispercpp.libs')
|
||||
|
||||
# --- launchers -----------------------------------------------------------
|
||||
# Same environment install.sh's wrapper establishes: the vendored
|
||||
# pywhispercpp.libs on LD_LIBRARY_PATH, user site-packages off so they cannot
|
||||
# shadow the distro modules, and sg input so evdev hotkeys work on Wayland
|
||||
# when the user is already in the input group but the session has not picked
|
||||
# up the membership yet. vocalinux-gui exists because the wheel declares a
|
||||
# gui-script of that name; on Linux it runs the same entry.
|
||||
write_launcher() {
|
||||
local path="$1"
|
||||
cat > "$path" <<'LAUNCHER_EOF'
|
||||
#!/bin/sh
|
||||
# Launcher for the distro-packaged Vocalinux. The vendored wheels (the
|
||||
# pywhispercpp/pynput copies Debian and Fedora do not ship) live under
|
||||
# /usr/lib/vocalinux/vendor with the app itself under .../app; the loader in
|
||||
# utils/pywhispercpp_loader.py finds the bundled .so files from sys.path.
|
||||
PYTHONNOUSERSITE=1
|
||||
VOCALINUX_VENDOR="/usr/lib/vocalinux/vendor"
|
||||
if [ -d "$VOCALINUX_VENDOR/pywhispercpp.libs" ]; then
|
||||
LD_LIBRARY_PATH="$VOCALINUX_VENDOR/pywhispercpp.libs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
||||
export LD_LIBRARY_PATH
|
||||
fi
|
||||
export PYTHONNOUSERSITE PYTHONPATH="/usr/lib/vocalinux/app:$VOCALINUX_VENDOR${PYTHONPATH:+:$PYTHONPATH}"
|
||||
if grep -q "^input:.*\b$(whoami)\b" /etc/group 2>/dev/null \
|
||||
&& ! groups | grep -q "\binput\b" && command -v sg >/dev/null 2>&1; then
|
||||
# sg(1) takes a single command string, so each argument is re-quoted for
|
||||
# the inner shell; joining $* would re-split paths containing spaces.
|
||||
QUOTED_ARGS=""
|
||||
for arg in "$@"; do
|
||||
arg="$(printf %s "$arg" | sed "s/'/'\\\\''/g")"
|
||||
QUOTED_ARGS="$QUOTED_ARGS '$arg'"
|
||||
done
|
||||
exec sg input -c "/usr/bin/python3 -m vocalinux.main$QUOTED_ARGS"
|
||||
fi
|
||||
exec /usr/bin/python3 -m vocalinux.main "$@"
|
||||
LAUNCHER_EOF
|
||||
chmod 755 "$path"
|
||||
}
|
||||
write_launcher "$PAYLOAD/usr/bin/vocalinux"
|
||||
write_launcher "$PAYLOAD/usr/bin/vocalinux-gui"
|
||||
|
||||
# --- desktop entry, icon, license ----------------------------------------
|
||||
install -Dm644 "$REPO_ROOT/vocalinux.desktop" \
|
||||
"$PAYLOAD/usr/share/applications/vocalinux.desktop"
|
||||
install -Dm644 "$REPO_ROOT/resources/icons/scalable/vocalinux.svg" \
|
||||
"$PAYLOAD/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
|
||||
install -Dm644 "$REPO_ROOT/LICENSE" "$DOC/LICENSE"
|
||||
|
||||
# --- package -------------------------------------------------------------
|
||||
# nfpm resolves contents src paths relative to its working directory, so run
|
||||
# it from $TOOLS where ./payload and ./pkg-doc live.
|
||||
cd "$TOOLS"
|
||||
VOCA_ARCH="$NFPM_ARCH" VOCA_VERSION="$VERSION" VOCA_PRERELEASE="$PRERELEASE" \
|
||||
"$NFPM" package --config "$REPO_ROOT/packaging/native/nfpm.yaml" \
|
||||
--packager deb --target "$OUTDIR/"
|
||||
VOCA_ARCH="$NFPM_ARCH" VOCA_VERSION="$VERSION" VOCA_PRERELEASE="$PRERELEASE" \
|
||||
"$NFPM" package --config "$REPO_ROOT/packaging/native/nfpm.yaml" \
|
||||
--packager rpm --target "$OUTDIR/"
|
||||
|
||||
ls -la "$OUTDIR"/*.deb "$OUTDIR"/*.rpm
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# Inside the pinned Debian 12 image: install the tools build.sh needs, then
|
||||
# build both packages. Called by docker-build.sh, never directly on a host.
|
||||
set -euo pipefail
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update
|
||||
# cmake, g++, make and binutils rebuild the vendored libggml-cpu from the
|
||||
# pinned pywhispercpp sdist at the portable baseline in build.sh.
|
||||
apt-get install -y --no-install-recommends \
|
||||
binutils ca-certificates cmake curl g++ make python3 python3-pip xz-utils
|
||||
|
||||
exec bash "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/build.sh" "$@"
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the native package build inside the pinned Debian 12 image.
|
||||
#
|
||||
# Usage: docker-build.sh <path-to-wheel> <version> [output-dir]
|
||||
#
|
||||
# This is what CI calls and what you should call locally, so that what you
|
||||
# get is what CI gets: the base image pins the pip that resolves the vendored
|
||||
# wheels, and building on the host instead means shipping whatever that host
|
||||
# happens to run. Debian 12 is old enough that its pip accepts every manylinux
|
||||
# tag in the pinned wheels.
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/../.." && pwd)"
|
||||
IMAGE="$(awk '$1=="base-image" {print $3}' "$REPO_ROOT/packaging/native/tool_checksums.txt")"
|
||||
if [ -z "$IMAGE" ]; then
|
||||
echo "No base-image pin in packaging/native/tool_checksums.txt" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The wheel and output dir are given as host paths; the repo is mounted at
|
||||
# the same place it lives, so relative arguments keep working inside. The
|
||||
# container needs python3, pip, curl and tar — install-build-tools.sh adds
|
||||
# them before handing off to build.sh.
|
||||
exec docker run --rm \
|
||||
-v "$REPO_ROOT:$REPO_ROOT" -w "$REPO_ROOT" \
|
||||
"$IMAGE" bash packaging/native/container-build.sh "$@"
|
||||
@@ -0,0 +1,114 @@
|
||||
# One nfpm config for both the .deb and the .rpm.
|
||||
#
|
||||
# Do not run nfpm on this file directly: build.sh assembles the payload tree
|
||||
# this config expects (./payload and ./pkg-doc next to the directory it runs
|
||||
# nfpm from) and sets the VOCA_* variables the fields below expand.
|
||||
#
|
||||
# Packaging stays thin on purpose (#600): the interpreter, GTK, PyGObject and
|
||||
# the gi typelibs come from the distribution, and so do every Python
|
||||
# dependency the distros package. Only pywhispercpp and pynput are vendored —
|
||||
# pywhispercpp is not packaged by Debian or Fedora at all, and pynput is
|
||||
# missing from Fedora — both under /usr/lib/vocalinux/vendor/, on sys.path via
|
||||
# the launcher in /usr/bin/vocalinux. Vendoring the pywhispercpp wheel per
|
||||
# supported CPython is what keeps the package free of a bundled interpreter.
|
||||
#
|
||||
# Version: VOCA_VERSION is the tag without its leading v and without a
|
||||
# prerelease suffix; VOCA_PRERELEASE carries that suffix (empty for stable).
|
||||
# nfpm maps a prerelease to 0.19.0~beta-1, which orders before the stable
|
||||
# 0.19.0-1 in both formats.
|
||||
|
||||
name: vocalinux
|
||||
arch: ${VOCA_ARCH}
|
||||
platform: linux
|
||||
version: ${VOCA_VERSION}
|
||||
release: 1
|
||||
prerelease: ${VOCA_PRERELEASE}
|
||||
section: utils
|
||||
priority: optional
|
||||
maintainer: "Jatin K Malik <jatinkrmalik@gmail.com>"
|
||||
description: |
|
||||
Free, offline voice dictation for Linux. Hold the push-to-talk key,
|
||||
transcribe speech locally (whisper.cpp by default), and type into the
|
||||
focused window. GTK, PyGObject and the interpreter come from the
|
||||
distribution; pywhispercpp and pynput are vendored under
|
||||
/usr/lib/vocalinux/vendor because neither distro packages them.
|
||||
homepage: https://github.com/VocaHQ/vocalinux
|
||||
license: AGPL-3.0-only
|
||||
|
||||
contents:
|
||||
# The staged payload tree: /usr/lib/vocalinux/{app,vendor}, the launchers in
|
||||
# /usr/bin, the desktop file and the hicolor icon. build.sh writes it.
|
||||
- src: ./payload/
|
||||
dst: /
|
||||
type: tree
|
||||
|
||||
# License placement differs between the formats: Debian policy wants the
|
||||
# copyright file under /usr/share/doc, Fedora marks /usr/share/licenses.
|
||||
- src: ./pkg-doc/LICENSE
|
||||
dst: /usr/share/doc/vocalinux/copyright
|
||||
packager: deb
|
||||
- src: ./pkg-doc/LICENSE
|
||||
dst: /usr/share/licenses/vocalinux/LICENSE
|
||||
packager: rpm
|
||||
|
||||
overrides:
|
||||
deb:
|
||||
depends:
|
||||
- python3 (>= 3.11)
|
||||
- python3-gi
|
||||
- python3-gi-cairo
|
||||
- gir1.2-gtk-3.0
|
||||
- gir1.2-ayatanaappindicator3-0.1
|
||||
- python3-numpy
|
||||
- python3-requests
|
||||
- python3-tqdm
|
||||
- python3-platformdirs
|
||||
- python3-psutil
|
||||
- python3-evdev
|
||||
- python3-pyaudio
|
||||
- python3-socks
|
||||
- python3-xlib
|
||||
recommends:
|
||||
# Host tools the injectors fall back through; install.d documents the
|
||||
# same set for install.sh. The app runs without them on degraded paths.
|
||||
- xdotool
|
||||
- wtype
|
||||
- ydotool
|
||||
- wl-clipboard
|
||||
- xclip
|
||||
- xsel
|
||||
# IBus engine (Wayland text injection): typelib plus the daemon itself.
|
||||
- gir1.2-ibus-1.0
|
||||
- ibus
|
||||
# Desktop notifications.
|
||||
- gir1.2-notify-0.7
|
||||
# Tray backend the app prefers when present: libayatana-appindicator
|
||||
# (GTK 3) logs a deprecation warning at startup. Debian 13+ ships it;
|
||||
# apt skips the recommendation where it does not exist (Debian 12).
|
||||
- gir1.2-ayatanaappindicatorglib-2.0
|
||||
rpm:
|
||||
depends:
|
||||
- python3 >= 3.11
|
||||
- python3-gobject
|
||||
- python3-cairo
|
||||
- gtk3
|
||||
- libayatana-appindicator-gtk3
|
||||
- python3-numpy
|
||||
- python3-requests
|
||||
- python3-tqdm
|
||||
- python3-platformdirs
|
||||
- python3-psutil
|
||||
- python3-evdev
|
||||
- python3-pyaudio
|
||||
- python3-pysocks
|
||||
- python3-xlib
|
||||
recommends:
|
||||
- xdotool
|
||||
- wtype
|
||||
- ydotool
|
||||
- wl-clipboard
|
||||
- xclip
|
||||
- xsel
|
||||
# ibus carries the IBus-1.0 typelib itself on Fedora.
|
||||
- ibus
|
||||
- libnotify
|
||||
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install the built native package inside its distro container and prove the
|
||||
# app it ships actually runs.
|
||||
#
|
||||
# Usage (mount the package dir at /out and this script's dir at /pk):
|
||||
# docker run --rm -v "$PWD/dist:/out:ro" -v "$PWD/packaging/native:/pk:ro" \
|
||||
# debian:12 bash /pk/smoke-test.sh
|
||||
# or: just native-smoke debian:12
|
||||
#
|
||||
# What this proves: the package manager accepts the package and resolves its
|
||||
# declared dependencies, the /usr/bin launcher runs, and the import graph —
|
||||
# gi, GTK, the app modules and the vendored wheels — resolves against the
|
||||
# distro interpreter. It is the native-package counterpart of install-gate
|
||||
# and the AppImage boot matrix: Debian and Ubuntu exercise the .deb, Fedora
|
||||
# the .rpm.
|
||||
#
|
||||
# What it does not prove: dictation. No container here has audio or a
|
||||
# display, and the point is the package, not the app — the app's own tests
|
||||
# cover behaviour.
|
||||
set -euo pipefail
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[ -r /etc/os-release ] || fail "/etc/os-release missing — not a distro container?"
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
case "$ID" in
|
||||
debian|ubuntu)
|
||||
PKG="$(find /out -name '*.deb' -print -quit)"
|
||||
[ -n "$PKG" ] || fail "no .deb under /out"
|
||||
apt-get update
|
||||
apt-get install -y "$PKG"
|
||||
;;
|
||||
fedora)
|
||||
PKG="$(find /out -name '*.rpm' -print -quit)"
|
||||
[ -n "$PKG" ] || fail "no .rpm under /out"
|
||||
dnf install -y "$PKG"
|
||||
;;
|
||||
*)
|
||||
fail "no smoke recipe for distro ID '$ID' — add one alongside the dependency list it is meant to exercise"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "== installed: $PKG"
|
||||
|
||||
# The launcher must answer: --version is an argparse action that exits
|
||||
# before check_dependencies() touches GTK, so it proves the wrapper, the
|
||||
# PYTHONPATH layout and the entry module's import chain — the dependency
|
||||
# typelibs are exercised by the import smoke below.
|
||||
vocalinux --version
|
||||
vocalinux-gui --version
|
||||
|
||||
# Import smoke in the shape of the AUR gate: the app modules, the vendored
|
||||
# pywhispercpp wheel, and the distro gi/GTK typelibs, all through the same
|
||||
# interpreter and environment the launcher sets up. pynput is only checked
|
||||
# for presence: its __init__ selects a display backend and raises ImportError
|
||||
# with no DISPLAY, which is why the app guards it with PYNPUT_AVAILABLE.
|
||||
PYTHONPATH="/usr/lib/vocalinux/app:/usr/lib/vocalinux/vendor" \
|
||||
PYTHONNOUSERSITE=1 \
|
||||
LD_LIBRARY_PATH="/usr/lib/vocalinux/vendor/pywhispercpp.libs" \
|
||||
/usr/bin/python3 - <<'PY'
|
||||
import importlib
|
||||
import importlib.util
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
MODULES = (
|
||||
"vocalinux.main",
|
||||
"vocalinux.ui.tray_indicator",
|
||||
"vocalinux.speech_recognition.recognition_manager",
|
||||
"vocalinux.speech_recognition.command_processor",
|
||||
"vocalinux.text_injection.text_injector",
|
||||
"vocalinux.text_injection.ibus_engine",
|
||||
"vocalinux.ui.keyboard_backends",
|
||||
"pywhispercpp.model",
|
||||
)
|
||||
for module in MODULES:
|
||||
importlib.import_module(module)
|
||||
|
||||
spec = importlib.util.find_spec("pynput")
|
||||
assert spec and spec.origin and spec.origin.startswith("/usr/lib/vocalinux/vendor/"), \
|
||||
f"vendored pynput not found on sys.path: {spec}"
|
||||
|
||||
tag = f"cpython-{sys.version_info.major}{sys.version_info.minor}-"
|
||||
exts = [p.name for p in Path("/usr/lib/vocalinux/vendor").glob("_pywhispercpp.*.so")]
|
||||
assert any(tag in name for name in exts), \
|
||||
f"no _pywhispercpp extension for {tag[:-1]} among {exts}"
|
||||
|
||||
print("import-smoke OK:", ", ".join(MODULES))
|
||||
PY
|
||||
|
||||
echo "SMOKE-TEST PASSED"
|
||||
@@ -0,0 +1,23 @@
|
||||
# Pinned build inputs for packaging/native/build.sh.
|
||||
#
|
||||
# Same contract as packaging/appimage/tool_checksums.txt: everything the
|
||||
# package build downloads is pinned and verified here, so two builds of the
|
||||
# same commit cannot differ.
|
||||
#
|
||||
# Columns: name, kind, value, source — parseable by awk.
|
||||
#
|
||||
# sha256 the file downloaded from <source> must hash to <value>
|
||||
# docker build inside image <value>; <source> records the tag it came from
|
||||
# version recorded for humans; the hash pins pin the artifacts themselves
|
||||
#
|
||||
# To bump nfpm: change the version in the <source> URLs, download the
|
||||
# tarballs, and replace <value> with `sha256sum` of each. The base image
|
||||
# digest comes from `docker buildx imagetools inspect debian:12` (use the
|
||||
# index digest, not a per-architecture one — the same line has to work on
|
||||
# x86_64 and aarch64).
|
||||
|
||||
base-image docker docker.io/library/debian@sha256:2c037a04925515fdd6ea85ea14a682d0e79931f5e9f5d07b6dbfc6ba12f9e858 debian:12
|
||||
nfpm version 2.47.0 https://github.com/goreleaser/nfpm/releases/tag/v2.47.0
|
||||
|
||||
nfpm-x86_64 sha256 0660ca602b2d2d2ae4781a06c692b3eeb9d437ffea05b831d76e41f4a3188783 https://github.com/goreleaser/nfpm/releases/download/v2.47.0/nfpm_2.47.0_Linux_x86_64.tar.gz
|
||||
nfpm-aarch64 sha256 1c0f5f2999b9a974bfb04fdb0cc3306096de530ac5dbb25d739cc5f5219c919c https://github.com/goreleaser/nfpm/releases/download/v2.47.0/nfpm_2.47.0_Linux_arm64.tar.gz
|
||||
@@ -0,0 +1,81 @@
|
||||
# Vocalinux for Nix
|
||||
|
||||
A flake that builds Vocalinux against nixpkgs: GTK 3, PyGObject and the
|
||||
AppIndicator typelib come from nixpkgs, and `pywhispercpp` — which nixpkgs
|
||||
does not package — is built from its PyPI sdist (it vendors whisper.cpp and
|
||||
pybind11). Every host tool the app probes for (`xdotool`, `wtype`, `ydotool`,
|
||||
`wl-clipboard`, `xclip`, `xsel`, `xprop`, `setxkbmap`, `ibus`, `gdbus`,
|
||||
`notify-send`, `paplay`, `aplay`) is wired onto PATH, so the wrapped binary
|
||||
behaves like a deb/rpm install with Recommends present.
|
||||
|
||||
## Try it
|
||||
|
||||
```bash
|
||||
nix run github:VocaHQ/vocalinux
|
||||
```
|
||||
|
||||
or install into a profile:
|
||||
|
||||
```bash
|
||||
nix profile install github:VocaHQ/vocalinux
|
||||
```
|
||||
|
||||
## NixOS
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.vocalinux.url = "github:VocaHQ/vocalinux";
|
||||
|
||||
outputs = { nixpkgs, vocalinux, ... }: {
|
||||
nixosConfigurations.host = nixpkgs.lib.nixosSystem {
|
||||
modules = [
|
||||
vocalinux.nixosModules.vocalinux
|
||||
{
|
||||
programs.vocalinux.enable = true;
|
||||
users.users.you.extraGroups = [ "input" "uinput" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
`hardware.uinput` (enabled by the module) covers `/dev/uinput`, which ydotool
|
||||
and the evdev backend's keyboard clone need. `input` group membership is a
|
||||
per-user decision — it grants read access to every keyboard and pointer
|
||||
device, the same trade-off `install.sh` documents. X11 sessions need neither
|
||||
and can skip the group lines entirely.
|
||||
|
||||
## Home Manager
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
inputs.home-manager.url = "github:nix-community/home-manager";
|
||||
inputs.home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.vocalinux.url = "github:VocaHQ/vocalinux";
|
||||
|
||||
outputs = { nixpkgs, home-manager, vocalinux, ... }: {
|
||||
homeConfigurations.you = home-manager.lib.homeManagerConfiguration {
|
||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||||
modules = [
|
||||
vocalinux.homeManagerModules.vocalinux
|
||||
{ programs.vocalinux.enable = true; }
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Home Manager on NixOS still needs the system-side pieces above (the NixOS
|
||||
module handles `hardware.uinput`; group membership stays per-user). On a
|
||||
non-NixOS host, `nix profile install` plus the equivalent udev rule and group
|
||||
membership from your distro does the same job — see docs/INSTALL.md.
|
||||
|
||||
## Scope
|
||||
|
||||
- Default engine whisper.cpp plus the `[vad]` extra (ONNX Runtime) are built
|
||||
in. The `vosk`, `whisper`, `parakeet` and `faster_whisper` extras are not
|
||||
packaged (PyTorch footprint / not in nixpkgs).
|
||||
- `pywhispercpp` is built with `GGML_NATIVE=OFF` — a portable baseline rather
|
||||
than `-march=native`, so binaries can move between machines.
|
||||
@@ -0,0 +1,25 @@
|
||||
# Home Manager module for Vocalinux.
|
||||
#
|
||||
# Installs the package into the user profile; device permissions are a
|
||||
# system concern, so pair it with the NixOS module (or the manual group
|
||||
# steps in docs/INSTALL.md) for Wayland/evdev shortcuts and ydotool typing.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.programs.vocalinux;
|
||||
in
|
||||
{
|
||||
options.programs.vocalinux = {
|
||||
enable = lib.mkEnableOption "Vocalinux voice dictation";
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
defaultText = "the package built by the vocalinux flake";
|
||||
description = "The vocalinux package to install.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [ cfg.package ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# NixOS module for Vocalinux.
|
||||
#
|
||||
# The flake wraps this file and injects the flake-built package as the
|
||||
# default (programs.vocalinux.package), so importing the module through
|
||||
# nixosModules.vocalinux needs no extra wiring. Imported on its own, set
|
||||
# programs.vocalinux.package to a vocalinux derivation.
|
||||
#
|
||||
# What it cannot do for you: membership in the "input" group is per-user,
|
||||
# so the module documents it and each user opts in:
|
||||
#
|
||||
# users.users.<name>.extraGroups = [ "input" "uinput" ];
|
||||
#
|
||||
# "input" grants read access to every keyboard and pointer device — the
|
||||
# evdev global-shortcut backend needs it on Wayland. X11 sessions need none
|
||||
# of this. See docs/INSTALL.md for the same notes the deb/rpm carry.
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.programs.vocalinux;
|
||||
in
|
||||
{
|
||||
options.programs.vocalinux = {
|
||||
enable = lib.mkEnableOption "Vocalinux voice dictation";
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
defaultText = "the package built by the vocalinux flake";
|
||||
description = "The vocalinux package to install.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
# /dev/uinput is what ydotool (native Wayland typing) and the evdev
|
||||
# backend's keyboard clone open. The option loads the module, creates
|
||||
# the "uinput" group and installs the matching udev rule.
|
||||
hardware.uinput.enable = true;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
# Vocalinux for Nix.
|
||||
#
|
||||
# Consumed by the repo flake (packages.<system>.vocalinux) and buildable with
|
||||
# plain callPackage:
|
||||
#
|
||||
# pkgs.python3Packages.callPackage ./packaging/nix/package.nix {
|
||||
# pywhispercpp = pkgs.python3Packages.callPackage ./packaging/nix/pywhispercpp.nix { };
|
||||
# src = ./.;
|
||||
# }
|
||||
#
|
||||
# Layout mirrors packaging/native/nfpm.yaml: the interpreter, GTK, PyGObject
|
||||
# and the AppIndicator typelib come from nixpkgs, pywhispercpp is built from
|
||||
# its vendored sdist, and every host tool the injectors probe for
|
||||
# (shutil.which) is wired onto PATH so the packaged binary behaves like the
|
||||
# deb/rpm install with Recommends installed.
|
||||
{
|
||||
lib,
|
||||
buildPythonApplication,
|
||||
setuptools,
|
||||
gobject-introspection,
|
||||
wrapGAppsHook3,
|
||||
gtk3,
|
||||
libayatana-appindicator,
|
||||
ibus,
|
||||
libnotify,
|
||||
glib,
|
||||
# Python dependencies (resolved from python3Packages scope).
|
||||
pywhispercpp,
|
||||
pynput,
|
||||
evdev,
|
||||
requests,
|
||||
pysocks,
|
||||
numpy,
|
||||
pyaudio,
|
||||
pygobject3,
|
||||
pycairo,
|
||||
psutil,
|
||||
onnxruntime,
|
||||
tqdm,
|
||||
platformdirs,
|
||||
# Host binaries the app probes for with shutil.which at runtime.
|
||||
xdotool,
|
||||
wtype,
|
||||
ydotool,
|
||||
wl-clipboard,
|
||||
xclip,
|
||||
xsel,
|
||||
xprop,
|
||||
setxkbmap,
|
||||
pulseaudio,
|
||||
alsa-utils,
|
||||
vulkan-tools,
|
||||
src,
|
||||
}:
|
||||
|
||||
let
|
||||
# Host tools the injectors, clipboard fallbacks, audio cues and layout
|
||||
# probing shell out to. Prepending them mirrors installing the deb/rpm
|
||||
# Recommends set. gdbus comes from glib.bin; ibus covers ibus/ibus-daemon.
|
||||
runtimeTools = [
|
||||
xdotool
|
||||
wtype
|
||||
ydotool # provides ydotoold too
|
||||
wl-clipboard # wl-copy / wl-paste
|
||||
xclip
|
||||
xsel
|
||||
xprop
|
||||
setxkbmap
|
||||
ibus
|
||||
libnotify # notify-send
|
||||
pulseaudio # paplay
|
||||
alsa-utils # aplay
|
||||
(lib.getBin glib) # gdbus
|
||||
vulkan-tools # vulkaninfo for Vulkan GPU discovery and selection
|
||||
];
|
||||
in
|
||||
buildPythonApplication {
|
||||
pname = "vocalinux";
|
||||
|
||||
# Track src/vocalinux/version.py so release bumps need no edit here.
|
||||
# builtins.match is POSIX ERE (no \s class), so flatten newlines first.
|
||||
version =
|
||||
let
|
||||
match = builtins.match ''.*__version__ = "([^"]+)".*'' (
|
||||
builtins.replaceStrings [ "\n" ] [ " " ] (
|
||||
builtins.readFile (src + "/src/vocalinux/version.py")
|
||||
)
|
||||
);
|
||||
in
|
||||
if match == null then "0.0.0" else builtins.head match;
|
||||
|
||||
inherit src;
|
||||
pyproject = true;
|
||||
|
||||
nativeBuildInputs = [
|
||||
# Registers GI_TYPELIB_PATH for every buildInput shipping typelibs, and
|
||||
# wraps the entry point with the GLib/GTK environment.
|
||||
gobject-introspection
|
||||
wrapGAppsHook3
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
gtk3 # Gtk-3.0
|
||||
libayatana-appindicator # AyatanaAppIndicator3-0.1 (+ AppIndicator3 fallback)
|
||||
ibus # IBus-1.0 typelib for the Wayland injection engine
|
||||
libnotify # Notify-0.7
|
||||
];
|
||||
|
||||
build-system = [ setuptools ];
|
||||
|
||||
dependencies = [
|
||||
pywhispercpp # default whisper.cpp engine; vendored sdist build
|
||||
pynput # X11 hotkey backend
|
||||
evdev # Wayland/evdev hotkey backend + uinput clone
|
||||
requests
|
||||
pysocks
|
||||
numpy
|
||||
pyaudio
|
||||
pygobject3
|
||||
pycairo
|
||||
psutil
|
||||
onnxruntime # [vad] extra: Silero VAD
|
||||
tqdm # model download progress (pywhispercpp also depends on it)
|
||||
platformdirs
|
||||
];
|
||||
|
||||
# Optional engines are intentionally not packaged: [whisper] pulls PyTorch,
|
||||
# and vosk/sherpa-onnx/faster-whisper are not in nixpkgs. The whisper.cpp
|
||||
# engine remains the default; other engines can be layered on with an
|
||||
# overlay later.
|
||||
|
||||
preFixup = ''
|
||||
gappsWrapperArgs+=(
|
||||
--prefix PATH : ${lib.makeBinPath runtimeTools}
|
||||
)
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
install -Dm644 vocalinux.desktop \
|
||||
$out/share/applications/vocalinux.desktop
|
||||
install -Dm644 resources/icons/scalable/vocalinux.svg \
|
||||
$out/share/icons/hicolor/scalable/apps/vocalinux.svg
|
||||
'';
|
||||
|
||||
dontCheck = true; # test suite needs a session bus and X display
|
||||
|
||||
pythonImportsCheck = [ "vocalinux" ];
|
||||
|
||||
meta = {
|
||||
description = "Free, offline voice dictation for Linux";
|
||||
longDescription = ''
|
||||
Hold a shortcut or toggle dictation and text lands in almost any app on
|
||||
X11 or Wayland. Speech recognition runs locally with whisper.cpp after
|
||||
downloading a model on first use.
|
||||
|
||||
Wayland/evdev shortcuts and ydotool injection need device access: on
|
||||
NixOS enable hardware.uinput and add your user to the "input" and
|
||||
"uinput" groups; the programs.vocalinux NixOS module does the first part.
|
||||
'';
|
||||
homepage = "https://github.com/VocaHQ/vocalinux";
|
||||
license = lib.licenses.agpl3Only;
|
||||
mainProgram = "vocalinux";
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
# pywhispercpp is not in nixpkgs (same gap the .deb/.rpm note in
|
||||
# packaging/native/nfpm.yaml calls out for Debian and Fedora), so the flake
|
||||
# builds it here. The PyPI sdist already vendors whisper.cpp and pybind11, so
|
||||
# no extra source fetches are needed; setup.py drives CMake from build_ext.
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchPypi,
|
||||
setuptools,
|
||||
wheel,
|
||||
cmake,
|
||||
shaderc,
|
||||
spirv-headers,
|
||||
vulkan-headers,
|
||||
vulkan-loader,
|
||||
numpy,
|
||||
requests,
|
||||
tqdm,
|
||||
platformdirs,
|
||||
autoPatchelfHook,
|
||||
stdenv,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "pywhispercpp";
|
||||
version = "1.5.1";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
hash = "sha256-XfiX5d2dnxaAT8k3vYW59YgKCymlX4hDWF4OA9dhleU=";
|
||||
};
|
||||
|
||||
# python -m build verifies every build-system.requires entry resolves to an
|
||||
# installed Python package. The ones setup.py never imports are dropped:
|
||||
# ninja is try/except'd (Unix Makefiles are the fallback), repairwheel only
|
||||
# runs on Windows, setuptools-scm is unused, and cmake is a PATH tool, not a
|
||||
# Python package.
|
||||
postPatch = ''
|
||||
substituteInPlace pyproject.toml \
|
||||
--replace-fail ' "ninja",' "" \
|
||||
--replace-fail ' "cmake>=3.12",' "" \
|
||||
--replace-fail ' "repairwheel",' "" \
|
||||
--replace-fail ' "setuptools-scm>=8"' ""
|
||||
|
||||
# setup() passes no version, so without setuptools-scm the wheel metadata
|
||||
# lands as 0.0.0; get_version() reads PYWHISPERCPP_VERSION instead.
|
||||
substituteInPlace setup.py \
|
||||
--replace-fail ' name="pywhispercpp",' ' name="pywhispercpp", version=get_version(),'
|
||||
'';
|
||||
|
||||
env = {
|
||||
# The sdist ships no version.txt; setup.py falls back to this env var.
|
||||
PYWHISPERCPP_VERSION = version;
|
||||
# Build Vulkan as a shared backend: Vocalinux's GPU detector looks for
|
||||
# libggml-vulkan.so. CMake's build-tree RPATH can leak /build into the
|
||||
# wheel; disable CMake RPATHs and let autoPatchelfHook set Nix runtime paths.
|
||||
CMAKE_ARGS = "-DBUILD_SHARED_LIBS=ON -DGGML_NATIVE=OFF -DGGML_VULKAN=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_SKIP_RPATH=ON";
|
||||
};
|
||||
|
||||
# env attrs are exported verbatim; expanding the core count needs a shell
|
||||
# phase.
|
||||
preBuild = ''
|
||||
export CMAKE_BUILD_PARALLEL_LEVEL="$NIX_BUILD_CORES"
|
||||
'';
|
||||
|
||||
# cmake is only here so setup.py's build_ext can invoke it; letting the
|
||||
# cmake configure hook run standalone leaves a build/ dir that breaks the
|
||||
# pypa wheel build.
|
||||
dontUseCmakeConfigure = true;
|
||||
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
shaderc # provides glslc, used to compile whisper.cpp's Vulkan shaders
|
||||
autoPatchelfHook
|
||||
];
|
||||
|
||||
build-system = [
|
||||
setuptools
|
||||
wheel
|
||||
];
|
||||
|
||||
# CMake's Vulkan backend calls find_package(SPIRV-Headers CONFIG REQUIRED),
|
||||
# so expose the package configuration as well as the Vulkan headers/loader.
|
||||
buildInputs = [
|
||||
stdenv.cc.cc.lib
|
||||
spirv-headers
|
||||
vulkan-headers
|
||||
vulkan-loader
|
||||
];
|
||||
|
||||
dependencies = [
|
||||
numpy
|
||||
requests
|
||||
tqdm
|
||||
platformdirs
|
||||
];
|
||||
|
||||
# pywhispercpp.model pulls in the compiled _pywhispercpp extension, so
|
||||
# checking all three proves the native binding loads, not just the package.
|
||||
pythonImportsCheck = [ "pywhispercpp" "pywhispercpp.model" "_pywhispercpp" ];
|
||||
|
||||
meta = {
|
||||
description = "Python bindings for whisper.cpp";
|
||||
homepage = "https://github.com/absadiki/pywhispercpp";
|
||||
license = lib.licenses.mit;
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
[build-system]
|
||||
# >=77 for the SPDX license string below. No upper bound: Arch extra
|
||||
# python-setuptools is 84, and the AUR PKGBUILD builds with --no-isolation.
|
||||
requires = ["setuptools>=77"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "vocalinux"
|
||||
dynamic = ["version"]
|
||||
description = "A seamless voice dictation system for Linux"
|
||||
readme = "README.md"
|
||||
license = "AGPL-3.0-only"
|
||||
license-files = ["LICENSE"]
|
||||
authors = [
|
||||
{name = "Jatin K Malik", email = "jatinkrmalik@gmail.com"}
|
||||
]
|
||||
maintainers = [
|
||||
{name = "Jatin K Malik", email = "jatinkrmalik@gmail.com"}
|
||||
]
|
||||
requires-python = ">=3.11"
|
||||
keywords = [
|
||||
"voice", "dictation", "speech", "recognition",
|
||||
"linux", "accessibility", "voice-typing", "speech-to-text"
|
||||
]
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Environment :: X11 Applications :: GTK",
|
||||
"Intended Audience :: End Users/Desktop",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: 3.14",
|
||||
"Topic :: Desktop Environment :: Gnome",
|
||||
"Topic :: Multimedia :: Sound/Audio :: Speech",
|
||||
"Topic :: Text Processing",
|
||||
"Topic :: Utilities",
|
||||
]
|
||||
dependencies = [
|
||||
"pywhispercpp>=1.5.0,<2",
|
||||
"pynput>=1.7.6,<2",
|
||||
"evdev>=1.6.0,<2; sys_platform == 'linux'",
|
||||
"requests>=2.28.0",
|
||||
"PySocks>=1.7.1,<2",
|
||||
"numpy>=1.22.0,<3",
|
||||
"pyaudio>=0.2.13",
|
||||
"PyGObject; sys_platform == 'linux'",
|
||||
"psutil>=5.9.0,<8",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
vosk = [
|
||||
"vosk>=0.3.45,<0.4",
|
||||
]
|
||||
whisper = [
|
||||
"openai-whisper>=20231117",
|
||||
"torch>=2.13.0",
|
||||
]
|
||||
parakeet = [
|
||||
"sherpa-onnx>=1.12.0,<2",
|
||||
# Match the locked sherpa-onnx version; bump both together. armv7l wheels omit this
|
||||
# dependency metadata, and the export test enforces the matching core pin.
|
||||
"sherpa-onnx-core==1.13.7; platform_machine != 'armv7l'",
|
||||
]
|
||||
faster_whisper = [
|
||||
"faster-whisper>=1.0.0,<2",
|
||||
]
|
||||
vad = [
|
||||
"onnxruntime>=1.16.0",
|
||||
]
|
||||
dev = [
|
||||
"pytest>=7.0.0",
|
||||
"pytest-cov>=4.0.0",
|
||||
"pytest-mock>=3.10.0",
|
||||
"pytest-timeout>=2.1.0",
|
||||
"pre-commit>=3.0.0",
|
||||
"mypy>=1.0.0",
|
||||
"pyyaml>=6.0,<7",
|
||||
]
|
||||
docs = [
|
||||
"sphinx>=6.0.0",
|
||||
"sphinx-rtd-theme>=1.2.0",
|
||||
]
|
||||
|
||||
# Formatters and linters, deliberately outside the `dev` extra: `uv sync
|
||||
# --only-group lint` installs them without the project, so the lint job needs
|
||||
# no portaudio/girepository headers to build pyaudio and PyGObject.
|
||||
[dependency-groups]
|
||||
# Release builds install this complete toolchain from its hash-pinned export,
|
||||
# then use --no-isolation so setuptools cannot be resolved a second time.
|
||||
release-build = [
|
||||
"build>=1.2,<2",
|
||||
"setuptools>=83",
|
||||
"wheel",
|
||||
"twine>=6,<7",
|
||||
]
|
||||
# install.sh installs this wheel-only toolchain before any source builds, then
|
||||
# disables build isolation so pip cannot resolve another unpinned environment.
|
||||
installer-build = [
|
||||
"pip>=25.3,<27",
|
||||
# Torch 2.13 supports setuptools 82+, so keep this at the patched version
|
||||
# for setuptools' 2026 sdist normalization advisory.
|
||||
"setuptools>=83",
|
||||
"wheel",
|
||||
"meson-python>=0.16",
|
||||
"cmake==3.31.10",
|
||||
"ninja==1.13.0",
|
||||
"repairwheel",
|
||||
"setuptools-scm>=8",
|
||||
]
|
||||
lint = [
|
||||
"black>=23.0.0",
|
||||
"isort>=5.12.0",
|
||||
"flake8>=6.0.0",
|
||||
"mypy>=1.0.0",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
vocalinux = "vocalinux.main:main"
|
||||
|
||||
[project.gui-scripts]
|
||||
vocalinux-gui = "vocalinux.main:main"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/VocaHQ/vocalinux"
|
||||
Documentation = "https://github.com/VocaHQ/vocalinux/tree/main/docs"
|
||||
Repository = "https://github.com/VocaHQ/vocalinux"
|
||||
Issues = "https://github.com/VocaHQ/vocalinux/issues"
|
||||
Changelog = "https://github.com/VocaHQ/vocalinux/releases"
|
||||
|
||||
[tool.uv]
|
||||
# Contributors may use uv 0.12 or 0.13. CI and lock/export generation use
|
||||
# uv 0.13.3 for reproducible export formatting (see `just lock`).
|
||||
required-version = ">=0.12,<0.14"
|
||||
|
||||
[tool.setuptools]
|
||||
# Resource dirs carry no .py files, but setuptools still treats them as packages.
|
||||
packages = [
|
||||
"vocalinux",
|
||||
"vocalinux.audio",
|
||||
"vocalinux.gateway_embed",
|
||||
"vocalinux.resources",
|
||||
"vocalinux.resources.icons",
|
||||
"vocalinux.resources.icons.scalable",
|
||||
"vocalinux.resources.sounds",
|
||||
"vocalinux.speech_recognition",
|
||||
"vocalinux.speech_recognition.data",
|
||||
"vocalinux.speech_recognition.engines",
|
||||
"vocalinux.text_injection",
|
||||
"vocalinux.ui",
|
||||
"vocalinux.ui.keyboard_backends",
|
||||
"vocalinux.utils",
|
||||
]
|
||||
package-dir = {"" = "src"}
|
||||
|
||||
[tool.setuptools.dynamic]
|
||||
version = {attr = "vocalinux.version.__version__"}
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
"*" = ["*.svg", "*.wav", "*.onnx"]
|
||||
"vocalinux" = ["resources/**/*"]
|
||||
"vocalinux.speech_recognition" = ["data/*.onnx", "data/LICENSE"]
|
||||
"vocalinux.utils" = ["model_checksums.txt"]
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
target-version = ['py311', 'py312', 'py313', 'py314']
|
||||
include = '\.pyi?$'
|
||||
exclude = '''
|
||||
/(
|
||||
\.git
|
||||
| \.hg
|
||||
| \.mypy_cache
|
||||
| \.tox
|
||||
| \.venv
|
||||
| venv
|
||||
| _build
|
||||
| buck-out
|
||||
| build
|
||||
| dist
|
||||
| node_modules
|
||||
)/
|
||||
'''
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
line_length = 100
|
||||
skip_gitignore = true
|
||||
skip = [".git", "venv", "node_modules", "build", "dist"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "7.0"
|
||||
addopts = "-ra -q --strict-markers --timeout=10 --timeout_method=thread"
|
||||
testpaths = ["tests"]
|
||||
python_files = ["test_*.py"]
|
||||
python_functions = ["test_*"]
|
||||
markers = [
|
||||
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
||||
"integration: marks tests as integration tests",
|
||||
"audio: marks tests that require audio hardware",
|
||||
]
|
||||
filterwarnings = [
|
||||
"ignore:The NumPy module was reloaded:UserWarning",
|
||||
"ignore:There is no current event loop:DeprecationWarning",
|
||||
]
|
||||
|
||||
[tool.coverage.run]
|
||||
source = ["src"]
|
||||
branch = true
|
||||
omit = [
|
||||
"*/tests/*",
|
||||
"*/__pycache__/*",
|
||||
# GTK dialog files are untestable without a real GTK environment
|
||||
"*/settings_dialog.py",
|
||||
"*/logging_dialog.py",
|
||||
]
|
||||
|
||||
[tool.coverage.report]
|
||||
exclude_lines = [
|
||||
"pragma: no cover",
|
||||
"def __repr__",
|
||||
"raise NotImplementedError",
|
||||
"if TYPE_CHECKING:",
|
||||
"if __name__ == .__main__.:",
|
||||
]
|
||||
show_missing = true
|
||||
|
||||
[tool.mypy]
|
||||
# Target the supported floor so typechecking covers what requires-python promises.
|
||||
python_version = "3.11"
|
||||
warn_return_any = true
|
||||
warn_unused_configs = true
|
||||
ignore_missing_imports = true
|
||||
exclude = ["venv", "build", "dist", "node_modules"]
|
||||
|
||||
# numpy 2.x ships stubs written in 3.12 syntax, which a 3.11 target cannot parse.
|
||||
# We only pass arrays through, so skipping the stubs costs little compared to
|
||||
# type-checking against the Python version we actually promise to support.
|
||||
[[tool.mypy.overrides]]
|
||||
module = ["numpy", "numpy.*"]
|
||||
follow_imports = "skip"
|
||||
follow_imports_for_stubs = true
|
||||
@@ -0,0 +1,10 @@
|
||||
# Build tools for packaging/appimage/build.sh — installed on the build host,
|
||||
# never into the AppImage.
|
||||
#
|
||||
# Taken from PyPI rather than the base image so the toolchain is pinned instead
|
||||
# of inherited: the base image's cmake is 3.22.1, exactly shaderc's floor and
|
||||
# below what newer ggml releases ask for. Stay on the 3.x line — CMake 4 removed
|
||||
# compatibility with the `cmake_minimum_required(VERSION 3.4...3.18)` that
|
||||
# pywhispercpp still declares.
|
||||
cmake==3.31.10
|
||||
ninja==1.13.0
|
||||
@@ -0,0 +1,44 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile requirements/appimage-tools.in --universal --no-deps --generate-hashes -o requirements/appimage-tools.txt
|
||||
cmake==3.31.10 \
|
||||
--hash=sha256:1debc3a0823ce5d8d1bc17154599bbbb337c2681f93622b618bc78f46576e42a \
|
||||
--hash=sha256:2f766bb46367e5e0559fa33184653754bce044583a06014dcaebf8e6dff8a1f1 \
|
||||
--hash=sha256:3c17bb24dba15f8ecc3fd706afe04264410ef88796f4115c119327c961d5dc57 \
|
||||
--hash=sha256:422a54711aa977af19d59b8f6010354cdda0b72a2e6d702b6d892e3e2cdf98a2 \
|
||||
--hash=sha256:4cefb0a28ac1268b4eed4b595bf3aaff8de9704089066027700ec36584eccab8 \
|
||||
--hash=sha256:678fc23db37cc69f01e18eb28790450ecc9401fd2fcd43364cc18f92330c12c2 \
|
||||
--hash=sha256:6970bb75c4dfc28cc31ff0cd848194d09094ae00d605181e1345b2ff70b61050 \
|
||||
--hash=sha256:7c300e4ae68fbc1414a85505f7feb262cee82ff3304a286885ebf803b11a997c \
|
||||
--hash=sha256:8d2ec5fc45d305227020c82213140a51a0cebe3c84f0299036f05716b3a52f60 \
|
||||
--hash=sha256:91410816db3beefe2f6032d721f9978c98dc7646e9992c0325486597164fab81 \
|
||||
--hash=sha256:a4a5615f31f692c9b9aa8b365704e4b76172348af6fa40e16fea3f118bb01194 \
|
||||
--hash=sha256:a7864605238759a4ae8e3bd1fda2bb03978e3e37df310852662dcf53866413c8 \
|
||||
--hash=sha256:ad697643a00d9ba85179590a383c4f7401169b55ebf4b8b2938daf28c6bdeb6d \
|
||||
--hash=sha256:b059a1810a2ce766b3e531bdc8d730bc192e260a9fa7dec7a0eb7a053d6063c7 \
|
||||
--hash=sha256:b331984de38dbda22d676f8812c8905526341ba7b397fe8c359255ff4d051193 \
|
||||
--hash=sha256:c2e5361dea9754ed3b06cf834894fb47dcbe7036d5e5d87acaeb10ff3dd5fd10 \
|
||||
--hash=sha256:e135d5f1e59f1dc1c80eea87321977d6c0eff86cb601c28e0965a1dd457ea587 \
|
||||
--hash=sha256:ec3d14a0e72e401b3665034dc37901df17f0b4e9c5b163be6cfedfb93470ac0f \
|
||||
--hash=sha256:f1ea1fe826355560e8976c3d5794d9357444209bc0e0d56676c71e6a571fd474
|
||||
# via -r requirements/appimage-tools.in
|
||||
ninja==1.13.0 \
|
||||
--hash=sha256:11be2d22027bde06f14c343f01d31446747dbb51e72d00decca2eb99be911e2f \
|
||||
--hash=sha256:1c97223cdda0417f414bf864cfb73b72d8777e57ebb279c5f6de368de0062988 \
|
||||
--hash=sha256:3c0b40b1f0bba764644385319028650087b4c1b18cdfa6f45cb39a3669b81aa9 \
|
||||
--hash=sha256:3d00c692fb717fd511abeb44b8c5d00340c36938c12d6538ba989fe764e79630 \
|
||||
--hash=sha256:3d7d7779d12cb20c6d054c61b702139fd23a7a964ec8f2c823f1ab1b084150db \
|
||||
--hash=sha256:4a40ce995ded54d9dc24f8ea37ff3bf62ad192b547f6c7126e7e25045e76f978 \
|
||||
--hash=sha256:4be9c1b082d244b1ad7ef41eb8ab088aae8c109a9f3f0b3e56a252d3e00f42c1 \
|
||||
--hash=sha256:5f8e1e8a1a30835eeb51db05cf5a67151ad37542f5a4af2a438e9490915e5b72 \
|
||||
--hash=sha256:60056592cf495e9a6a4bea3cd178903056ecb0943e4de45a2ea825edb6dc8d3e \
|
||||
--hash=sha256:6739d3352073341ad284246f81339a384eec091d9851a886dfa5b00a6d48b3e2 \
|
||||
--hash=sha256:8cfbb80b4a53456ae8a39f90ae3d7a2129f45ea164f43fadfa15dc38c4aef1c9 \
|
||||
--hash=sha256:aa45b4037b313c2f698bc13306239b8b93b4680eb47e287773156ac9e9304714 \
|
||||
--hash=sha256:b4f2a072db3c0f944c32793e91532d8948d20d9ab83da9c0c7c15b5768072200 \
|
||||
--hash=sha256:be7f478ff9f96a128b599a964fc60a6a87b9fa332ee1bd44fa243ac88d50291c \
|
||||
--hash=sha256:d741a5e6754e0bda767e3274a0f0deeef4807f1fec6c0d7921a0244018926ae5 \
|
||||
--hash=sha256:e8bad11f8a00b64137e9b315b137d8bb6cbf3086fbdc43bf1f90fd33324d2e96 \
|
||||
--hash=sha256:fa2a8bfc62e31b08f83127d1613d10821775a0eb334197154c4d6067b7068ff1 \
|
||||
--hash=sha256:fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa \
|
||||
--hash=sha256:fb8ee8719f8af47fed145cced4a85f0755dd55d45b2bddaf7431fa89803c5f3e
|
||||
# via -r requirements/appimage-tools.in
|
||||
@@ -0,0 +1,10 @@
|
||||
# Python packages bundled into the AppImage on top of requirements/vad.txt.
|
||||
#
|
||||
# PyGObject is excluded from the lock exports (--no-emit-package pygobject)
|
||||
# because every other install path takes it from the distro. The AppImage has no
|
||||
# distro to take it from: it bundles a managed CPython, so it builds PyGObject
|
||||
# against the base image's girepository, which caps it at the 3.50 line —
|
||||
# uv.lock's 3.56 needs girepository-2.0 (glib 2.80+), and the base image the
|
||||
# AppImage builds in ships glib 2.72. Compiled with --no-deps: pycairo is
|
||||
# already pinned in requirements/runtime.txt and must not be resolved twice.
|
||||
pygobject==3.50.2
|
||||
@@ -0,0 +1,5 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile requirements/appimage.in --universal --no-deps --generate-hashes -o requirements/appimage.txt
|
||||
pygobject==3.50.2 \
|
||||
--hash=sha256:ece6b860aab77cb649fdfc6e88d8a83765e7a62f7ffd39a628d6e2a0d397a7ff
|
||||
# via -r requirements/appimage.in
|
||||
@@ -0,0 +1,722 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --no-dev --extra faster-whisper --no-emit-project --no-emit-package pygobject -o requirements/faster-whisper.txt
|
||||
anyio==4.15.1 \
|
||||
--hash=sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101 \
|
||||
--hash=sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94
|
||||
# via httpx
|
||||
av==18.1.0 \
|
||||
--hash=sha256:025f84494cb23278498f03b0d8117d3e47a1cbc9c44b97eb31875cf02251e46b \
|
||||
--hash=sha256:08a9ae288299cfcbf739dba4ad0c53b9b71f45184303dd45947920d022fed695 \
|
||||
--hash=sha256:191224788d87af06c31784a395bb73f14b72f33d7f4871ace0157de2abdc6276 \
|
||||
--hash=sha256:3c8b1f8b46f99d52e2d8b0ed5d0cdadf172d24794d46e2077b16e44ed08e26ff \
|
||||
--hash=sha256:47bfc286e1bc9de7ab4681fc2b575cd2460a66919d31ffe1bd5aa54fae531a28 \
|
||||
--hash=sha256:5509ec12aaa19fd6601de13cfa6f4cdad450da07982118510592875d970454d6 \
|
||||
--hash=sha256:5548b79e2bf1f59b3e9aedc918a72d9dc45b9adaac10ff9470d5dbdda0002e47 \
|
||||
--hash=sha256:5cd9085028902c9880622bd37a12fd4b33060f06a52311f6f4867ca9f29a2c3b \
|
||||
--hash=sha256:6fc837cc51adf80331ac850779cd53b5d4c4460b0ebe9057a02a921c6736f19d \
|
||||
--hash=sha256:8a032e8d8ebc73dec079364b9b4a6837638a2d106e8472314e685ffbf163e700 \
|
||||
--hash=sha256:ab5ac081bc9eaf54109120d4e56284674fecfbe520d9aa1707c7fa911ec5f4d2 \
|
||||
--hash=sha256:ae75d8bb6467895ed1f8572ededf7ffa49eac07f6e483222f5d7d62a41d12f04 \
|
||||
--hash=sha256:b30a4e8d934558e19602b68998a4d9ac9f250fa0dacef216f7e8e40153b13316 \
|
||||
--hash=sha256:b36b0bae9e4c62f9487c99481ec15e4e3870fcc868522cd6d18fc2d6bfa04f01 \
|
||||
--hash=sha256:cf8a17466bef07765dbdecc9e66ed9b25d20b4e14f654fbf35345a58ac45fa0c \
|
||||
--hash=sha256:d49a5c542dfdc00f43c6cdb6cc41dac1781ee206fe180b56aa7433dfa816dfae \
|
||||
--hash=sha256:e4d48b9f12cad009cc72fe4f4099107de5e819c95f82767f4fd01a01481c0661 \
|
||||
--hash=sha256:e7ea063f6690193ea335a1d592d6e0274350d45e2ed6af83ee107cb90cbfd84f \
|
||||
--hash=sha256:ea1480b7a8d5405cb5f382b344731bf125fd2c1c6fae3964f6c48595628387ff
|
||||
# via faster-whisper
|
||||
certifi==2026.10.19 \
|
||||
--hash=sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae \
|
||||
--hash=sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b
|
||||
# via
|
||||
# httpcore
|
||||
# httpx
|
||||
# requests
|
||||
charset-normalizer==3.5.1 \
|
||||
--hash=sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5 \
|
||||
--hash=sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b \
|
||||
--hash=sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f \
|
||||
--hash=sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5 \
|
||||
--hash=sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22 \
|
||||
--hash=sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5 \
|
||||
--hash=sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac \
|
||||
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
||||
--hash=sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626 \
|
||||
--hash=sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4 \
|
||||
--hash=sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369 \
|
||||
--hash=sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b \
|
||||
--hash=sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e \
|
||||
--hash=sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee \
|
||||
--hash=sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1 \
|
||||
--hash=sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102 \
|
||||
--hash=sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8 \
|
||||
--hash=sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9 \
|
||||
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
||||
--hash=sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031 \
|
||||
--hash=sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e \
|
||||
--hash=sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235 \
|
||||
--hash=sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072 \
|
||||
--hash=sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb \
|
||||
--hash=sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c \
|
||||
--hash=sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950 \
|
||||
--hash=sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2 \
|
||||
--hash=sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e \
|
||||
--hash=sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6 \
|
||||
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
||||
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
||||
--hash=sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2 \
|
||||
--hash=sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032 \
|
||||
--hash=sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71 \
|
||||
--hash=sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96 \
|
||||
--hash=sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687 \
|
||||
--hash=sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8 \
|
||||
--hash=sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3 \
|
||||
--hash=sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61 \
|
||||
--hash=sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9 \
|
||||
--hash=sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1 \
|
||||
--hash=sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4 \
|
||||
--hash=sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65 \
|
||||
--hash=sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663 \
|
||||
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
||||
--hash=sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591 \
|
||||
--hash=sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a \
|
||||
--hash=sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e \
|
||||
--hash=sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7 \
|
||||
--hash=sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3 \
|
||||
--hash=sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c \
|
||||
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
||||
--hash=sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7 \
|
||||
--hash=sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96 \
|
||||
--hash=sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486 \
|
||||
--hash=sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3 \
|
||||
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
||||
--hash=sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b \
|
||||
--hash=sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731 \
|
||||
--hash=sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959 \
|
||||
--hash=sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9 \
|
||||
--hash=sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf \
|
||||
--hash=sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8 \
|
||||
--hash=sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e \
|
||||
--hash=sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885 \
|
||||
--hash=sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0 \
|
||||
--hash=sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506 \
|
||||
--hash=sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2 \
|
||||
--hash=sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0 \
|
||||
--hash=sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e \
|
||||
--hash=sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e \
|
||||
--hash=sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491 \
|
||||
--hash=sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a \
|
||||
--hash=sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20 \
|
||||
--hash=sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449 \
|
||||
--hash=sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af \
|
||||
--hash=sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c \
|
||||
--hash=sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712 \
|
||||
--hash=sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7 \
|
||||
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
||||
--hash=sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9 \
|
||||
--hash=sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e \
|
||||
--hash=sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5 \
|
||||
--hash=sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36 \
|
||||
--hash=sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263 \
|
||||
--hash=sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4 \
|
||||
--hash=sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11 \
|
||||
--hash=sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a \
|
||||
--hash=sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3 \
|
||||
--hash=sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375 \
|
||||
--hash=sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d \
|
||||
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
||||
--hash=sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c \
|
||||
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
||||
--hash=sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6 \
|
||||
--hash=sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc \
|
||||
--hash=sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b \
|
||||
--hash=sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f \
|
||||
--hash=sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00 \
|
||||
--hash=sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10 \
|
||||
--hash=sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598 \
|
||||
--hash=sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6 \
|
||||
--hash=sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962 \
|
||||
--hash=sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c \
|
||||
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
||||
--hash=sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573 \
|
||||
--hash=sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90 \
|
||||
--hash=sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5 \
|
||||
--hash=sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18 \
|
||||
--hash=sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af \
|
||||
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
||||
--hash=sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b \
|
||||
--hash=sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6 \
|
||||
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
||||
--hash=sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774 \
|
||||
--hash=sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004 \
|
||||
--hash=sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a \
|
||||
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
||||
--hash=sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2 \
|
||||
--hash=sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe \
|
||||
--hash=sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3 \
|
||||
--hash=sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc \
|
||||
--hash=sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d \
|
||||
--hash=sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc \
|
||||
--hash=sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893 \
|
||||
--hash=sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef \
|
||||
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
||||
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30 \
|
||||
--hash=sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7 \
|
||||
--hash=sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5 \
|
||||
--hash=sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f \
|
||||
--hash=sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9 \
|
||||
--hash=sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada \
|
||||
--hash=sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876 \
|
||||
--hash=sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a \
|
||||
--hash=sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348 \
|
||||
--hash=sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3 \
|
||||
--hash=sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f \
|
||||
--hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \
|
||||
--hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f
|
||||
# via requests
|
||||
click==8.4.2 \
|
||||
--hash=sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6 \
|
||||
--hash=sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76
|
||||
# via huggingface-hub
|
||||
colorama==0.4.6 ; sys_platform == 'win32' \
|
||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via
|
||||
# click
|
||||
# tqdm
|
||||
ctranslate2==4.8.2 \
|
||||
--hash=sha256:00bc9f44172d05bd2becefe757d2397ab3292fad1695169f9ebb9c16eb497ce2 \
|
||||
--hash=sha256:1e866ccf5f5668f7302c39b535d19d7e5811f3f00d6246faf6ed6fa070fa1af3 \
|
||||
--hash=sha256:249b35f575adf8dd11e6ba43b212d5cbfc845d1140abc610c2872eef1ffb3481 \
|
||||
--hash=sha256:2778eaf89340062feb0d2d3dd35bedb14644673ccbce8934782dc8d093b2cab9 \
|
||||
--hash=sha256:32b9d0e984aa17a0da9b37bb7e4dcc638e898a2c32de08d5a4db53f15f640faa \
|
||||
--hash=sha256:3823c9883c2c410a76b2f19feda9da628a3c112cedfd912db815e0055c8235e2 \
|
||||
--hash=sha256:399c20a7336b6358f69ce3c615e090eabc08f29735a079fd1ac1e464119e0861 \
|
||||
--hash=sha256:5385f15493e7b6f41377da83d0d5afeb8e0f36188260722f3800c3c7121455af \
|
||||
--hash=sha256:554a0b2abf098a11c66ef7930c0a05b3de683a455e8ea3f2e6ab6966aaabc136 \
|
||||
--hash=sha256:573dcf5d96034dd9bcf7ee0db1657af490a52292ffc77dfb4b104da1e93322ad \
|
||||
--hash=sha256:58b1a78d050a7f281907b8acfe6f0cdbbf2feaf7464f38eb05b846f83fbaa297 \
|
||||
--hash=sha256:633f19d1ff8d053a8b179ca742b242002ac7882a2ab44e319c6efcde27d586a4 \
|
||||
--hash=sha256:70e2388d31dfb59968e6e011d01a6fc6bf802c0e1ad920a8d2a413f1c9da02ae \
|
||||
--hash=sha256:781f835da7fdc4adcc38f9d674dbe9b37eaf3c9aee3b2bc17d684342ff59d549 \
|
||||
--hash=sha256:8221875b09ef982e3579a5165f8c9fcfb3d5de0f710af228eca2f73d69635ace \
|
||||
--hash=sha256:980f13e1d41987908af945861081158fbcb2983f4f9399514adc8c87378b5587 \
|
||||
--hash=sha256:995938fcd24a1174a7abf9765e7fa216b5b91a1d8e8c4c8f383c7a186e8bab2e \
|
||||
--hash=sha256:a24e0a95151b970941867fec94c983df978630f1996242a587c072d455607d28 \
|
||||
--hash=sha256:a40b190248389e1adb38ff90407937131c6bb9d7f9771f29ca1dca01946ff252 \
|
||||
--hash=sha256:cb2a5b4c206b3bd1f7f4b44d07e86e42050af6753053cdc86444f8d0ead9d6d8 \
|
||||
--hash=sha256:d94421d565d0de61c032998f737a18942b0f2bef40c0424b1846ec6f67300105 \
|
||||
--hash=sha256:dd9ab8b521230e8e962a58362b1ccde582806e781af8c1b9d7b244f3024468b1 \
|
||||
--hash=sha256:e32ae5e625a8999749745de43c2de5c12ceebb6d0d9cc9a3a956e8912bd68edb \
|
||||
--hash=sha256:f6f0b576c247984d3fc299a372ccc9319b668d6d25b0539f3c861beba15d0504 \
|
||||
--hash=sha256:fedda669421a57f8164568ee86ea265727016988d310fcc2e24ca30e9ec457cd
|
||||
# via faster-whisper
|
||||
evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
faster-whisper==1.2.1 \
|
||||
--hash=sha256:79a66ad50688c0b794dd501dc340a736992a6342f7f95e5811be60b5224a26a7
|
||||
# via vocalinux
|
||||
filelock==4.2.1 \
|
||||
--hash=sha256:7be2662e9e826b9bba28afc0f843a123280d799a2ea44bb5d35ccec67905ae44 \
|
||||
--hash=sha256:c4c937ccac2a813cee448e662a56366cfb374c0f8702e75f295c412cc1c5d5a3
|
||||
# via huggingface-hub
|
||||
flatbuffers==25.12.19 \
|
||||
--hash=sha256:7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4
|
||||
# via onnxruntime
|
||||
fsspec==2026.7.0 \
|
||||
--hash=sha256:b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279 \
|
||||
--hash=sha256:c803c40f4cf860b49dea58ee3e1c33cb9c790520e233537e1340049f89b82a88
|
||||
# via huggingface-hub
|
||||
h11==0.16.0 \
|
||||
--hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \
|
||||
--hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86
|
||||
# via httpcore
|
||||
hf-xet==1.6.0 ; platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64' \
|
||||
--hash=sha256:0e6e21fa3cdfcdcd76748564bf593870a5e013f47d97cf10aed63aa222cff5b7 \
|
||||
--hash=sha256:23379c2f9ec8696d952b16414a2bae72cad86a52df869b050698ba60f538c675 \
|
||||
--hash=sha256:2e58454a340b3556dfa4972d5451aff4fba8dd42a236600ba1a1d2b1514f0fef \
|
||||
--hash=sha256:35cec30d75c6f9eb9c16a77cef68e85a103b72e24d4b473714ec9ff06428bab9 \
|
||||
--hash=sha256:3dc3e35441ba395006af5aaacc40ef2e603c51ef46c3530b9156185f00935ea3 \
|
||||
--hash=sha256:4fc74352a17015bd0ee90038bc9efe38db894cde45f268b6712b04fce8cd0acb \
|
||||
--hash=sha256:5153e6bb103ad49d6ea9f1b2e230db5a2ea32551ad09a706d2f61d7c7c80d80e \
|
||||
--hash=sha256:5789835d7c6bc9436962853192082374297fb72d7eff7e7762ec25ceb7e25338 \
|
||||
--hash=sha256:633dc0cd71d32da58ab8c03ad38e2fac452c15c2b0a2866ebf6ededfe0a5061d \
|
||||
--hash=sha256:70cbb9c896901600128cb9b6f06e132954fbede1db30f31f7c6c63f84cb7c31d \
|
||||
--hash=sha256:75765820ce4700db3750c94acc8fe27c5fae4c9ec000a0dbac3ca082acf97765 \
|
||||
--hash=sha256:8fb4f71cba6129110c3374a33f919001ff130488fc23553698e34cc1c2a1198c \
|
||||
--hash=sha256:948f15d3a9545cfe5932f6bd8b440f6ae630aee108f14b7bd6c561f7c2dcc522 \
|
||||
--hash=sha256:d62671bb130879cef0ee4c9ebe47a14af6c66ec53e6d84dc15936e5ffdfac82f \
|
||||
--hash=sha256:f0906082d9932ae0c0057fa194041c22b4e2cdb46b2592ef3b91f020d62a081a \
|
||||
--hash=sha256:f2f7278c05c22fd60cb436cda1269649b3e81db65ecdc8496e5e164aa4143e7b \
|
||||
--hash=sha256:fb4fadde1b2b70bf4c0c14a6dccbe7194b1c28947fefd5bbe3fed9d940676c3b
|
||||
# via huggingface-hub
|
||||
httpcore==1.0.9 \
|
||||
--hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \
|
||||
--hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8
|
||||
# via httpx
|
||||
httpx==0.28.1 \
|
||||
--hash=sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc \
|
||||
--hash=sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad
|
||||
# via huggingface-hub
|
||||
huggingface-hub==1.30.0 \
|
||||
--hash=sha256:96ae0a8e99a234374a6fe43e989ebd21c04640b91ab2927e7e5773ba1131ca59 \
|
||||
--hash=sha256:e6a6120bc8c8e2723d03648434ee247088cceb55ba7067e7d34d692cad5fdb57
|
||||
# via
|
||||
# faster-whisper
|
||||
# tokenizers
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
# requests
|
||||
numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \
|
||||
--hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \
|
||||
--hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \
|
||||
--hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \
|
||||
--hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \
|
||||
--hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \
|
||||
--hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \
|
||||
--hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \
|
||||
--hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \
|
||||
--hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \
|
||||
--hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \
|
||||
--hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \
|
||||
--hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \
|
||||
--hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \
|
||||
--hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \
|
||||
--hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \
|
||||
--hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \
|
||||
--hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \
|
||||
--hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \
|
||||
--hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \
|
||||
--hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \
|
||||
--hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \
|
||||
--hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \
|
||||
--hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \
|
||||
--hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \
|
||||
--hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \
|
||||
--hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \
|
||||
--hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \
|
||||
--hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \
|
||||
--hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \
|
||||
--hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \
|
||||
--hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \
|
||||
--hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \
|
||||
--hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \
|
||||
--hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \
|
||||
--hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \
|
||||
--hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \
|
||||
--hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \
|
||||
--hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \
|
||||
--hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \
|
||||
--hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \
|
||||
--hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \
|
||||
--hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \
|
||||
--hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \
|
||||
--hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \
|
||||
--hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \
|
||||
--hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \
|
||||
--hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \
|
||||
--hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \
|
||||
--hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \
|
||||
--hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \
|
||||
--hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \
|
||||
--hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \
|
||||
--hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \
|
||||
--hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \
|
||||
--hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \
|
||||
--hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \
|
||||
--hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \
|
||||
--hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \
|
||||
--hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \
|
||||
--hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \
|
||||
--hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \
|
||||
--hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \
|
||||
--hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \
|
||||
--hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \
|
||||
--hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \
|
||||
--hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \
|
||||
--hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \
|
||||
--hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \
|
||||
--hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \
|
||||
--hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# ctranslate2
|
||||
# onnxruntime
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
--hash=sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7 \
|
||||
--hash=sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0 \
|
||||
--hash=sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3 \
|
||||
--hash=sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c \
|
||||
--hash=sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce \
|
||||
--hash=sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8 \
|
||||
--hash=sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1 \
|
||||
--hash=sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4 \
|
||||
--hash=sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee \
|
||||
--hash=sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740 \
|
||||
--hash=sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98 \
|
||||
--hash=sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710 \
|
||||
--hash=sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee \
|
||||
--hash=sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68 \
|
||||
--hash=sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf \
|
||||
--hash=sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8 \
|
||||
--hash=sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf \
|
||||
--hash=sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b \
|
||||
--hash=sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884 \
|
||||
--hash=sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03 \
|
||||
--hash=sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69 \
|
||||
--hash=sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4 \
|
||||
--hash=sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842 \
|
||||
--hash=sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65 \
|
||||
--hash=sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080 \
|
||||
--hash=sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e \
|
||||
--hash=sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e \
|
||||
--hash=sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414 \
|
||||
--hash=sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59 \
|
||||
--hash=sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8 \
|
||||
--hash=sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617 \
|
||||
--hash=sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4 \
|
||||
--hash=sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb \
|
||||
--hash=sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251 \
|
||||
--hash=sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d \
|
||||
--hash=sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2 \
|
||||
--hash=sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab \
|
||||
--hash=sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657 \
|
||||
--hash=sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15 \
|
||||
--hash=sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9 \
|
||||
--hash=sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8 \
|
||||
--hash=sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323 \
|
||||
--hash=sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788 \
|
||||
--hash=sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc \
|
||||
--hash=sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56 \
|
||||
--hash=sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1 \
|
||||
--hash=sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d \
|
||||
--hash=sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec \
|
||||
--hash=sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2 \
|
||||
--hash=sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e \
|
||||
--hash=sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7 \
|
||||
--hash=sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26 \
|
||||
--hash=sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514 \
|
||||
--hash=sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860 \
|
||||
--hash=sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a \
|
||||
--hash=sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1 \
|
||||
--hash=sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab \
|
||||
--hash=sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba \
|
||||
--hash=sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12 \
|
||||
--hash=sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6 \
|
||||
--hash=sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e \
|
||||
--hash=sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac \
|
||||
--hash=sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# ctranslate2
|
||||
# onnxruntime
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
onnxruntime==1.29.0 \
|
||||
--hash=sha256:07c5907474dec4a2792fd7626b753dc66707808385a6d9eecf993db0066a9d0f \
|
||||
--hash=sha256:0d4f427afac434b0070fe992b540ddf20a7aff2265f760f314d91331935b6b98 \
|
||||
--hash=sha256:11264bb58f7b7cf6af835ab10d36838d73680580820fd6f51d90124a1ca8f449 \
|
||||
--hash=sha256:16925ef8497e2c07e4b5ae15b504079b3ab3f65e22c58efd10dde0f3caea969a \
|
||||
--hash=sha256:1ea91cef3b971506e51ae9c37c16d027774ec64994a524ec1bdfb027d68a9832 \
|
||||
--hash=sha256:2945e1f82f81f27e88decea88c7861f45baea23818950d467bf3909aa303119e \
|
||||
--hash=sha256:2b80d8c7ec2cc7438e4da3760b88c24568cba72c9ace96d668800a6c79419acb \
|
||||
--hash=sha256:3a3814c041251d6a77fdf513fb282056538ee826d2f1178a0df3c549d3fff6ba \
|
||||
--hash=sha256:4a3129ae56e70d2618ff773920166916310370a7e3cacb60b9e0e8910092725f \
|
||||
--hash=sha256:4acf2b4948b7ede87221ca6332344b8facdc8059d6ac751a7d367d04532b02dd \
|
||||
--hash=sha256:4b940b0d777590c7e20bf298f5c16af1ea6ad1b400a1c822a6be192f64f4d954 \
|
||||
--hash=sha256:4eae472cf7dc3107dec1bb53cd6d142d1964616d08aae48654cd4254b2363c4b \
|
||||
--hash=sha256:533f8370ce124304e5cb08ab961836cf755631e3dd77adc5f3bbdab70c2b7d99 \
|
||||
--hash=sha256:6c0c37b92f67ed68dd36221ce0403e1d9bd4f7efce724439978a2597848530e5 \
|
||||
--hash=sha256:85f8e8406c52658735fe5c7fbfd3ebaa1ed340768324f6252e4274e374580a23 \
|
||||
--hash=sha256:939e5d65f332e6d399774b2bd0d3559fd8fa629c1e77833db29d968d2384f23d \
|
||||
--hash=sha256:be0f8ed688cfb1d4d5765a137193b7bfab0c8ea214eed99260b380bb525a3a7f \
|
||||
--hash=sha256:c1ad3f437153fe77f9d01a08fbaac0beb030e09b8a80ace1603bcf69b6c95481 \
|
||||
--hash=sha256:d2fb19e848f7c33ed8d3182b52504aaa11c5e8da438bbb47296f85b133cbcf6b \
|
||||
--hash=sha256:d67673c5367727860922c5262d724472f1b5539fb7ccf4c81a638f9b71719803 \
|
||||
--hash=sha256:dc61a79cb39afd66ab3f01fd2c23591a7f01de89c1668e1fb6315067fc279164 \
|
||||
--hash=sha256:e2128f31f449e922c62dbe5d8b6b7b079f0bcaf2d56a102fa203cb6e5bb5ab19 \
|
||||
--hash=sha256:e417ef8628dcce310d2d53023e750ea298ec14d4341ae6dc3a572bfd9bc7fa97 \
|
||||
--hash=sha256:e74b278af1d949876f5d91d1268fd6c680e79f2bac194967394eaba9fdf69e7e
|
||||
# via faster-whisper
|
||||
packaging==26.3 \
|
||||
--hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
|
||||
--hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
|
||||
# via
|
||||
# huggingface-hub
|
||||
# onnxruntime
|
||||
platformdirs==4.11.3 \
|
||||
--hash=sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7 \
|
||||
--hash=sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab
|
||||
# via pywhispercpp
|
||||
protobuf==7.35.1 \
|
||||
--hash=sha256:11d6b0ec246892d85215b0a13ca6e0233cf5284b68f0ac02646427f4ff88a799 \
|
||||
--hash=sha256:230a75ddfc2de4806e56696ce9640c1cdfdb6543b7cfce98d42a4c0a0e7bdb87 \
|
||||
--hash=sha256:24f857477359a85c0c235261b8ba905fd51b2562f4a64ca1df5473f29850cbf6 \
|
||||
--hash=sha256:353652e4efd0bca5b5fc2656abf8307ef351f0cf938c9eba09f0e09c20a25c30 \
|
||||
--hash=sha256:4bc97768d8fe4ad6743c8a19403e314511ed9f6d13205b687e52421c023ac1b9 \
|
||||
--hash=sha256:74758715c53d7158fb76caf4f0cfdacc5329a4b1bb994f865d6cf302d413a1c4 \
|
||||
--hash=sha256:b73f9489a4b8b1c9cb1f8ed951c736392592edb24b9d6819f36d2e10b171d5b4 \
|
||||
--hash=sha256:ce115a26fe0c39a2c29973d914d327e516a6455464489fe3cd1e51a1b354f81a
|
||||
# via onnxruntime
|
||||
psutil==7.2.2 \
|
||||
--hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \
|
||||
--hash=sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 \
|
||||
--hash=sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841 \
|
||||
--hash=sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63 \
|
||||
--hash=sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979 \
|
||||
--hash=sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a \
|
||||
--hash=sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b \
|
||||
--hash=sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9 \
|
||||
--hash=sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee \
|
||||
--hash=sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312 \
|
||||
--hash=sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b \
|
||||
--hash=sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9 \
|
||||
--hash=sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e \
|
||||
--hash=sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc \
|
||||
--hash=sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1 \
|
||||
--hash=sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf \
|
||||
--hash=sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea \
|
||||
--hash=sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
--hash=sha256:5fce4bcdd2e0e8c063d835dbe2860dac46437506af509353c7f8114d4bacbd5b \
|
||||
--hash=sha256:692d8c1446f52ed2662120bcd9ddcb5aa2b71f38bda31e58b19fb4672fffba69 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
--hash=sha256:2c7ef3d2f865b4b3ebb14ec3556f7a3e8abb6d130c67275cd9daa08dbd6e4e4e \
|
||||
--hash=sha256:3772b406edb3ff78171530a17cda1c4a7817f87b87ded0d8715b3fa664df16db \
|
||||
--hash=sha256:3906452339cd06a3bb07df103c2511d4cb0f7a22d8771c0b802eba15d9a642b6 \
|
||||
--hash=sha256:59a77038ebe0ab1240f61c341e7fb67b8674f2b4cd41bc71a6472511a12b50f7 \
|
||||
--hash=sha256:89acc6bc13aaa6e3f52b0ce652ede7e201edb6bf062741b246b0c5a44582f25f \
|
||||
--hash=sha256:950bd2d9c74634398c4e3d24ef2f213d4e23d705083697464fa67afedc53c1ad \
|
||||
--hash=sha256:b9cdd686e32db8e451feb19f8a85bc4cd52c2893103881d04aca51e1f35371d1
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-cocoa
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-applicationservices==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0bcc09531d5854598fd74706d999e4ae3b7c503204d318910d02eba30e8eecef \
|
||||
--hash=sha256:1af01a271b85eae2a327e93cf3ec46de0199a1a933594f78d4c2b9b9c2240e5e \
|
||||
--hash=sha256:3b5693a377480cf127caa1c8c835b8620896971029c545d99d01aa31a2c38159 \
|
||||
--hash=sha256:3f9dde6d8e8fb8ebd79ac6e84212c1d294eba48fa2d4c467a29614c3ca5ef2f8 \
|
||||
--hash=sha256:4188a79f2774778dd5f2bcfb49b856d08dd824862f072924be40274b5a5cad95 \
|
||||
--hash=sha256:5506bd6b5268a97fcb79b5b021f6cbbaaf5cdff3ec87094d8870268d8cf096ed \
|
||||
--hash=sha256:82275ea56be975ee84fafdb340dcfee6b5289422c3f674c1982d3fcd47ba68c9 \
|
||||
--hash=sha256:93ba63aad6607f369c1b38bf91306731da6306fdde5eb67afa407b3f8a87dda7 \
|
||||
--hash=sha256:fc861e14f78e7370e982202b21db8bcb562dc14cd4098e557a17961d3411de45
|
||||
# via pynput
|
||||
pyobjc-framework-cocoa==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0e8ace0d44a00d281281a723d17fcd05eea7544a38a6a512e1fd018ddb7aece2 \
|
||||
--hash=sha256:600b1723184ca094931330e79355274949965460e23de38628d601b5a967baf9 \
|
||||
--hash=sha256:851dca4c16e70b405e5cd5a8c166cf7c445ae54a4cdd95ce9a523803172f32d1 \
|
||||
--hash=sha256:875f2aad73963faa81a6b36ae674fd494a4658d6d999e1075e0e2aca3d2391df \
|
||||
--hash=sha256:889d7bbd4ba2d4941078bfbbfb882138e51dbead27df006abfe0f2e0d49b5b2e \
|
||||
--hash=sha256:8fe5b2e79c9530f667b4e58a87a3a15ea62f86a5d19eec405517ecbd4f454868 \
|
||||
--hash=sha256:c96c0ef69a71afbbb0e6a7d594b455c5fe47d62e0db376ee7a2b4b828c16ace9 \
|
||||
--hash=sha256:de69c5933750f3a4599ed962eccd92b6a71914c7e4318dacc7895738a8ae60d7 \
|
||||
--hash=sha256:e106f395531e67694376b0f1184612cbeea3ec8b9bf56b55ef41d026171d2a2d
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-coretext==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:1324d91305022b1de03a12cf82de2b42c87dafe9b12cde6237253658a8637139 \
|
||||
--hash=sha256:1dc50de18346c4d6c89a51df066f03beea81e3557e3090ddc2a7a59395332fd8 \
|
||||
--hash=sha256:295d1037494630527acc24d116b0301ab5cf5e918952f49f7bf4f76ebae24d0c \
|
||||
--hash=sha256:64ddc02303217028e32e22c7cc00b5112d84e9d9a67c37d00c2e54f9172284ab \
|
||||
--hash=sha256:77a379ff47c599cb2bab918eb75680d30d950692ec19d67b734d11ded090b4e1 \
|
||||
--hash=sha256:a69611de569d92776e6391ca25492a5bbb4a05ba744006349e377a4fc5f7c8a5 \
|
||||
--hash=sha256:b585f0db77280930cb32e71cf8d27f5203d8c0f42a65fba690294530ab6e1aa6 \
|
||||
--hash=sha256:dbd0f288a859e359ee8e7ccf45bc2c489f38ae1087c21468b61d700433e0c91b \
|
||||
--hash=sha256:f1ad871d761bad9a0d461cceeeff7375a39f4d181c2a206dada6fc05307fec12
|
||||
# via pyobjc-framework-applicationservices
|
||||
pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0ec9751904ef975bf0789d760dc4fadcb400edc4ffe4a736eb54971968babe5c \
|
||||
--hash=sha256:1f7f3d9010e38f03ea1fa266664c10ea349cd7492bd603b403584f49d713dbed \
|
||||
--hash=sha256:4b01e325b0cdc121e78730dde9756e971b23069bf141cd62efbcaac76d7b6dbb \
|
||||
--hash=sha256:63f6f0f3233dcf650aac1374781e78961b0b17b33e3351953bacf8bd0c430593 \
|
||||
--hash=sha256:7f668979d0c7320bf8f7ed6e030da578f93ab0f5dd619b295ec735cd8d5faa34 \
|
||||
--hash=sha256:810f97b210cfd93704d240860286dfd6df09f9f1c52525fc5c2166723aea3f9e \
|
||||
--hash=sha256:8f58c589b5a76ba98f186b1f3b19fb1c8b730e82351f81fb62e6194f64a71622 \
|
||||
--hash=sha256:cee63b891c2b6b7ccf98f233175411529f3e80286f58438793b3634af79858f1 \
|
||||
--hash=sha256:ebf8167ca2096cf3a05199decfa517be0df4c56048f49cf132bd6b1a6ab9c086
|
||||
# via
|
||||
# pynput
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
# via pynput
|
||||
pywhispercpp==1.5.0 \
|
||||
--hash=sha256:03025227d0da211e382db6b6b16d910a267c663b6b2c57092b1200965ec45393 \
|
||||
--hash=sha256:0c393c01a0a77007a17d17cb706e08cba97f0e35ea0268733af1792949d03ceb \
|
||||
--hash=sha256:0f895cbbf5ba71a9e3f0e6afb4b6ae49bae5c716dc6a8a4d905eb789d9fe2238 \
|
||||
--hash=sha256:1bc31f684b6a38000e397824155bda3b45b61af6acc9f7e0f3bfa70e20b574e3 \
|
||||
--hash=sha256:22f9ddf12f6fb0fe3c43465d976b554e8928fcc113c902127e94c792d85f0631 \
|
||||
--hash=sha256:24602b8d0329a224fe6eb1c1e455853e983a5e04a63d4cb759ae2f275e254f5f \
|
||||
--hash=sha256:24da0c0bd33068f4c9c3f45eae3e6b7fb31d9b5d3487e4e1e1323b4253288d62 \
|
||||
--hash=sha256:2ea8fa7f5ce602d3e986fb11c4c2973b471f1b14e0fe75e01a66f1a60aecbfbf \
|
||||
--hash=sha256:358261055c56a96a04f6b0ff419633ffc61ef61027788b2bb2c6e7dca69abdb7 \
|
||||
--hash=sha256:3f825942067da3b0c48fc5b552b816fcee1761e955b9fdfdc911f0ab2d6fff11 \
|
||||
--hash=sha256:4363fa893e398d1f18a5775374109aa310022b9f4fc777a89329b12963f3149d \
|
||||
--hash=sha256:4bb409027566b473100e43f07fac48f9c8bdb6cba1ac0fbff5594a6f5a0e1b7e \
|
||||
--hash=sha256:568669bae45bd879bba1e35401cefc89d572428bd17326ce8437107ab80003d0 \
|
||||
--hash=sha256:57dd5111d4dd9fe3f0e784a03a3337df5abd514260a7d16656733d110316d2f0 \
|
||||
--hash=sha256:5aa54c73ec96617d97aa519dbbf817e44255eddd9bd52ee1243be61028dbd018 \
|
||||
--hash=sha256:64415b7687c0b39e66652b38683983ef7f23e174d7b3b05caa539955da8b088e \
|
||||
--hash=sha256:649af3ae0f9dc0d0dd757d8c2adfc6d929b1b203ac1ba85d5ac453015ddd6e63 \
|
||||
--hash=sha256:6ad4071772eb9dad59a741611e44e3819e6249c46e295ab8468609d03c6e4232 \
|
||||
--hash=sha256:70e925fad2c48554d3f5baf79e2746540268d2974b5cf40a4880887e4a065c2f \
|
||||
--hash=sha256:77d4d0ff382b5bc1369e9f77a851b45659edf5974e0903ffb15b981a043d216b \
|
||||
--hash=sha256:9806e084ebf956c7e492c76ea31c708e894849024772b3c3a57f85c342afc341 \
|
||||
--hash=sha256:9b43ddd44e65ca53d5ab1f62b623bc3edc64019bbe06b9641fff2dfef704c990 \
|
||||
--hash=sha256:a2fe9312fe3c08f832da392296118cc8cc1fc901753289132253f2066d911357 \
|
||||
--hash=sha256:a6777b5d40c0679952ded7934f7119d5fbfd606ec348293f869f430795609bae \
|
||||
--hash=sha256:a839b738936a8cd72cdd55c59a83a462820532bee78e233241bf9a3503e92144 \
|
||||
--hash=sha256:b1f94300f2fa1748f67f63a9240b526e8542b2dad1ceca5ea87ec2e9e15a939a \
|
||||
--hash=sha256:b592011cd992a5bcd36d0923477fb4cfdd338a0c7ce58997de195a14ab2b6d9a \
|
||||
--hash=sha256:c35c16f5da31d79be604dfd082b8bb67d5d46ba2f7f59bf5ab13857d5cd6ec6b \
|
||||
--hash=sha256:c9498eb9f4c38ea121da2435b5275c267486a5e14dddf5e72ec54a480b1fb44e \
|
||||
--hash=sha256:d2805f15361247ada04a34b51c556514527b984f9b089a4e32f1b2a4abbc5367 \
|
||||
--hash=sha256:d92eec44b49595ab1454cff1d10faa83b0b27779db8d8f00592ed363f0c5a262 \
|
||||
--hash=sha256:dc8dbcb6033db306e9ec450d835c005dd491c457937c79ef2673ea8797cbb93c \
|
||||
--hash=sha256:ea34ae824a6f934ba7736e6440f93cc467a7ec98b9c8fb2e5a37bb439ffa93b9 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
pyyaml==6.0.3 \
|
||||
--hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \
|
||||
--hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \
|
||||
--hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \
|
||||
--hash=sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c \
|
||||
--hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \
|
||||
--hash=sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a \
|
||||
--hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \
|
||||
--hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \
|
||||
--hash=sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4 \
|
||||
--hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \
|
||||
--hash=sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e \
|
||||
--hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \
|
||||
--hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \
|
||||
--hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \
|
||||
--hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \
|
||||
--hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \
|
||||
--hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \
|
||||
--hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \
|
||||
--hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \
|
||||
--hash=sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 \
|
||||
--hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \
|
||||
--hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \
|
||||
--hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \
|
||||
--hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \
|
||||
--hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \
|
||||
--hash=sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b \
|
||||
--hash=sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00 \
|
||||
--hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \
|
||||
--hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \
|
||||
--hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \
|
||||
--hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \
|
||||
--hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \
|
||||
--hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \
|
||||
--hash=sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf \
|
||||
--hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \
|
||||
--hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \
|
||||
--hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \
|
||||
--hash=sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d \
|
||||
--hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \
|
||||
--hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \
|
||||
--hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \
|
||||
--hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \
|
||||
--hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \
|
||||
--hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \
|
||||
--hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \
|
||||
--hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \
|
||||
--hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \
|
||||
--hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0
|
||||
# via
|
||||
# ctranslate2
|
||||
# huggingface-hub
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
# via
|
||||
# pynput
|
||||
# python-xlib
|
||||
tokenizers==0.23.2 \
|
||||
--hash=sha256:12f0835dc2ee694746a76adf7b1567d4346a4a502ebe93fb1f5f80ea49799b78 \
|
||||
--hash=sha256:2e96f5699d5249c9c64aa8412e044f727aae3a4098cf830f9901ec1afc361cde \
|
||||
--hash=sha256:325fee2e0418a9dc6c9ecf736a5f5f0db7875183ace9549ae339da76f7a1fbb7 \
|
||||
--hash=sha256:41c2f84d172449b4dadb9cdc508e3e364076613c35b16e76ecfe47a60d1e3305 \
|
||||
--hash=sha256:43e4f2071e3cc8d5d86421c874aebc82659bb51a68bcdef5a0da75ee89511ccb \
|
||||
--hash=sha256:5c56bda1511921587789163e524d196ed8284174ac23abd7685d5ea8da6c4718 \
|
||||
--hash=sha256:7b7e37ba198f24150f523e1242e83c4970de4a525480586be5dcc24d9add32c5 \
|
||||
--hash=sha256:7f0f085686b9de0d0079e6f874ae053600db64c5d13049e0bbc0119926d25aac \
|
||||
--hash=sha256:85a9a357a3764aecc904ee76bdaf8cf1ad8e5a67a1b929a487c4a39b49ed0e90 \
|
||||
--hash=sha256:950d7c9426fa72406a0ffeacdbc0bb9985f5db20eb8b263f29c79aaf83105703 \
|
||||
--hash=sha256:986670e43691469dcee610ea0f846f91a8f84e91fc6f7a48d4c064414c0ec2bf \
|
||||
--hash=sha256:a37039b5dfc4af84eb3ef0a92f4307e28936c8f9adccba2629d36f652e9bf7a2 \
|
||||
--hash=sha256:bef235815a067b2648caf6dcc7a71091b0b0fff9ee8057f6451eb9335fae52ef \
|
||||
--hash=sha256:debf978920d93ba9c219bd67cc4bbfaf912c9039e41e7a28b91ec15e3728c95a \
|
||||
--hash=sha256:e49c394456dd9985787fec76132438ba3fb8911f857b1bf3d40119f9292d41aa \
|
||||
--hash=sha256:eb2f9c8a24da020ea8c11a01a19c1c2547912d92121ae4a01cfbca46125dee40 \
|
||||
--hash=sha256:f486f402f6f9abee5bb032553736813af0c710a86b2e0ca592634c55cea1f835
|
||||
# via faster-whisper
|
||||
tqdm==4.70.0 \
|
||||
--hash=sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220 \
|
||||
--hash=sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953
|
||||
# via
|
||||
# faster-whisper
|
||||
# huggingface-hub
|
||||
# pywhispercpp
|
||||
typing-extensions==4.16.0 \
|
||||
--hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \
|
||||
--hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5
|
||||
# via
|
||||
# anyio
|
||||
# huggingface-hub
|
||||
urllib3==2.8.0 \
|
||||
--hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \
|
||||
--hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63
|
||||
# via requests
|
||||
@@ -0,0 +1,109 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --only-group installer-build --no-emit-project -o requirements/installer-build.txt
|
||||
altgraph==0.17.5 \
|
||||
--hash=sha256:c87b395dd12fabde9c99573a9749d67da8d29ef9de0125c7f536699b4a9bc9e7 \
|
||||
--hash=sha256:f3a22400bce1b0c701683820ac4f3b159cd301acab067c51c653e06961600597
|
||||
# via macholib
|
||||
cmake==3.31.10 \
|
||||
--hash=sha256:1debc3a0823ce5d8d1bc17154599bbbb337c2681f93622b618bc78f46576e42a \
|
||||
--hash=sha256:2f766bb46367e5e0559fa33184653754bce044583a06014dcaebf8e6dff8a1f1 \
|
||||
--hash=sha256:3c17bb24dba15f8ecc3fd706afe04264410ef88796f4115c119327c961d5dc57 \
|
||||
--hash=sha256:422a54711aa977af19d59b8f6010354cdda0b72a2e6d702b6d892e3e2cdf98a2 \
|
||||
--hash=sha256:4cefb0a28ac1268b4eed4b595bf3aaff8de9704089066027700ec36584eccab8 \
|
||||
--hash=sha256:678fc23db37cc69f01e18eb28790450ecc9401fd2fcd43364cc18f92330c12c2 \
|
||||
--hash=sha256:6970bb75c4dfc28cc31ff0cd848194d09094ae00d605181e1345b2ff70b61050 \
|
||||
--hash=sha256:7c300e4ae68fbc1414a85505f7feb262cee82ff3304a286885ebf803b11a997c \
|
||||
--hash=sha256:8d2ec5fc45d305227020c82213140a51a0cebe3c84f0299036f05716b3a52f60 \
|
||||
--hash=sha256:91410816db3beefe2f6032d721f9978c98dc7646e9992c0325486597164fab81 \
|
||||
--hash=sha256:a4a5615f31f692c9b9aa8b365704e4b76172348af6fa40e16fea3f118bb01194 \
|
||||
--hash=sha256:a7864605238759a4ae8e3bd1fda2bb03978e3e37df310852662dcf53866413c8 \
|
||||
--hash=sha256:ad697643a00d9ba85179590a383c4f7401169b55ebf4b8b2938daf28c6bdeb6d \
|
||||
--hash=sha256:b059a1810a2ce766b3e531bdc8d730bc192e260a9fa7dec7a0eb7a053d6063c7 \
|
||||
--hash=sha256:b331984de38dbda22d676f8812c8905526341ba7b397fe8c359255ff4d051193 \
|
||||
--hash=sha256:c2e5361dea9754ed3b06cf834894fb47dcbe7036d5e5d87acaeb10ff3dd5fd10 \
|
||||
--hash=sha256:e135d5f1e59f1dc1c80eea87321977d6c0eff86cb601c28e0965a1dd457ea587 \
|
||||
--hash=sha256:ec3d14a0e72e401b3665034dc37901df17f0b4e9c5b163be6cfedfb93470ac0f \
|
||||
--hash=sha256:f1ea1fe826355560e8976c3d5794d9357444209bc0e0d56676c71e6a571fd474
|
||||
delvewheel==1.13.1 \
|
||||
--hash=sha256:1b3bc696193a57e322b8bfd644de240be6e003066aae44cc3d5aef8cbee22ca3 \
|
||||
--hash=sha256:ae445f35f411c367f5b350431ac5f1435af8128bff31ccf34035a409704da8c6
|
||||
# via repairwheel
|
||||
macholib==1.16.4 \
|
||||
--hash=sha256:da1a3fa8266e30f0ce7e97c6a54eefaae8edd1e5f86f3eb8b95457cae90265ea \
|
||||
--hash=sha256:f408c93ab2e995cd2c46e34fe328b130404be143469e41bc366c807448979362
|
||||
# via repairwheel
|
||||
meson==1.12.0 \
|
||||
--hash=sha256:71f133147fa0fcfe8f4df49fa1045771064947834538409e5d97b3613aac8b4e \
|
||||
--hash=sha256:88afe0c20e52030218924ac37d0c81c59b4b5f3ae3752c8c6d7470c7d365886c
|
||||
# via meson-python
|
||||
meson-python==0.21.1 \
|
||||
--hash=sha256:270bc9b78957c47e0aa1758ad616dba3f943d8f9cbdb944d318c3c1c7a49e4bd \
|
||||
--hash=sha256:78b3345dcbc0fed7b939e7e37a9faab35bddaae07bf62e7542c8ad479c395af5
|
||||
ninja==1.13.0 \
|
||||
--hash=sha256:11be2d22027bde06f14c343f01d31446747dbb51e72d00decca2eb99be911e2f \
|
||||
--hash=sha256:1c97223cdda0417f414bf864cfb73b72d8777e57ebb279c5f6de368de0062988 \
|
||||
--hash=sha256:3c0b40b1f0bba764644385319028650087b4c1b18cdfa6f45cb39a3669b81aa9 \
|
||||
--hash=sha256:3d00c692fb717fd511abeb44b8c5d00340c36938c12d6538ba989fe764e79630 \
|
||||
--hash=sha256:3d7d7779d12cb20c6d054c61b702139fd23a7a964ec8f2c823f1ab1b084150db \
|
||||
--hash=sha256:4a40ce995ded54d9dc24f8ea37ff3bf62ad192b547f6c7126e7e25045e76f978 \
|
||||
--hash=sha256:4be9c1b082d244b1ad7ef41eb8ab088aae8c109a9f3f0b3e56a252d3e00f42c1 \
|
||||
--hash=sha256:5f8e1e8a1a30835eeb51db05cf5a67151ad37542f5a4af2a438e9490915e5b72 \
|
||||
--hash=sha256:60056592cf495e9a6a4bea3cd178903056ecb0943e4de45a2ea825edb6dc8d3e \
|
||||
--hash=sha256:6739d3352073341ad284246f81339a384eec091d9851a886dfa5b00a6d48b3e2 \
|
||||
--hash=sha256:8cfbb80b4a53456ae8a39f90ae3d7a2129f45ea164f43fadfa15dc38c4aef1c9 \
|
||||
--hash=sha256:aa45b4037b313c2f698bc13306239b8b93b4680eb47e287773156ac9e9304714 \
|
||||
--hash=sha256:b4f2a072db3c0f944c32793e91532d8948d20d9ab83da9c0c7c15b5768072200 \
|
||||
--hash=sha256:be7f478ff9f96a128b599a964fc60a6a87b9fa332ee1bd44fa243ac88d50291c \
|
||||
--hash=sha256:d741a5e6754e0bda767e3274a0f0deeef4807f1fec6c0d7921a0244018926ae5 \
|
||||
--hash=sha256:e8bad11f8a00b64137e9b315b137d8bb6cbf3086fbdc43bf1f90fd33324d2e96 \
|
||||
--hash=sha256:fa2a8bfc62e31b08f83127d1613d10821775a0eb334197154c4d6067b7068ff1 \
|
||||
--hash=sha256:fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa \
|
||||
--hash=sha256:fb8ee8719f8af47fed145cced4a85f0755dd55d45b2bddaf7431fa89803c5f3e
|
||||
packaging==26.3 \
|
||||
--hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
|
||||
--hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
|
||||
# via
|
||||
# meson-python
|
||||
# pyproject-metadata
|
||||
# repairwheel
|
||||
# setuptools-scm
|
||||
# vcs-versioning
|
||||
# wheel
|
||||
pefile==2024.8.26 \
|
||||
--hash=sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632 \
|
||||
--hash=sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f
|
||||
# via
|
||||
# delvewheel
|
||||
# repairwheel
|
||||
pip==26.2.1 \
|
||||
--hash=sha256:71138adf1f4ca900cdb7d289c21b7494329f2332b6d85f0e1c42108c0384ed3e \
|
||||
--hash=sha256:f6ad667e89a1fe78046c8f13232b247200f5258d7828f3f7883d660878e0813f
|
||||
pyelftools==0.33 \
|
||||
--hash=sha256:660d82dcbeb8e83d1702bd97f223f761625da06111c0cc988eac6b8ab0c1b61f \
|
||||
--hash=sha256:f215ad5f47d3f1373a21496a6c9e0707c622840d0622f23ff7ce08678b020036
|
||||
# via repairwheel
|
||||
pyproject-metadata==0.12.1 \
|
||||
--hash=sha256:8809a4df6fe08279b39a8890669506ed3158e0617855ac9aff098fcbe772ae4c \
|
||||
--hash=sha256:f7162d580a96386a8eb096da06215f981f547d1490f03055ef99e323bc2da427
|
||||
# via meson-python
|
||||
repairwheel==0.7.0 \
|
||||
--hash=sha256:46083dad76e35595712ae593c1c9f112fb3f37a0e63268906e6de8182de55122 \
|
||||
--hash=sha256:7fff43ed5abbf9710ef5ea6478c10cfd551aae043f445fd46307d4b602674ce0
|
||||
setuptools==84.1.0 \
|
||||
--hash=sha256:23657205b63d4d31395ab917815247f694aafad28cd21316bf5fd45a51048ea0 \
|
||||
--hash=sha256:5231689c6ac8156cd155cfb98c3fd6fb252c3e7e9bd3d78b64d3c55f132624c9
|
||||
# via setuptools-scm
|
||||
setuptools-scm==10.2.3 \
|
||||
--hash=sha256:7fcf8ff55c95eb8b572a23c81495e5559b9b90f3e82fcf0952bb76c37de27a81 \
|
||||
--hash=sha256:f179ed3e2a63cf5823e5ee9aa9ca08386219400443a0553224d72dde3f206b44
|
||||
typing-extensions==4.16.0 \
|
||||
--hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \
|
||||
--hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5
|
||||
# via repairwheel
|
||||
vcs-versioning==2.4.1 \
|
||||
--hash=sha256:b7089ec9bef67b2cad82148366e8eac4d63173f440ec62628282b59eb96bbcb0 \
|
||||
--hash=sha256:d4575de3115ec9434393c87c80ffb0eb98a16056bfe2b11ce0f3a97aff67fe0a
|
||||
# via setuptools-scm
|
||||
wheel==0.48.0 \
|
||||
--hash=sha256:3217dcc807155e45db462d7ef2431f5ddda0d7273b700d05a67b271ceb1287ab \
|
||||
--hash=sha256:94800765601e9171bf5d58d066e640662842bcedcbab982b2c90787a2c987322
|
||||
@@ -0,0 +1,539 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --no-dev --extra parakeet --no-emit-project --no-emit-package pygobject -o requirements/parakeet.txt
|
||||
certifi==2026.10.19 \
|
||||
--hash=sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae \
|
||||
--hash=sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b
|
||||
# via requests
|
||||
charset-normalizer==3.5.1 \
|
||||
--hash=sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5 \
|
||||
--hash=sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b \
|
||||
--hash=sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f \
|
||||
--hash=sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5 \
|
||||
--hash=sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22 \
|
||||
--hash=sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5 \
|
||||
--hash=sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac \
|
||||
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
||||
--hash=sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626 \
|
||||
--hash=sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4 \
|
||||
--hash=sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369 \
|
||||
--hash=sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b \
|
||||
--hash=sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e \
|
||||
--hash=sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee \
|
||||
--hash=sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1 \
|
||||
--hash=sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102 \
|
||||
--hash=sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8 \
|
||||
--hash=sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9 \
|
||||
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
||||
--hash=sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031 \
|
||||
--hash=sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e \
|
||||
--hash=sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235 \
|
||||
--hash=sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072 \
|
||||
--hash=sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb \
|
||||
--hash=sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c \
|
||||
--hash=sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950 \
|
||||
--hash=sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2 \
|
||||
--hash=sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e \
|
||||
--hash=sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6 \
|
||||
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
||||
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
||||
--hash=sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2 \
|
||||
--hash=sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032 \
|
||||
--hash=sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71 \
|
||||
--hash=sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96 \
|
||||
--hash=sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687 \
|
||||
--hash=sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8 \
|
||||
--hash=sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3 \
|
||||
--hash=sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61 \
|
||||
--hash=sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9 \
|
||||
--hash=sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1 \
|
||||
--hash=sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4 \
|
||||
--hash=sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65 \
|
||||
--hash=sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663 \
|
||||
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
||||
--hash=sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591 \
|
||||
--hash=sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a \
|
||||
--hash=sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e \
|
||||
--hash=sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7 \
|
||||
--hash=sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3 \
|
||||
--hash=sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c \
|
||||
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
||||
--hash=sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7 \
|
||||
--hash=sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96 \
|
||||
--hash=sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486 \
|
||||
--hash=sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3 \
|
||||
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
||||
--hash=sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b \
|
||||
--hash=sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731 \
|
||||
--hash=sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959 \
|
||||
--hash=sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9 \
|
||||
--hash=sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf \
|
||||
--hash=sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8 \
|
||||
--hash=sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e \
|
||||
--hash=sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885 \
|
||||
--hash=sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0 \
|
||||
--hash=sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506 \
|
||||
--hash=sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2 \
|
||||
--hash=sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0 \
|
||||
--hash=sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e \
|
||||
--hash=sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e \
|
||||
--hash=sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491 \
|
||||
--hash=sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a \
|
||||
--hash=sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20 \
|
||||
--hash=sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449 \
|
||||
--hash=sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af \
|
||||
--hash=sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c \
|
||||
--hash=sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712 \
|
||||
--hash=sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7 \
|
||||
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
||||
--hash=sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9 \
|
||||
--hash=sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e \
|
||||
--hash=sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5 \
|
||||
--hash=sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36 \
|
||||
--hash=sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263 \
|
||||
--hash=sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4 \
|
||||
--hash=sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11 \
|
||||
--hash=sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a \
|
||||
--hash=sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3 \
|
||||
--hash=sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375 \
|
||||
--hash=sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d \
|
||||
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
||||
--hash=sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c \
|
||||
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
||||
--hash=sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6 \
|
||||
--hash=sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc \
|
||||
--hash=sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b \
|
||||
--hash=sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f \
|
||||
--hash=sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00 \
|
||||
--hash=sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10 \
|
||||
--hash=sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598 \
|
||||
--hash=sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6 \
|
||||
--hash=sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962 \
|
||||
--hash=sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c \
|
||||
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
||||
--hash=sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573 \
|
||||
--hash=sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90 \
|
||||
--hash=sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5 \
|
||||
--hash=sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18 \
|
||||
--hash=sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af \
|
||||
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
||||
--hash=sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b \
|
||||
--hash=sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6 \
|
||||
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
||||
--hash=sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774 \
|
||||
--hash=sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004 \
|
||||
--hash=sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a \
|
||||
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
||||
--hash=sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2 \
|
||||
--hash=sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe \
|
||||
--hash=sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3 \
|
||||
--hash=sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc \
|
||||
--hash=sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d \
|
||||
--hash=sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc \
|
||||
--hash=sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893 \
|
||||
--hash=sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef \
|
||||
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
||||
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30 \
|
||||
--hash=sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7 \
|
||||
--hash=sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5 \
|
||||
--hash=sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f \
|
||||
--hash=sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9 \
|
||||
--hash=sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada \
|
||||
--hash=sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876 \
|
||||
--hash=sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a \
|
||||
--hash=sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348 \
|
||||
--hash=sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3 \
|
||||
--hash=sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f \
|
||||
--hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \
|
||||
--hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f
|
||||
# via requests
|
||||
colorama==0.4.6 ; sys_platform == 'win32' \
|
||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via tqdm
|
||||
evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
# via requests
|
||||
numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \
|
||||
--hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \
|
||||
--hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \
|
||||
--hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \
|
||||
--hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \
|
||||
--hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \
|
||||
--hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \
|
||||
--hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \
|
||||
--hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \
|
||||
--hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \
|
||||
--hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \
|
||||
--hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \
|
||||
--hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \
|
||||
--hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \
|
||||
--hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \
|
||||
--hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \
|
||||
--hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \
|
||||
--hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \
|
||||
--hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \
|
||||
--hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \
|
||||
--hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \
|
||||
--hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \
|
||||
--hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \
|
||||
--hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \
|
||||
--hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \
|
||||
--hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \
|
||||
--hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \
|
||||
--hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \
|
||||
--hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \
|
||||
--hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \
|
||||
--hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \
|
||||
--hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \
|
||||
--hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \
|
||||
--hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \
|
||||
--hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \
|
||||
--hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \
|
||||
--hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \
|
||||
--hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \
|
||||
--hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \
|
||||
--hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \
|
||||
--hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \
|
||||
--hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \
|
||||
--hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \
|
||||
--hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \
|
||||
--hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \
|
||||
--hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \
|
||||
--hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \
|
||||
--hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \
|
||||
--hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \
|
||||
--hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \
|
||||
--hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \
|
||||
--hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \
|
||||
--hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \
|
||||
--hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \
|
||||
--hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \
|
||||
--hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \
|
||||
--hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \
|
||||
--hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \
|
||||
--hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \
|
||||
--hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \
|
||||
--hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \
|
||||
--hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \
|
||||
--hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \
|
||||
--hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \
|
||||
--hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \
|
||||
--hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \
|
||||
--hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \
|
||||
--hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \
|
||||
--hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \
|
||||
--hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \
|
||||
--hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
--hash=sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7 \
|
||||
--hash=sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0 \
|
||||
--hash=sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3 \
|
||||
--hash=sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c \
|
||||
--hash=sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce \
|
||||
--hash=sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8 \
|
||||
--hash=sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1 \
|
||||
--hash=sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4 \
|
||||
--hash=sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee \
|
||||
--hash=sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740 \
|
||||
--hash=sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98 \
|
||||
--hash=sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710 \
|
||||
--hash=sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee \
|
||||
--hash=sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68 \
|
||||
--hash=sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf \
|
||||
--hash=sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8 \
|
||||
--hash=sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf \
|
||||
--hash=sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b \
|
||||
--hash=sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884 \
|
||||
--hash=sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03 \
|
||||
--hash=sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69 \
|
||||
--hash=sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4 \
|
||||
--hash=sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842 \
|
||||
--hash=sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65 \
|
||||
--hash=sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080 \
|
||||
--hash=sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e \
|
||||
--hash=sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e \
|
||||
--hash=sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414 \
|
||||
--hash=sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59 \
|
||||
--hash=sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8 \
|
||||
--hash=sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617 \
|
||||
--hash=sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4 \
|
||||
--hash=sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb \
|
||||
--hash=sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251 \
|
||||
--hash=sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d \
|
||||
--hash=sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2 \
|
||||
--hash=sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab \
|
||||
--hash=sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657 \
|
||||
--hash=sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15 \
|
||||
--hash=sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9 \
|
||||
--hash=sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8 \
|
||||
--hash=sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323 \
|
||||
--hash=sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788 \
|
||||
--hash=sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc \
|
||||
--hash=sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56 \
|
||||
--hash=sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1 \
|
||||
--hash=sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d \
|
||||
--hash=sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec \
|
||||
--hash=sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2 \
|
||||
--hash=sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e \
|
||||
--hash=sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7 \
|
||||
--hash=sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26 \
|
||||
--hash=sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514 \
|
||||
--hash=sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860 \
|
||||
--hash=sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a \
|
||||
--hash=sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1 \
|
||||
--hash=sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab \
|
||||
--hash=sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba \
|
||||
--hash=sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12 \
|
||||
--hash=sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6 \
|
||||
--hash=sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e \
|
||||
--hash=sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac \
|
||||
--hash=sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
platformdirs==4.11.3 \
|
||||
--hash=sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7 \
|
||||
--hash=sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab
|
||||
# via pywhispercpp
|
||||
psutil==7.2.2 \
|
||||
--hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \
|
||||
--hash=sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 \
|
||||
--hash=sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841 \
|
||||
--hash=sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63 \
|
||||
--hash=sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979 \
|
||||
--hash=sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a \
|
||||
--hash=sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b \
|
||||
--hash=sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9 \
|
||||
--hash=sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee \
|
||||
--hash=sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312 \
|
||||
--hash=sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b \
|
||||
--hash=sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9 \
|
||||
--hash=sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e \
|
||||
--hash=sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc \
|
||||
--hash=sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1 \
|
||||
--hash=sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf \
|
||||
--hash=sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea \
|
||||
--hash=sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
--hash=sha256:5fce4bcdd2e0e8c063d835dbe2860dac46437506af509353c7f8114d4bacbd5b \
|
||||
--hash=sha256:692d8c1446f52ed2662120bcd9ddcb5aa2b71f38bda31e58b19fb4672fffba69 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
--hash=sha256:2c7ef3d2f865b4b3ebb14ec3556f7a3e8abb6d130c67275cd9daa08dbd6e4e4e \
|
||||
--hash=sha256:3772b406edb3ff78171530a17cda1c4a7817f87b87ded0d8715b3fa664df16db \
|
||||
--hash=sha256:3906452339cd06a3bb07df103c2511d4cb0f7a22d8771c0b802eba15d9a642b6 \
|
||||
--hash=sha256:59a77038ebe0ab1240f61c341e7fb67b8674f2b4cd41bc71a6472511a12b50f7 \
|
||||
--hash=sha256:89acc6bc13aaa6e3f52b0ce652ede7e201edb6bf062741b246b0c5a44582f25f \
|
||||
--hash=sha256:950bd2d9c74634398c4e3d24ef2f213d4e23d705083697464fa67afedc53c1ad \
|
||||
--hash=sha256:b9cdd686e32db8e451feb19f8a85bc4cd52c2893103881d04aca51e1f35371d1
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-cocoa
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-applicationservices==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0bcc09531d5854598fd74706d999e4ae3b7c503204d318910d02eba30e8eecef \
|
||||
--hash=sha256:1af01a271b85eae2a327e93cf3ec46de0199a1a933594f78d4c2b9b9c2240e5e \
|
||||
--hash=sha256:3b5693a377480cf127caa1c8c835b8620896971029c545d99d01aa31a2c38159 \
|
||||
--hash=sha256:3f9dde6d8e8fb8ebd79ac6e84212c1d294eba48fa2d4c467a29614c3ca5ef2f8 \
|
||||
--hash=sha256:4188a79f2774778dd5f2bcfb49b856d08dd824862f072924be40274b5a5cad95 \
|
||||
--hash=sha256:5506bd6b5268a97fcb79b5b021f6cbbaaf5cdff3ec87094d8870268d8cf096ed \
|
||||
--hash=sha256:82275ea56be975ee84fafdb340dcfee6b5289422c3f674c1982d3fcd47ba68c9 \
|
||||
--hash=sha256:93ba63aad6607f369c1b38bf91306731da6306fdde5eb67afa407b3f8a87dda7 \
|
||||
--hash=sha256:fc861e14f78e7370e982202b21db8bcb562dc14cd4098e557a17961d3411de45
|
||||
# via pynput
|
||||
pyobjc-framework-cocoa==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0e8ace0d44a00d281281a723d17fcd05eea7544a38a6a512e1fd018ddb7aece2 \
|
||||
--hash=sha256:600b1723184ca094931330e79355274949965460e23de38628d601b5a967baf9 \
|
||||
--hash=sha256:851dca4c16e70b405e5cd5a8c166cf7c445ae54a4cdd95ce9a523803172f32d1 \
|
||||
--hash=sha256:875f2aad73963faa81a6b36ae674fd494a4658d6d999e1075e0e2aca3d2391df \
|
||||
--hash=sha256:889d7bbd4ba2d4941078bfbbfb882138e51dbead27df006abfe0f2e0d49b5b2e \
|
||||
--hash=sha256:8fe5b2e79c9530f667b4e58a87a3a15ea62f86a5d19eec405517ecbd4f454868 \
|
||||
--hash=sha256:c96c0ef69a71afbbb0e6a7d594b455c5fe47d62e0db376ee7a2b4b828c16ace9 \
|
||||
--hash=sha256:de69c5933750f3a4599ed962eccd92b6a71914c7e4318dacc7895738a8ae60d7 \
|
||||
--hash=sha256:e106f395531e67694376b0f1184612cbeea3ec8b9bf56b55ef41d026171d2a2d
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-coretext==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:1324d91305022b1de03a12cf82de2b42c87dafe9b12cde6237253658a8637139 \
|
||||
--hash=sha256:1dc50de18346c4d6c89a51df066f03beea81e3557e3090ddc2a7a59395332fd8 \
|
||||
--hash=sha256:295d1037494630527acc24d116b0301ab5cf5e918952f49f7bf4f76ebae24d0c \
|
||||
--hash=sha256:64ddc02303217028e32e22c7cc00b5112d84e9d9a67c37d00c2e54f9172284ab \
|
||||
--hash=sha256:77a379ff47c599cb2bab918eb75680d30d950692ec19d67b734d11ded090b4e1 \
|
||||
--hash=sha256:a69611de569d92776e6391ca25492a5bbb4a05ba744006349e377a4fc5f7c8a5 \
|
||||
--hash=sha256:b585f0db77280930cb32e71cf8d27f5203d8c0f42a65fba690294530ab6e1aa6 \
|
||||
--hash=sha256:dbd0f288a859e359ee8e7ccf45bc2c489f38ae1087c21468b61d700433e0c91b \
|
||||
--hash=sha256:f1ad871d761bad9a0d461cceeeff7375a39f4d181c2a206dada6fc05307fec12
|
||||
# via pyobjc-framework-applicationservices
|
||||
pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0ec9751904ef975bf0789d760dc4fadcb400edc4ffe4a736eb54971968babe5c \
|
||||
--hash=sha256:1f7f3d9010e38f03ea1fa266664c10ea349cd7492bd603b403584f49d713dbed \
|
||||
--hash=sha256:4b01e325b0cdc121e78730dde9756e971b23069bf141cd62efbcaac76d7b6dbb \
|
||||
--hash=sha256:63f6f0f3233dcf650aac1374781e78961b0b17b33e3351953bacf8bd0c430593 \
|
||||
--hash=sha256:7f668979d0c7320bf8f7ed6e030da578f93ab0f5dd619b295ec735cd8d5faa34 \
|
||||
--hash=sha256:810f97b210cfd93704d240860286dfd6df09f9f1c52525fc5c2166723aea3f9e \
|
||||
--hash=sha256:8f58c589b5a76ba98f186b1f3b19fb1c8b730e82351f81fb62e6194f64a71622 \
|
||||
--hash=sha256:cee63b891c2b6b7ccf98f233175411529f3e80286f58438793b3634af79858f1 \
|
||||
--hash=sha256:ebf8167ca2096cf3a05199decfa517be0df4c56048f49cf132bd6b1a6ab9c086
|
||||
# via
|
||||
# pynput
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
# via pynput
|
||||
pywhispercpp==1.5.0 \
|
||||
--hash=sha256:03025227d0da211e382db6b6b16d910a267c663b6b2c57092b1200965ec45393 \
|
||||
--hash=sha256:0c393c01a0a77007a17d17cb706e08cba97f0e35ea0268733af1792949d03ceb \
|
||||
--hash=sha256:0f895cbbf5ba71a9e3f0e6afb4b6ae49bae5c716dc6a8a4d905eb789d9fe2238 \
|
||||
--hash=sha256:1bc31f684b6a38000e397824155bda3b45b61af6acc9f7e0f3bfa70e20b574e3 \
|
||||
--hash=sha256:22f9ddf12f6fb0fe3c43465d976b554e8928fcc113c902127e94c792d85f0631 \
|
||||
--hash=sha256:24602b8d0329a224fe6eb1c1e455853e983a5e04a63d4cb759ae2f275e254f5f \
|
||||
--hash=sha256:24da0c0bd33068f4c9c3f45eae3e6b7fb31d9b5d3487e4e1e1323b4253288d62 \
|
||||
--hash=sha256:2ea8fa7f5ce602d3e986fb11c4c2973b471f1b14e0fe75e01a66f1a60aecbfbf \
|
||||
--hash=sha256:358261055c56a96a04f6b0ff419633ffc61ef61027788b2bb2c6e7dca69abdb7 \
|
||||
--hash=sha256:3f825942067da3b0c48fc5b552b816fcee1761e955b9fdfdc911f0ab2d6fff11 \
|
||||
--hash=sha256:4363fa893e398d1f18a5775374109aa310022b9f4fc777a89329b12963f3149d \
|
||||
--hash=sha256:4bb409027566b473100e43f07fac48f9c8bdb6cba1ac0fbff5594a6f5a0e1b7e \
|
||||
--hash=sha256:568669bae45bd879bba1e35401cefc89d572428bd17326ce8437107ab80003d0 \
|
||||
--hash=sha256:57dd5111d4dd9fe3f0e784a03a3337df5abd514260a7d16656733d110316d2f0 \
|
||||
--hash=sha256:5aa54c73ec96617d97aa519dbbf817e44255eddd9bd52ee1243be61028dbd018 \
|
||||
--hash=sha256:64415b7687c0b39e66652b38683983ef7f23e174d7b3b05caa539955da8b088e \
|
||||
--hash=sha256:649af3ae0f9dc0d0dd757d8c2adfc6d929b1b203ac1ba85d5ac453015ddd6e63 \
|
||||
--hash=sha256:6ad4071772eb9dad59a741611e44e3819e6249c46e295ab8468609d03c6e4232 \
|
||||
--hash=sha256:70e925fad2c48554d3f5baf79e2746540268d2974b5cf40a4880887e4a065c2f \
|
||||
--hash=sha256:77d4d0ff382b5bc1369e9f77a851b45659edf5974e0903ffb15b981a043d216b \
|
||||
--hash=sha256:9806e084ebf956c7e492c76ea31c708e894849024772b3c3a57f85c342afc341 \
|
||||
--hash=sha256:9b43ddd44e65ca53d5ab1f62b623bc3edc64019bbe06b9641fff2dfef704c990 \
|
||||
--hash=sha256:a2fe9312fe3c08f832da392296118cc8cc1fc901753289132253f2066d911357 \
|
||||
--hash=sha256:a6777b5d40c0679952ded7934f7119d5fbfd606ec348293f869f430795609bae \
|
||||
--hash=sha256:a839b738936a8cd72cdd55c59a83a462820532bee78e233241bf9a3503e92144 \
|
||||
--hash=sha256:b1f94300f2fa1748f67f63a9240b526e8542b2dad1ceca5ea87ec2e9e15a939a \
|
||||
--hash=sha256:b592011cd992a5bcd36d0923477fb4cfdd338a0c7ce58997de195a14ab2b6d9a \
|
||||
--hash=sha256:c35c16f5da31d79be604dfd082b8bb67d5d46ba2f7f59bf5ab13857d5cd6ec6b \
|
||||
--hash=sha256:c9498eb9f4c38ea121da2435b5275c267486a5e14dddf5e72ec54a480b1fb44e \
|
||||
--hash=sha256:d2805f15361247ada04a34b51c556514527b984f9b089a4e32f1b2a4abbc5367 \
|
||||
--hash=sha256:d92eec44b49595ab1454cff1d10faa83b0b27779db8d8f00592ed363f0c5a262 \
|
||||
--hash=sha256:dc8dbcb6033db306e9ec450d835c005dd491c457937c79ef2673ea8797cbb93c \
|
||||
--hash=sha256:ea34ae824a6f934ba7736e6440f93cc467a7ec98b9c8fb2e5a37bb439ffa93b9 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
sherpa-onnx==1.13.7 \
|
||||
--hash=sha256:01c4d001390f282bef653d229dce5d9da5009a804999449e33f890139f1f2da0 \
|
||||
--hash=sha256:026917d88fde36d5d86661e4a61c968dd741f43a96773ad742da13bffd030471 \
|
||||
--hash=sha256:0508bcf514b0ee914f57d2517e3783e383f68e5984a815f303284331097ac3de \
|
||||
--hash=sha256:05e4d9b208ea08b48cd5aec0a07bc3134c6ca5091d7a3df75fe70dd326eff745 \
|
||||
--hash=sha256:08cdb0b0971c27d7f8d13c7c6b090dd284469c46fb2469f23f9d21905db4c6d2 \
|
||||
--hash=sha256:0e9445d5d3f65a87b7a158edad4c630f21fcb1692aa006d19d70cbbccd38d71d \
|
||||
--hash=sha256:1333b929a71830ecd2f945e3c06f9ed2207e4aa9642a3a84ad1cbd2c9ffa230b \
|
||||
--hash=sha256:16292efe5fa07ca4532f57c2b5e67f2ef8cad83c418a60593a2dc60438048836 \
|
||||
--hash=sha256:2053956c4575b6ce4621f54ff0af6fae595d7df10691032c79d271b089988ff5 \
|
||||
--hash=sha256:234a4ef4ce48d98a7e12e278c0e9b69eeca6b571ca0057f2553781ded14ba099 \
|
||||
--hash=sha256:26293b1db9a2772f69bd286cfe37551d0bd0437c1f1382e98cfe7d0c4435d331 \
|
||||
--hash=sha256:3bc1fe8dd85a6db146b21db6a1900e1fea0fb4a0dbc27af4401d35407effa401 \
|
||||
--hash=sha256:3f58d2c3ece36b908cfb070ebe1b23c7bfaadd78a0ce205b412349c53375a4dd \
|
||||
--hash=sha256:470f2e2251d13c632b6ba37878bb355cd4672b6feedc57e9d9823bb04ed5df84 \
|
||||
--hash=sha256:4a149bb0e5d8ff382d9d0ec906411d5ba220b8732a7155c0e0cbee27b5a5ff19 \
|
||||
--hash=sha256:5094fac8ece316383f43c9fed287e5852057d21c1fb99645a75741386bde660b \
|
||||
--hash=sha256:511edfcedf9b90c4b3b44a14725e9397da95e9b9322efd6772c8e7d7e520d0de \
|
||||
--hash=sha256:52ca4392620bb4a0cb30373f245861107516c8831bface1c82c17a9e34f3f5c9 \
|
||||
--hash=sha256:58ec30d2702ebe86889fc24c077f5ecf6cbdd57d260eca00f179513a0d8bb6ee \
|
||||
--hash=sha256:68183b11eda2a866231b9e9aaa35b77222918edef5848a4ff6add6d89f523f6d \
|
||||
--hash=sha256:6dc8cd03e88a9d1e451bf83d3956c72cd78c5eb4d5a1af602243de75f77ff976 \
|
||||
--hash=sha256:70eecfee42f9104911be6af6573fa8eb9e5e9f658ca04454b5dc24ede1c99f2a \
|
||||
--hash=sha256:71a32c04e34c7c4cfc9300c2c4c3ede9cd8b0d1b00ccf0bfa24f202402368855 \
|
||||
--hash=sha256:7b3bef2a558f57c403bb7afb994e081cd242e5df3384295b6738b198cb2f8382 \
|
||||
--hash=sha256:7b4cce2e44f989f6c830103c8449e4df84833f66fa4f625fd092270b54918a55 \
|
||||
--hash=sha256:7fbdc37a3b2a1f45369a918b47960035fd15b0d365d42157d5cdc5335271ab86 \
|
||||
--hash=sha256:803013701e0acb95c704143adc2ac9c4dc587dfeba7a9bc5cfafd5d70da921b1 \
|
||||
--hash=sha256:81fea366ccc88074e15b9b7710723f0266cdd13f53b8bff1e5e8b5f95582c00a \
|
||||
--hash=sha256:9a88cfd3b6296b1e9056a6ab843f9f7c4e362f6f27c26e33aafbf917f536d20b \
|
||||
--hash=sha256:9d26e4514a04ddd344970b82c7b32e4e1de332312af5cd2f0e8dc385021d4c5e \
|
||||
--hash=sha256:9fb46a9b0844b2636b099dfa5ef26513fa0b91df28cd710a97d1cda2c9344fec \
|
||||
--hash=sha256:a641badd087c9a82a90fe4127ff0b29921348e6a86c21e94d59e3b5cc8321428 \
|
||||
--hash=sha256:aa04b2ecf7563f86e8a34e3e2666fc0b480618ccca11c6d629dcb31323c1d041 \
|
||||
--hash=sha256:c2e9c56d453bc804592d65834504e376a4fa90488adba042becf5213cf226328 \
|
||||
--hash=sha256:c5d99c89a1c83bed2e930798f614deed05c41136e0e3cc046977320132f56473 \
|
||||
--hash=sha256:d22753738497c162f381c545c35ee245d160031faa3993b5e3d3424ceb80c3a3 \
|
||||
--hash=sha256:d6b8adb339e0e89cf9914de610c85d2d5e4715b09f566eaf796a92eb72c014d1 \
|
||||
--hash=sha256:d7d00b9cec5011d518ae3a99c646fc3d058a8261b58044fac33f25cda0a9147c \
|
||||
--hash=sha256:ed40aee149f9e2e47d0b5cf1be21b2d662e5816bebdabdcdbbdb98b8a9928cbe \
|
||||
--hash=sha256:fce7cfab223d6bee0a58fa940b5057e2f3cf63613928b88e09ac99b477e40be0 \
|
||||
--hash=sha256:fed61cc23dba8f212eeb2723d2e90108d6de95734c5ae427aeafdb10f09ec184
|
||||
# via vocalinux
|
||||
sherpa-onnx-core==1.13.7 ; platform_machine != 'armv7l' \
|
||||
--hash=sha256:07de22f590299a68d9b5c985264f380579600a831ee95510ab12f4068800d08c \
|
||||
--hash=sha256:861c1e18fbf9bd2c725992c5a1797efe1b934b7df7bb18986d1fdc60e91290c9 \
|
||||
--hash=sha256:9ee6d4f05c14eb961370ba794f363088407465bf2006b73ab67508abd80be033 \
|
||||
--hash=sha256:b191e79d4952199bd11ce05c5b29c5efb08ed43a5d96839202e8ab603ab96278 \
|
||||
--hash=sha256:befe8193f02ed7935875acf540b8a554da0a89060965b32c1364f37c4ca7f3b3 \
|
||||
--hash=sha256:c53a930543f3a0f1063956fd3d01081acd6cb66f46c9b1f544b4393d6cbc1893 \
|
||||
--hash=sha256:cbcb78ef8a3bb74acf0b9d0a8715e9b857491be8e2b1e8f589f09ecf3d2f2a0b \
|
||||
--hash=sha256:cf17e20cada234df952f71a0e9412422c557e08246a6759b8aa6ea4bbd215a5a \
|
||||
--hash=sha256:d0131f93e8fabca773701e28301d81dff4f7445ba59e280fca319c585bac850a \
|
||||
--hash=sha256:e11c2dca5526ff473bd5cf94f40da7ff7075ec4c44f3464cc1bceffdc6f5e487 \
|
||||
--hash=sha256:e1e6333ecde50c69b8a43feff6eedf1033ec2a3fe58009506572bd717fc78e42 \
|
||||
--hash=sha256:e3066e94c24c898c5794e08507f955e14bc904299bac80f357d0bcb7d93e3825 \
|
||||
--hash=sha256:f48029e0c79b4cc654076806cbf62094a51dcd26c6bd1ce17db3bad03aff02b1
|
||||
# via vocalinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
# via
|
||||
# pynput
|
||||
# python-xlib
|
||||
tqdm==4.70.0 \
|
||||
--hash=sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220 \
|
||||
--hash=sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953
|
||||
# via pywhispercpp
|
||||
urllib3==2.8.0 \
|
||||
--hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \
|
||||
--hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63
|
||||
# via requests
|
||||
@@ -0,0 +1,444 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --only-group release-build --no-emit-project -o requirements/release-build.txt
|
||||
backports-tarfile==1.2.0 ; python_full_version < '3.12' and platform_machine != 'ppc64le' and platform_machine != 's390x' \
|
||||
--hash=sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34 \
|
||||
--hash=sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991
|
||||
# via jaraco-context
|
||||
build==1.6.1 \
|
||||
--hash=sha256:51cc11666391ab6f092070437ac747002ff46f3e4113a3622177ee6b488bfc53 \
|
||||
--hash=sha256:ecd351a4be9d35a9eaaba244a7687143c9c7d4aea6ac964e7e7ddab20cbcf4e7
|
||||
certifi==2026.10.19 \
|
||||
--hash=sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae \
|
||||
--hash=sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b
|
||||
# via requests
|
||||
cffi==2.1.1 ; platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_python_implementation != 'PyPy' and sys_platform == 'linux' \
|
||||
--hash=sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e \
|
||||
--hash=sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66 \
|
||||
--hash=sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2 \
|
||||
--hash=sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0 \
|
||||
--hash=sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971 \
|
||||
--hash=sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c \
|
||||
--hash=sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d \
|
||||
--hash=sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517 \
|
||||
--hash=sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735 \
|
||||
--hash=sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80 \
|
||||
--hash=sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f \
|
||||
--hash=sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1 \
|
||||
--hash=sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29 \
|
||||
--hash=sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8 \
|
||||
--hash=sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c \
|
||||
--hash=sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e \
|
||||
--hash=sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48 \
|
||||
--hash=sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813 \
|
||||
--hash=sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac \
|
||||
--hash=sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632 \
|
||||
--hash=sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6 \
|
||||
--hash=sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1 \
|
||||
--hash=sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688 \
|
||||
--hash=sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0 \
|
||||
--hash=sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062 \
|
||||
--hash=sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779 \
|
||||
--hash=sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94 \
|
||||
--hash=sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50 \
|
||||
--hash=sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab \
|
||||
--hash=sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac \
|
||||
--hash=sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6 \
|
||||
--hash=sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676 \
|
||||
--hash=sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1 \
|
||||
--hash=sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13 \
|
||||
--hash=sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e \
|
||||
--hash=sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e \
|
||||
--hash=sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973 \
|
||||
--hash=sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527 \
|
||||
--hash=sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72 \
|
||||
--hash=sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890 \
|
||||
--hash=sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c \
|
||||
--hash=sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990 \
|
||||
--hash=sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd \
|
||||
--hash=sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94 \
|
||||
--hash=sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3 \
|
||||
--hash=sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80 \
|
||||
--hash=sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5 \
|
||||
--hash=sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c \
|
||||
--hash=sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a \
|
||||
--hash=sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4 \
|
||||
--hash=sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e \
|
||||
--hash=sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6 \
|
||||
--hash=sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b \
|
||||
--hash=sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03 \
|
||||
--hash=sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af \
|
||||
--hash=sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231 \
|
||||
--hash=sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2 \
|
||||
--hash=sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3 \
|
||||
--hash=sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836 \
|
||||
--hash=sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5 \
|
||||
--hash=sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399 \
|
||||
--hash=sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96 \
|
||||
--hash=sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e \
|
||||
--hash=sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf \
|
||||
--hash=sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc \
|
||||
--hash=sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455 \
|
||||
--hash=sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0 \
|
||||
--hash=sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12 \
|
||||
--hash=sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7 \
|
||||
--hash=sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692 \
|
||||
--hash=sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54 \
|
||||
--hash=sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3 \
|
||||
--hash=sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b \
|
||||
--hash=sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be \
|
||||
--hash=sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d \
|
||||
--hash=sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358 \
|
||||
--hash=sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a \
|
||||
--hash=sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7 \
|
||||
--hash=sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc \
|
||||
--hash=sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960 \
|
||||
--hash=sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125 \
|
||||
--hash=sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb \
|
||||
--hash=sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a \
|
||||
--hash=sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa \
|
||||
--hash=sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf \
|
||||
--hash=sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3 \
|
||||
--hash=sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4 \
|
||||
--hash=sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264
|
||||
# via cryptography
|
||||
charset-normalizer==3.5.1 \
|
||||
--hash=sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5 \
|
||||
--hash=sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b \
|
||||
--hash=sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f \
|
||||
--hash=sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5 \
|
||||
--hash=sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22 \
|
||||
--hash=sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5 \
|
||||
--hash=sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac \
|
||||
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
||||
--hash=sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626 \
|
||||
--hash=sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4 \
|
||||
--hash=sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369 \
|
||||
--hash=sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b \
|
||||
--hash=sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e \
|
||||
--hash=sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee \
|
||||
--hash=sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1 \
|
||||
--hash=sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102 \
|
||||
--hash=sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8 \
|
||||
--hash=sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9 \
|
||||
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
||||
--hash=sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031 \
|
||||
--hash=sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e \
|
||||
--hash=sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235 \
|
||||
--hash=sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072 \
|
||||
--hash=sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb \
|
||||
--hash=sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c \
|
||||
--hash=sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950 \
|
||||
--hash=sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2 \
|
||||
--hash=sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e \
|
||||
--hash=sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6 \
|
||||
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
||||
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
||||
--hash=sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2 \
|
||||
--hash=sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032 \
|
||||
--hash=sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71 \
|
||||
--hash=sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96 \
|
||||
--hash=sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687 \
|
||||
--hash=sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8 \
|
||||
--hash=sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3 \
|
||||
--hash=sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61 \
|
||||
--hash=sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9 \
|
||||
--hash=sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1 \
|
||||
--hash=sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4 \
|
||||
--hash=sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65 \
|
||||
--hash=sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663 \
|
||||
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
||||
--hash=sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591 \
|
||||
--hash=sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a \
|
||||
--hash=sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e \
|
||||
--hash=sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7 \
|
||||
--hash=sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3 \
|
||||
--hash=sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c \
|
||||
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
||||
--hash=sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7 \
|
||||
--hash=sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96 \
|
||||
--hash=sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486 \
|
||||
--hash=sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3 \
|
||||
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
||||
--hash=sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b \
|
||||
--hash=sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731 \
|
||||
--hash=sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959 \
|
||||
--hash=sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9 \
|
||||
--hash=sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf \
|
||||
--hash=sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8 \
|
||||
--hash=sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e \
|
||||
--hash=sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885 \
|
||||
--hash=sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0 \
|
||||
--hash=sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506 \
|
||||
--hash=sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2 \
|
||||
--hash=sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0 \
|
||||
--hash=sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e \
|
||||
--hash=sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e \
|
||||
--hash=sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491 \
|
||||
--hash=sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a \
|
||||
--hash=sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20 \
|
||||
--hash=sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449 \
|
||||
--hash=sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af \
|
||||
--hash=sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c \
|
||||
--hash=sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712 \
|
||||
--hash=sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7 \
|
||||
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
||||
--hash=sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9 \
|
||||
--hash=sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e \
|
||||
--hash=sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5 \
|
||||
--hash=sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36 \
|
||||
--hash=sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263 \
|
||||
--hash=sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4 \
|
||||
--hash=sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11 \
|
||||
--hash=sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a \
|
||||
--hash=sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3 \
|
||||
--hash=sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375 \
|
||||
--hash=sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d \
|
||||
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
||||
--hash=sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c \
|
||||
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
||||
--hash=sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6 \
|
||||
--hash=sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc \
|
||||
--hash=sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b \
|
||||
--hash=sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f \
|
||||
--hash=sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00 \
|
||||
--hash=sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10 \
|
||||
--hash=sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598 \
|
||||
--hash=sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6 \
|
||||
--hash=sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962 \
|
||||
--hash=sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c \
|
||||
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
||||
--hash=sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573 \
|
||||
--hash=sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90 \
|
||||
--hash=sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5 \
|
||||
--hash=sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18 \
|
||||
--hash=sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af \
|
||||
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
||||
--hash=sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b \
|
||||
--hash=sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6 \
|
||||
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
||||
--hash=sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774 \
|
||||
--hash=sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004 \
|
||||
--hash=sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a \
|
||||
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
||||
--hash=sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2 \
|
||||
--hash=sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe \
|
||||
--hash=sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3 \
|
||||
--hash=sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc \
|
||||
--hash=sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d \
|
||||
--hash=sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc \
|
||||
--hash=sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893 \
|
||||
--hash=sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef \
|
||||
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
||||
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30 \
|
||||
--hash=sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7 \
|
||||
--hash=sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5 \
|
||||
--hash=sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f \
|
||||
--hash=sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9 \
|
||||
--hash=sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada \
|
||||
--hash=sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876 \
|
||||
--hash=sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a \
|
||||
--hash=sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348 \
|
||||
--hash=sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3 \
|
||||
--hash=sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f \
|
||||
--hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \
|
||||
--hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f
|
||||
# via requests
|
||||
colorama==0.4.6 ; os_name == 'nt' and sys_platform != 'ios' \
|
||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via build
|
||||
cryptography==50.0.2 ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'linux' \
|
||||
--hash=sha256:0ddc924c04591c2811ca024d62ecad4f7f6f08af8939c211438f48a16bd23602 \
|
||||
--hash=sha256:0ecbc5652bdb6fc9eaf89a7d196e20941adfe812f43bc4ca05d9150496821047 \
|
||||
--hash=sha256:1981f1db4630889b9ef7803fadef12b056f428cb6b85c27ba57b774793b6093c \
|
||||
--hash=sha256:1ba34f04897fcdaa73f74145c25f3ec146fbd56593853e88adc2e811303c5f42 \
|
||||
--hash=sha256:241449bf940a5d27309bd317e6f9a2af6932113818bb2b8f5c59ddc7ef16da18 \
|
||||
--hash=sha256:25784ce8b9621c90c643efb9e1e2162ab3b0224cae446ad5e70e7fcb1ce18b51 \
|
||||
--hash=sha256:4061c0079120205fb760c58acab6443e217307dcf05e3702cf970e0689972856 \
|
||||
--hash=sha256:4a20ce1e5cb4284a86692fdcba7cb8754185c6b2e5c56fcef3751cf451d3cdc2 \
|
||||
--hash=sha256:58a0c478eeca76fe5e07993c5a0703def34a6dc6a0cda4f5564639b33112ffe7 \
|
||||
--hash=sha256:630ebfea3bf689d075f82316324ff7433dc447fe6bc1bfc76524b74b4a9567d2 \
|
||||
--hash=sha256:6f8700550aa1474a91e5dc07049c46f98b423b5b1ddd0483e0b51362eeeaf5be \
|
||||
--hash=sha256:79def8d059362e7831389ed3be0ecdf58a89386e1271e35dd9f5af84e81bffd0 \
|
||||
--hash=sha256:7a8701d6b584d76e909e3d305b7d126b41439876a5aaf76cddc67fc230eafa2e \
|
||||
--hash=sha256:7b46165bb56eb4704e2eaaf86f3c940d19154535d9b0ca7d6d590b04060e00d5 \
|
||||
--hash=sha256:7c6d0330c472d96f6a6afe24d80dfdf15176c33096f0a4397ae4c60f3dd3be48 \
|
||||
--hash=sha256:828d49b0ff5a0e3975865571c5d91dbbdd0d38d8289b249a163e9425413a5e05 \
|
||||
--hash=sha256:85d0d9a31b9098e98534226d5686b47264b95e62ce459dc2e62fdfc809f9fe93 \
|
||||
--hash=sha256:87e9ce85beb6b328ba370cc6e6aea483c92617b4c95b1d33a49297eb662bfb04 \
|
||||
--hash=sha256:8c71ba2cd31fc93748c38e1b613200ff1c2665cbfd5341fe3a61cfde35a1430e \
|
||||
--hash=sha256:92e665960f25fcdc73725b9cec7a3824f279ba97a98653afe9ffac2e43668f67 \
|
||||
--hash=sha256:9c8402a82ea0dc4ceeab793db05f0fafa8ca139ca34fcde5df0f596103c74107 \
|
||||
--hash=sha256:9dab55f57c74c3cad24c323bacbbd04be4705ba6eb0d92e920b1fc4837ed5079 \
|
||||
--hash=sha256:a9f7355e6fab51f6c369b86fb7571cffa05edee2c2121e0380a37fb9ac1cd5c1 \
|
||||
--hash=sha256:ab50ee449bf968271e820086f10a33d101dd060370abc10bcd22279be2656539 \
|
||||
--hash=sha256:ac9ed99d81760c62fe89d5f0815cdfa1ba9a35141cf30f1c2d044f04b4803d2e \
|
||||
--hash=sha256:c5e67125c7dca78d199ec4e116aa93dbb83494808ecbb8211a2cb09b1bf41dbd \
|
||||
--hash=sha256:c71be1cbfa5cd9a41ee452acf1eccd82b2c05950358b106ec8ceb83411d1a020 \
|
||||
--hash=sha256:ce47f66801c20ec6c6632453bb5960fe38939e9306970b48b3a5a26de7745d94 \
|
||||
--hash=sha256:d370b8d1dfcdf7130178137f6fbee6140774a1acc6cacefc4b42643ec11d0a3a \
|
||||
--hash=sha256:d38cdff612d06fa6a32840d5e1b1f7a27cee4a349aa9085d94a67789d6bfd408 \
|
||||
--hash=sha256:d8947001be83df1394050758ce0e745dd74fb134eef0a4b5124208dfc3a68c37 \
|
||||
--hash=sha256:deb9fde5c60e437ee4821bc9bc39ff31b42135c27e1dc61ef0a629389c1de62e \
|
||||
--hash=sha256:dfe9763530994147d9af1def057a5b9658b00e8f8fe8743d144d1e0911c2e454 \
|
||||
--hash=sha256:e105ab60406787da31fccc883fc0f733af1efd78f0136a4599692c4083a73d0c \
|
||||
--hash=sha256:e275096ea1e60cc595cda2836fd4a6c725d1125108b868be17f53684d164e2cc \
|
||||
--hash=sha256:ee247f5c245c9a2fe7c8e2214e295918838e44e00a45a6718451e4004219e767 \
|
||||
--hash=sha256:eef4c2f3423810b3070ab391f85436d2f8bbfcb286ac15cbc73190b3563b1f1a \
|
||||
--hash=sha256:f21e8a22c8605750c7af886bab299a363721264061b4ac0a30efb73cfd58efc5 \
|
||||
--hash=sha256:f2f9bd7f90c64fe89253f0a2c05e3c4856072660429ce8831b4235bf29403a67 \
|
||||
--hash=sha256:f9f6143a8c75945eb960d9eb98905a441394abfa24afaae239d514ffb2586480 \
|
||||
--hash=sha256:fdd28f912fccfec1846a94e2e1e8f9b0012f557f0c46fe4f3eb0d7a87afcf90b
|
||||
# via secretstorage
|
||||
docutils==0.22.4 \
|
||||
--hash=sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968 \
|
||||
--hash=sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de
|
||||
# via readme-renderer
|
||||
id==1.6.1 \
|
||||
--hash=sha256:d0732d624fb46fd4e7bc4e5152f00214450953b9e772c182c1c22964def1a069 \
|
||||
--hash=sha256:f5ec41ed2629a508f5d0988eda142e190c9c6da971100612c4de9ad9f9b237ca
|
||||
# via twine
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
# via requests
|
||||
importlib-metadata==9.0.1 ; python_full_version < '3.12' and platform_machine != 'ppc64le' and platform_machine != 's390x' \
|
||||
--hash=sha256:ab830580bc0ef3db61ce8fae716389e5462b67e033018bab6d8f80ef17172f99 \
|
||||
--hash=sha256:bba5600596a7e21f3eef53281cf28d6a5195634d2f2b78ff9501a3272c6eaab0
|
||||
# via keyring
|
||||
jaraco-classes==3.4.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x' \
|
||||
--hash=sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd \
|
||||
--hash=sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790
|
||||
# via keyring
|
||||
jaraco-context==6.1.2 ; platform_machine != 'ppc64le' and platform_machine != 's390x' \
|
||||
--hash=sha256:bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535 \
|
||||
--hash=sha256:f1a6c9d391e661cc5b8d39861ff077a7dc24dc23833ccee564b234b81c82dfe3
|
||||
# via keyring
|
||||
jaraco-functools==4.6.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x' \
|
||||
--hash=sha256:880c577ec9720b3a052d5bc611fb9f2269b3d87902ef42440df443b88e443280 \
|
||||
--hash=sha256:99e3dc0060c5cbe8fcd1cdb36258e2a65ca40f1566b2033b12abb1bb44dd3c30
|
||||
# via keyring
|
||||
jeepney==0.9.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'linux' \
|
||||
--hash=sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683 \
|
||||
--hash=sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732
|
||||
# via
|
||||
# keyring
|
||||
# secretstorage
|
||||
keyring==25.7.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x' \
|
||||
--hash=sha256:be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f \
|
||||
--hash=sha256:fe01bd85eb3f8fb3dd0405defdeac9a5b4f6f0439edbb3149577f244a2e8245b
|
||||
# via twine
|
||||
markdown-it-py==4.2.0 \
|
||||
--hash=sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49 \
|
||||
--hash=sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a
|
||||
# via rich
|
||||
mdurl==0.1.2 \
|
||||
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
|
||||
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
|
||||
# via markdown-it-py
|
||||
more-itertools==11.1.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x' \
|
||||
--hash=sha256:48e8f4d9e7e5878571ecf6f2b4e57634f93cd474cc8cfbd2376f2d11b396e30d \
|
||||
--hash=sha256:4b65538ae22f6fed0ce4874efd317463a7489796a0939fa66824dd542125a192
|
||||
# via
|
||||
# jaraco-classes
|
||||
# jaraco-functools
|
||||
nh3==0.3.7 \
|
||||
--hash=sha256:157ec1eb7a62f3d9a7badb8d82d89aa810e3e24e097eedfa481a25d0c8a99877 \
|
||||
--hash=sha256:15f5fbf090f5c88d61c820e1fc1fceecb6520cca9fe85649c06b57ef9dc9ff62 \
|
||||
--hash=sha256:18f4278ecd157d43cb35acd5aae9f35cfa79f546b4922bd86536adc0f6312102 \
|
||||
--hash=sha256:19f288c938ec6eef1f5d2c6cab47838e71fef8097e1c1233802be5a6230ba086 \
|
||||
--hash=sha256:4968fe8d2db97c6f047659bf46a449fd8ec377f44ebf3e0a1b96c0d3a333ae32 \
|
||||
--hash=sha256:5ffdfcb9a686ffb12765376bcfb6b5b55728516d3c0ee317d29982381ded3df8 \
|
||||
--hash=sha256:614dac4a4c36ad084e78447d16fe898dedd762e354a7ab9cda2984e82f67883d \
|
||||
--hash=sha256:618e3059caf41ccdf5dcccb3fa9df4cf6e4efe23d1382a8bbfca272a8a4f8bfc \
|
||||
--hash=sha256:6698a822132beedab80f131c08d8d0ac5a178ddeb488d02ca4b67716ecfac7af \
|
||||
--hash=sha256:6c3aa50eb26e9228238271db9f983cbc3b006dfbfeca2d4dc34c33ddc6ac5ea5 \
|
||||
--hash=sha256:6e4280115d44c3b278eef712a86748c1a723105cd79feec46952383117ab4e59 \
|
||||
--hash=sha256:70f5ac8626e899a4bab0ef74ca2f5bd602f49c7b739e6e5026b4afc6d63dac42 \
|
||||
--hash=sha256:71860d01c16f4d8c72e334e0674beb2b0899dbd0bf760de18932ef4390303848 \
|
||||
--hash=sha256:808def0c8c07843e6e50dc84f532457bfa2cfd17417b219a5d9e7c773709331a \
|
||||
--hash=sha256:874b7d67a067bd29a59223f6270fc30da4edd8e6d87fd219fc93bcbaa662c946 \
|
||||
--hash=sha256:91a4dab4e94d9fc54b9f67b1adfb23e81fab7ab43f33c3b8c97be9aa38f789ba \
|
||||
--hash=sha256:94fd6e59553fbb9ffd8ba71bbd5a54e3126ba01799a097ae30d5341d750bc6ac \
|
||||
--hash=sha256:9b7279d43323a25225df23576af6594a16693f61431170848b8b2ac21ad4f174 \
|
||||
--hash=sha256:bc42bb1193c1e28a1e74c2cabaca178e118a7103e8832699fef8a2b3e2496493 \
|
||||
--hash=sha256:be53a4825585f701955cb9baf49f478f56eb81e20294329fe4bc689dd5dd81fa \
|
||||
--hash=sha256:d56e76bd3cadb09b6b0cef364850811663734b348a25f5f587a2819c495367bd \
|
||||
--hash=sha256:de2b2aab32ea303405debefdcfc58043d3e635fa3f67b9eb140d2b0e0c0d2563 \
|
||||
--hash=sha256:e8fd1ab205258b29254f72db377d99e2c96aa7653ef3b015ccab0420b094b506 \
|
||||
--hash=sha256:eae64328e46a25785535afcb6885b6f182ecaf5ee8c88f8c075422db8aacc65b \
|
||||
--hash=sha256:f04b7d333b27f13ca439da3cf1c75c2fba34f104969f6ce4ac8e7079699c2f4a \
|
||||
--hash=sha256:f266d3f1b3647449923a8e406524632220dd5d8b647078dfe45b885d33d10479 \
|
||||
--hash=sha256:fd4a70efb45d5372174f718878eb7a35c12677626a63b2f103b23b833457dcac
|
||||
# via readme-renderer
|
||||
packaging==26.3 \
|
||||
--hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
|
||||
--hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
|
||||
# via
|
||||
# build
|
||||
# twine
|
||||
# wheel
|
||||
pycparser==3.0 ; implementation_name != 'PyPy' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_python_implementation != 'PyPy' and sys_platform == 'linux' \
|
||||
--hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \
|
||||
--hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992
|
||||
# via cffi
|
||||
pygments==2.21.0 \
|
||||
--hash=sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9 \
|
||||
--hash=sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c
|
||||
# via
|
||||
# readme-renderer
|
||||
# rich
|
||||
pyproject-hooks==1.3.3 \
|
||||
--hash=sha256:5fc53fdac9f7bd63fbcdc868fb5f90b4784d78a53a3d3388cd738b807441a20b \
|
||||
--hash=sha256:defda19b854fa0d3bd4f76ea4ddcba8abd7dcfcdd585a6690ade050744fc5f43
|
||||
# via build
|
||||
pywin32-ctypes==0.2.3 ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'win32' \
|
||||
--hash=sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8 \
|
||||
--hash=sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755
|
||||
# via keyring
|
||||
readme-renderer==46.0 \
|
||||
--hash=sha256:af3e964914f6310a33ff67b72a4bdd940bed8d7c3bdecd2d14f40edf284bfe90 \
|
||||
--hash=sha256:d0dae1f74bb273b534770cb4cccb6bb78735540afdb03c2146f4e19dcd412560
|
||||
# via twine
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# requests-toolbelt
|
||||
# twine
|
||||
requests-toolbelt==1.0.0 \
|
||||
--hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \
|
||||
--hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06
|
||||
# via twine
|
||||
rfc3986==2.0.0 \
|
||||
--hash=sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd \
|
||||
--hash=sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c
|
||||
# via twine
|
||||
rich==15.0.0 \
|
||||
--hash=sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb \
|
||||
--hash=sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36
|
||||
# via twine
|
||||
secretstorage==3.5.0 ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'linux' \
|
||||
--hash=sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137 \
|
||||
--hash=sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be
|
||||
# via keyring
|
||||
setuptools==84.1.0 \
|
||||
--hash=sha256:23657205b63d4d31395ab917815247f694aafad28cd21316bf5fd45a51048ea0 \
|
||||
--hash=sha256:5231689c6ac8156cd155cfb98c3fd6fb252c3e7e9bd3d78b64d3c55f132624c9
|
||||
twine==6.2.0 \
|
||||
--hash=sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8 \
|
||||
--hash=sha256:e5ed0d2fd70c9959770dce51c8f39c8945c574e18173a7b81802dab51b4b75cf
|
||||
urllib3==2.8.0 \
|
||||
--hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \
|
||||
--hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63
|
||||
# via
|
||||
# id
|
||||
# requests
|
||||
# twine
|
||||
wheel==0.48.0 \
|
||||
--hash=sha256:3217dcc807155e45db462d7ef2431f5ddda0d7273b700d05a67b271ceb1287ab \
|
||||
--hash=sha256:94800765601e9171bf5d58d066e640662842bcedcbab982b2c90787a2c987322
|
||||
zipp==4.1.1 ; python_full_version < '3.12' and platform_machine != 'ppc64le' and platform_machine != 's390x' \
|
||||
--hash=sha256:7ebb7a44c021b29fd8dbd7cce6812d0d7b5b454521f93cc71af6ccd155aaa70b \
|
||||
--hash=sha256:8979f52d874162f485ff2981e3891f3a3317b7a3dd43ff1e1775b9304f307a9c
|
||||
# via importlib-metadata
|
||||
@@ -0,0 +1,481 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --no-dev --no-emit-project --no-emit-package pygobject -o requirements/runtime.txt
|
||||
certifi==2026.10.19 \
|
||||
--hash=sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae \
|
||||
--hash=sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b
|
||||
# via requests
|
||||
charset-normalizer==3.5.1 \
|
||||
--hash=sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5 \
|
||||
--hash=sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b \
|
||||
--hash=sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f \
|
||||
--hash=sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5 \
|
||||
--hash=sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22 \
|
||||
--hash=sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5 \
|
||||
--hash=sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac \
|
||||
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
||||
--hash=sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626 \
|
||||
--hash=sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4 \
|
||||
--hash=sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369 \
|
||||
--hash=sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b \
|
||||
--hash=sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e \
|
||||
--hash=sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee \
|
||||
--hash=sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1 \
|
||||
--hash=sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102 \
|
||||
--hash=sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8 \
|
||||
--hash=sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9 \
|
||||
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
||||
--hash=sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031 \
|
||||
--hash=sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e \
|
||||
--hash=sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235 \
|
||||
--hash=sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072 \
|
||||
--hash=sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb \
|
||||
--hash=sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c \
|
||||
--hash=sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950 \
|
||||
--hash=sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2 \
|
||||
--hash=sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e \
|
||||
--hash=sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6 \
|
||||
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
||||
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
||||
--hash=sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2 \
|
||||
--hash=sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032 \
|
||||
--hash=sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71 \
|
||||
--hash=sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96 \
|
||||
--hash=sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687 \
|
||||
--hash=sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8 \
|
||||
--hash=sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3 \
|
||||
--hash=sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61 \
|
||||
--hash=sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9 \
|
||||
--hash=sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1 \
|
||||
--hash=sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4 \
|
||||
--hash=sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65 \
|
||||
--hash=sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663 \
|
||||
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
||||
--hash=sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591 \
|
||||
--hash=sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a \
|
||||
--hash=sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e \
|
||||
--hash=sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7 \
|
||||
--hash=sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3 \
|
||||
--hash=sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c \
|
||||
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
||||
--hash=sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7 \
|
||||
--hash=sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96 \
|
||||
--hash=sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486 \
|
||||
--hash=sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3 \
|
||||
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
||||
--hash=sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b \
|
||||
--hash=sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731 \
|
||||
--hash=sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959 \
|
||||
--hash=sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9 \
|
||||
--hash=sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf \
|
||||
--hash=sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8 \
|
||||
--hash=sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e \
|
||||
--hash=sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885 \
|
||||
--hash=sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0 \
|
||||
--hash=sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506 \
|
||||
--hash=sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2 \
|
||||
--hash=sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0 \
|
||||
--hash=sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e \
|
||||
--hash=sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e \
|
||||
--hash=sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491 \
|
||||
--hash=sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a \
|
||||
--hash=sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20 \
|
||||
--hash=sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449 \
|
||||
--hash=sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af \
|
||||
--hash=sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c \
|
||||
--hash=sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712 \
|
||||
--hash=sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7 \
|
||||
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
||||
--hash=sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9 \
|
||||
--hash=sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e \
|
||||
--hash=sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5 \
|
||||
--hash=sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36 \
|
||||
--hash=sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263 \
|
||||
--hash=sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4 \
|
||||
--hash=sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11 \
|
||||
--hash=sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a \
|
||||
--hash=sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3 \
|
||||
--hash=sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375 \
|
||||
--hash=sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d \
|
||||
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
||||
--hash=sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c \
|
||||
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
||||
--hash=sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6 \
|
||||
--hash=sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc \
|
||||
--hash=sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b \
|
||||
--hash=sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f \
|
||||
--hash=sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00 \
|
||||
--hash=sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10 \
|
||||
--hash=sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598 \
|
||||
--hash=sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6 \
|
||||
--hash=sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962 \
|
||||
--hash=sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c \
|
||||
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
||||
--hash=sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573 \
|
||||
--hash=sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90 \
|
||||
--hash=sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5 \
|
||||
--hash=sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18 \
|
||||
--hash=sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af \
|
||||
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
||||
--hash=sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b \
|
||||
--hash=sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6 \
|
||||
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
||||
--hash=sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774 \
|
||||
--hash=sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004 \
|
||||
--hash=sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a \
|
||||
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
||||
--hash=sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2 \
|
||||
--hash=sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe \
|
||||
--hash=sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3 \
|
||||
--hash=sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc \
|
||||
--hash=sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d \
|
||||
--hash=sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc \
|
||||
--hash=sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893 \
|
||||
--hash=sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef \
|
||||
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
||||
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30 \
|
||||
--hash=sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7 \
|
||||
--hash=sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5 \
|
||||
--hash=sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f \
|
||||
--hash=sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9 \
|
||||
--hash=sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada \
|
||||
--hash=sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876 \
|
||||
--hash=sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a \
|
||||
--hash=sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348 \
|
||||
--hash=sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3 \
|
||||
--hash=sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f \
|
||||
--hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \
|
||||
--hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f
|
||||
# via requests
|
||||
colorama==0.4.6 ; sys_platform == 'win32' \
|
||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via tqdm
|
||||
evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
# via requests
|
||||
numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \
|
||||
--hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \
|
||||
--hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \
|
||||
--hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \
|
||||
--hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \
|
||||
--hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \
|
||||
--hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \
|
||||
--hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \
|
||||
--hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \
|
||||
--hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \
|
||||
--hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \
|
||||
--hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \
|
||||
--hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \
|
||||
--hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \
|
||||
--hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \
|
||||
--hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \
|
||||
--hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \
|
||||
--hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \
|
||||
--hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \
|
||||
--hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \
|
||||
--hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \
|
||||
--hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \
|
||||
--hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \
|
||||
--hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \
|
||||
--hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \
|
||||
--hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \
|
||||
--hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \
|
||||
--hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \
|
||||
--hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \
|
||||
--hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \
|
||||
--hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \
|
||||
--hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \
|
||||
--hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \
|
||||
--hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \
|
||||
--hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \
|
||||
--hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \
|
||||
--hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \
|
||||
--hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \
|
||||
--hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \
|
||||
--hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \
|
||||
--hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \
|
||||
--hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \
|
||||
--hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \
|
||||
--hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \
|
||||
--hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \
|
||||
--hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \
|
||||
--hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \
|
||||
--hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \
|
||||
--hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \
|
||||
--hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \
|
||||
--hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \
|
||||
--hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \
|
||||
--hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \
|
||||
--hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \
|
||||
--hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \
|
||||
--hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \
|
||||
--hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \
|
||||
--hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \
|
||||
--hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \
|
||||
--hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \
|
||||
--hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \
|
||||
--hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \
|
||||
--hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \
|
||||
--hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \
|
||||
--hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \
|
||||
--hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \
|
||||
--hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \
|
||||
--hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \
|
||||
--hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \
|
||||
--hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \
|
||||
--hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
--hash=sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7 \
|
||||
--hash=sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0 \
|
||||
--hash=sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3 \
|
||||
--hash=sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c \
|
||||
--hash=sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce \
|
||||
--hash=sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8 \
|
||||
--hash=sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1 \
|
||||
--hash=sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4 \
|
||||
--hash=sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee \
|
||||
--hash=sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740 \
|
||||
--hash=sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98 \
|
||||
--hash=sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710 \
|
||||
--hash=sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee \
|
||||
--hash=sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68 \
|
||||
--hash=sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf \
|
||||
--hash=sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8 \
|
||||
--hash=sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf \
|
||||
--hash=sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b \
|
||||
--hash=sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884 \
|
||||
--hash=sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03 \
|
||||
--hash=sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69 \
|
||||
--hash=sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4 \
|
||||
--hash=sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842 \
|
||||
--hash=sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65 \
|
||||
--hash=sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080 \
|
||||
--hash=sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e \
|
||||
--hash=sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e \
|
||||
--hash=sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414 \
|
||||
--hash=sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59 \
|
||||
--hash=sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8 \
|
||||
--hash=sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617 \
|
||||
--hash=sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4 \
|
||||
--hash=sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb \
|
||||
--hash=sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251 \
|
||||
--hash=sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d \
|
||||
--hash=sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2 \
|
||||
--hash=sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab \
|
||||
--hash=sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657 \
|
||||
--hash=sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15 \
|
||||
--hash=sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9 \
|
||||
--hash=sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8 \
|
||||
--hash=sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323 \
|
||||
--hash=sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788 \
|
||||
--hash=sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc \
|
||||
--hash=sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56 \
|
||||
--hash=sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1 \
|
||||
--hash=sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d \
|
||||
--hash=sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec \
|
||||
--hash=sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2 \
|
||||
--hash=sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e \
|
||||
--hash=sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7 \
|
||||
--hash=sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26 \
|
||||
--hash=sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514 \
|
||||
--hash=sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860 \
|
||||
--hash=sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a \
|
||||
--hash=sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1 \
|
||||
--hash=sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab \
|
||||
--hash=sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba \
|
||||
--hash=sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12 \
|
||||
--hash=sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6 \
|
||||
--hash=sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e \
|
||||
--hash=sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac \
|
||||
--hash=sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
platformdirs==4.11.3 \
|
||||
--hash=sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7 \
|
||||
--hash=sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab
|
||||
# via pywhispercpp
|
||||
psutil==7.2.2 \
|
||||
--hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \
|
||||
--hash=sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 \
|
||||
--hash=sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841 \
|
||||
--hash=sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63 \
|
||||
--hash=sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979 \
|
||||
--hash=sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a \
|
||||
--hash=sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b \
|
||||
--hash=sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9 \
|
||||
--hash=sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee \
|
||||
--hash=sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312 \
|
||||
--hash=sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b \
|
||||
--hash=sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9 \
|
||||
--hash=sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e \
|
||||
--hash=sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc \
|
||||
--hash=sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1 \
|
||||
--hash=sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf \
|
||||
--hash=sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea \
|
||||
--hash=sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
--hash=sha256:5fce4bcdd2e0e8c063d835dbe2860dac46437506af509353c7f8114d4bacbd5b \
|
||||
--hash=sha256:692d8c1446f52ed2662120bcd9ddcb5aa2b71f38bda31e58b19fb4672fffba69 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
--hash=sha256:2c7ef3d2f865b4b3ebb14ec3556f7a3e8abb6d130c67275cd9daa08dbd6e4e4e \
|
||||
--hash=sha256:3772b406edb3ff78171530a17cda1c4a7817f87b87ded0d8715b3fa664df16db \
|
||||
--hash=sha256:3906452339cd06a3bb07df103c2511d4cb0f7a22d8771c0b802eba15d9a642b6 \
|
||||
--hash=sha256:59a77038ebe0ab1240f61c341e7fb67b8674f2b4cd41bc71a6472511a12b50f7 \
|
||||
--hash=sha256:89acc6bc13aaa6e3f52b0ce652ede7e201edb6bf062741b246b0c5a44582f25f \
|
||||
--hash=sha256:950bd2d9c74634398c4e3d24ef2f213d4e23d705083697464fa67afedc53c1ad \
|
||||
--hash=sha256:b9cdd686e32db8e451feb19f8a85bc4cd52c2893103881d04aca51e1f35371d1
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-cocoa
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-applicationservices==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0bcc09531d5854598fd74706d999e4ae3b7c503204d318910d02eba30e8eecef \
|
||||
--hash=sha256:1af01a271b85eae2a327e93cf3ec46de0199a1a933594f78d4c2b9b9c2240e5e \
|
||||
--hash=sha256:3b5693a377480cf127caa1c8c835b8620896971029c545d99d01aa31a2c38159 \
|
||||
--hash=sha256:3f9dde6d8e8fb8ebd79ac6e84212c1d294eba48fa2d4c467a29614c3ca5ef2f8 \
|
||||
--hash=sha256:4188a79f2774778dd5f2bcfb49b856d08dd824862f072924be40274b5a5cad95 \
|
||||
--hash=sha256:5506bd6b5268a97fcb79b5b021f6cbbaaf5cdff3ec87094d8870268d8cf096ed \
|
||||
--hash=sha256:82275ea56be975ee84fafdb340dcfee6b5289422c3f674c1982d3fcd47ba68c9 \
|
||||
--hash=sha256:93ba63aad6607f369c1b38bf91306731da6306fdde5eb67afa407b3f8a87dda7 \
|
||||
--hash=sha256:fc861e14f78e7370e982202b21db8bcb562dc14cd4098e557a17961d3411de45
|
||||
# via pynput
|
||||
pyobjc-framework-cocoa==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0e8ace0d44a00d281281a723d17fcd05eea7544a38a6a512e1fd018ddb7aece2 \
|
||||
--hash=sha256:600b1723184ca094931330e79355274949965460e23de38628d601b5a967baf9 \
|
||||
--hash=sha256:851dca4c16e70b405e5cd5a8c166cf7c445ae54a4cdd95ce9a523803172f32d1 \
|
||||
--hash=sha256:875f2aad73963faa81a6b36ae674fd494a4658d6d999e1075e0e2aca3d2391df \
|
||||
--hash=sha256:889d7bbd4ba2d4941078bfbbfb882138e51dbead27df006abfe0f2e0d49b5b2e \
|
||||
--hash=sha256:8fe5b2e79c9530f667b4e58a87a3a15ea62f86a5d19eec405517ecbd4f454868 \
|
||||
--hash=sha256:c96c0ef69a71afbbb0e6a7d594b455c5fe47d62e0db376ee7a2b4b828c16ace9 \
|
||||
--hash=sha256:de69c5933750f3a4599ed962eccd92b6a71914c7e4318dacc7895738a8ae60d7 \
|
||||
--hash=sha256:e106f395531e67694376b0f1184612cbeea3ec8b9bf56b55ef41d026171d2a2d
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-coretext==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:1324d91305022b1de03a12cf82de2b42c87dafe9b12cde6237253658a8637139 \
|
||||
--hash=sha256:1dc50de18346c4d6c89a51df066f03beea81e3557e3090ddc2a7a59395332fd8 \
|
||||
--hash=sha256:295d1037494630527acc24d116b0301ab5cf5e918952f49f7bf4f76ebae24d0c \
|
||||
--hash=sha256:64ddc02303217028e32e22c7cc00b5112d84e9d9a67c37d00c2e54f9172284ab \
|
||||
--hash=sha256:77a379ff47c599cb2bab918eb75680d30d950692ec19d67b734d11ded090b4e1 \
|
||||
--hash=sha256:a69611de569d92776e6391ca25492a5bbb4a05ba744006349e377a4fc5f7c8a5 \
|
||||
--hash=sha256:b585f0db77280930cb32e71cf8d27f5203d8c0f42a65fba690294530ab6e1aa6 \
|
||||
--hash=sha256:dbd0f288a859e359ee8e7ccf45bc2c489f38ae1087c21468b61d700433e0c91b \
|
||||
--hash=sha256:f1ad871d761bad9a0d461cceeeff7375a39f4d181c2a206dada6fc05307fec12
|
||||
# via pyobjc-framework-applicationservices
|
||||
pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0ec9751904ef975bf0789d760dc4fadcb400edc4ffe4a736eb54971968babe5c \
|
||||
--hash=sha256:1f7f3d9010e38f03ea1fa266664c10ea349cd7492bd603b403584f49d713dbed \
|
||||
--hash=sha256:4b01e325b0cdc121e78730dde9756e971b23069bf141cd62efbcaac76d7b6dbb \
|
||||
--hash=sha256:63f6f0f3233dcf650aac1374781e78961b0b17b33e3351953bacf8bd0c430593 \
|
||||
--hash=sha256:7f668979d0c7320bf8f7ed6e030da578f93ab0f5dd619b295ec735cd8d5faa34 \
|
||||
--hash=sha256:810f97b210cfd93704d240860286dfd6df09f9f1c52525fc5c2166723aea3f9e \
|
||||
--hash=sha256:8f58c589b5a76ba98f186b1f3b19fb1c8b730e82351f81fb62e6194f64a71622 \
|
||||
--hash=sha256:cee63b891c2b6b7ccf98f233175411529f3e80286f58438793b3634af79858f1 \
|
||||
--hash=sha256:ebf8167ca2096cf3a05199decfa517be0df4c56048f49cf132bd6b1a6ab9c086
|
||||
# via
|
||||
# pynput
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
# via pynput
|
||||
pywhispercpp==1.5.0 \
|
||||
--hash=sha256:03025227d0da211e382db6b6b16d910a267c663b6b2c57092b1200965ec45393 \
|
||||
--hash=sha256:0c393c01a0a77007a17d17cb706e08cba97f0e35ea0268733af1792949d03ceb \
|
||||
--hash=sha256:0f895cbbf5ba71a9e3f0e6afb4b6ae49bae5c716dc6a8a4d905eb789d9fe2238 \
|
||||
--hash=sha256:1bc31f684b6a38000e397824155bda3b45b61af6acc9f7e0f3bfa70e20b574e3 \
|
||||
--hash=sha256:22f9ddf12f6fb0fe3c43465d976b554e8928fcc113c902127e94c792d85f0631 \
|
||||
--hash=sha256:24602b8d0329a224fe6eb1c1e455853e983a5e04a63d4cb759ae2f275e254f5f \
|
||||
--hash=sha256:24da0c0bd33068f4c9c3f45eae3e6b7fb31d9b5d3487e4e1e1323b4253288d62 \
|
||||
--hash=sha256:2ea8fa7f5ce602d3e986fb11c4c2973b471f1b14e0fe75e01a66f1a60aecbfbf \
|
||||
--hash=sha256:358261055c56a96a04f6b0ff419633ffc61ef61027788b2bb2c6e7dca69abdb7 \
|
||||
--hash=sha256:3f825942067da3b0c48fc5b552b816fcee1761e955b9fdfdc911f0ab2d6fff11 \
|
||||
--hash=sha256:4363fa893e398d1f18a5775374109aa310022b9f4fc777a89329b12963f3149d \
|
||||
--hash=sha256:4bb409027566b473100e43f07fac48f9c8bdb6cba1ac0fbff5594a6f5a0e1b7e \
|
||||
--hash=sha256:568669bae45bd879bba1e35401cefc89d572428bd17326ce8437107ab80003d0 \
|
||||
--hash=sha256:57dd5111d4dd9fe3f0e784a03a3337df5abd514260a7d16656733d110316d2f0 \
|
||||
--hash=sha256:5aa54c73ec96617d97aa519dbbf817e44255eddd9bd52ee1243be61028dbd018 \
|
||||
--hash=sha256:64415b7687c0b39e66652b38683983ef7f23e174d7b3b05caa539955da8b088e \
|
||||
--hash=sha256:649af3ae0f9dc0d0dd757d8c2adfc6d929b1b203ac1ba85d5ac453015ddd6e63 \
|
||||
--hash=sha256:6ad4071772eb9dad59a741611e44e3819e6249c46e295ab8468609d03c6e4232 \
|
||||
--hash=sha256:70e925fad2c48554d3f5baf79e2746540268d2974b5cf40a4880887e4a065c2f \
|
||||
--hash=sha256:77d4d0ff382b5bc1369e9f77a851b45659edf5974e0903ffb15b981a043d216b \
|
||||
--hash=sha256:9806e084ebf956c7e492c76ea31c708e894849024772b3c3a57f85c342afc341 \
|
||||
--hash=sha256:9b43ddd44e65ca53d5ab1f62b623bc3edc64019bbe06b9641fff2dfef704c990 \
|
||||
--hash=sha256:a2fe9312fe3c08f832da392296118cc8cc1fc901753289132253f2066d911357 \
|
||||
--hash=sha256:a6777b5d40c0679952ded7934f7119d5fbfd606ec348293f869f430795609bae \
|
||||
--hash=sha256:a839b738936a8cd72cdd55c59a83a462820532bee78e233241bf9a3503e92144 \
|
||||
--hash=sha256:b1f94300f2fa1748f67f63a9240b526e8542b2dad1ceca5ea87ec2e9e15a939a \
|
||||
--hash=sha256:b592011cd992a5bcd36d0923477fb4cfdd338a0c7ce58997de195a14ab2b6d9a \
|
||||
--hash=sha256:c35c16f5da31d79be604dfd082b8bb67d5d46ba2f7f59bf5ab13857d5cd6ec6b \
|
||||
--hash=sha256:c9498eb9f4c38ea121da2435b5275c267486a5e14dddf5e72ec54a480b1fb44e \
|
||||
--hash=sha256:d2805f15361247ada04a34b51c556514527b984f9b089a4e32f1b2a4abbc5367 \
|
||||
--hash=sha256:d92eec44b49595ab1454cff1d10faa83b0b27779db8d8f00592ed363f0c5a262 \
|
||||
--hash=sha256:dc8dbcb6033db306e9ec450d835c005dd491c457937c79ef2673ea8797cbb93c \
|
||||
--hash=sha256:ea34ae824a6f934ba7736e6440f93cc467a7ec98b9c8fb2e5a37bb439ffa93b9 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
# via
|
||||
# pynput
|
||||
# python-xlib
|
||||
tqdm==4.70.0 \
|
||||
--hash=sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220 \
|
||||
--hash=sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953
|
||||
# via pywhispercpp
|
||||
urllib3==2.8.0 \
|
||||
--hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \
|
||||
--hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63
|
||||
# via requests
|
||||
@@ -0,0 +1,526 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --no-dev --extra vad --no-emit-project --no-emit-package pygobject -o requirements/vad.txt
|
||||
certifi==2026.10.19 \
|
||||
--hash=sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae \
|
||||
--hash=sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b
|
||||
# via requests
|
||||
charset-normalizer==3.5.1 \
|
||||
--hash=sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5 \
|
||||
--hash=sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b \
|
||||
--hash=sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f \
|
||||
--hash=sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5 \
|
||||
--hash=sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22 \
|
||||
--hash=sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5 \
|
||||
--hash=sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac \
|
||||
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
||||
--hash=sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626 \
|
||||
--hash=sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4 \
|
||||
--hash=sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369 \
|
||||
--hash=sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b \
|
||||
--hash=sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e \
|
||||
--hash=sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee \
|
||||
--hash=sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1 \
|
||||
--hash=sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102 \
|
||||
--hash=sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8 \
|
||||
--hash=sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9 \
|
||||
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
||||
--hash=sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031 \
|
||||
--hash=sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e \
|
||||
--hash=sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235 \
|
||||
--hash=sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072 \
|
||||
--hash=sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb \
|
||||
--hash=sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c \
|
||||
--hash=sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950 \
|
||||
--hash=sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2 \
|
||||
--hash=sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e \
|
||||
--hash=sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6 \
|
||||
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
||||
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
||||
--hash=sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2 \
|
||||
--hash=sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032 \
|
||||
--hash=sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71 \
|
||||
--hash=sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96 \
|
||||
--hash=sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687 \
|
||||
--hash=sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8 \
|
||||
--hash=sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3 \
|
||||
--hash=sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61 \
|
||||
--hash=sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9 \
|
||||
--hash=sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1 \
|
||||
--hash=sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4 \
|
||||
--hash=sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65 \
|
||||
--hash=sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663 \
|
||||
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
||||
--hash=sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591 \
|
||||
--hash=sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a \
|
||||
--hash=sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e \
|
||||
--hash=sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7 \
|
||||
--hash=sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3 \
|
||||
--hash=sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c \
|
||||
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
||||
--hash=sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7 \
|
||||
--hash=sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96 \
|
||||
--hash=sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486 \
|
||||
--hash=sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3 \
|
||||
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
||||
--hash=sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b \
|
||||
--hash=sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731 \
|
||||
--hash=sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959 \
|
||||
--hash=sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9 \
|
||||
--hash=sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf \
|
||||
--hash=sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8 \
|
||||
--hash=sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e \
|
||||
--hash=sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885 \
|
||||
--hash=sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0 \
|
||||
--hash=sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506 \
|
||||
--hash=sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2 \
|
||||
--hash=sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0 \
|
||||
--hash=sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e \
|
||||
--hash=sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e \
|
||||
--hash=sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491 \
|
||||
--hash=sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a \
|
||||
--hash=sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20 \
|
||||
--hash=sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449 \
|
||||
--hash=sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af \
|
||||
--hash=sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c \
|
||||
--hash=sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712 \
|
||||
--hash=sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7 \
|
||||
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
||||
--hash=sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9 \
|
||||
--hash=sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e \
|
||||
--hash=sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5 \
|
||||
--hash=sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36 \
|
||||
--hash=sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263 \
|
||||
--hash=sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4 \
|
||||
--hash=sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11 \
|
||||
--hash=sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a \
|
||||
--hash=sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3 \
|
||||
--hash=sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375 \
|
||||
--hash=sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d \
|
||||
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
||||
--hash=sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c \
|
||||
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
||||
--hash=sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6 \
|
||||
--hash=sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc \
|
||||
--hash=sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b \
|
||||
--hash=sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f \
|
||||
--hash=sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00 \
|
||||
--hash=sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10 \
|
||||
--hash=sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598 \
|
||||
--hash=sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6 \
|
||||
--hash=sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962 \
|
||||
--hash=sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c \
|
||||
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
||||
--hash=sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573 \
|
||||
--hash=sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90 \
|
||||
--hash=sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5 \
|
||||
--hash=sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18 \
|
||||
--hash=sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af \
|
||||
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
||||
--hash=sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b \
|
||||
--hash=sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6 \
|
||||
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
||||
--hash=sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774 \
|
||||
--hash=sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004 \
|
||||
--hash=sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a \
|
||||
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
||||
--hash=sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2 \
|
||||
--hash=sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe \
|
||||
--hash=sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3 \
|
||||
--hash=sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc \
|
||||
--hash=sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d \
|
||||
--hash=sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc \
|
||||
--hash=sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893 \
|
||||
--hash=sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef \
|
||||
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
||||
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30 \
|
||||
--hash=sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7 \
|
||||
--hash=sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5 \
|
||||
--hash=sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f \
|
||||
--hash=sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9 \
|
||||
--hash=sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada \
|
||||
--hash=sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876 \
|
||||
--hash=sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a \
|
||||
--hash=sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348 \
|
||||
--hash=sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3 \
|
||||
--hash=sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f \
|
||||
--hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \
|
||||
--hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f
|
||||
# via requests
|
||||
colorama==0.4.6 ; sys_platform == 'win32' \
|
||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via tqdm
|
||||
evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
flatbuffers==25.12.19 \
|
||||
--hash=sha256:7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4
|
||||
# via onnxruntime
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
# via requests
|
||||
numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \
|
||||
--hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \
|
||||
--hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \
|
||||
--hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \
|
||||
--hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \
|
||||
--hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \
|
||||
--hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \
|
||||
--hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \
|
||||
--hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \
|
||||
--hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \
|
||||
--hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \
|
||||
--hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \
|
||||
--hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \
|
||||
--hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \
|
||||
--hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \
|
||||
--hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \
|
||||
--hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \
|
||||
--hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \
|
||||
--hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \
|
||||
--hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \
|
||||
--hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \
|
||||
--hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \
|
||||
--hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \
|
||||
--hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \
|
||||
--hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \
|
||||
--hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \
|
||||
--hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \
|
||||
--hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \
|
||||
--hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \
|
||||
--hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \
|
||||
--hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \
|
||||
--hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \
|
||||
--hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \
|
||||
--hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \
|
||||
--hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \
|
||||
--hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \
|
||||
--hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \
|
||||
--hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \
|
||||
--hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \
|
||||
--hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \
|
||||
--hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \
|
||||
--hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \
|
||||
--hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \
|
||||
--hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \
|
||||
--hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \
|
||||
--hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \
|
||||
--hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \
|
||||
--hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \
|
||||
--hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \
|
||||
--hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \
|
||||
--hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \
|
||||
--hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \
|
||||
--hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \
|
||||
--hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \
|
||||
--hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \
|
||||
--hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \
|
||||
--hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \
|
||||
--hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \
|
||||
--hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \
|
||||
--hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \
|
||||
--hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \
|
||||
--hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \
|
||||
--hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \
|
||||
--hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \
|
||||
--hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \
|
||||
--hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \
|
||||
--hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \
|
||||
--hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \
|
||||
--hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \
|
||||
--hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \
|
||||
--hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# onnxruntime
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
--hash=sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7 \
|
||||
--hash=sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0 \
|
||||
--hash=sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3 \
|
||||
--hash=sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c \
|
||||
--hash=sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce \
|
||||
--hash=sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8 \
|
||||
--hash=sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1 \
|
||||
--hash=sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4 \
|
||||
--hash=sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee \
|
||||
--hash=sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740 \
|
||||
--hash=sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98 \
|
||||
--hash=sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710 \
|
||||
--hash=sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee \
|
||||
--hash=sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68 \
|
||||
--hash=sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf \
|
||||
--hash=sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8 \
|
||||
--hash=sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf \
|
||||
--hash=sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b \
|
||||
--hash=sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884 \
|
||||
--hash=sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03 \
|
||||
--hash=sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69 \
|
||||
--hash=sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4 \
|
||||
--hash=sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842 \
|
||||
--hash=sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65 \
|
||||
--hash=sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080 \
|
||||
--hash=sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e \
|
||||
--hash=sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e \
|
||||
--hash=sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414 \
|
||||
--hash=sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59 \
|
||||
--hash=sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8 \
|
||||
--hash=sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617 \
|
||||
--hash=sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4 \
|
||||
--hash=sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb \
|
||||
--hash=sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251 \
|
||||
--hash=sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d \
|
||||
--hash=sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2 \
|
||||
--hash=sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab \
|
||||
--hash=sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657 \
|
||||
--hash=sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15 \
|
||||
--hash=sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9 \
|
||||
--hash=sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8 \
|
||||
--hash=sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323 \
|
||||
--hash=sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788 \
|
||||
--hash=sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc \
|
||||
--hash=sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56 \
|
||||
--hash=sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1 \
|
||||
--hash=sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d \
|
||||
--hash=sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec \
|
||||
--hash=sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2 \
|
||||
--hash=sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e \
|
||||
--hash=sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7 \
|
||||
--hash=sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26 \
|
||||
--hash=sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514 \
|
||||
--hash=sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860 \
|
||||
--hash=sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a \
|
||||
--hash=sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1 \
|
||||
--hash=sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab \
|
||||
--hash=sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba \
|
||||
--hash=sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12 \
|
||||
--hash=sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6 \
|
||||
--hash=sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e \
|
||||
--hash=sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac \
|
||||
--hash=sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# onnxruntime
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
onnxruntime==1.29.0 \
|
||||
--hash=sha256:07c5907474dec4a2792fd7626b753dc66707808385a6d9eecf993db0066a9d0f \
|
||||
--hash=sha256:0d4f427afac434b0070fe992b540ddf20a7aff2265f760f314d91331935b6b98 \
|
||||
--hash=sha256:11264bb58f7b7cf6af835ab10d36838d73680580820fd6f51d90124a1ca8f449 \
|
||||
--hash=sha256:16925ef8497e2c07e4b5ae15b504079b3ab3f65e22c58efd10dde0f3caea969a \
|
||||
--hash=sha256:1ea91cef3b971506e51ae9c37c16d027774ec64994a524ec1bdfb027d68a9832 \
|
||||
--hash=sha256:2945e1f82f81f27e88decea88c7861f45baea23818950d467bf3909aa303119e \
|
||||
--hash=sha256:2b80d8c7ec2cc7438e4da3760b88c24568cba72c9ace96d668800a6c79419acb \
|
||||
--hash=sha256:3a3814c041251d6a77fdf513fb282056538ee826d2f1178a0df3c549d3fff6ba \
|
||||
--hash=sha256:4a3129ae56e70d2618ff773920166916310370a7e3cacb60b9e0e8910092725f \
|
||||
--hash=sha256:4acf2b4948b7ede87221ca6332344b8facdc8059d6ac751a7d367d04532b02dd \
|
||||
--hash=sha256:4b940b0d777590c7e20bf298f5c16af1ea6ad1b400a1c822a6be192f64f4d954 \
|
||||
--hash=sha256:4eae472cf7dc3107dec1bb53cd6d142d1964616d08aae48654cd4254b2363c4b \
|
||||
--hash=sha256:533f8370ce124304e5cb08ab961836cf755631e3dd77adc5f3bbdab70c2b7d99 \
|
||||
--hash=sha256:6c0c37b92f67ed68dd36221ce0403e1d9bd4f7efce724439978a2597848530e5 \
|
||||
--hash=sha256:85f8e8406c52658735fe5c7fbfd3ebaa1ed340768324f6252e4274e374580a23 \
|
||||
--hash=sha256:939e5d65f332e6d399774b2bd0d3559fd8fa629c1e77833db29d968d2384f23d \
|
||||
--hash=sha256:be0f8ed688cfb1d4d5765a137193b7bfab0c8ea214eed99260b380bb525a3a7f \
|
||||
--hash=sha256:c1ad3f437153fe77f9d01a08fbaac0beb030e09b8a80ace1603bcf69b6c95481 \
|
||||
--hash=sha256:d2fb19e848f7c33ed8d3182b52504aaa11c5e8da438bbb47296f85b133cbcf6b \
|
||||
--hash=sha256:d67673c5367727860922c5262d724472f1b5539fb7ccf4c81a638f9b71719803 \
|
||||
--hash=sha256:dc61a79cb39afd66ab3f01fd2c23591a7f01de89c1668e1fb6315067fc279164 \
|
||||
--hash=sha256:e2128f31f449e922c62dbe5d8b6b7b079f0bcaf2d56a102fa203cb6e5bb5ab19 \
|
||||
--hash=sha256:e417ef8628dcce310d2d53023e750ea298ec14d4341ae6dc3a572bfd9bc7fa97 \
|
||||
--hash=sha256:e74b278af1d949876f5d91d1268fd6c680e79f2bac194967394eaba9fdf69e7e
|
||||
# via vocalinux
|
||||
packaging==26.3 \
|
||||
--hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
|
||||
--hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
|
||||
# via onnxruntime
|
||||
platformdirs==4.11.3 \
|
||||
--hash=sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7 \
|
||||
--hash=sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab
|
||||
# via pywhispercpp
|
||||
protobuf==7.35.1 \
|
||||
--hash=sha256:11d6b0ec246892d85215b0a13ca6e0233cf5284b68f0ac02646427f4ff88a799 \
|
||||
--hash=sha256:230a75ddfc2de4806e56696ce9640c1cdfdb6543b7cfce98d42a4c0a0e7bdb87 \
|
||||
--hash=sha256:24f857477359a85c0c235261b8ba905fd51b2562f4a64ca1df5473f29850cbf6 \
|
||||
--hash=sha256:353652e4efd0bca5b5fc2656abf8307ef351f0cf938c9eba09f0e09c20a25c30 \
|
||||
--hash=sha256:4bc97768d8fe4ad6743c8a19403e314511ed9f6d13205b687e52421c023ac1b9 \
|
||||
--hash=sha256:74758715c53d7158fb76caf4f0cfdacc5329a4b1bb994f865d6cf302d413a1c4 \
|
||||
--hash=sha256:b73f9489a4b8b1c9cb1f8ed951c736392592edb24b9d6819f36d2e10b171d5b4 \
|
||||
--hash=sha256:ce115a26fe0c39a2c29973d914d327e516a6455464489fe3cd1e51a1b354f81a
|
||||
# via onnxruntime
|
||||
psutil==7.2.2 \
|
||||
--hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \
|
||||
--hash=sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 \
|
||||
--hash=sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841 \
|
||||
--hash=sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63 \
|
||||
--hash=sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979 \
|
||||
--hash=sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a \
|
||||
--hash=sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b \
|
||||
--hash=sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9 \
|
||||
--hash=sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee \
|
||||
--hash=sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312 \
|
||||
--hash=sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b \
|
||||
--hash=sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9 \
|
||||
--hash=sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e \
|
||||
--hash=sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc \
|
||||
--hash=sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1 \
|
||||
--hash=sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf \
|
||||
--hash=sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea \
|
||||
--hash=sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
--hash=sha256:5fce4bcdd2e0e8c063d835dbe2860dac46437506af509353c7f8114d4bacbd5b \
|
||||
--hash=sha256:692d8c1446f52ed2662120bcd9ddcb5aa2b71f38bda31e58b19fb4672fffba69 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
--hash=sha256:2c7ef3d2f865b4b3ebb14ec3556f7a3e8abb6d130c67275cd9daa08dbd6e4e4e \
|
||||
--hash=sha256:3772b406edb3ff78171530a17cda1c4a7817f87b87ded0d8715b3fa664df16db \
|
||||
--hash=sha256:3906452339cd06a3bb07df103c2511d4cb0f7a22d8771c0b802eba15d9a642b6 \
|
||||
--hash=sha256:59a77038ebe0ab1240f61c341e7fb67b8674f2b4cd41bc71a6472511a12b50f7 \
|
||||
--hash=sha256:89acc6bc13aaa6e3f52b0ce652ede7e201edb6bf062741b246b0c5a44582f25f \
|
||||
--hash=sha256:950bd2d9c74634398c4e3d24ef2f213d4e23d705083697464fa67afedc53c1ad \
|
||||
--hash=sha256:b9cdd686e32db8e451feb19f8a85bc4cd52c2893103881d04aca51e1f35371d1
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-cocoa
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-applicationservices==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0bcc09531d5854598fd74706d999e4ae3b7c503204d318910d02eba30e8eecef \
|
||||
--hash=sha256:1af01a271b85eae2a327e93cf3ec46de0199a1a933594f78d4c2b9b9c2240e5e \
|
||||
--hash=sha256:3b5693a377480cf127caa1c8c835b8620896971029c545d99d01aa31a2c38159 \
|
||||
--hash=sha256:3f9dde6d8e8fb8ebd79ac6e84212c1d294eba48fa2d4c467a29614c3ca5ef2f8 \
|
||||
--hash=sha256:4188a79f2774778dd5f2bcfb49b856d08dd824862f072924be40274b5a5cad95 \
|
||||
--hash=sha256:5506bd6b5268a97fcb79b5b021f6cbbaaf5cdff3ec87094d8870268d8cf096ed \
|
||||
--hash=sha256:82275ea56be975ee84fafdb340dcfee6b5289422c3f674c1982d3fcd47ba68c9 \
|
||||
--hash=sha256:93ba63aad6607f369c1b38bf91306731da6306fdde5eb67afa407b3f8a87dda7 \
|
||||
--hash=sha256:fc861e14f78e7370e982202b21db8bcb562dc14cd4098e557a17961d3411de45
|
||||
# via pynput
|
||||
pyobjc-framework-cocoa==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0e8ace0d44a00d281281a723d17fcd05eea7544a38a6a512e1fd018ddb7aece2 \
|
||||
--hash=sha256:600b1723184ca094931330e79355274949965460e23de38628d601b5a967baf9 \
|
||||
--hash=sha256:851dca4c16e70b405e5cd5a8c166cf7c445ae54a4cdd95ce9a523803172f32d1 \
|
||||
--hash=sha256:875f2aad73963faa81a6b36ae674fd494a4658d6d999e1075e0e2aca3d2391df \
|
||||
--hash=sha256:889d7bbd4ba2d4941078bfbbfb882138e51dbead27df006abfe0f2e0d49b5b2e \
|
||||
--hash=sha256:8fe5b2e79c9530f667b4e58a87a3a15ea62f86a5d19eec405517ecbd4f454868 \
|
||||
--hash=sha256:c96c0ef69a71afbbb0e6a7d594b455c5fe47d62e0db376ee7a2b4b828c16ace9 \
|
||||
--hash=sha256:de69c5933750f3a4599ed962eccd92b6a71914c7e4318dacc7895738a8ae60d7 \
|
||||
--hash=sha256:e106f395531e67694376b0f1184612cbeea3ec8b9bf56b55ef41d026171d2a2d
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-coretext==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:1324d91305022b1de03a12cf82de2b42c87dafe9b12cde6237253658a8637139 \
|
||||
--hash=sha256:1dc50de18346c4d6c89a51df066f03beea81e3557e3090ddc2a7a59395332fd8 \
|
||||
--hash=sha256:295d1037494630527acc24d116b0301ab5cf5e918952f49f7bf4f76ebae24d0c \
|
||||
--hash=sha256:64ddc02303217028e32e22c7cc00b5112d84e9d9a67c37d00c2e54f9172284ab \
|
||||
--hash=sha256:77a379ff47c599cb2bab918eb75680d30d950692ec19d67b734d11ded090b4e1 \
|
||||
--hash=sha256:a69611de569d92776e6391ca25492a5bbb4a05ba744006349e377a4fc5f7c8a5 \
|
||||
--hash=sha256:b585f0db77280930cb32e71cf8d27f5203d8c0f42a65fba690294530ab6e1aa6 \
|
||||
--hash=sha256:dbd0f288a859e359ee8e7ccf45bc2c489f38ae1087c21468b61d700433e0c91b \
|
||||
--hash=sha256:f1ad871d761bad9a0d461cceeeff7375a39f4d181c2a206dada6fc05307fec12
|
||||
# via pyobjc-framework-applicationservices
|
||||
pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0ec9751904ef975bf0789d760dc4fadcb400edc4ffe4a736eb54971968babe5c \
|
||||
--hash=sha256:1f7f3d9010e38f03ea1fa266664c10ea349cd7492bd603b403584f49d713dbed \
|
||||
--hash=sha256:4b01e325b0cdc121e78730dde9756e971b23069bf141cd62efbcaac76d7b6dbb \
|
||||
--hash=sha256:63f6f0f3233dcf650aac1374781e78961b0b17b33e3351953bacf8bd0c430593 \
|
||||
--hash=sha256:7f668979d0c7320bf8f7ed6e030da578f93ab0f5dd619b295ec735cd8d5faa34 \
|
||||
--hash=sha256:810f97b210cfd93704d240860286dfd6df09f9f1c52525fc5c2166723aea3f9e \
|
||||
--hash=sha256:8f58c589b5a76ba98f186b1f3b19fb1c8b730e82351f81fb62e6194f64a71622 \
|
||||
--hash=sha256:cee63b891c2b6b7ccf98f233175411529f3e80286f58438793b3634af79858f1 \
|
||||
--hash=sha256:ebf8167ca2096cf3a05199decfa517be0df4c56048f49cf132bd6b1a6ab9c086
|
||||
# via
|
||||
# pynput
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
# via pynput
|
||||
pywhispercpp==1.5.0 \
|
||||
--hash=sha256:03025227d0da211e382db6b6b16d910a267c663b6b2c57092b1200965ec45393 \
|
||||
--hash=sha256:0c393c01a0a77007a17d17cb706e08cba97f0e35ea0268733af1792949d03ceb \
|
||||
--hash=sha256:0f895cbbf5ba71a9e3f0e6afb4b6ae49bae5c716dc6a8a4d905eb789d9fe2238 \
|
||||
--hash=sha256:1bc31f684b6a38000e397824155bda3b45b61af6acc9f7e0f3bfa70e20b574e3 \
|
||||
--hash=sha256:22f9ddf12f6fb0fe3c43465d976b554e8928fcc113c902127e94c792d85f0631 \
|
||||
--hash=sha256:24602b8d0329a224fe6eb1c1e455853e983a5e04a63d4cb759ae2f275e254f5f \
|
||||
--hash=sha256:24da0c0bd33068f4c9c3f45eae3e6b7fb31d9b5d3487e4e1e1323b4253288d62 \
|
||||
--hash=sha256:2ea8fa7f5ce602d3e986fb11c4c2973b471f1b14e0fe75e01a66f1a60aecbfbf \
|
||||
--hash=sha256:358261055c56a96a04f6b0ff419633ffc61ef61027788b2bb2c6e7dca69abdb7 \
|
||||
--hash=sha256:3f825942067da3b0c48fc5b552b816fcee1761e955b9fdfdc911f0ab2d6fff11 \
|
||||
--hash=sha256:4363fa893e398d1f18a5775374109aa310022b9f4fc777a89329b12963f3149d \
|
||||
--hash=sha256:4bb409027566b473100e43f07fac48f9c8bdb6cba1ac0fbff5594a6f5a0e1b7e \
|
||||
--hash=sha256:568669bae45bd879bba1e35401cefc89d572428bd17326ce8437107ab80003d0 \
|
||||
--hash=sha256:57dd5111d4dd9fe3f0e784a03a3337df5abd514260a7d16656733d110316d2f0 \
|
||||
--hash=sha256:5aa54c73ec96617d97aa519dbbf817e44255eddd9bd52ee1243be61028dbd018 \
|
||||
--hash=sha256:64415b7687c0b39e66652b38683983ef7f23e174d7b3b05caa539955da8b088e \
|
||||
--hash=sha256:649af3ae0f9dc0d0dd757d8c2adfc6d929b1b203ac1ba85d5ac453015ddd6e63 \
|
||||
--hash=sha256:6ad4071772eb9dad59a741611e44e3819e6249c46e295ab8468609d03c6e4232 \
|
||||
--hash=sha256:70e925fad2c48554d3f5baf79e2746540268d2974b5cf40a4880887e4a065c2f \
|
||||
--hash=sha256:77d4d0ff382b5bc1369e9f77a851b45659edf5974e0903ffb15b981a043d216b \
|
||||
--hash=sha256:9806e084ebf956c7e492c76ea31c708e894849024772b3c3a57f85c342afc341 \
|
||||
--hash=sha256:9b43ddd44e65ca53d5ab1f62b623bc3edc64019bbe06b9641fff2dfef704c990 \
|
||||
--hash=sha256:a2fe9312fe3c08f832da392296118cc8cc1fc901753289132253f2066d911357 \
|
||||
--hash=sha256:a6777b5d40c0679952ded7934f7119d5fbfd606ec348293f869f430795609bae \
|
||||
--hash=sha256:a839b738936a8cd72cdd55c59a83a462820532bee78e233241bf9a3503e92144 \
|
||||
--hash=sha256:b1f94300f2fa1748f67f63a9240b526e8542b2dad1ceca5ea87ec2e9e15a939a \
|
||||
--hash=sha256:b592011cd992a5bcd36d0923477fb4cfdd338a0c7ce58997de195a14ab2b6d9a \
|
||||
--hash=sha256:c35c16f5da31d79be604dfd082b8bb67d5d46ba2f7f59bf5ab13857d5cd6ec6b \
|
||||
--hash=sha256:c9498eb9f4c38ea121da2435b5275c267486a5e14dddf5e72ec54a480b1fb44e \
|
||||
--hash=sha256:d2805f15361247ada04a34b51c556514527b984f9b089a4e32f1b2a4abbc5367 \
|
||||
--hash=sha256:d92eec44b49595ab1454cff1d10faa83b0b27779db8d8f00592ed363f0c5a262 \
|
||||
--hash=sha256:dc8dbcb6033db306e9ec450d835c005dd491c457937c79ef2673ea8797cbb93c \
|
||||
--hash=sha256:ea34ae824a6f934ba7736e6440f93cc467a7ec98b9c8fb2e5a37bb439ffa93b9 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
# via
|
||||
# pynput
|
||||
# python-xlib
|
||||
tqdm==4.70.0 \
|
||||
--hash=sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220 \
|
||||
--hash=sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953
|
||||
# via pywhispercpp
|
||||
urllib3==2.8.0 \
|
||||
--hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \
|
||||
--hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63
|
||||
# via requests
|
||||
@@ -0,0 +1,697 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv export --no-dev --extra vosk --no-emit-project --no-emit-package pygobject -o requirements/vosk.txt
|
||||
certifi==2026.10.19 \
|
||||
--hash=sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae \
|
||||
--hash=sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b
|
||||
# via requests
|
||||
cffi==2.1.1 \
|
||||
--hash=sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e \
|
||||
--hash=sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66 \
|
||||
--hash=sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2 \
|
||||
--hash=sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0 \
|
||||
--hash=sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971 \
|
||||
--hash=sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c \
|
||||
--hash=sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d \
|
||||
--hash=sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517 \
|
||||
--hash=sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735 \
|
||||
--hash=sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80 \
|
||||
--hash=sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f \
|
||||
--hash=sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1 \
|
||||
--hash=sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29 \
|
||||
--hash=sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8 \
|
||||
--hash=sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c \
|
||||
--hash=sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e \
|
||||
--hash=sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48 \
|
||||
--hash=sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813 \
|
||||
--hash=sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac \
|
||||
--hash=sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632 \
|
||||
--hash=sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6 \
|
||||
--hash=sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1 \
|
||||
--hash=sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688 \
|
||||
--hash=sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0 \
|
||||
--hash=sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062 \
|
||||
--hash=sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779 \
|
||||
--hash=sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94 \
|
||||
--hash=sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50 \
|
||||
--hash=sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab \
|
||||
--hash=sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac \
|
||||
--hash=sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6 \
|
||||
--hash=sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676 \
|
||||
--hash=sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1 \
|
||||
--hash=sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13 \
|
||||
--hash=sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e \
|
||||
--hash=sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e \
|
||||
--hash=sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973 \
|
||||
--hash=sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527 \
|
||||
--hash=sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72 \
|
||||
--hash=sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890 \
|
||||
--hash=sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c \
|
||||
--hash=sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990 \
|
||||
--hash=sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd \
|
||||
--hash=sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94 \
|
||||
--hash=sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3 \
|
||||
--hash=sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80 \
|
||||
--hash=sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5 \
|
||||
--hash=sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c \
|
||||
--hash=sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a \
|
||||
--hash=sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4 \
|
||||
--hash=sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e \
|
||||
--hash=sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6 \
|
||||
--hash=sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b \
|
||||
--hash=sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03 \
|
||||
--hash=sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af \
|
||||
--hash=sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231 \
|
||||
--hash=sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2 \
|
||||
--hash=sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3 \
|
||||
--hash=sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836 \
|
||||
--hash=sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5 \
|
||||
--hash=sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399 \
|
||||
--hash=sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96 \
|
||||
--hash=sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e \
|
||||
--hash=sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf \
|
||||
--hash=sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc \
|
||||
--hash=sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455 \
|
||||
--hash=sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0 \
|
||||
--hash=sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12 \
|
||||
--hash=sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7 \
|
||||
--hash=sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692 \
|
||||
--hash=sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54 \
|
||||
--hash=sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3 \
|
||||
--hash=sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b \
|
||||
--hash=sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be \
|
||||
--hash=sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d \
|
||||
--hash=sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358 \
|
||||
--hash=sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a \
|
||||
--hash=sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7 \
|
||||
--hash=sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc \
|
||||
--hash=sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960 \
|
||||
--hash=sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125 \
|
||||
--hash=sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb \
|
||||
--hash=sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a \
|
||||
--hash=sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa \
|
||||
--hash=sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf \
|
||||
--hash=sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3 \
|
||||
--hash=sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4 \
|
||||
--hash=sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264
|
||||
# via vosk
|
||||
charset-normalizer==3.5.1 \
|
||||
--hash=sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5 \
|
||||
--hash=sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b \
|
||||
--hash=sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f \
|
||||
--hash=sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5 \
|
||||
--hash=sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22 \
|
||||
--hash=sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5 \
|
||||
--hash=sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac \
|
||||
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
||||
--hash=sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626 \
|
||||
--hash=sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4 \
|
||||
--hash=sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369 \
|
||||
--hash=sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b \
|
||||
--hash=sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e \
|
||||
--hash=sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee \
|
||||
--hash=sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1 \
|
||||
--hash=sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102 \
|
||||
--hash=sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8 \
|
||||
--hash=sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9 \
|
||||
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
||||
--hash=sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031 \
|
||||
--hash=sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e \
|
||||
--hash=sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235 \
|
||||
--hash=sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072 \
|
||||
--hash=sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb \
|
||||
--hash=sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c \
|
||||
--hash=sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950 \
|
||||
--hash=sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2 \
|
||||
--hash=sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e \
|
||||
--hash=sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6 \
|
||||
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
||||
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
||||
--hash=sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2 \
|
||||
--hash=sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032 \
|
||||
--hash=sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71 \
|
||||
--hash=sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96 \
|
||||
--hash=sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687 \
|
||||
--hash=sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8 \
|
||||
--hash=sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3 \
|
||||
--hash=sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61 \
|
||||
--hash=sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9 \
|
||||
--hash=sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1 \
|
||||
--hash=sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4 \
|
||||
--hash=sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65 \
|
||||
--hash=sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663 \
|
||||
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
||||
--hash=sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591 \
|
||||
--hash=sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a \
|
||||
--hash=sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e \
|
||||
--hash=sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7 \
|
||||
--hash=sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3 \
|
||||
--hash=sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c \
|
||||
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
||||
--hash=sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7 \
|
||||
--hash=sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96 \
|
||||
--hash=sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486 \
|
||||
--hash=sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3 \
|
||||
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
||||
--hash=sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b \
|
||||
--hash=sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731 \
|
||||
--hash=sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959 \
|
||||
--hash=sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9 \
|
||||
--hash=sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf \
|
||||
--hash=sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8 \
|
||||
--hash=sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e \
|
||||
--hash=sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885 \
|
||||
--hash=sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0 \
|
||||
--hash=sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506 \
|
||||
--hash=sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2 \
|
||||
--hash=sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0 \
|
||||
--hash=sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e \
|
||||
--hash=sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e \
|
||||
--hash=sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491 \
|
||||
--hash=sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a \
|
||||
--hash=sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20 \
|
||||
--hash=sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449 \
|
||||
--hash=sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af \
|
||||
--hash=sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c \
|
||||
--hash=sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712 \
|
||||
--hash=sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7 \
|
||||
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
||||
--hash=sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9 \
|
||||
--hash=sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e \
|
||||
--hash=sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5 \
|
||||
--hash=sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36 \
|
||||
--hash=sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263 \
|
||||
--hash=sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4 \
|
||||
--hash=sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11 \
|
||||
--hash=sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a \
|
||||
--hash=sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3 \
|
||||
--hash=sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375 \
|
||||
--hash=sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d \
|
||||
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
||||
--hash=sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c \
|
||||
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
||||
--hash=sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6 \
|
||||
--hash=sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc \
|
||||
--hash=sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b \
|
||||
--hash=sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f \
|
||||
--hash=sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00 \
|
||||
--hash=sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10 \
|
||||
--hash=sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598 \
|
||||
--hash=sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6 \
|
||||
--hash=sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962 \
|
||||
--hash=sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c \
|
||||
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
||||
--hash=sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573 \
|
||||
--hash=sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90 \
|
||||
--hash=sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5 \
|
||||
--hash=sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18 \
|
||||
--hash=sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af \
|
||||
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
||||
--hash=sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b \
|
||||
--hash=sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6 \
|
||||
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
||||
--hash=sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774 \
|
||||
--hash=sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004 \
|
||||
--hash=sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a \
|
||||
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
||||
--hash=sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2 \
|
||||
--hash=sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe \
|
||||
--hash=sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3 \
|
||||
--hash=sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc \
|
||||
--hash=sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d \
|
||||
--hash=sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc \
|
||||
--hash=sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893 \
|
||||
--hash=sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef \
|
||||
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
||||
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30 \
|
||||
--hash=sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7 \
|
||||
--hash=sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5 \
|
||||
--hash=sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f \
|
||||
--hash=sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9 \
|
||||
--hash=sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada \
|
||||
--hash=sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876 \
|
||||
--hash=sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a \
|
||||
--hash=sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348 \
|
||||
--hash=sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3 \
|
||||
--hash=sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f \
|
||||
--hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \
|
||||
--hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f
|
||||
# via requests
|
||||
colorama==0.4.6 ; sys_platform == 'win32' \
|
||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via tqdm
|
||||
evdev==1.9.3 ; sys_platform == 'linux' or 'linux' in sys_platform \
|
||||
--hash=sha256:2c140e01ac8437758fa23fe5c871397412461f42d421aa20241dc8fe8cfccbc9
|
||||
# via
|
||||
# pynput
|
||||
# vocalinux
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
# via requests
|
||||
numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \
|
||||
--hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \
|
||||
--hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \
|
||||
--hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \
|
||||
--hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \
|
||||
--hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \
|
||||
--hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \
|
||||
--hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \
|
||||
--hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \
|
||||
--hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \
|
||||
--hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \
|
||||
--hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \
|
||||
--hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \
|
||||
--hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \
|
||||
--hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \
|
||||
--hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \
|
||||
--hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \
|
||||
--hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \
|
||||
--hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \
|
||||
--hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \
|
||||
--hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \
|
||||
--hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \
|
||||
--hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \
|
||||
--hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \
|
||||
--hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \
|
||||
--hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \
|
||||
--hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \
|
||||
--hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \
|
||||
--hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \
|
||||
--hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \
|
||||
--hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \
|
||||
--hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \
|
||||
--hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \
|
||||
--hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \
|
||||
--hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \
|
||||
--hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \
|
||||
--hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \
|
||||
--hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \
|
||||
--hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \
|
||||
--hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \
|
||||
--hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \
|
||||
--hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \
|
||||
--hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \
|
||||
--hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \
|
||||
--hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \
|
||||
--hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \
|
||||
--hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \
|
||||
--hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \
|
||||
--hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \
|
||||
--hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \
|
||||
--hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \
|
||||
--hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \
|
||||
--hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \
|
||||
--hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \
|
||||
--hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \
|
||||
--hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \
|
||||
--hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \
|
||||
--hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \
|
||||
--hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \
|
||||
--hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \
|
||||
--hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \
|
||||
--hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \
|
||||
--hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \
|
||||
--hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \
|
||||
--hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \
|
||||
--hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \
|
||||
--hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \
|
||||
--hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \
|
||||
--hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \
|
||||
--hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \
|
||||
--hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
--hash=sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7 \
|
||||
--hash=sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0 \
|
||||
--hash=sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3 \
|
||||
--hash=sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c \
|
||||
--hash=sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce \
|
||||
--hash=sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8 \
|
||||
--hash=sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1 \
|
||||
--hash=sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4 \
|
||||
--hash=sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee \
|
||||
--hash=sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740 \
|
||||
--hash=sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98 \
|
||||
--hash=sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710 \
|
||||
--hash=sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee \
|
||||
--hash=sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68 \
|
||||
--hash=sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf \
|
||||
--hash=sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8 \
|
||||
--hash=sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf \
|
||||
--hash=sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b \
|
||||
--hash=sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884 \
|
||||
--hash=sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03 \
|
||||
--hash=sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69 \
|
||||
--hash=sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4 \
|
||||
--hash=sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842 \
|
||||
--hash=sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65 \
|
||||
--hash=sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080 \
|
||||
--hash=sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e \
|
||||
--hash=sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e \
|
||||
--hash=sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414 \
|
||||
--hash=sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59 \
|
||||
--hash=sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8 \
|
||||
--hash=sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617 \
|
||||
--hash=sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4 \
|
||||
--hash=sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb \
|
||||
--hash=sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251 \
|
||||
--hash=sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d \
|
||||
--hash=sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2 \
|
||||
--hash=sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab \
|
||||
--hash=sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657 \
|
||||
--hash=sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15 \
|
||||
--hash=sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9 \
|
||||
--hash=sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8 \
|
||||
--hash=sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323 \
|
||||
--hash=sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788 \
|
||||
--hash=sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc \
|
||||
--hash=sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56 \
|
||||
--hash=sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1 \
|
||||
--hash=sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d \
|
||||
--hash=sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec \
|
||||
--hash=sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2 \
|
||||
--hash=sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e \
|
||||
--hash=sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7 \
|
||||
--hash=sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26 \
|
||||
--hash=sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514 \
|
||||
--hash=sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860 \
|
||||
--hash=sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a \
|
||||
--hash=sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1 \
|
||||
--hash=sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab \
|
||||
--hash=sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba \
|
||||
--hash=sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12 \
|
||||
--hash=sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6 \
|
||||
--hash=sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e \
|
||||
--hash=sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac \
|
||||
--hash=sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
platformdirs==4.11.3 \
|
||||
--hash=sha256:5ed065d443751de711da036041a7a214122efc4a4de393b3f4137ba5576540e7 \
|
||||
--hash=sha256:66a73d38a849810252df809a3d8bcbda8e26f6c189920e7535ad608a48dbb5ab
|
||||
# via pywhispercpp
|
||||
psutil==7.2.2 \
|
||||
--hash=sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372 \
|
||||
--hash=sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9 \
|
||||
--hash=sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841 \
|
||||
--hash=sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63 \
|
||||
--hash=sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979 \
|
||||
--hash=sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a \
|
||||
--hash=sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b \
|
||||
--hash=sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9 \
|
||||
--hash=sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee \
|
||||
--hash=sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312 \
|
||||
--hash=sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b \
|
||||
--hash=sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9 \
|
||||
--hash=sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e \
|
||||
--hash=sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc \
|
||||
--hash=sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1 \
|
||||
--hash=sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf \
|
||||
--hash=sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea \
|
||||
--hash=sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988 \
|
||||
--hash=sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486 \
|
||||
--hash=sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00 \
|
||||
--hash=sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8
|
||||
# via vocalinux
|
||||
pyaudio==0.2.14 \
|
||||
--hash=sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3 \
|
||||
--hash=sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289 \
|
||||
--hash=sha256:5fce4bcdd2e0e8c063d835dbe2860dac46437506af509353c7f8114d4bacbd5b \
|
||||
--hash=sha256:692d8c1446f52ed2662120bcd9ddcb5aa2b71f38bda31e58b19fb4672fffba69 \
|
||||
--hash=sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87 \
|
||||
--hash=sha256:95328285b4dab57ea8c52a4a996cb52be6d629353315be5bfda403d15932a497 \
|
||||
--hash=sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903
|
||||
# via vocalinux
|
||||
pycairo==1.29.1 ; sys_platform == 'linux' \
|
||||
--hash=sha256:4fbd26b4af24c9787d84cf5448e34eb8dca064b732479aaecd03109520eebd5f
|
||||
# via pygobject
|
||||
pycparser==3.0 ; implementation_name != 'PyPy' \
|
||||
--hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \
|
||||
--hash=sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992
|
||||
# via cffi
|
||||
pynput==1.8.2 \
|
||||
--hash=sha256:8cc38cf13a6ab2749cb375678be8a0fd705d7ce49c8001ff5db4007a723bbef1 \
|
||||
--hash=sha256:f493c87157cd3861b4468f7f896857051762f44ed26f1b641e7cc5840a457087
|
||||
# via vocalinux
|
||||
pyobjc-core==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:122e6ad302a2abf5d4d4adb0156db751600ddf2768441696cba17b31323085e7 \
|
||||
--hash=sha256:2062e8ad30a310441cd022544a897553408bebeaa7820d5edba3c96fd7fd693b \
|
||||
--hash=sha256:2c7ef3d2f865b4b3ebb14ec3556f7a3e8abb6d130c67275cd9daa08dbd6e4e4e \
|
||||
--hash=sha256:3772b406edb3ff78171530a17cda1c4a7817f87b87ded0d8715b3fa664df16db \
|
||||
--hash=sha256:3906452339cd06a3bb07df103c2511d4cb0f7a22d8771c0b802eba15d9a642b6 \
|
||||
--hash=sha256:59a77038ebe0ab1240f61c341e7fb67b8674f2b4cd41bc71a6472511a12b50f7 \
|
||||
--hash=sha256:89acc6bc13aaa6e3f52b0ce652ede7e201edb6bf062741b246b0c5a44582f25f \
|
||||
--hash=sha256:950bd2d9c74634398c4e3d24ef2f213d4e23d705083697464fa67afedc53c1ad \
|
||||
--hash=sha256:b9cdd686e32db8e451feb19f8a85bc4cd52c2893103881d04aca51e1f35371d1
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-cocoa
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-applicationservices==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0bcc09531d5854598fd74706d999e4ae3b7c503204d318910d02eba30e8eecef \
|
||||
--hash=sha256:1af01a271b85eae2a327e93cf3ec46de0199a1a933594f78d4c2b9b9c2240e5e \
|
||||
--hash=sha256:3b5693a377480cf127caa1c8c835b8620896971029c545d99d01aa31a2c38159 \
|
||||
--hash=sha256:3f9dde6d8e8fb8ebd79ac6e84212c1d294eba48fa2d4c467a29614c3ca5ef2f8 \
|
||||
--hash=sha256:4188a79f2774778dd5f2bcfb49b856d08dd824862f072924be40274b5a5cad95 \
|
||||
--hash=sha256:5506bd6b5268a97fcb79b5b021f6cbbaaf5cdff3ec87094d8870268d8cf096ed \
|
||||
--hash=sha256:82275ea56be975ee84fafdb340dcfee6b5289422c3f674c1982d3fcd47ba68c9 \
|
||||
--hash=sha256:93ba63aad6607f369c1b38bf91306731da6306fdde5eb67afa407b3f8a87dda7 \
|
||||
--hash=sha256:fc861e14f78e7370e982202b21db8bcb562dc14cd4098e557a17961d3411de45
|
||||
# via pynput
|
||||
pyobjc-framework-cocoa==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0e8ace0d44a00d281281a723d17fcd05eea7544a38a6a512e1fd018ddb7aece2 \
|
||||
--hash=sha256:600b1723184ca094931330e79355274949965460e23de38628d601b5a967baf9 \
|
||||
--hash=sha256:851dca4c16e70b405e5cd5a8c166cf7c445ae54a4cdd95ce9a523803172f32d1 \
|
||||
--hash=sha256:875f2aad73963faa81a6b36ae674fd494a4658d6d999e1075e0e2aca3d2391df \
|
||||
--hash=sha256:889d7bbd4ba2d4941078bfbbfb882138e51dbead27df006abfe0f2e0d49b5b2e \
|
||||
--hash=sha256:8fe5b2e79c9530f667b4e58a87a3a15ea62f86a5d19eec405517ecbd4f454868 \
|
||||
--hash=sha256:c96c0ef69a71afbbb0e6a7d594b455c5fe47d62e0db376ee7a2b4b828c16ace9 \
|
||||
--hash=sha256:de69c5933750f3a4599ed962eccd92b6a71914c7e4318dacc7895738a8ae60d7 \
|
||||
--hash=sha256:e106f395531e67694376b0f1184612cbeea3ec8b9bf56b55ef41d026171d2a2d
|
||||
# via
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
# pyobjc-framework-quartz
|
||||
pyobjc-framework-coretext==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:1324d91305022b1de03a12cf82de2b42c87dafe9b12cde6237253658a8637139 \
|
||||
--hash=sha256:1dc50de18346c4d6c89a51df066f03beea81e3557e3090ddc2a7a59395332fd8 \
|
||||
--hash=sha256:295d1037494630527acc24d116b0301ab5cf5e918952f49f7bf4f76ebae24d0c \
|
||||
--hash=sha256:64ddc02303217028e32e22c7cc00b5112d84e9d9a67c37d00c2e54f9172284ab \
|
||||
--hash=sha256:77a379ff47c599cb2bab918eb75680d30d950692ec19d67b734d11ded090b4e1 \
|
||||
--hash=sha256:a69611de569d92776e6391ca25492a5bbb4a05ba744006349e377a4fc5f7c8a5 \
|
||||
--hash=sha256:b585f0db77280930cb32e71cf8d27f5203d8c0f42a65fba690294530ab6e1aa6 \
|
||||
--hash=sha256:dbd0f288a859e359ee8e7ccf45bc2c489f38ae1087c21468b61d700433e0c91b \
|
||||
--hash=sha256:f1ad871d761bad9a0d461cceeeff7375a39f4d181c2a206dada6fc05307fec12
|
||||
# via pyobjc-framework-applicationservices
|
||||
pyobjc-framework-quartz==12.2.2 ; sys_platform == 'darwin' \
|
||||
--hash=sha256:0ec9751904ef975bf0789d760dc4fadcb400edc4ffe4a736eb54971968babe5c \
|
||||
--hash=sha256:1f7f3d9010e38f03ea1fa266664c10ea349cd7492bd603b403584f49d713dbed \
|
||||
--hash=sha256:4b01e325b0cdc121e78730dde9756e971b23069bf141cd62efbcaac76d7b6dbb \
|
||||
--hash=sha256:63f6f0f3233dcf650aac1374781e78961b0b17b33e3351953bacf8bd0c430593 \
|
||||
--hash=sha256:7f668979d0c7320bf8f7ed6e030da578f93ab0f5dd619b295ec735cd8d5faa34 \
|
||||
--hash=sha256:810f97b210cfd93704d240860286dfd6df09f9f1c52525fc5c2166723aea3f9e \
|
||||
--hash=sha256:8f58c589b5a76ba98f186b1f3b19fb1c8b730e82351f81fb62e6194f64a71622 \
|
||||
--hash=sha256:cee63b891c2b6b7ccf98f233175411529f3e80286f58438793b3634af79858f1 \
|
||||
--hash=sha256:ebf8167ca2096cf3a05199decfa517be0df4c56048f49cf132bd6b1a6ab9c086
|
||||
# via
|
||||
# pynput
|
||||
# pyobjc-framework-applicationservices
|
||||
# pyobjc-framework-coretext
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via vocalinux
|
||||
python-xlib==0.33 ; 'linux' in sys_platform \
|
||||
--hash=sha256:55af7906a2c75ce6cb280a584776080602444f75815a7aff4d287bb2d7018b32 \
|
||||
--hash=sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398
|
||||
# via pynput
|
||||
pywhispercpp==1.5.0 \
|
||||
--hash=sha256:03025227d0da211e382db6b6b16d910a267c663b6b2c57092b1200965ec45393 \
|
||||
--hash=sha256:0c393c01a0a77007a17d17cb706e08cba97f0e35ea0268733af1792949d03ceb \
|
||||
--hash=sha256:0f895cbbf5ba71a9e3f0e6afb4b6ae49bae5c716dc6a8a4d905eb789d9fe2238 \
|
||||
--hash=sha256:1bc31f684b6a38000e397824155bda3b45b61af6acc9f7e0f3bfa70e20b574e3 \
|
||||
--hash=sha256:22f9ddf12f6fb0fe3c43465d976b554e8928fcc113c902127e94c792d85f0631 \
|
||||
--hash=sha256:24602b8d0329a224fe6eb1c1e455853e983a5e04a63d4cb759ae2f275e254f5f \
|
||||
--hash=sha256:24da0c0bd33068f4c9c3f45eae3e6b7fb31d9b5d3487e4e1e1323b4253288d62 \
|
||||
--hash=sha256:2ea8fa7f5ce602d3e986fb11c4c2973b471f1b14e0fe75e01a66f1a60aecbfbf \
|
||||
--hash=sha256:358261055c56a96a04f6b0ff419633ffc61ef61027788b2bb2c6e7dca69abdb7 \
|
||||
--hash=sha256:3f825942067da3b0c48fc5b552b816fcee1761e955b9fdfdc911f0ab2d6fff11 \
|
||||
--hash=sha256:4363fa893e398d1f18a5775374109aa310022b9f4fc777a89329b12963f3149d \
|
||||
--hash=sha256:4bb409027566b473100e43f07fac48f9c8bdb6cba1ac0fbff5594a6f5a0e1b7e \
|
||||
--hash=sha256:568669bae45bd879bba1e35401cefc89d572428bd17326ce8437107ab80003d0 \
|
||||
--hash=sha256:57dd5111d4dd9fe3f0e784a03a3337df5abd514260a7d16656733d110316d2f0 \
|
||||
--hash=sha256:5aa54c73ec96617d97aa519dbbf817e44255eddd9bd52ee1243be61028dbd018 \
|
||||
--hash=sha256:64415b7687c0b39e66652b38683983ef7f23e174d7b3b05caa539955da8b088e \
|
||||
--hash=sha256:649af3ae0f9dc0d0dd757d8c2adfc6d929b1b203ac1ba85d5ac453015ddd6e63 \
|
||||
--hash=sha256:6ad4071772eb9dad59a741611e44e3819e6249c46e295ab8468609d03c6e4232 \
|
||||
--hash=sha256:70e925fad2c48554d3f5baf79e2746540268d2974b5cf40a4880887e4a065c2f \
|
||||
--hash=sha256:77d4d0ff382b5bc1369e9f77a851b45659edf5974e0903ffb15b981a043d216b \
|
||||
--hash=sha256:9806e084ebf956c7e492c76ea31c708e894849024772b3c3a57f85c342afc341 \
|
||||
--hash=sha256:9b43ddd44e65ca53d5ab1f62b623bc3edc64019bbe06b9641fff2dfef704c990 \
|
||||
--hash=sha256:a2fe9312fe3c08f832da392296118cc8cc1fc901753289132253f2066d911357 \
|
||||
--hash=sha256:a6777b5d40c0679952ded7934f7119d5fbfd606ec348293f869f430795609bae \
|
||||
--hash=sha256:a839b738936a8cd72cdd55c59a83a462820532bee78e233241bf9a3503e92144 \
|
||||
--hash=sha256:b1f94300f2fa1748f67f63a9240b526e8542b2dad1ceca5ea87ec2e9e15a939a \
|
||||
--hash=sha256:b592011cd992a5bcd36d0923477fb4cfdd338a0c7ce58997de195a14ab2b6d9a \
|
||||
--hash=sha256:c35c16f5da31d79be604dfd082b8bb67d5d46ba2f7f59bf5ab13857d5cd6ec6b \
|
||||
--hash=sha256:c9498eb9f4c38ea121da2435b5275c267486a5e14dddf5e72ec54a480b1fb44e \
|
||||
--hash=sha256:d2805f15361247ada04a34b51c556514527b984f9b089a4e32f1b2a4abbc5367 \
|
||||
--hash=sha256:d92eec44b49595ab1454cff1d10faa83b0b27779db8d8f00592ed363f0c5a262 \
|
||||
--hash=sha256:dc8dbcb6033db306e9ec450d835c005dd491c457937c79ef2673ea8797cbb93c \
|
||||
--hash=sha256:ea34ae824a6f934ba7736e6440f93cc467a7ec98b9c8fb2e5a37bb439ffa93b9 \
|
||||
--hash=sha256:f5d13b4a7e34b9f4eebf70bff150ec36f4145c580bd5d812b9a3139611e7433c \
|
||||
--hash=sha256:f9b1cd9dd4c3eb7fb2b777529eb62618e58a6bb05be20f82b7b1afe3d0b12274 \
|
||||
--hash=sha256:fbdbb1bb236f4481ff6ea475aed9ed091393ddb02271df309645d71de207778d
|
||||
# via vocalinux
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vocalinux
|
||||
# vosk
|
||||
six==1.17.0 \
|
||||
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
|
||||
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
|
||||
# via
|
||||
# pynput
|
||||
# python-xlib
|
||||
srt==3.5.3 \
|
||||
--hash=sha256:4884315043a4f0740fd1f878ed6caa376ac06d70e135f306a6dc44632eed0cc0
|
||||
# via vosk
|
||||
tqdm==4.70.0 \
|
||||
--hash=sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220 \
|
||||
--hash=sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953
|
||||
# via
|
||||
# pywhispercpp
|
||||
# vosk
|
||||
urllib3==2.8.0 \
|
||||
--hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \
|
||||
--hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63
|
||||
# via requests
|
||||
vosk==0.3.45 \
|
||||
--hash=sha256:25e025093c4399d7278f543568ed8cc5460ac3a4bf48c23673ace1e25d26619f \
|
||||
--hash=sha256:4221f83287eefe5abbe54fc6f1da5774e9e3ffcbbdca1705a466b341093b072e \
|
||||
--hash=sha256:54efb47dd890e544e9e20f0316413acec7f8680d04ec095c6140ab4e70262704 \
|
||||
--hash=sha256:6994ddc68556c7e5730c3b6f6bad13320e3519b13ce3ed2aa25a86724e7c10ac
|
||||
# via vocalinux
|
||||
websockets==17.0.1 \
|
||||
--hash=sha256:02ed63bf26dda9fa27df730a41f6664586c4ee05972c8fb667ce1725b3fd13d3 \
|
||||
--hash=sha256:02f0b037a737d0cb0c33866c97bcd1a0b73170dfbf42d69d8fb86f51002fd5ae \
|
||||
--hash=sha256:038cfad5d5417f8bb09295abe986029a26d22f34bda622ccc79b670efd4dab56 \
|
||||
--hash=sha256:07abc3bd196a48af476a82fd47f3f79a6a3f70937a9f930cef703cfa0c9d83b6 \
|
||||
--hash=sha256:07d78a509c3333f5908c83d7f78144ea68a6c9ec28110f5c54d81d8fcdc262c4 \
|
||||
--hash=sha256:0b52c76b8a870b141b7ca0705289452183ce7a523101954ccfe29a25986a673f \
|
||||
--hash=sha256:10b1587c599fa0f2c89154587c80e0fda98ade6c9fa8c0260a2823fb1800b685 \
|
||||
--hash=sha256:10f461191125c63902ea7394ae9e752b1b5785641850c1d365bb30b0f88bc53f \
|
||||
--hash=sha256:15920057a6b723f84734f0641403bca163a4b176e5af809ee4f0c4a1e75e9fed \
|
||||
--hash=sha256:17ac37716c0244e82c9e384c41653c090b1864c6610224ca3857e7f7b58fce10 \
|
||||
--hash=sha256:18ded646ce98cdd3c0235825b3252f1df55765ba49b616bb10282f758667b4d0 \
|
||||
--hash=sha256:1b363bfd72a52c0658a3154a4cff219f15a474b35a235057d38853bf151acce7 \
|
||||
--hash=sha256:1bdd8c4be420905dd732e00dcd669852d8128cc723efa585a0c0e51adb00a28a \
|
||||
--hash=sha256:1d4cf7e8e5b8b1fa40758ac7524843a00237b124ab217e227542cafcfeb7a946 \
|
||||
--hash=sha256:1df81d174c1561292de9e40b141cafc04f69077272f6c352afe1d743e20810df \
|
||||
--hash=sha256:20a92f78ac8250984ed459faa9ca48c285adbfc0038ddc3fdac6046990a9c9ed \
|
||||
--hash=sha256:22bd00f8bae2bccdb5dbe41e20f58ba44ca9fff0b4b561aaf39099c35da762ed \
|
||||
--hash=sha256:2437d4ca208cc0f246d3a2297ae7474b4ba18261aaf5b9c79c84c031ecf348e1 \
|
||||
--hash=sha256:246927ae9ae06ca0d42a483a4bdb80d4862e1ee5b4cab37c354a5e1ad8356448 \
|
||||
--hash=sha256:2503c7e2a5049a12d5dac917a46d5d52591283a766165b8176bb167560421b38 \
|
||||
--hash=sha256:2604de7228506b13a44a256a9d223943340c0e725af5d367dc068e192b027761 \
|
||||
--hash=sha256:28012a54510fe8301bb893ef143cec30a2780a2d3bc20b7bbdf4379d7a63945d \
|
||||
--hash=sha256:2a855b6dfe21c4d3420be265ae031829ba8ba0be0ea350d9f7c3ef30ae63ebe2 \
|
||||
--hash=sha256:2abb1ba0a5133b7d2ef3c1c9f4b0c1e8a101012dce0b594ab2b2888d9a64820e \
|
||||
--hash=sha256:2b3f3020171202b135ca078e20434977c6b2b02af647130d6980c9e39b9462e3 \
|
||||
--hash=sha256:2bc14b481e05e331811108daa1aeb41a5e237a5564ef2f02ec5a356a0f102f78 \
|
||||
--hash=sha256:2fa2cb465a131c347ba6717a78c887746e73edb1c131d01c982d6ef0d68b82e0 \
|
||||
--hash=sha256:409d93efcaa14f7a99592c5baaef5ec6ca94fba0f5aec1a86f693977c69c9c1c \
|
||||
--hash=sha256:41d6aa06b5ab832aee72fedf47a149535b121ac900b6bb4d3fe14712afac9a79 \
|
||||
--hash=sha256:49266e4488309b38783257293a38298942b9a03aa106fcb45195377a77c0c1e2 \
|
||||
--hash=sha256:4d1d99db29b5444e3982f1ce2ba8a833508ad44b2f1fbd0bd99e81d825c0b461 \
|
||||
--hash=sha256:4d41c0a1d47a478bc432b3b9068097bee1ce0c5b19327ea6f75c2ab34ab1f2fb \
|
||||
--hash=sha256:5033ffe6804dd53afafa7d08e8c3eef2d2431f34d58ca30507a8442dd04a033a \
|
||||
--hash=sha256:53b90c00bc6201ab6695c7ff51a04d0e425514c37515e9eeecd2c1b978ac6c0e \
|
||||
--hash=sha256:54cdcaa56f5d3eafd57058f0fa4a3de93a310b43a3c4699f06efc4c0bd054a5a \
|
||||
--hash=sha256:5508f38c98ac29def9e747b87543b008a58b075df6da70b2cf2e0b47073d33bb \
|
||||
--hash=sha256:55383d8177b3c99fd873ee5db0e0193f4c1dd4a3feaccf1a4a03c1b7cf539cac \
|
||||
--hash=sha256:55b12e47dcee83673a40d07686cfb6f9d6dfc285976ade9463f61d2bef3fad22 \
|
||||
--hash=sha256:5661f868ef191d33dfc6a0cc7c5b3d495f0cc8bb3f8b30d87bda8755c61c95f5 \
|
||||
--hash=sha256:57d2ee9b24b404ce75f3814f92073c0ed88106c950148d2427fe8d25ca254d1f \
|
||||
--hash=sha256:599b03beb77633bffc095334338fad79cafc2b01fbd58953838130a9ae967d7b \
|
||||
--hash=sha256:5baa9bc0dfbae8c507e51c8cf1b6d4628086f7a87bbd3a9952bd5f035451f1cc \
|
||||
--hash=sha256:5f33a649bfcb8312524173cc4bbafa7dbb236e18eee9aa31a1d324ca0ddda28c \
|
||||
--hash=sha256:6740be6d1bab69f08ab52cb15b08f76c143b6fe61c580ba62bd929f3ab7a1d42 \
|
||||
--hash=sha256:6a434e59962a4fb9016bea327e1d14d6cd67670ecfb8942b4f4a0c24036634ce \
|
||||
--hash=sha256:6db9e5bf3649ab506c6ae8a3ac85a00fb1ae3816d75962771b2df8adbc5d40d2 \
|
||||
--hash=sha256:6fd88365da261c53d3e943fb37e0d0721b9cde119f6b2e3fc84369b6ab234d63 \
|
||||
--hash=sha256:7002d5f9e1c3ddd991cdfdbfee18cc8c8b196b2445022892badacd6cb338bbbc \
|
||||
--hash=sha256:70d438268e49f1a4bd096b6b6f7010f3ab48b5db2574dbf7d8c864c46ce7a06a \
|
||||
--hash=sha256:72d7f2a5aeb4e82daa4ee18f125b4277f427033359be5c745ad709608446cc2c \
|
||||
--hash=sha256:733e3cc7171fa1b899edbe725ef9382d0e960657dc1fd933f3281ae910c01dab \
|
||||
--hash=sha256:734d20364dc2cfe03674883cafcf580b6e431c5ce42b476312b9285310230cf9 \
|
||||
--hash=sha256:759adeb5b0c5775b563254ec63b5b79089fc0045b479143a0b1b8c0ebaae1253 \
|
||||
--hash=sha256:769ce7e2acfd9a89f2bed3a9c0da229459516bbc00bd4c9e2ca492c613ae4861 \
|
||||
--hash=sha256:810cb3fb5fa6e447216f4e82d9a85cb8aed0929ae3538153ddfe8a6e3121a58d \
|
||||
--hash=sha256:81ce19c6046ace11da7001781be7317bb1dc389f399af4b2ed962190f76f9add \
|
||||
--hash=sha256:846a4a8b0833e3cad57523d9e3bd50ec8ea05ab9d06c582f82a1340ba096af5f \
|
||||
--hash=sha256:872273e629ca7e3d35f16a2dc6ede84e1d5c831e616b8277de6e4f83114e7c58 \
|
||||
--hash=sha256:8848c207049ad49d318e5f64a3d4d7bb189f8328d0d98e65647788f2a085785c \
|
||||
--hash=sha256:884af729b8ab50486acd94d9768c2b60914bf39b579ebba0a5cb73bfdfd61fd2 \
|
||||
--hash=sha256:8c07f145d0b9e90cbd96035f31fb79199aef4da1872854e36ebeb258e3d57594 \
|
||||
--hash=sha256:8cd3369e42c0246afaf9d669cfc19797e3a49e8c0a639544459c57597108b966 \
|
||||
--hash=sha256:8e387adb0c692c6b5571bdeafc8ac9d1901ea30f10309134780b16ecd35e6605 \
|
||||
--hash=sha256:90246fa9e6cb192a778ce6ce024057ec54317a894db7899c922dcdc1f4cbf6a5 \
|
||||
--hash=sha256:90973a3a00f23afdfd1c9b06fb84289bf0220f247ef8a62501a1967c7af54f7b \
|
||||
--hash=sha256:9493314a99e599163c854fb5900ad7f7ea38c5cb9d9103aa30b3c6b8181c01fa \
|
||||
--hash=sha256:9f7747d3daa41a11f25f7cca5dc988fc51da97b311bed4c9d843860f79779283 \
|
||||
--hash=sha256:a39ce3a7b0e6059be093213d637963101380157bcbad355916738fafb490698d \
|
||||
--hash=sha256:a60fa1a25cca1bcc2bf87b8d6be37a741f0a3239fb5e9cfb7a37173b68ffcf87 \
|
||||
--hash=sha256:a68e604c6d1b0338e46652e2688cbce8096ad9c03548b075fda9e2ea19a9b7dd \
|
||||
--hash=sha256:a8af570fc29cd998a921c7131c8ac81d9434466d6d25300cb12a690fb56a8a08 \
|
||||
--hash=sha256:aadc298969ad229d8e3029fc5cc751fdad286696230f9cf014e90ff9cd8e6ea0 \
|
||||
--hash=sha256:ab56439c9f74c52770690c7b2f616b3bf775cb3920453ee355ac765c032d8bbf \
|
||||
--hash=sha256:ab9f962a5b64a5c3c845d556b7dc4e6fb683f7b67179f8205e814bb2e0213ffe \
|
||||
--hash=sha256:afbce6e3f0fac32dc87c2a0d84869d1a706460d64f39f3889386413e6e4d3d26 \
|
||||
--hash=sha256:b3ff0ad440ad52dda64138f16895f66403f40192365e39b1010e889f289746b0 \
|
||||
--hash=sha256:b580794e926cab7ff42ee4371ef14e0b22cb2bb722a607f77769136468f49a3f \
|
||||
--hash=sha256:b85b960a4507b0714c0a1246d031be9118d908ee974dc085257297a955205f1d \
|
||||
--hash=sha256:b98860aefbd3d9bc8e3c7f0eefb83b11142b16110739c68cd33d3b4d6e84e536 \
|
||||
--hash=sha256:bb31f42ea095ea826463c770829aa188a86c9a5c976b1467cbbf583c811de833 \
|
||||
--hash=sha256:bc0bca48ba24c6c866847fd20478a51dd547fa0ad258dab9615c414ec534bbc0 \
|
||||
--hash=sha256:bd1470d2c53fe53269bf5619da7725d30dd9b9693f1689f7a85eab8dea734442 \
|
||||
--hash=sha256:c09e097d0e46e3c289bedab9a475ae344b70c30ff5646e46af22b4e6fdc97b21 \
|
||||
--hash=sha256:c1bec5d6a19f5fbe87e4940739cfc65e7bb53d8b353e1029b8037a1653b321bc \
|
||||
--hash=sha256:c1c118a6b0e25bfc9a6802075d748fa6321714ffbdf3c88d29d9a0e3c7386c75 \
|
||||
--hash=sha256:c23e532c8a2325a1e7486de8763a60dc43e83f01bcaeca07e3ba79652c156db1 \
|
||||
--hash=sha256:c356dbddab0a529ed7574f78f559d75a223735c321c28f6f587fbf02b11ed301 \
|
||||
--hash=sha256:c38515cb54902f7e97d0239e81ef46c4444f9475f4807fb9bbdb789b4089abcf \
|
||||
--hash=sha256:c395bda8e7d8f51a02e80261fb57127979e5c472675d9a96b2860619ad47da48 \
|
||||
--hash=sha256:c6be9cba65c65cc76dfa3d4619e359ff02a4476c74e179b215236c11a0b32345 \
|
||||
--hash=sha256:cd526c8228e759c1006c4b7c9ac71dc4e925ced1a6a6a5a8e94643709738f63e \
|
||||
--hash=sha256:cddc675ec31bca65473321f9a9794e488b43b3b8de5d02c8ef4810c5d5792163 \
|
||||
--hash=sha256:cffc84ddec6da7f447677266fee2a3c40ecc78172f00752aa1150b8a8d65df1d \
|
||||
--hash=sha256:d41e9845514754a42d1d83b2fca9d27fee2ca7b3b0bee6843ba5a9bb2b6e25ac \
|
||||
--hash=sha256:d69fd559f9f0e8a52d2fce6f04ee143f86e70df0a189cd95164eddac599e810f \
|
||||
--hash=sha256:d7d72843691f50b91127c50688df10cb72ec6f4c4b1d7e2c11ab33b16acf8e51 \
|
||||
--hash=sha256:d9aac6081513f02eac3f8caace800dbfc5c608b69e4a7bef69e414eabfc95aa1 \
|
||||
--hash=sha256:dbfae8e75b342e31fc6fd1a8bbb393b7cbb91d6cfd581650300a94381e7b7e2b \
|
||||
--hash=sha256:e8208f2729cba030ff872a92064c97584eeb9502f53d32a05a0f05d5a17ca6c6 \
|
||||
--hash=sha256:e95e321d0d763f2b6633512605f6112ebd70d5746f3ce05c941909d4a25233f2 \
|
||||
--hash=sha256:e98ec9ec61cce5bc4b8b218322ad090b0994eb060bb04da704c62ef0a3d864e6 \
|
||||
--hash=sha256:eab6de8a98b9a7772cf686d00b4de439fc7efb8ab05ae106ef227291d06f87c5 \
|
||||
--hash=sha256:efe0ae052a8d023b87198921e8a7ce1dc7768816bcd2fbc20df171ac73a04891 \
|
||||
--hash=sha256:f11a398d8170b7ac5000baf7f258dcda579ef3ea744e0cc6a165e0dfbc0d3198 \
|
||||
--hash=sha256:f3fd9a1f87f8f0f3f8e9f9bd0195f7516562d13f5b178db8c5784d1f60b60bed \
|
||||
--hash=sha256:f47b0815af3948ec6a440b3afa02f05b18cc0939549e91b5c677b5d9c2c8472a \
|
||||
--hash=sha256:f991247276797d0c61ab7770bc9791eadc16f683b4d83517f624932adc1a8bab \
|
||||
--hash=sha256:ffad64ce7ad3703d652a3fd9af26238377d24ce52c6ad8ff35d26d82f61f493f
|
||||
# via vosk
|
||||
@@ -0,0 +1,17 @@
|
||||
# OpenAI Whisper engine, CPU-only wheels from the PyTorch index.
|
||||
#
|
||||
# torch is pinned to a +cpu local-version build so the CUDA-bundled PyPI wheel
|
||||
# can never match, regardless of index order. OpenAI Whisper does not use
|
||||
# torchaudio, and the CPU index has not published a matching 2.13 release.
|
||||
# Bump this pin when regenerating
|
||||
# (`just lock`).
|
||||
# Resolve across supported Python versions and constrain shared packages to
|
||||
# runtime.txt / installer-build.txt; otherwise this export can downgrade the
|
||||
# runtime (or select a numpy requiring a newer Python than the installer).
|
||||
#
|
||||
# The extra-index line below propagates into whisper.txt so plain
|
||||
# `pip install -r requirements/whisper.txt` resolves against the CPU index.
|
||||
--extra-index-url https://download.pytorch.org/whl/cpu
|
||||
|
||||
openai-whisper>=20231117
|
||||
torch==2.13.0+cpu
|
||||
@@ -0,0 +1,785 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile requirements/whisper.in --generate-hashes --emit-index-url --index-url https://pypi.org/simple --extra-index-url https://download.pytorch.org/whl/cpu --index-strategy unsafe-best-match --universal --python-version 3.11 -c requirements/runtime.txt -c requirements/installer-build.txt -o requirements/whisper.txt
|
||||
--index-url https://pypi.org/simple
|
||||
--extra-index-url https://download.pytorch.org/whl/cpu
|
||||
|
||||
certifi==2026.10.19 \
|
||||
--hash=sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae \
|
||||
--hash=sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# requests
|
||||
charset-normalizer==3.5.1 \
|
||||
--hash=sha256:00668ebb0609751758682eb0b5857e7c35b9f00e84dfdef062e103244ec94d45 \
|
||||
--hash=sha256:012a22b88a77ca2e59b98ac5889b0deb604147666032f45e6d6e217634d2550d \
|
||||
--hash=sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5 \
|
||||
--hash=sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b \
|
||||
--hash=sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f \
|
||||
--hash=sha256:07ffd07412fc5d5e84cd8952acf9ff7e4ed7a708e69d1bada19d8ba91711353f \
|
||||
--hash=sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5 \
|
||||
--hash=sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22 \
|
||||
--hash=sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5 \
|
||||
--hash=sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac \
|
||||
--hash=sha256:13e3afe97712e8887cd516e960c63f0b93122971e5b5e4b2622fe7701771e838 \
|
||||
--hash=sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90 \
|
||||
--hash=sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626 \
|
||||
--hash=sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4 \
|
||||
--hash=sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369 \
|
||||
--hash=sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b \
|
||||
--hash=sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e \
|
||||
--hash=sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee \
|
||||
--hash=sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1 \
|
||||
--hash=sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102 \
|
||||
--hash=sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8 \
|
||||
--hash=sha256:29880d17a8eb0b5cfdfd8944b468322928059aa35f1f5fa8ff22b149ec0b42f8 \
|
||||
--hash=sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9 \
|
||||
--hash=sha256:2e9cf9253119d8e5d111f05d71626786fd3d6193817316eab1ca088cdb8593cf \
|
||||
--hash=sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0 \
|
||||
--hash=sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031 \
|
||||
--hash=sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e \
|
||||
--hash=sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235 \
|
||||
--hash=sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072 \
|
||||
--hash=sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb \
|
||||
--hash=sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c \
|
||||
--hash=sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950 \
|
||||
--hash=sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2 \
|
||||
--hash=sha256:366ec70f5547c640d3ce1985722490f23faf4eb5216a7eeba78277490e78dacb \
|
||||
--hash=sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e \
|
||||
--hash=sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6 \
|
||||
--hash=sha256:3e5e1224c0a6a90e05843e07adfec669edebec17801c67072f51e59561d63c0b \
|
||||
--hash=sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2 \
|
||||
--hash=sha256:433c5a81eade63b47e522303bad236f59dba55ea6951746f5558355eeed8c75d \
|
||||
--hash=sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa \
|
||||
--hash=sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2 \
|
||||
--hash=sha256:494b70049a4d69aec6e8137c13af4cf8db8c9f9820a1392ac293b0dd2987a818 \
|
||||
--hash=sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032 \
|
||||
--hash=sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71 \
|
||||
--hash=sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96 \
|
||||
--hash=sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687 \
|
||||
--hash=sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8 \
|
||||
--hash=sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3 \
|
||||
--hash=sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61 \
|
||||
--hash=sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9 \
|
||||
--hash=sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1 \
|
||||
--hash=sha256:55261ac0d2941c42f196dd576f543d87a8ee03cd6f5e30dfb4d807b2e3b9121a \
|
||||
--hash=sha256:56490c595a28b1bb27dfc583e816152a9767721ef58b2c03b13f954d2f707420 \
|
||||
--hash=sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4 \
|
||||
--hash=sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65 \
|
||||
--hash=sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663 \
|
||||
--hash=sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f \
|
||||
--hash=sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591 \
|
||||
--hash=sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a \
|
||||
--hash=sha256:5ca0555312ae2fe82715cada7fac375530c2f3349e1eaa1bcb33d0283ac79a18 \
|
||||
--hash=sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e \
|
||||
--hash=sha256:5e2d0e146dcb57034f8b97dc58d2d512cb90aba253960ce449f695fec6a82c6f \
|
||||
--hash=sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7 \
|
||||
--hash=sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3 \
|
||||
--hash=sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c \
|
||||
--hash=sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3 \
|
||||
--hash=sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7 \
|
||||
--hash=sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96 \
|
||||
--hash=sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486 \
|
||||
--hash=sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3 \
|
||||
--hash=sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6 \
|
||||
--hash=sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b \
|
||||
--hash=sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731 \
|
||||
--hash=sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959 \
|
||||
--hash=sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9 \
|
||||
--hash=sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf \
|
||||
--hash=sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8 \
|
||||
--hash=sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e \
|
||||
--hash=sha256:789b8982559ae28dad2356519f841655756cdcd96616410590ae0b17454ee64f \
|
||||
--hash=sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885 \
|
||||
--hash=sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0 \
|
||||
--hash=sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506 \
|
||||
--hash=sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2 \
|
||||
--hash=sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0 \
|
||||
--hash=sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e \
|
||||
--hash=sha256:85de3134b5379856e323ba37c19c9256d39425f7b76a63af52b09fb4664c2e8f \
|
||||
--hash=sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e \
|
||||
--hash=sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491 \
|
||||
--hash=sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a \
|
||||
--hash=sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20 \
|
||||
--hash=sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449 \
|
||||
--hash=sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af \
|
||||
--hash=sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c \
|
||||
--hash=sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712 \
|
||||
--hash=sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7 \
|
||||
--hash=sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a \
|
||||
--hash=sha256:94fbf1c0c6cc0d3d5e50f9a9313a8cdca90dd696d34b381cd1704f8c9e939f20 \
|
||||
--hash=sha256:950f23cb393f85543777b0433f082cddd25b51ab398eac7971146495679efe5f \
|
||||
--hash=sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3 \
|
||||
--hash=sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9 \
|
||||
--hash=sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e \
|
||||
--hash=sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5 \
|
||||
--hash=sha256:994e883d17c559cdfd38c84003c8b27d25424a1077272a17e7cd27bfe0bf57b2 \
|
||||
--hash=sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36 \
|
||||
--hash=sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263 \
|
||||
--hash=sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4 \
|
||||
--hash=sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11 \
|
||||
--hash=sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a \
|
||||
--hash=sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3 \
|
||||
--hash=sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375 \
|
||||
--hash=sha256:a545775cfe815855ea32d7c27731d79da358ef2055b4a25830231b1622dd18aa \
|
||||
--hash=sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d \
|
||||
--hash=sha256:a6d095662e73e74f0a49988e0593373e243e3a52e27bfeea0a859e88acf4a0f5 \
|
||||
--hash=sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99 \
|
||||
--hash=sha256:a951ad59cad9145664a730d3036b40b844e74d2d3683da40111463cd3a83845d \
|
||||
--hash=sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c \
|
||||
--hash=sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488 \
|
||||
--hash=sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6 \
|
||||
--hash=sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc \
|
||||
--hash=sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b \
|
||||
--hash=sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f \
|
||||
--hash=sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00 \
|
||||
--hash=sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10 \
|
||||
--hash=sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598 \
|
||||
--hash=sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6 \
|
||||
--hash=sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962 \
|
||||
--hash=sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c \
|
||||
--hash=sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08 \
|
||||
--hash=sha256:ba2f37ee79e6338845261a3c5b1784e5d1acdff2c0785b284f1b633033d136ab \
|
||||
--hash=sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573 \
|
||||
--hash=sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90 \
|
||||
--hash=sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5 \
|
||||
--hash=sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18 \
|
||||
--hash=sha256:be47f99644b208bff7766314013f9acf57b056b04191d570d68ad14022cf5b1d \
|
||||
--hash=sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af \
|
||||
--hash=sha256:c1dcc36dcb96abc02236e182d17e0f71430152a6c2c7447421da2d2dc144edea \
|
||||
--hash=sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c \
|
||||
--hash=sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b \
|
||||
--hash=sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6 \
|
||||
--hash=sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8 \
|
||||
--hash=sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774 \
|
||||
--hash=sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004 \
|
||||
--hash=sha256:ce854f5f478050ade5a238731c4ca985a7d3b3cb53ff600a9b5c3b689b5f0a7a \
|
||||
--hash=sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a \
|
||||
--hash=sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2 \
|
||||
--hash=sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2 \
|
||||
--hash=sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa \
|
||||
--hash=sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe \
|
||||
--hash=sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3 \
|
||||
--hash=sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc \
|
||||
--hash=sha256:e06efa066f7dbadbc84ebc126a97c452a6451dfcf589d89d788484949e1cf795 \
|
||||
--hash=sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d \
|
||||
--hash=sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc \
|
||||
--hash=sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893 \
|
||||
--hash=sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef \
|
||||
--hash=sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d \
|
||||
--hash=sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda \
|
||||
--hash=sha256:eb12fb2ba69ffa05f8695f61c69e591dc4b4a12ac3757ac8af8adb259bf56d17 \
|
||||
--hash=sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30 \
|
||||
--hash=sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7 \
|
||||
--hash=sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5 \
|
||||
--hash=sha256:f5542f9b941279d82d41eb0aa9f98eba36fe4df5c7086c651df7944935b37182 \
|
||||
--hash=sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f \
|
||||
--hash=sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9 \
|
||||
--hash=sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada \
|
||||
--hash=sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876 \
|
||||
--hash=sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a \
|
||||
--hash=sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348 \
|
||||
--hash=sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3 \
|
||||
--hash=sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f \
|
||||
--hash=sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0 \
|
||||
--hash=sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# requests
|
||||
colorama==0.4.6 ; sys_platform == 'win32' \
|
||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# tqdm
|
||||
filelock==3.32.3 \
|
||||
--hash=sha256:0ffa185a3540854c95caa7fa76b76cb219d907415e2c5dc9af25fd970563487f \
|
||||
--hash=sha256:7f0ca4bcc0e181c60dbbd8aa9ab5b120ebb99e4e064e83636340056f833a1f09
|
||||
# via torch
|
||||
fsspec==2026.7.0 \
|
||||
--hash=sha256:b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279 \
|
||||
--hash=sha256:c803c40f4cf860b49dea58ee3e1c33cb9c790520e233537e1340049f89b82a88
|
||||
# via torch
|
||||
idna==3.19 \
|
||||
--hash=sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15 \
|
||||
--hash=sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# requests
|
||||
jinja2==3.1.6 \
|
||||
--hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \
|
||||
--hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67
|
||||
# via torch
|
||||
llvmlite==0.49.0 \
|
||||
--hash=sha256:00f16db782f4a13c78c5804aedc434e46794a77e89999a168f9401106270e50a \
|
||||
--hash=sha256:039fa4054a06f537fb39248d4472284ca96be311a142ec09e69f95630ab469cc \
|
||||
--hash=sha256:20496a5c9fdb8179fb9300e7d19f6782555d98aeeb4a322264aa7fd99f980618 \
|
||||
--hash=sha256:294e2f0b70aef8f92d0ae7b203e2609f08beb39437eee73de59a21669331aae9 \
|
||||
--hash=sha256:3a9c9e3af4e214acfefa4f73ebe7bc3fb35854a62b654edb3953f5ae33c08ba3 \
|
||||
--hash=sha256:4281a0171d66d2098adce4ba706b8c550b1b10718650f682d64cde16e84e4de5 \
|
||||
--hash=sha256:4b0e710880b7cc910392bd6b9f1bbf468fed99b182e4420d51598f36114b3dce \
|
||||
--hash=sha256:4ec8ad805e7515cb8440a690eb3cef4d34acb29eef80b705ec4e1c1ad3c43c68 \
|
||||
--hash=sha256:6a5b06c1b5fc4ae4c9b169b065f42b719448ef1f873687ef224ef69969b75ec3 \
|
||||
--hash=sha256:6acba646d88abbc87d5c113a3d62c1fbf8b8fee11c6493f516803e30f21ae870 \
|
||||
--hash=sha256:80a84683d04516bb51da1bbeebddaf2c2f558809c93078a8f91807909ae331f8 \
|
||||
--hash=sha256:854941c2267fd4fc5b2ce02b8af8ecdffa79fb7784591d3a89370322039ea09f \
|
||||
--hash=sha256:95d1071023ed858b79f6971954fd7cc1f5dbcbab987718a4ccbe1411e47d0b81 \
|
||||
--hash=sha256:a1b414dc6b164738ec39dd8987cea73829057b7dd92fc6d91b52838385fc1dd2 \
|
||||
--hash=sha256:a8c0fc9d624bdc30a3d2db11eb2fb98f80fb209d20b37604eda516cd9b699cf4 \
|
||||
--hash=sha256:b095f15fb12c4d90495df5b1a3772b4732cc408398b204a787dbedd370e09c69 \
|
||||
--hash=sha256:b352c14353330c879e339b8f8d7491d565fe94242697714a24e80bd757202384 \
|
||||
--hash=sha256:b541c8fac3450db7574d1f53cf9dff83f285bfed9d69bf81fe71fc2a7d4f97fe \
|
||||
--hash=sha256:be637e465010bc9c50f070468f7f1cf5385e92fee364d192dd5e6cea790ecba9 \
|
||||
--hash=sha256:d3dee64784201b64c13a8df62c48a4f4218858faaa65889866bb29bdc243c038 \
|
||||
--hash=sha256:d5555ea1d63928481cbf7fcb1d67452b216c7e5b393a4eb7aa1401e67f2a4fc4 \
|
||||
--hash=sha256:da7b64474ac15ca595efa2644d5c6836638ccf70709fad3aba3fc56a55966928 \
|
||||
--hash=sha256:ddc7aecd4f56397ed6e8f120ec5dcd5a1a8f0e6032ca4af413462792d4dca2e3 \
|
||||
--hash=sha256:e32adb84fdaae28aeb86fdb6253084ee707ee157289a2e98fe3caf48a62bee82 \
|
||||
--hash=sha256:ee81e96c15a6f870918f1eb60c913551c16aa23defb4f5f1acfa660d6a0aaac2 \
|
||||
--hash=sha256:f3f2ff0aeb17d34fcce9f79b99baac441cfd3efa41b83e233ca4530a72381f72
|
||||
# via numba
|
||||
markupsafe==3.0.3 \
|
||||
--hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \
|
||||
--hash=sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a \
|
||||
--hash=sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf \
|
||||
--hash=sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19 \
|
||||
--hash=sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf \
|
||||
--hash=sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c \
|
||||
--hash=sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175 \
|
||||
--hash=sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219 \
|
||||
--hash=sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb \
|
||||
--hash=sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6 \
|
||||
--hash=sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab \
|
||||
--hash=sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26 \
|
||||
--hash=sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1 \
|
||||
--hash=sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce \
|
||||
--hash=sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218 \
|
||||
--hash=sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634 \
|
||||
--hash=sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695 \
|
||||
--hash=sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad \
|
||||
--hash=sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73 \
|
||||
--hash=sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c \
|
||||
--hash=sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe \
|
||||
--hash=sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa \
|
||||
--hash=sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559 \
|
||||
--hash=sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa \
|
||||
--hash=sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37 \
|
||||
--hash=sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758 \
|
||||
--hash=sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f \
|
||||
--hash=sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8 \
|
||||
--hash=sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d \
|
||||
--hash=sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c \
|
||||
--hash=sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 \
|
||||
--hash=sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a \
|
||||
--hash=sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19 \
|
||||
--hash=sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9 \
|
||||
--hash=sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9 \
|
||||
--hash=sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc \
|
||||
--hash=sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2 \
|
||||
--hash=sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4 \
|
||||
--hash=sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354 \
|
||||
--hash=sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50 \
|
||||
--hash=sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698 \
|
||||
--hash=sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9 \
|
||||
--hash=sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b \
|
||||
--hash=sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc \
|
||||
--hash=sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115 \
|
||||
--hash=sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e \
|
||||
--hash=sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485 \
|
||||
--hash=sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f \
|
||||
--hash=sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12 \
|
||||
--hash=sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025 \
|
||||
--hash=sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009 \
|
||||
--hash=sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d \
|
||||
--hash=sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b \
|
||||
--hash=sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a \
|
||||
--hash=sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5 \
|
||||
--hash=sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f \
|
||||
--hash=sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d \
|
||||
--hash=sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1 \
|
||||
--hash=sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287 \
|
||||
--hash=sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6 \
|
||||
--hash=sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f \
|
||||
--hash=sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581 \
|
||||
--hash=sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed \
|
||||
--hash=sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b \
|
||||
--hash=sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c \
|
||||
--hash=sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026 \
|
||||
--hash=sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8 \
|
||||
--hash=sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 \
|
||||
--hash=sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6 \
|
||||
--hash=sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e \
|
||||
--hash=sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d \
|
||||
--hash=sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d \
|
||||
--hash=sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01 \
|
||||
--hash=sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7 \
|
||||
--hash=sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419 \
|
||||
--hash=sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795 \
|
||||
--hash=sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1 \
|
||||
--hash=sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5 \
|
||||
--hash=sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d \
|
||||
--hash=sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42 \
|
||||
--hash=sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe \
|
||||
--hash=sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda \
|
||||
--hash=sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e \
|
||||
--hash=sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737 \
|
||||
--hash=sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523 \
|
||||
--hash=sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591 \
|
||||
--hash=sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc \
|
||||
--hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \
|
||||
--hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50
|
||||
# via jinja2
|
||||
more-itertools==11.1.0 \
|
||||
--hash=sha256:48e8f4d9e7e5878571ecf6f2b4e57634f93cd474cc8cfbd2376f2d11b396e30d \
|
||||
--hash=sha256:4b65538ae22f6fed0ce4874efd317463a7489796a0939fa66824dd542125a192
|
||||
# via openai-whisper
|
||||
mpmath==1.3.0 \
|
||||
--hash=sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f \
|
||||
--hash=sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c
|
||||
# via sympy
|
||||
networkx==3.6.1 \
|
||||
--hash=sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509 \
|
||||
--hash=sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762
|
||||
# via torch
|
||||
numba==0.67.0 \
|
||||
--hash=sha256:00c964a5b94d3ae82d83ac162cd610755875b98dadb779fdde06e6bfcdbca47e \
|
||||
--hash=sha256:3fa3d1b27f96f2c0d54513d953d7197886aa1eaa7d2439a0eedc44d993fb181a \
|
||||
--hash=sha256:4a2ed006635bbd0fe45681ed49f3b4f4bad1abf0c233bcc5842c9e3a34cabd61 \
|
||||
--hash=sha256:4d576e62bf2c9370f61312b51573c4bb1f3fe96798bbab56730847a368a316c4 \
|
||||
--hash=sha256:50e2b72406c18cda5dd7431b0082cb85ea94e06c64c33607248fc8bef92cfb81 \
|
||||
--hash=sha256:5269245a675abdd3e2c35ec6bb2f250355effa9032514d8f2354f0d2d10854bd \
|
||||
--hash=sha256:6004d8d5f28d4028687fb2d972d629295b13685943bd2ed5cd8810c3b848e219 \
|
||||
--hash=sha256:694c81c6560b2b47e5fc1dc39c29175b907adf862d9af0af801453400a022a61 \
|
||||
--hash=sha256:76d3335aaeffb9dc88309420890e73497a00be08a7530441bc2b58ffe025bfa5 \
|
||||
--hash=sha256:77e1c7173fee57a0d84e006c7e70346689d6cb3e7db503489bae58646b4eff7b \
|
||||
--hash=sha256:7930748ce8355d2a5a28602abab056a61fdc676d17377f27d17993905428171f \
|
||||
--hash=sha256:83ab968b0e0fa744eba03351282dd8000796e6ec8e4518f47bd3ed86c0a20c7b \
|
||||
--hash=sha256:88f6e0f5cb6c545e158b6ef0496c01b6d6958a7ccc6634a1576a94bbbab29ff2 \
|
||||
--hash=sha256:8c0e88acd4341ddf40779db3c0228b9188aca7fcab5f5f3ce9949a1fc71e9a02 \
|
||||
--hash=sha256:8c80c847301dc33dc8f84a97a952004023d9a05578ae4512b087176264cc1960 \
|
||||
--hash=sha256:9c4953387c77864b596d8296e2cfbdef82b0eea4166ab4864b05d226c51143e0 \
|
||||
--hash=sha256:aa5f002f665bec321b950dacaa26ee009e1d720f6ac9d9856eed5efe1caa03a6 \
|
||||
--hash=sha256:b68ad5125fe245339cc8dcc036081fc1ea482c5063387b9612a76ccd83dc91cd \
|
||||
--hash=sha256:cd75aa535b33fa05d9d930b1ae8af9f97a2881e96d72dfb38ec9b78284d9f851 \
|
||||
--hash=sha256:cfba1ac34f0363fb1a250a10e97240780d11e05227892f7286b26fbfd0ad58ce \
|
||||
--hash=sha256:d6c8e9ba3f9602471e8c6f563ffcce8db8046741f0bafb782a052e41dc6b6861 \
|
||||
--hash=sha256:e7a7b0121466f1e9a8a074b0545fe90e16389623abf979b5d7c299dca1294d7e \
|
||||
--hash=sha256:ed333e0af4386294e7f03e550e01411856b6935e717d859225e0a7338c6b6795 \
|
||||
--hash=sha256:f074a8e23db78490f11a3930c940be758316c10ac5985be83d2f298dc080acf7 \
|
||||
--hash=sha256:f63d43db06b4756424d6d2484737c902e0ae944a0eec3e8b0b4de2c695b15caa \
|
||||
--hash=sha256:f99f880ff25f418a67f9a1d00d0ddfbc63430f627b523e515085a592a7567f4b
|
||||
# via openai-whisper
|
||||
numpy==2.4.6 ; python_full_version < '3.12' \
|
||||
--hash=sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1 \
|
||||
--hash=sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4 \
|
||||
--hash=sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f \
|
||||
--hash=sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079 \
|
||||
--hash=sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096 \
|
||||
--hash=sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47 \
|
||||
--hash=sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66 \
|
||||
--hash=sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d \
|
||||
--hash=sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1 \
|
||||
--hash=sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e \
|
||||
--hash=sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147 \
|
||||
--hash=sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd \
|
||||
--hash=sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75 \
|
||||
--hash=sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063 \
|
||||
--hash=sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73 \
|
||||
--hash=sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab \
|
||||
--hash=sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4 \
|
||||
--hash=sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41 \
|
||||
--hash=sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402 \
|
||||
--hash=sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698 \
|
||||
--hash=sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7 \
|
||||
--hash=sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8 \
|
||||
--hash=sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b \
|
||||
--hash=sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8 \
|
||||
--hash=sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0 \
|
||||
--hash=sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662 \
|
||||
--hash=sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91 \
|
||||
--hash=sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0 \
|
||||
--hash=sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f \
|
||||
--hash=sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3 \
|
||||
--hash=sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f \
|
||||
--hash=sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67 \
|
||||
--hash=sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6 \
|
||||
--hash=sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997 \
|
||||
--hash=sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b \
|
||||
--hash=sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e \
|
||||
--hash=sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538 \
|
||||
--hash=sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627 \
|
||||
--hash=sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93 \
|
||||
--hash=sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02 \
|
||||
--hash=sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853 \
|
||||
--hash=sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c \
|
||||
--hash=sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43 \
|
||||
--hash=sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd \
|
||||
--hash=sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8 \
|
||||
--hash=sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089 \
|
||||
--hash=sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778 \
|
||||
--hash=sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1 \
|
||||
--hash=sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb \
|
||||
--hash=sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261 \
|
||||
--hash=sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb \
|
||||
--hash=sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a \
|
||||
--hash=sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8 \
|
||||
--hash=sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359 \
|
||||
--hash=sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5 \
|
||||
--hash=sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7 \
|
||||
--hash=sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751 \
|
||||
--hash=sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8 \
|
||||
--hash=sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605 \
|
||||
--hash=sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e \
|
||||
--hash=sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45 \
|
||||
--hash=sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2 \
|
||||
--hash=sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895 \
|
||||
--hash=sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe \
|
||||
--hash=sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb \
|
||||
--hash=sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a \
|
||||
--hash=sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577 \
|
||||
--hash=sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d \
|
||||
--hash=sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a \
|
||||
--hash=sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda \
|
||||
--hash=sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6 \
|
||||
--hash=sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# numba
|
||||
# openai-whisper
|
||||
numpy==2.5.2 ; python_full_version >= '3.12' \
|
||||
--hash=sha256:0090ccdd57ec2703e9b49d0bf554767370581c1dd0a6b2bb2b2d9def317d042a \
|
||||
--hash=sha256:078f9b027b478c9379b9677babbf0f8b8f1ecfada27636d7b9a93990c638739f \
|
||||
--hash=sha256:07d4e89f3a9ab0a9ba24264ccdb642b3dd951b2281e8883a5481a4aa79cc31a7 \
|
||||
--hash=sha256:0a4035ae1129ff8777f08bfbd44f1e5d8e9c049ce0c2dd78fc0d92c13e7251c0 \
|
||||
--hash=sha256:0aadf13b60048d501e05fa699efaf7734e2494f3498a4c2a5521d822640324f3 \
|
||||
--hash=sha256:14e373cfc6387177e8409dac3c7159be8eb05cd77096cd7c950268b86f62831c \
|
||||
--hash=sha256:1ab3d4a901f844ea836c3e80bf463c6a27d7f3c14e8e292fcf28d348b25b9bce \
|
||||
--hash=sha256:24b9dc2e3d84aa58523798805194e23e736f3f6ce2d1a5b92583ae734e6dbda8 \
|
||||
--hash=sha256:27650bb0e7140fa3d37b9923b4803645e0b125d190f326eecfd3f4dad8e8ade1 \
|
||||
--hash=sha256:28ac63476ec7651484215ee7fa15a1f78b57c14621f01e392afe17b9a1390ce4 \
|
||||
--hash=sha256:29b86ff8a6cc556b47ec6b64b194815cc80e6bf5eedcc6cddfd65318cb0b4eee \
|
||||
--hash=sha256:29d81e97f668489cba8ebfd796b9bdd453525d35dd9e162e2daec94bf3fc7740 \
|
||||
--hash=sha256:2cc779226e476d1e1f08c74068c419e60f41a9e0e069c92f6671d31d5c985e98 \
|
||||
--hash=sha256:2ffa7bacab3e2ee1b19ed31766bb60bb380b68c23f051e199c5cc598afd68710 \
|
||||
--hash=sha256:318b9a4c845dbea06708a29c84ee429cc3065048db34cdb799047643492050ee \
|
||||
--hash=sha256:34c319e2963be042673fb46570501b2f06c41924e17e3563d58646b4380dfb68 \
|
||||
--hash=sha256:3a2f061cebd9e3d23bdcfaaded5e2293a4c6a5b60fa42df85d410a725ce621bf \
|
||||
--hash=sha256:3cdec01fa790a186d430433fdd4d4ffb70eed6f0eeb4bf05c8dbe2dce0a9bcb8 \
|
||||
--hash=sha256:3e4c367352d3747784248a227fbec218e193b56f7e6692e3b64fc805478ecfdf \
|
||||
--hash=sha256:40f4d451aed46a8046a1aae41c4e55fb3612273df9c502480135e1501576a34b \
|
||||
--hash=sha256:44ef9675d908e65f9953063837c3277730f3f4437615a4cdab67b366cabaf884 \
|
||||
--hash=sha256:4bbd96c833ecc8cc069ce518078fc8c60cb9cbfb0fea5b7a803ad65035596d03 \
|
||||
--hash=sha256:4ec954036759bcee3aa484f8603bd9c14f3e776293b85578b8734c2d72777c69 \
|
||||
--hash=sha256:4f9744f9fbdcea0bc552e8f19e1f141f811a3f9bc2be2cc6e86d982cab23e3f4 \
|
||||
--hash=sha256:50a68f4bacd8a2b33d8da3d2269d0d78500f86ea582e4786dc10f5ef2c2c6842 \
|
||||
--hash=sha256:50e500dc868e9313530ce12ba470fe50ff3afe3d62993ed6eff652dacd555b65 \
|
||||
--hash=sha256:52c808f96484f5571a5cc863775ce50247c17dfb3b0361f8ed6b4b0456f80080 \
|
||||
--hash=sha256:5f8e00be2ec6f45f4e8a41a527f68d44a7d96fee92a650e4d8b1326f77f61e6e \
|
||||
--hash=sha256:60e902ac295855348a5ca2ea4c89108989a9f5fddfad3dfc0a8f36b10358567e \
|
||||
--hash=sha256:65f188481f1669e26f62b701e8205d19e460fa4a9b52a1414ba382330e4a3414 \
|
||||
--hash=sha256:6950c4b7dd562453090548ba7f5da7e59f57f85663f15d5dcc60e249192f7e59 \
|
||||
--hash=sha256:6a9bb119fb8dd21ba30b3f0e555b7e2b081bd9883af21ec9c1c633d161cda3a8 \
|
||||
--hash=sha256:6b588cc8f902d6bff201c19fd00c43ab8545671e3554d014e12e14139e5e8617 \
|
||||
--hash=sha256:6df895598c0edcb41030126c89e0f353b07d93238116143b7405e937359736c4 \
|
||||
--hash=sha256:6e8172ddfcf5cf74b811d372b570b83c60bd2de87a6fbfbebdadb4a9bd9c6cbb \
|
||||
--hash=sha256:7354826bc6f8f69402e9b7fe28d15fcd34feebd74f856f111585c5b0c9fb0251 \
|
||||
--hash=sha256:7587f53dfbd5edc0f7b87c6217b4c6d2d1f2ef9c3da70bc1315e7db5f8d7ec9d \
|
||||
--hash=sha256:77843ca236b777e67f8d6b3660ea116e499612703a0ecd7093f316201eb9d8e2 \
|
||||
--hash=sha256:7999d4ddb0c4025018373fd787510d46e04c769467af22869707b3c1cfd459ab \
|
||||
--hash=sha256:85aaccb24182c25df891ad0ec333585967e115269d5f1b17f2c9ae005bc96657 \
|
||||
--hash=sha256:8e4cb9a754c8a0c62eaa88273a5fba3391f4a610d1dee893c0755da31c083f15 \
|
||||
--hash=sha256:8ee9c4eeb8454b3660a8b53493563c3e121c2fc94fbd72b848ef814ed7b676a9 \
|
||||
--hash=sha256:9a0731745a72a184490a582fb4af2533512bd071ace67785b5fdffc0ae58dce8 \
|
||||
--hash=sha256:9e9413326d726c2545bfa65d2c0876871e8d8386e77f992c1d426e180bbd4323 \
|
||||
--hash=sha256:a610dc7e3c52edd39c2bc2375ff9c3fd59cb3ad00e4472d36f83bc1457145788 \
|
||||
--hash=sha256:a839318485284a6fb31be4f8f2c91c8f2cb22f4543c4a8903f12b0671ffe07cc \
|
||||
--hash=sha256:afb3f0632d6b2e3ba04dbce8d1e48d321b369138b73830b5ca371a0e8d479d56 \
|
||||
--hash=sha256:b879fb674276e331513fb136b78dbc6bd3c848309e0d841cfd63be3896c4cfc1 \
|
||||
--hash=sha256:b9727f472d2f3888053b8a75ab0cb94745a9de224bb5846dbadc0092101bc71d \
|
||||
--hash=sha256:ba0a474801b8dc67b66bf465548abc90e82b44d2611b5770f33008dcabffe8ec \
|
||||
--hash=sha256:bd68ece1553d2023c09a4226d9e41c586ad2d20594d1a456186c33513d2cb3f2 \
|
||||
--hash=sha256:c081cbe16ba1ab53078e5ff29013621e33c509eedab055775d956427712c236e \
|
||||
--hash=sha256:c1f017dc0875c9209d219f97feceb7d54c2661bb243deb4114478e1295808af7 \
|
||||
--hash=sha256:cebc2d6dbb605a7703d59751dea4bd6b0ab127a5a4338a6f432df1936fef8b26 \
|
||||
--hash=sha256:cf7de32f486e4ac9e2d93b810f9e9ac72a728dd46a32a0bb403222f27f653514 \
|
||||
--hash=sha256:d482d171c406ae88c5b19cad3b6a1c4c5209f886ab74bc44c2c865c23f52d860 \
|
||||
--hash=sha256:d6a48072864e3324e194a8fbb3c657bcc5b5c869dbc64c9537b1d5c862572c0a \
|
||||
--hash=sha256:d787cf769c3baeb5f6235e778edb52c08dfa923789b5958f28e6450f96107cb1 \
|
||||
--hash=sha256:dc649493697006bc90614a5f0bbc8cb3cb1866715c474e473694968d7e6b99ab \
|
||||
--hash=sha256:ddf47472af2e4280d79bac82304f5e80150211f1b9e614b760061d5fdfbb6eba \
|
||||
--hash=sha256:e5651f3f87add730ee6608d915009e19c911fba0cb000c7e3ea994b7d768eb12 \
|
||||
--hash=sha256:e79aba74ffaf5f78a050d777c184cddf8fdffabab38acf5f3ef1fecbc17895d6 \
|
||||
--hash=sha256:eaa088384c46f519dacb93b7ec483a6d6b19a4a2085ae4f25ab9b1c43d387d1e \
|
||||
--hash=sha256:eaca7ff36f0f52e2111ec71f169d8fd3e889e7ddc0d2592e0d703fd8d3ce8fac \
|
||||
--hash=sha256:f06571a052127dc1b4e8b83029b4d1b20daa2b64a31cdd181fc6bc774e9000eb \
|
||||
--hash=sha256:fd0d703772bba096843785bd38371e31bb4a0c1151497ad5739d182114a73f7f
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# numba
|
||||
# openai-whisper
|
||||
openai-whisper==20250625 \
|
||||
--hash=sha256:37a91a3921809d9f44748ffc73c0a55c9f366c85a3ef5c2ae0cc09540432eb96
|
||||
# via -r requirements/whisper.in
|
||||
regex==2026.7.19 \
|
||||
--hash=sha256:062f8cb7a9739c4835d22bd96f370c59aba89f257adcfa53be3cc209e08d3ae0 \
|
||||
--hash=sha256:064f1760a5a4ade65c5419be23e782f29147528e8a66e0c42dd4cedb8d4e9fc6 \
|
||||
--hash=sha256:09523a592938aa9f587fb74467c63ff0cf88fc3df14c82ab0f0517dcf76aaa62 \
|
||||
--hash=sha256:09d3007fc76249a83cdd33de160d50e6cb77f54e09d8fa9e7148e10607ce24af \
|
||||
--hash=sha256:09f3e5287f94f17b709dc9a9e70865855feee835c861613be144218ce4ca82cc \
|
||||
--hash=sha256:0c41c63992bf1874cebb6e7f56fd7d3c007924659a604ae3d90e427d40d4fd13 \
|
||||
--hash=sha256:0e9554c8785eac5cffe6300f69a91f58ba72bc88a5f8d661235ad7c6aa5b8ccd \
|
||||
--hash=sha256:1123ef4211d763ee771d47916a1596e2f4915794f7aabdc1adcb20e4249a6951 \
|
||||
--hash=sha256:15b364b9b98d6d2fe1a85034c23a3180ff913f46caddc3895f6fd65186255ccc \
|
||||
--hash=sha256:1649eb39fcc9ea80c4d2f110fde2b8ab2aef3877b98f02ab9b14e961f418c511 \
|
||||
--hash=sha256:17ed5692f6acc4183e98331101a5f9e4f64d72fe58b753da4d444a2c77d05b12 \
|
||||
--hash=sha256:199535629f25caf89698039af3d1ad5fcae7f933e2112c73f1cdf49165c99518 \
|
||||
--hash=sha256:1c398716054621aa300b3d411f467dda903806c5da0df6945ab73982b8d115db \
|
||||
--hash=sha256:1d3372064506b94dd2c67c845f2db8062e9e9ba84d04e33cb96d7d33c11fe1ae \
|
||||
--hash=sha256:1d58561843f0ff7dc78b4c28b5e2dc388f3eff94ebc8a232a3adba961fc00009 \
|
||||
--hash=sha256:1d793a7988e04fcb1e2e135567443d82173225d657419ec09414a9b5a145b986 \
|
||||
--hash=sha256:1ebac3474b8589fce2f9b225b650afd61448f7c73a5d0255a10cc6366471aed1 \
|
||||
--hash=sha256:20568e182eb82d39a6bf7cff3fd58566f14c75c6f74b2c8c96537eecf9010e3a \
|
||||
--hash=sha256:22a992de9a0d91bda927bf02b94351d737a0302905432c88a53de7c4b9ce62e2 \
|
||||
--hash=sha256:2955907b7157a6660f27079edf7e0229e9c9c5325c77a2ef6a890cba91efa6f0 \
|
||||
--hash=sha256:2c4e61e2e1be56f63ec3cc618aa9e0de81ef6f43d177205451840022e24f5b78 \
|
||||
--hash=sha256:2cc3460cedf7579948486eab03bc9ad7089df4d7281c0f47f4afe03e8d13f02d \
|
||||
--hash=sha256:2ce9e679f776649746729b6c86382da519ef649c8e34cc41df0d2e5e0f6c36d4 \
|
||||
--hash=sha256:2ef7eeb108c47ce7bcc9513e51bcb1bf57e8f483d52fce68a8642e3527141ae0 \
|
||||
--hash=sha256:3080a7fd38ef049bd489e01c970c97dd84ff446a885b0f1f6b26d9b1ad13ce11 \
|
||||
--hash=sha256:343a4504e3fb688c47cad451221ca5d4814f42b1e16c0065bde9cbf7f473bd52 \
|
||||
--hash=sha256:36aacfb15faaff3ced55afbf35ec72f50d4aee22082c4f7fe0573a33e2fca92e \
|
||||
--hash=sha256:3d3143f159261b1ce5b24c261c590e5913370c3200c5e9ebbb92b5aa5e111902 \
|
||||
--hash=sha256:40b34dd88658e4fedd2fddbf0275ac970d00614b731357f425722a3ed1983d11 \
|
||||
--hash=sha256:4458124d71339f505bf1fb94f69fd1bb8fa9d2481eebfef27c10ef4f2b9e12f6 \
|
||||
--hash=sha256:4896db1f4ce0576765b8272aa922df324e0f5b9bb2c3d03044ff32a7234a9aba \
|
||||
--hash=sha256:4a0530bb1b8c1c985e7e2122e2b4d3aedd8a3c21c6bfddae6767c4405668b56e \
|
||||
--hash=sha256:4aa5435cdb3eb6f55fe98a171b05e3fbcd95fadaa4aa32acf62afd9b0cfdbcac \
|
||||
--hash=sha256:4c3501bfa814ab07b5580741f9bf78dfdfe146a04057f82df9e2402d2a975939 \
|
||||
--hash=sha256:4e5413bd5f13d3a4e3539ca98f70f75e7fca92518dd7f117f030ebedd10b60cb \
|
||||
--hash=sha256:4e6883a021db30511d9fb8cfb0f222ce1f2c369f7d4d8b0448f449a93ba0bdfc \
|
||||
--hash=sha256:52579c60a6078be70a0e49c81d6e56d677f34cd439af281a0083b8c7bc75c095 \
|
||||
--hash=sha256:555497390743af1a65045fa4527782d10ff5b88970359412baa4a1e628fe393b \
|
||||
--hash=sha256:56ad4d9f77df871a99e25c37091052a02528ec0eb059de928ee33956b854b45b \
|
||||
--hash=sha256:571fde9741eb0ccde23dd4e0c1d50fbae910e901fa7e629faf39b2dda740d220 \
|
||||
--hash=sha256:572fc57b0009c735ee56c175ea021b637a15551a312f56734277f923d6fd0f6c \
|
||||
--hash=sha256:59787bd5f8c70aa339084e961d2996b53fbdeab4d5393bba5c1fe1fc32e02bae \
|
||||
--hash=sha256:5a2721c8720e2cb3c209925dfb9200199b4b07361c9e01d321719404b21458b3 \
|
||||
--hash=sha256:5cc26a66e212fa5d6c6170c3a40d99d888db3020c6fdab1523250d4341382e44 \
|
||||
--hash=sha256:5ebee1ee89c39c953baac6924fcde08c5bb427c4057510862f9d7c7bdb3d8665 \
|
||||
--hash=sha256:60be8693a1dadc210bbcbc0db3e26da5f7d01d1d5a3da594e99b4fa42df404f5 \
|
||||
--hash=sha256:618a0aed532be87294c4477b0481f3aa0f1520f4014a4374dd4cf789b4cd2c97 \
|
||||
--hash=sha256:61bb1bd45520aacd56dd80943bd34991fb5350afdd1f36f2282230fd5154a218 \
|
||||
--hash=sha256:6383cd2ed53a646c659ba1fe65727db76437fdaa069e697a0b44a51d5843d864 \
|
||||
--hash=sha256:64729333167c2dcaaa56a331d40ee097bd9c5617ffd51dabb09eaddafb1b532e \
|
||||
--hash=sha256:64b6ca7391a1395c2638dd5c7456d67bea44fc6c5e8e92c5dc8aa6a8f23292b4 \
|
||||
--hash=sha256:65dcd28d3eba2ab7c2fd906485cc301392b47cc2234790d27d4e4814e02cdfda \
|
||||
--hash=sha256:65fa6cb38ed5e9c3637e68e544f598b39c3b86b808ed0627a67b68320384b459 \
|
||||
--hash=sha256:66bd62c59a5427746e8c44becae1d9b99d22fb13f30f492083dfb9ad7c45cc18 \
|
||||
--hash=sha256:6e44c0e7c5664be20aee92085153150c0a7967310a73a43c0f832b7cd35d0dd3 \
|
||||
--hash=sha256:6f8c6e7a1cfa3dc9d0ee2de0e65e834537fa29992cc3976ffec914afc35c5dd5 \
|
||||
--hash=sha256:7322ec6cc9fba9d49ab888bb82d67ac5625627aa168f0165139b17018df3fb8a \
|
||||
--hash=sha256:73b133a9e6fb512858e7f065e96f1180aa46646bc74a83aea62f1d314f3dd035 \
|
||||
--hash=sha256:73f272fba87b8ccfe70a137d02a54af386f6d27aa509fbffdd978f5947aae1aa \
|
||||
--hash=sha256:7e77b324909c1617cbb4c668677e2c6ae13f44d7c1de0d4f15f2e3c10f3315b5 \
|
||||
--hash=sha256:80115dd39481fd3a4b4080220799dbcacb921a844de4b827264ececacbe17c78 \
|
||||
--hash=sha256:87ccab0db8d5f4fbb0272642113c1adb2ffc698c16d3a0944580222331fa7a20 \
|
||||
--hash=sha256:89dfee3319f5ae3f75ebd5c2445a809bb320252ba5529ffdafea4ef25d79cf1a \
|
||||
--hash=sha256:8ac59a0900474a52b7c04af8196affc22bd9842acb0950df12f7b813e983609a \
|
||||
--hash=sha256:8cae6fd77a5b72dae505084b1a2ee0360139faf72fedbab667cd7cc65aae7a6a \
|
||||
--hash=sha256:8d3469c91dd92ee41b7c95280edbd975ef1ba9195086686623a1c6e8935ce965 \
|
||||
--hash=sha256:90c633e7e8d6bf4e992b8b36ce69e018f834b641dd6de8cea6d78c06ffa119c5 \
|
||||
--hash=sha256:93db40c8de0815baab96a06e08a984bac71f989d13bab789e382158c5d426797 \
|
||||
--hash=sha256:9724e6cb5e478cd7d8cabf027826178739cb18cf0e117d0e32814d479fa02276 \
|
||||
--hash=sha256:98c6ac18480fcdb33f35439183f1d2e79760ab41930309c6d951cb1f8e46694c \
|
||||
--hash=sha256:9a15e785f244f3e07847b984ce8773fc3da10a9f3c131cc49a4c5b4d672b4547 \
|
||||
--hash=sha256:9b60d7814174f059e5de4ab98271cc5ba9259cfea55273a81544dceea32dc8d9 \
|
||||
--hash=sha256:9be2a6647740dd3cca6acb24e87f03d7632cd280dbce9bbe40c26353a215a45d \
|
||||
--hash=sha256:9c7472192ebfad53a6be7c4a8bfb2d64b81c0e93a1fc8c57e1dd0b638297b5d1 \
|
||||
--hash=sha256:9dce8ec9695f531a1b8a6f314fd4b393adcccf2ea861db480cdf97a301d01a68 \
|
||||
--hash=sha256:9e50d748a32da622f256e8d505867f5d3c43a837c6a9f0efb149655fadd1042a \
|
||||
--hash=sha256:a81758ed242b861b72e778ba34d41366441a2e10b16b472784c88da2dea7e2dd \
|
||||
--hash=sha256:ac777001cdfc28b72477d93c8564bb7583081ea8fb45cdca3d568e0a4f87183c \
|
||||
--hash=sha256:b2b506b1788df5fecd270a10d5e70a95fe77b87ea2b370a318043f6f5f817ee6 \
|
||||
--hash=sha256:b2ea4a3e8357be8849e833beeae757ac3c7a6b3fc055c03c808a53c91ad30d82 \
|
||||
--hash=sha256:bf1516fe58fc104f39b2d1dbe2d5e27d0cd45c4be2e42ba6ee0cc763701ec3c7 \
|
||||
--hash=sha256:c0d702548d89d572b2929879bc883bb7a4c4709efafe4512cadee56c55c9bd15 \
|
||||
--hash=sha256:c10b82c2634df08dfb13b1f04e38fe310d086ee092f4f69c0c8da234251e556e \
|
||||
--hash=sha256:c42572142ed0b9d5d261ba727157c426510da78e20828b66bbb855098b8a4e38 \
|
||||
--hash=sha256:c4585c3e64b4f9e583b4d2683f18f5d5d872b3d71dcf24594b74ecc23602fa96 \
|
||||
--hash=sha256:c639ea314df70a7b2811e8020448c75af8c9445f5a60f8a4ced81c306a9380c2 \
|
||||
--hash=sha256:c670fe7be5b6020b76bc6e8d2196074657e1327595bca93a389e1a76ab130ad8 \
|
||||
--hash=sha256:cc1b2440423a851fad781309dd87843868f4f66a6bcd1ddb9225cf4ec2c84732 \
|
||||
--hash=sha256:cd3584591ea4429026cdb931b054342c2bcf189b44ff367f8d5c15bc092a2966 \
|
||||
--hash=sha256:d15df07081d91b76ff20d43f94592ee110330152d617b730fdbe5ef9fb680053 \
|
||||
--hash=sha256:d19662dbedbe783d323196312d38f5ba53cf56296378252171985da6899887d3 \
|
||||
--hash=sha256:d24ecb4f5e009ea0bd275ee37ad9953b32005e2e5e60f8bbae16da0dbbf0d3a0 \
|
||||
--hash=sha256:d446c6ac40bb6e05025ccee55b84d80fe9bf8e93010ffc4bb9484f13d498835f \
|
||||
--hash=sha256:d51ffd3427640fa2da6ade574ceba932f210ad095f65fcc450a2b0a0d454868e \
|
||||
--hash=sha256:d6ce43a0269d68cee79a7d1ade7def53c20f8f2a047b92d7b5d5bcc73ae88327 \
|
||||
--hash=sha256:d721e53758b2cca74990185eb0671dd466d7a388a1a45d0c6f4c13cef41a68ac \
|
||||
--hash=sha256:d7da47a0f248977f08e2cb659ff3c17ddc13a4d39b3a7baa0a81bf5b415430f6 \
|
||||
--hash=sha256:db47b561c9afd884baa1f96f797c9ca369872c4b65912bc691cfa99e68340af2 \
|
||||
--hash=sha256:dbe6493fbd27321b1d1f2dd4f5c7e5bd4d8b1d7cab7f32fd67db3d0b2ed8248a \
|
||||
--hash=sha256:dbece16025afda5e3031af0c4059207e61dcf73ef13af844964f57f387d1c435 \
|
||||
--hash=sha256:ddd67571c10869f65a5d7dde536d1e066e306cc90de57d7de4d5f34802428bb5 \
|
||||
--hash=sha256:de9208bb427130c82a5dbfd104f92c8876fc9559278c880b3002755bbbe9c83d \
|
||||
--hash=sha256:e30d40268a28d54ce0437031750497004c22602b8e3ab891f759b795a003b312 \
|
||||
--hash=sha256:e8b0abe7d870f53ca5143895fef7d1041a0c831a140d3dc2c760dd7ba25d4a8b \
|
||||
--hash=sha256:f035d9dc1d25eff9d361456572231c7d27b5ccd473ca7dc0adfce732bd006d40 \
|
||||
--hash=sha256:f04b9f56b0e0614c0126be12c2c2d9f8850c1e57af302bd0a63bed379d4af974 \
|
||||
--hash=sha256:f0fa4fa9c3632d708742baf2282f2055c11d888a790362670a403cbf48a2c404 \
|
||||
--hash=sha256:f2e7f8e2ab6c2922be02c7ec45185aa5bd771e2e57b95455ee343a44d8130dff \
|
||||
--hash=sha256:f8f6fa298bb4f7f58a33334406218ba74716e68feddf5e4e54cd5d8082705abf \
|
||||
--hash=sha256:fbf300e2070bb35038660b3be1be4b91b0024edb41517e6996320b49b92b4175 \
|
||||
--hash=sha256:fce7760bf283405b2c7999cab3da4e72f7deca6396013115e3f7a955db9760da \
|
||||
--hash=sha256:fcee38cd8e5089d6d4f048ba1233b3ad76e5954f545382180889112ff5cb712d \
|
||||
--hash=sha256:fe31f28c94402043161876a258a9c6f757cb485905c7614ce8d6cd40e6b7bdc1 \
|
||||
--hash=sha256:ffd8893ccc1c2fce6e0d6ca402d716fe1b29db70c7132609a05955e31b2aa8f2
|
||||
# via tiktoken
|
||||
requests==2.34.2 \
|
||||
--hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
|
||||
--hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# tiktoken
|
||||
setuptools==84.1.0 \
|
||||
--hash=sha256:23657205b63d4d31395ab917815247f694aafad28cd21316bf5fd45a51048ea0 \
|
||||
--hash=sha256:5231689c6ac8156cd155cfb98c3fd6fb252c3e7e9bd3d78b64d3c55f132624c9
|
||||
# via
|
||||
# -c requirements/installer-build.txt
|
||||
# torch
|
||||
sympy==1.14.0 \
|
||||
--hash=sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517 \
|
||||
--hash=sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5
|
||||
# via torch
|
||||
tiktoken==0.14.0 \
|
||||
--hash=sha256:087538c080e5ff421abd3a0785ed63c5111d06af98e6cd0d374dbe5969147ca3 \
|
||||
--hash=sha256:10f31e63e40313f2e518d87f7086cfa44e45f64cc14d8ae14103b41220c30a14 \
|
||||
--hash=sha256:11d8211b290855d2721334ff17dd9b3a17bfb26872be01f25d73612ef7ece890 \
|
||||
--hash=sha256:144a3fc369f92b7d548995217c5d6e84038d3572157a0f6f34080d65291d0f78 \
|
||||
--hash=sha256:149d97453c4c98c04b081d64a85e635921269b532710d6faf81e9e82b790e7d3 \
|
||||
--hash=sha256:14b47e3674f2624803a8acc8fb367b7e24fc53055f9df3296482fe9a3a34a232 \
|
||||
--hash=sha256:151d37a150c8f3dfc5f4345597b10e101876bd1bd13494e0185af6b508758d2e \
|
||||
--hash=sha256:18a1b651c4b032004bf7b4f1713391a54b2a341a52c6e8a2b59acae9d16e13c7 \
|
||||
--hash=sha256:19d643d701fdaa70e5b9c7f8f96abcaffe77ca5e482a3a1a7dde46feb4284695 \
|
||||
--hash=sha256:1b6e4adcfd285c44502aed51df98aaaca4f0fea028165dbf8a9e857b9f98d8ea \
|
||||
--hash=sha256:1f83081065ee5833d35b49e9180f3d8d15622a603dd1c435da0da6cc12b3662f \
|
||||
--hash=sha256:2157f52e4b4d7ac5ecc7457b3716834706e7ef9a46f5144029bfeb7cf71f4e06 \
|
||||
--hash=sha256:231dec90efcdccf1b565a1416107736f1e09b1a08fe736ef9d6363e626d03874 \
|
||||
--hash=sha256:26cc4b4840fa0e9f4b72ed489883e12f57e00d1021ca794720e3c29a12f0edef \
|
||||
--hash=sha256:26e60f6a956ee171ab728b37b8439905d7ea1db435c30f9822f291e9861c861d \
|
||||
--hash=sha256:2cc19ac87b41c9493c9778ff5847f0c8bbcf5bd0ec6b87ce06c1c802adc8a771 \
|
||||
--hash=sha256:2ea70afba6b9eddbf22c165142e5f0a2ad7aa36a452873c48b57bb2aeb8492ae \
|
||||
--hash=sha256:2ec16eb585332c55d022d86354e209ddf27326b1ea3477585ab248e7776d3b1f \
|
||||
--hash=sha256:2fc834fbe3f6a0736905c36ab709537e6840dbd63b982dc9e0216ae7d305ba1a \
|
||||
--hash=sha256:380873f330b741c4435574f37edb20813d04603ace2d53e0a63560e1fec83010 \
|
||||
--hash=sha256:3b12e54f8bec91433e41aff65d8d1f209a4f678081163747079806e5361f6c91 \
|
||||
--hash=sha256:3c5349c9f916283bba32bec8af69b763e4faa304dc004d0eaaea66a3cf004c1f \
|
||||
--hash=sha256:3de75343041a1c57333b1e707ac8a9769738241d7d6a55d39e12cf84548337c6 \
|
||||
--hash=sha256:3fd7c14b1cb45b486c39fc9b3443bb341f3e2fc7e6f31247f3435a5836651632 \
|
||||
--hash=sha256:447ada49af4898b5e992f0b5799d2f3af385921102c211947ce3fe960dd919da \
|
||||
--hash=sha256:4d8d91d68353bd167fdf26467e5ff9e56aaa5f87d6410c0238608629e4dc0d33 \
|
||||
--hash=sha256:50a7e5646cbac2a8f7c3e8c0934ffda1a4357ee9c44b652434b23c3ed54d0900 \
|
||||
--hash=sha256:561e7580f84a79859af1ef6f676968e9030fcc3fe195700b15235bca64f009c9 \
|
||||
--hash=sha256:60c47ca69ddda0dea8256fffd12e1b86f4b59734a20e4a70c61f63cc5f021df4 \
|
||||
--hash=sha256:6eb94895c45f26bb8f5546e5fd8a069efcf6e3f108ea9d5cbe3bf6f7f3983438 \
|
||||
--hash=sha256:728303a072163130c5b477b1f20d6211895569c1d5302c24ffc93a3009160871 \
|
||||
--hash=sha256:78571efc311c30b73f31eb949a921d6dac39a5d9dc42d1cfa8f8db157b3447b1 \
|
||||
--hash=sha256:7896eea257fe497a2b7134474d909156c6744ce8da35bce88011a960e008aa0d \
|
||||
--hash=sha256:7aab286a020660a039097912a088236b985d18a3090d73f136c4413d29d37ca0 \
|
||||
--hash=sha256:7b7acbb7a4b8383707bce22ad3c162006478c27b56368acd3e1fcb1658a80425 \
|
||||
--hash=sha256:7db45b98e94adf4173a5cd7422b150999a7ee11ff847783a14f6e1b80cc38cb6 \
|
||||
--hash=sha256:86951a971c53979ec857bd8c4a32dc227ab0fd33f6c12a3bd62d3fbf5f0bfcaa \
|
||||
--hash=sha256:86f66c85e796f5d05d5c4a60ec1d40cbfebc47a32464053528c797163fa9ab89 \
|
||||
--hash=sha256:8e947aefe98ef74cce94923f90e48c98fe34eb1ec0a6bfdfadfc5a96359bfc36 \
|
||||
--hash=sha256:90a762670c7f968184723769a06ed51f5cf5ce5dcd1e30164f25c72d85c2d1f1 \
|
||||
--hash=sha256:94f77b60a8ab23580db19ae822744c9716c1720020d2179ca5605112d12326f1 \
|
||||
--hash=sha256:979c1524f753b662b0f3cd261b135afe6659cce33caaa7a5ea00dd1756b3055c \
|
||||
--hash=sha256:a140e83317fef02faeeb78d9a8efac623887f2feaf0055c55dcdb2b17f0226ad \
|
||||
--hash=sha256:aa428a559d5fd02ae619aacaace86c7474a1f2702d2c01fc828908dd60f20f7a \
|
||||
--hash=sha256:b950248272f1b303dc32986396e2dccfa10cf6d1e83ec8f0bba1776660305482 \
|
||||
--hash=sha256:c2edf09b381fafbc014ae8e018ed25087abb9a3dafa8465a0ea63c6558c47a79 \
|
||||
--hash=sha256:c3093001ddce822b4587e6e94bf6de36a5f97b3f31de1c9fc8d4fda144c59ff4 \
|
||||
--hash=sha256:c6cb9896a82b9ee44e15ba0b5c8044072f2e4d48acaa704c8d3feeef5ad9487c \
|
||||
--hash=sha256:c77d4a3e1deb2707819df92046b89aad1ac81d27e07616b797cbff3f62c037da \
|
||||
--hash=sha256:ca4db6ff5c5bf600f9b7761a0070ed44dfe5797a76bd432fb978bc480ef40c58 \
|
||||
--hash=sha256:cbe2cc3bba939bcdaf103e03df9d5039d33887080b315624be28ec69059e5f94 \
|
||||
--hash=sha256:cd8ca1305c1c902fe42c486165f2e4808d9997625c98ffb05b9e0366d99d3948 \
|
||||
--hash=sha256:d0781223705199b289faa59601bb9c2441712d4c600dd13c43d8fd6a33d22cd5 \
|
||||
--hash=sha256:d6cebe67765569df3dafac8474e4eccf5c19d24140492567a5e58a11445732a4 \
|
||||
--hash=sha256:e067f4cbcc5d036e8aff7fe7a6b530a8f4de2e4616ad9005a24a1879e24e6450 \
|
||||
--hash=sha256:e2eca764c53490f8930dbce329e0769f11108d87d908282a80c5c130e26e7037 \
|
||||
--hash=sha256:e3442bbb2f0c588cec876061e37ae67b455b9df9978b003c8fe30e45f2ef5b42 \
|
||||
--hash=sha256:e4ddf863b59347deaa92302dcd90e5eb003cdc9be06ec2b692c38d1bdd9efd49 \
|
||||
--hash=sha256:e9c5fe393aab56469f04e432ff851216d3def3436cf5f07e442a240164bf500f \
|
||||
--hash=sha256:eceeff0c62419bc78d4b6e70a4762a4d25df3ae8f2d5946e3853ce93e7a57098 \
|
||||
--hash=sha256:f2af4a336ea56d6c14f27741a0e1d8294a35dd0b038bcf990d232ebb54eb994b \
|
||||
--hash=sha256:f3d6cf93fbe2e7117eb7bedca684216fbe328a41f0843ce34245451d8eb2df1c \
|
||||
--hash=sha256:f5e7665f6624e052e5e7f6a36919ab69279decdc976d7b16b4fa15e1897d0513 \
|
||||
--hash=sha256:f702e0aeeb6506e57687e881c59e844ebe8f0a6a097ddafe20e3ab25f387be4e
|
||||
# via openai-whisper
|
||||
torch==2.13.0+cpu \
|
||||
--hash=sha256:0555fde6108ca90247ae33d4e1237cbae475c86a223bb2f0f91d9addf1f611bd \
|
||||
--hash=sha256:0b8f7d0423027ae8b90c7977c627f3379f325363a08224dffad9b4b2d684a83d \
|
||||
--hash=sha256:10717d8b3b67c45a4788bf7ffc0bab1ea1e5ebbedd24466be6100102d141fac1 \
|
||||
--hash=sha256:1a3a35229fdc13446b4eab50e7fcf9399ff941e89a3b761497786297a5d8dde5 \
|
||||
--hash=sha256:222a6681467cc7f6f05cd3068dfbc603def3a1e46d1d4620c1c8cdf6178bd563 \
|
||||
--hash=sha256:2b3d093abd919ad934c43d47e73ba63ceba7cbd7269fc2e9c1e4fc29e8fe45fa \
|
||||
--hash=sha256:3bbb357161e8db43ba7cdcc7e03561eba0c449392f2f27d3566887198fcb4ead \
|
||||
--hash=sha256:3fbf9c9d1f3c10c2d59d04aca426dee9ccc6ceb32d255c61e93acc3b4f75fae6 \
|
||||
--hash=sha256:4ca4a9394b0c771238a4f73590fdbbc4debad85ed0fa63d026ae1b085da7d6e2 \
|
||||
--hash=sha256:6746dbcbeb526eb61330b76b41ff1b4eb848951103a892eeb080dfa2b264667b \
|
||||
--hash=sha256:6e9817dbdf5ea76789babd46e457eac5bf14ff566cf85f8addbfdff2d56601ce \
|
||||
--hash=sha256:6f307c2c32d764ffc6ff6893b801fad6d4752f3e67966cb8abf1843427c02604 \
|
||||
--hash=sha256:7b8d26e29bceafbdaa8d63bfe7612f23875b5af2cc07e13f809c3ed890bbe1d8 \
|
||||
--hash=sha256:84453b69508ec79902f899c5ed9495acb9e2bbe9fda5f1d5d6f19e3c3842e1a7 \
|
||||
--hash=sha256:8e109528e6bab044815daebaf71770fbaace3a66ef1c816cb55c875350f78a60 \
|
||||
--hash=sha256:8eb5002ca81af00ae69b57540f615b58b8ae922b6d4848176b366a52bd2196e6 \
|
||||
--hash=sha256:966d020354f465672dc7dd10d3a5c6cd17d7eb48620aa1d265b48a1f78f06898 \
|
||||
--hash=sha256:991cc14b39e751122c01f017be6448533989868731cb5eecd1006893d26787c2 \
|
||||
--hash=sha256:a17ff48608634db245e17e8bb00a9558554a49aeb1e4f5fe6cd039af2a10515b \
|
||||
--hash=sha256:a43376bd094124ef626bfdd3d4c2c62eacb0b5ddc99776f4a32d4fd16f1f3420 \
|
||||
--hash=sha256:a8b450c1e58e5800e5b4691dac412f8d2d65a1dc3298166f91596603a3531e6f \
|
||||
--hash=sha256:ac7aaf322be4777765a53bed7264a214dd81b3a1d276b93150515a3c5f75e4b0 \
|
||||
--hash=sha256:b222c15a0fc2ce207d1c1a59700b46c8fa6748df1f447ad11e5c870dde0933d9 \
|
||||
--hash=sha256:ca021f9eb2f8345c83fa03e3a04587308afb8df71bd472670b3ece00df58621c \
|
||||
--hash=sha256:d20fa53ee744502fa4c69818a720b05ca0d37abd055d4f6e66cae155114bc691 \
|
||||
--hash=sha256:dec241fef3984c0d1edadd1f58708e218d4eae881ceef7bc10cf9964d41b68b9 \
|
||||
--hash=sha256:e2e5134decf00e218da62318f3dc5df156231d367871918e91eba95ab0ad43ab \
|
||||
--hash=sha256:f028e428bddee95cdb86e2470254e95c9af629362488550c200ed4793125a817 \
|
||||
--hash=sha256:f5cbb61180a9793d9e12fe115a2310d2600bd449dfb9a01ec5640e21359fa5ea \
|
||||
--hash=sha256:fa0762705b933624d59f6823db9ce7ec2e35b3e1e9c319c9db51fbeecfc3e319 \
|
||||
--hash=sha256:ffadde149901c8afa138daa38d898264003cfcf1a3336ca5cd964b5af227d867
|
||||
# via
|
||||
# -r requirements/whisper.in
|
||||
# openai-whisper
|
||||
tqdm==4.70.0 \
|
||||
--hash=sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220 \
|
||||
--hash=sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# openai-whisper
|
||||
triton==3.7.1 ; (platform_machine == 'x86_64' and sys_platform == 'linux') or sys_platform == 'linux2' \
|
||||
--hash=sha256:10ba85fa2cca4a2fbdeb36bf1cb082f2c252bda55bf9fccd74f65ec5bc647e68 \
|
||||
--hash=sha256:2020153b08280415ec0da6607834e79166442147e78e144df06b508c75b186d2 \
|
||||
--hash=sha256:3daf64305d6cea88d3334c65ebc9bcd0c64c9564a977084366aa768d57cbcf64 \
|
||||
--hash=sha256:58c0e131da05134a2a4788ccbcc0c1105cf0f54c8e98f19e34cd465396dc15eb \
|
||||
--hash=sha256:6744957e9fd610a29680ec2346057d0c86948ed3812468670719f391e94b44a5 \
|
||||
--hash=sha256:7e40869937a68206ec70d7f25bb7ec6433cb083f9135e1f36dbd318dc449a728 \
|
||||
--hash=sha256:9497f2e696ee368862a181a90b2dcc03ca978cc4f602abd67c7d81022a6988e1 \
|
||||
--hash=sha256:c58e4c61f0c73b5dba3b5d19b4a7093c32f90dc18b2a7f121a7c16ccd31107b7 \
|
||||
--hash=sha256:cdbfc09d9ec58bc5e68321525653220de7515c199e7a8097a97c85e62b52cd0a \
|
||||
--hash=sha256:d4a0e1cd4c4a76370ed74a8432a53cea28716827d19e40ffc732233e35ceb3f6 \
|
||||
--hash=sha256:ee89fbf782ec2ad50391dd1cf26cbea4f4467154c37f4773026da8fc31c0f58e \
|
||||
--hash=sha256:fe4ea396a06171f1f1f58cbd39c70b09294398f7dd7c620939bab54ad6f934fa
|
||||
# via openai-whisper
|
||||
typing-extensions==4.16.0 \
|
||||
--hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \
|
||||
--hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5
|
||||
# via
|
||||
# -c requirements/installer-build.txt
|
||||
# torch
|
||||
urllib3==2.8.0 \
|
||||
--hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \
|
||||
--hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63
|
||||
# via
|
||||
# -c requirements/runtime.txt
|
||||
# requests
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true">
|
||||
<title>Discord</title>
|
||||
<path fill="currentColor" d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true">
|
||||
<title>GitHub</title>
|
||||
<path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 869 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-hidden="true">
|
||||
<title>Email</title>
|
||||
<path fill="currentColor" d="M3 5h18a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2zm0 2v.2l9 6.3 9-6.3V7H3zm18 2.4-8.4 5.9a1 1 0 0 1-1.2 0L3 9.4V17h18V9.4z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 299 B |