Metadata-Version: 2.5
Name: pip-auto
Version: 1.2.3
Summary: Just import it. Missing packages install themselves - fast, safe, and in your language.
License-Expression: MIT
License-File: LICENSE
Keywords: auto-install,dependencies,import,installer,pep723,pip
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: Chinese (Simplified)
Classifier: Natural Language :: Chinese (Traditional)
Classifier: Natural Language :: English
Classifier: Natural Language :: French
Classifier: Natural Language :: German
Classifier: Natural Language :: Japanese
Classifier: Natural Language :: Korean
Classifier: Natural Language :: Portuguese
Classifier: Natural Language :: Russian
Classifier: Natural Language :: Spanish
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: System :: Software Distribution
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# pip-auto

**Just `import` it. Missing packages install themselves.**

```bash
pip install pip-auto
```

**0.8.5 is a big release, and fixes a security problem in 0.8.4 and earlier: see [CHANGELOG.md](CHANGELOG.md).**

No pip at all? `python get-autopip.py` (in the source distribution) installs it without pip: it downloads the wheel from PyPI, checks its
sha256 against the digest PyPI publishes, and installs it with its own installer (`--version X`, `--target DIR`, `--wheel FILE` for offline use).

That's the whole setup. From now on, when your code imports something that isn't installed, pip-auto finds the
right package on PyPI, installs it on the spot, and your program keeps running — no `ModuleNotFoundError`,
no stopping to run `pip install`, no restarting.

```python
import pyfiglet               # not installed? fine
from PIL import Image         # import name ≠ package name? fine (installs pillow)
import cv2                    # installs opencv-python
print(pyfiglet.figlet_format("hello"))
```

```
[autopip] 'pyfiglet' not found → installing pyfiglet
[autopip] installed pyfiglet==1.0.4 (2.51s)
```

## Why it's nice

- **Zero setup.** `pip install pip-auto` turns it on for that Python. `pip uninstall pip-auto` removes every trace.
- **It knows the real package name.** `PIL` → `pillow`, `cv2` → `opencv-python`, `sklearn` → `scikit-learn`,
  `bs4` → `beautifulsoup4`, `google.generativeai` → `google-generativeai`, plus ~1,000 more mappings — and it
  learns new ones from every wheel it sees. Before installing, it **opens the wheel and checks the module is really
  inside**, so a same-named impostor never gets installed.
- **Fast.** Its own installer (pip is not used): the whole dependency tree is discovered in parallel over one shared
  connection setup, and every file of every wheel is written in a single parallel pass. From the second time on it just
  hard-links from a local cache (filled in the background, at low priority).
  Measured with `bench/bench.py`, which gives pip, uv and pip-auto the same throttled network (10 MB/s shared, +30 ms per connection),
  a brand-new venv every run, no bytecode compiled by anyone, and checks that all three installed the same packages.
  Heavy set (numpy, pandas, scipy, matplotlib, scikit-learn, pillow: 19 packages, 7,757 files), median of 3 on one Windows PC:

  | | first install (empty cache) | second install (warm cache) |
  |---|---|---|
  | pip | 40 s | 47 s |
  | uv (default: hard links) | 35 s | 3.3 s |
  | pip-auto (`junction` mode, measured in 0.8.4) | 19.5 s | 0.8 s |
  | uv (`--link-mode copy`) | 35.5 s | 8.9 s |
  | pip-auto (`link_mode copy`, same work as pip) | 34.8 s | 5.2 s |

  Read it honestly: the first install is dominated by the network and by writing ~8,700 files, so with the same amount of
  writing (copy mode) pip-auto and uv are about equal; the big differences are on repeat installs, where folder links
  (junctions, Windows) skip the writing altogether. Numbers vary with machine load; run `bench/bench.py` yourself.
  It adds only about **5 ms** to Python startup.
- **Safe.** Names that look like popular packages (typosquats such as `requets`) and brand-new unknown packages are
  never installed automatically. If anything fails halfway, everything — including the old versions it replaced — is
  rolled back. Checking a candidate never runs its code: wheels are only opened, and source packages are only listed —
  a `setup.py` runs only after the safety check (and your answer, if `ask` is on).
- **Respects "optional" imports.** `try: import x / except ImportError:` in your code, optional imports inside
  libraries, and `importlib.util.find_spec("x")` checks are left alone.
- **Works everywhere you run Python:** scripts, Jupyter / IPython, virtual environments.
- **Speaks your language.** Messages follow your OS language: English, 日本語, 简体中文, 繁體中文, 한국어,
  Español, Français, Deutsch, Português, Русский.

## Tell it what you want (optional)

```python
# /// script
# dependencies = ["requests<3", "rich"]
# ///
import requests, rich            # a PEP 723 block is installed up front, all at once
import numpy  # autopip: numpy<2   ← pin a version with an end-of-line comment
```

## Project settings: allow / deny lists (optional)

Put an `autopip.toml` (or a `[tool.autopip]` table in `pyproject.toml`) next to your scripts. `autopip init` creates one.

```toml
[autopip]
allow = ["requests<3", "numpy", "types-*"]   # only these may be installed automatically (versions and wildcards OK)
deny  = ["evil-pkg"]                         # never — even when something else needs it as a dependency
constraints = ["numpy<2"]                    # version limits for automatic installs (same as pip -c)
ask = true                                   # settings here override your personal ones
```

It is looked up from the script's folder upwards and applies to automatic installs only (imports, `autopip run`, PEP 723);
what you type yourself with `autopip install` is never blocked. `autopip policy [x.py] [pkg...]` shows what is in effect
and whether a package would be allowed. With a settings file present, autopip never falls back to plain `pip`
(which would bypass the lists).

## One-file bundles

```bash
autopip bundle app.py            # → app.pyz
python app.pyz                   # the other person needs nothing else installed
```

`app.py`, the local modules it imports, and every dependency are packed into **one solid-compressed block** (all files
concatenated, compressed once — smaller than zipping file by file: e.g. 28 MB of wheels → 18 MB). At run time the block
is decompressed in a single streaming pass while files are written in parallel, then cached; later runs start instantly.

Bundles that contain compiled packages (numpy, …) are tied to the Python version and OS they were built for. For those,
**all bytecode goes into one code-archive file** instead of thousands of `.py`/`.pyc` files: a tiny import hook loads
modules straight from it (sources are kept inside, so tracebacks and `inspect.getsource` still show code), and only real
files — `.pyd`/`.so`, data — are written to disk. Example (numpy + pandas + flask + rich + requests): 7,357 files → 2,022;
first run ≈ 8 s instead of ≈ 40 s. Child processes (`multiprocessing` spawn) work too. Pure-Python bundles are portable and
are extracted as ordinary files.

Options: `--codec lzma|zlib|none`, `--level N`, `--include "pkg==1.0"`, `--loose` (ordinary files, no code archive),
`--no-pyc`, `--info app.pyz`, `--diff old.pyz new.pyz` (which packages and files changed). The loader depends on nothing but the standard library. Limitation: with
`python -S` / `-I` (no `site`), child processes cannot use the code archive.

## Speed and robustness details

- **Connection reuse:** requests to the same host share one keep-alive connection (about 30 ms of TLS handshake saved per request;
  a cold resolve of 9 packages went from a median 3.2 s to 2.4 s). Proxy settings still use urllib. `AUTOPIP_NO_POOL=1` turns it off.
- **Resumable, single downloader:** an interrupted download continues from where it stopped (`Range`), and when several
  pip-auto processes need the same wheel, one downloads and the others wait for it; the same applies to building the
  unpacked cache. Stale locks from crashed processes are taken over.
- **Longer-lived solutions:** a resolved dependency set is reused for up to 6 hours as long as the index pages of every
  package in it are unchanged (checked with ETag, about 0.5 s instead of about 1.1 s for a 9-package set with stale indexes).
- **Own parallel unpacker (no external tool):** the first unpack of a wheel into the cache is done by pip-auto's own engine instead of writing
  file by file from Python or calling `tar`. It cuts each file's compressed bytes straight out of the memory-mapped wheel, inflates them with
  `zlib` and checks the CRC32 (no SHA-256 is computed: the hashes for `RECORD` come from each wheel's own `RECORD`), writes each file with one
  `os.write`, and hands out whole folders as units of work (largest first), for all wheels of an install in one pass. Heavy set (19 wheels,
  7,745 files), median of 5: Python writer 5.71 s, `tar.exe` x8 4.25 s, **own engine 4.09 s** (identical files). Whole first install into an empty
  cache: `junction` 8.3 s -> 6.9 s, `virtual` + junction 5.3 s -> 4.8 s. It behaves the same on every Windows version (no dependence on which
  `tar.exe` ships with it, no processes to start); unsafe names, encrypted entries and CRC errors are refused, and any failure falls back to the
  Python writer for that wheel. `AUTOPIP_FAST_UNPACK=0` turns it off.
- **Shared `.pyc`:** with junction mode, `.pyc` files are compiled once into the shared cache (in the background), so
  every environment and its first import use them.
- `autopip prefetch pkg...` resolves, downloads and prepares the cache without installing, so a later install is only links.
- **Download and unpack overlap (auto):** when the network is slower than about 30 MB/s the disk is idle while waiting, so each
  wheel is unpacked into the cache as soon as it arrives. Same throttled network, heavy set, first install, median of 3:
  10 MB/s 19.8 s -> 18.5 s, 40 MB/s 16.1 s -> 14.3 s, unthrottled 16.1 s -> 13.6 s (a small but steady gain; forcing it on for a
  fast network made things worse in an earlier test, hence the automatic switch). `AUTOPIP_EARLY_UNPACK=0/1/auto`.
- **Bandwidth limit:** `autopip install --limit-rate 5M ...`, `AUTOPIP_LIMIT_RATE=500K`, or `autopip config limit_rate 5M` caps the total download
  speed of all threads (useful on a shared connection, or to make benchmarks repeatable).
- **Repeatable benchmarks:** `bench/bench.py` runs pip, uv and pip-auto through `bench/throttle_proxy.py`, a local proxy with a fixed
  shared rate and added latency, so every tool sees the same network (`python bench/bench.py --rate 10M --latency 30`).

> **Default since 1.2.2: `teleport`** (Windows). `autopip config link_mode junction` goes back to the previous default; `AUTOPIP_TELEPORT_FILL=used` stops the background fill.

## Virtual install (`autopip config link_mode virtual`, or `autopip install --link-mode virtual ...`)

With `virtual`, a package's `.py` files are **not written to disk at all**. pip-auto writes only the real files
(compiled extensions, data, dist-info) plus a tiny index, and a small import finder (`_apk_lazy.py`, standard library only,
loaded through a `.pth` file) reads each `.py` straight out of the cached wheel the moment it is imported. Tracebacks and
`inspect.getsource` still show the source. Measured on numpy + pandas + scipy + matplotlib + scikit-learn + pillow: **7,769 files ->
3,465 files on disk**, disk-only cold install about 15-20% faster than `junction`, steady-state imports slightly faster, and the
whole set imports and runs (regression, FFT, random forest, plotting).
Fastest mode overall (see the numbers below); opt-in because of the trade-offs. `autopip doctor` checks that every virtual package can still
read its cached wheel. Trade-offs: the wheel cache must stay (don't delete `~/.autopip`); tools that read `.py` files from disk
(type checkers, IDE indexing, `pkgutil.iter_modules` on such a package) will not see them; the environment must be a real
site directory (so `.pth` files are processed). Default stays `junction` (Windows) / `hardlink`.

**Known limitation (Python 3.12 and later):** `importlib.metadata.Distribution.files` silently leaves out files that are not on disk, so in `virtual` mode (and in `teleport` until the background fill has finished) the `.py` files are missing from that list. The `RECORD` file itself is complete (`d.read_text('RECORD')`), and pip-auto's own commands read it directly.

On Windows, `virtual` also links the real files **one folder junction per package** (instead of one link per file), so a repeat
install is as fast as `junction` mode. Same heavy set, wheels already cached, median of 3: first install into an empty cache
`junction` 6.7 s / old `virtual` 5.9 s / **`virtual` + junction 5.4 s**; second install 1.16 s / 1.85 s / **1.21 s**.
`AUTOPIP_VIRTUAL_JUNCTION=0` goes back to per-file links.

**Slim (opt-in, virtual only: `autopip install --slim ...`, `AUTOPIP_SLIM=1` or `autopip config slim on`):** creating a file costs about
0.5 ms on NTFS (bytes hardly matter: 127 MB of `.pyd` in 270 files takes 0.12 s; 8,700 files take about 4 s, 4,000 folders 13 s; one block
file 0.3 s), so slim also skips the real files that are not read when running: data under `tests/` / `test/` folders and C / Cython /
Fortran development files (`.h .hpp .lib .a .c .cpp .pyx .pxd .pxi .f90 .f`). Type stubs (`.pyi`) are kept, and the `.py` files of `tests/`
are still importable. Heavy set: real files 3,398 -> 1,891; first install about 10% faster (6.2 s -> 5.6 s). The cost: `numpy.get_include()`
headers, and running a package's own test suite, no longer work. The slim cache is kept apart from the full one. The real files of the cache are unpacked with the same engine (`.py` are
not extracted at all): heavy set, cache build 3.13 s -> 1.97 s.

### Use `autopip install` instead of `pip install`

`autopip install` takes the options you already type after `pip install`, so you can swap the command and keep the rest:

```bash
autopip install requests "numpy>=1.26" -r requirements.txt -c constraints.txt
autopip install -U rich            # upgrade (also works for pip-auto itself, even while autopip.exe is running)
autopip install --pre foo          # pre-releases, newest first (like pip)
autopip install --no-index -f ./wheels foo        # offline, from a folder of wheels
autopip download -d ./wheels foo   # save the wheels (+ dependencies) without installing
autopip check                      # are the requirements of everything installed satisfied? (like pip check)
```

| Same as pip | `-r -c -e -U --no-deps -t --user -i --extra-index-url --dry-run -I/--ignore-installed --force-reinstall --pre --no-index -f/--find-links --only-binary --no-binary --no-compile -q` and `--hash=sha256:` in requirements files |
|---|---|
| Accepted and ignored (nothing to do) | `--no-cache-dir --disable-pip-version-check --no-warn-script-location --break-system-packages --no-input --prefer-binary --no-build-isolation --progress-bar --retries --timeout --upgrade-strategy -v` |
| `--trusted-host` | accepted, ignored: TLS certificates are always checked |
| Also available | `uninstall`, `list [--outdated]`, `show`, `freeze`, `check`, `download`, `tree`, `why`, `snapshot`, `audit`, `doctor` |

Not supported: `pip wheel`, `--root`, `--prefix`. Set `alias pip=autopip` (or a
PowerShell function) if you want your muscle memory to keep working.

### Teleport and code blocks (Windows, opt-in: `autopip config link_mode teleport`)

**Teleport** goes one step further than `virtual`: installing creates **no real files at all** except `dist-info`, a small index and one
(empty) folder link per package. The real files of a wheel (`.pyd`, data) are unpacked **once, in one go, when the package is first
imported** (the same engine), straight into the folder the link points to; a package that is never imported never gets its files. Heavy set,
wheels cached: install 5.5 s (`virtual` + junction) -> **3.6 s**; the unpacking moves to the first import, so install + first run is about
the same. Small wheels (fewer than 20 real files), and anything that cannot be linked, are unpacked right away.
Since 1.2.2 it unpacks **what is used first**: an extension module (`.pyd`) is written when that module is imported (together with the other `.pyd`
files of the same package, in parallel). When the first program that imported the package has finished, a low-priority background process writes the
rest (the `.py` files, the `.pyd` files nobody imported, test data), so after a minute the folder is the same as a `junction` install. Five heavy
packages, install + three runs: `junction` 22-26 s, `teleport` 24-26 s (install 5 s instead of 9 s, the first run longer). `AUTOPIP_TELEPORT_FILL=used`
keeps only what was used.

**Code blocks** (used by `virtual`, `teleport` and, since 1.1, `junction` / `hardlink` too; on by default; with `junction` the `.py` files stay on disk and `AUTOPIP_REAL_BLOCKS=0` turns this part off): the first time a wheel is imported, pip-auto starts a low-priority
background process that compiles **every module of the wheel once, in parallel, into one file** (`~/.autopip/codeblocks/`, one per wheel and
Python version; tests/ folders are left out). Every environment then reads that one file directly (memory-mapped): no `.pyc` files are
written into environments and nothing is compiled again. Heavy set, first run of a script in a cold environment: **6.0 s -> 3.1 s** once the
blocks exist; the very first environment runs as before (6.6 s) while the blocks are built. A missing, stale (source CRC differs) or broken block
is ignored and the module is loaded the usual way. `AUTOPIP_NO_BLOCKS=1` turns it off, `AUTOPIP_BLOCKS=sync` builds in the foreground.

**First-run warm-up** (all link modes except `copy`, on by default): right after an install, a detached background process reads the new files in
parallel (16 threads), so a real-time antivirus has checked them before your script needs them. Heavy set, install + first run at once: about
**35% less** with `junction`, 24% with `virtual`, 31% with `teleport` (one Windows 10 PC with Defender on; see CHANGELOG). `AUTOPIP_WARM=off` turns
it off, `AUTOPIP_WARM=sync` runs it in the foreground, `AUTOPIP_WARM_THREADS` sets the thread count.

## Commands

| Command | What it does |
|---|---|
| `autopip run x.py` | Install everything `x.py` needs first, then run it (`--venv` creates and uses `.venv` next to it) |
| `autopip lock x.py` | Write `x.autopip.lock` with every version **and sha256** pinned; `run` then installs exactly that |
| `autopip install ...` | **Same syntax as `pip install`**: `-r requirements.txt` (nested `-r`, `-c`, `--hash`, `-i`), `-e .`, `-U`, `--no-deps`, `--force-reinstall`, `--dry-run`, `-t DIR`, `--user` (`--dry-run` prints a per-package plan: new / upgrade) |
| `autopip uninstall pkg...` | Remove (also `-r file`). Use this, not `pip uninstall`, for packages autopip linked (junction/virtual/teleport): pip follows the link and moves the shared cache |
| `autopip list [--outdated]` / `show pkg` | Installed packages / packages with newer versions / details |
| `autopip upgrade pkg...` / `--all` | Upgrade (`--dry-run` to only show) |
| `autopip freeze [x.py]` | Pin what a script uses (`--requirements`, `--pep723`), or the whole environment |
| `autopip clean [--days 30] [--yes]` | Remove auto-installed packages you haven't used for a while |
| `autopip bundle x.py` | Pack a script + dependencies into one solid-compressed file: `python x.pyz` |
| `autopip init` / `policy` | Create / inspect the project settings file (allow / deny lists) |
| `autopip gui` | Browser dashboard: sizes, last used, clean-up, settings (127.0.0.1 only) |
| `autopip tree [pkg]` / `why pkg` | Dependency tree of what is installed / which installed packages need `pkg` |
| `autopip why-slow pkg...` / `install --timing` | Where the time went (resolve / download / disk / link) with a hint about the likely cause |
| `autopip snapshot save\|list\|restore\|delete` | Save the installed set by name; `restore NAME --yes` rolls the environment back to it |
| `autopip list --outdated --security` / `upgrade --security` | Outdated packages with known-vulnerable ones first; upgrade only the vulnerable ones |
| `autopip sandbox x.py [--keep]` | Run a script in a throwaway environment that is deleted afterwards |
| `autopip size [--top N]` | Which packages take the most space (and which are linked to the cache) |
| `autopip compile req.in [-o req.txt]` | Resolve and pin every version (+ sha256 of the file this Python installs, + `# via` reasons) into a requirements file |
| `autopip prefetch pkg... [--recent]` | Resolve + download + prepare the cache without installing |
| `autopip cache [status]` | How much space the cache uses and where |
| `autopip audit` | Look up known vulnerabilities (PyPI advisory data) for everything installed; exit code 1 if any are found |
| `autopip doctor [--fix]` | Diagnose the setup (hook, cache, settings file, PyPI); `--fix` repairs the hook file, leftovers of interrupted installs and broken links |
| `autopip check pkg` | Run the safety check only |
| `autopip off` / `on` | Turn it off / back on |

`AUTOPIP_DISABLE=1` turns it off for a single command.

## Settings (`autopip config KEY VALUE`)

- `ask` — `true` to confirm before every install (asks on the console; never installs when nobody can answer)
- `safety` — `strict` (default) / `warn` / `off`
- `link_mode` — `teleport` (**default on Windows since 1.2.2**: the install writes almost nothing, what is imported is unpacked first and the rest is filled in a minute later by a background process, so the folder ends up like a `junction` one; plain `--target` folders automatically use `junction` instead) / `junction` (the previous default, a safe choice: one folder link per package instead of one link per file; real `.py` files in the cache, so IDEs and type checkers see them; since 1.1 their compiled code is also read from a shared *code block*, see below) / `virtual` (opt-in: no `.py` files are written) / `teleport` (opt-in: an install creates only links) / `hardlink` (default elsewhere) / `virtual` (no `.py` files at all) / `hardlink` (default elsewhere) / `copy` (separate files per environment). With `junction` and `hardlink` the files are shared with the cache (`~/.autopip`): don't delete the cache while environments use it, and don't edit installed files in place (use `copy` for that).
- `slim` — `on` to skip tests/ data and C/Cython/Fortran development files in `virtual` mode (see Slim; default off)
- `lang` — `en`, `ja`, `zh`, `zh-TW`, `ko`, `es`, `fr`, `de`, `pt`, `ru` (default: your OS language; also `AUTOPIP_LANG`)
- `index_url` / `extra_index_urls` — other package indexes (`pip.ini` / `PIP_INDEX_URL` are read too)

## Compatibility

- **Check it on your own PC: `autopip selftest`.** One command, offline, about 40 seconds, **83 checks of many kinds** (exit code 0 only if all pass;
  everything is created in one temporary folder that is deleted at the end). Groups: *this PC* (zlib / ssl, free disk, hardlinks, file speed with your
  antivirus, Japanese / space / symbol folder names, very long paths), *own unpacker* (a 40 MB file, stored / bzip2 / lzma wheels, Japanese and emoji file
  names, `../` and absolute paths refused, a damaged file detected), *link modes* (install -> use -> upgrade -> uninstall in all five modes, downgrade,
  scripts, `.pth` files, `.data` folders, namespace packages, package data and tracebacks, RECORD hashes), *dependency resolution* (extras, markers,
  conflicts, `--pre`, Requires-Python, wheels for another platform, yanked releases, `--hash`, `-r`, `--no-index -f`), *network* (a small web server on
  your own PC: download, cache, a login page instead of a wheel, a connection cut in the middle, a damaged cached wheel), *safety* (rollback, look-alike
  names, allow / deny), *import-triggered install* (the main feature, with and without internet), *tools* and *real-life trouble* (3 installs at the same
  time, a lock left by a stopped program, read-only files, **a file held open by a running program**).
  `autopip selftest --quick` runs the first 10 only (about 5 s), `--only safety,net` picks groups, `--list` shows all checks.
  It has been run on Windows 10 (NTFS) and, in its first form (10 checks), on **one real Windows 11 PC** (all passed). That is two machines, not a
  guarantee for every Windows 11 PC: if anything fails on yours, please send the output of `autopip selftest`. The CI workflow also covers the
  Windows 11 generation (Windows Server 2025, Windows 11 ARM) once the project is on GitHub.
- **Windows 10 / 11 is the supported platform for now.** Everything is tested there, on **Python 3.8 – 3.14** (all seven versions, with and
  without `packaging` installed). Linux and macOS are **not supported yet**: parts of the code have fallbacks for them (and there is a CI
  workflow for them), but nothing has been run there, and `teleport` and the junction modes are Windows-only by design.
- Modules removed from the standard library in Python 3.13 (`imghdr`, `cgi`, `telnetlib`, …) are provided by
  installing their maintained successors (`standard-imghdr`, `legacy-cgi`, …).
- No dependencies. MIT license.

## Good to know

- Only packages from PyPI (or the indexes you configure) are installed, and every install is logged.
- In `junction` / `hardlink` mode, environments share the same files. If you edit installed files in place, use `link_mode copy`.

日本語の説明: README.ja.md (included in the source distribution)
