VMAFX Production Docker Images¶
This page covers pulling, running, and building the VMAFX production container images hosted at ghcr.io/vmafx/vmafx.
Note
For the development MCP container (full GPU toolchain, oneAPI, CUDA, HIP, MCP server pre-installed), see dev-mcp.md. That container is separate from the production images described here, and it carries a different MCP server: the dev container runs the Go vmafx-mcp, while the -server image below still runs the Python vmaf-mcp (see MCP server variant).
Quick start¶
Name the release you want. latest points at the newest final release only; release candidates (vX.Y.Z-rc.N) are never tagged latest, so until 1.0.0 is out, latest does not exist. The examples use v1.0.0-rc.2; substitute the newest release listed on the GitHub releases page.
Images published after v1.0.0-rc.2 have zstd layers and need Docker Engine 23.0 or later, Docker Desktop 4.19 or later, Podman or containerd 1.5 or later (what can pull them).
tag=v1.0.0-rc.2
# Pull and run the vmaf CLI (CPU, smallest image)
docker pull ghcr.io/vmafx/vmafx:$tag
docker run --rm ghcr.io/vmafx/vmafx:$tag --version
# Score a video pair (mount a local directory)
docker run --rm \
-v /path/to/videos:/data:ro \
ghcr.io/vmafx/vmafx:$tag \
--reference /data/ref.yuv \
--distorted /data/dis.yuv \
--width 576 --height 324 \
--pixel_format 420 \
--bitdepth 8 \
--model path=/usr/local/share/vmafx/model/vmaf_v0.6.1.json \
--output /dev/stdout
Tag matrix¶
| Tag | Platforms | Description | Approx. size |
|---|---|---|---|
vX.Y.Z (also latest for a final release) | amd64, arm64 | CPU-only CLI (default) | ~144 MB unpacked, ~55 MB compressed |
vX.Y.Z-server | amd64, arm64 | CPU CLI + vmaf-mcp MCP server + vmaf-tune | ~1.1 GB unpacked, ~283 MB compressed |
vX.Y.Z-cuda13 | amd64 | CUDA 13 build of the CLI; no NVIDIA library (the host driver provides libcuda) | ~234 MB unpacked, ~76 MB compressed |
vX.Y.Z-rocm10 | amd64 | HIP build of the CLI with the ROCm 10 runtime files it loads | ~611 MB unpacked, ~175 MB compressed |
vX.Y.Z-oneapi2026 (also vX.Y.Z-oneapi2025) | amd64 | SYCL build of the CLI with the oneAPI 2026.1 SYCL runtime files it loads and the Intel GPU compute runtime | ~590 MB unpacked, ~163 MB compressed |
Base images¶
| Variant | Base image | Why |
|---|---|---|
| CPU CLI | gcr.io/distroless/cc-debian13:nonroot | Matches its Debian 13 builder ABI. |
| Server | Official Python 3.14 slim image (also Debian 13) | A virtualenv requires its matching interpreter and standard library. |
| CUDA | debian:13-slim, the CPU image's builder base, for builder and runtime | The builder installs nvcc from NVIDIA's debian13 repository; the runtime holds no NVIDIA file. |
| ROCm | debian:13-slim for builder and runtime | The builder streams /opt/rocm out of AMD's pinned rocm/dev-ubuntu-26.04 image; the runtime holds only the HIP runtime files vmaf loads. |
| oneAPI | debian:13-slim for builder and runtime | The builder installs Intel's compiler at an exact apt build; the runtime holds the SYCL runtime files vmaf loads; see oneAPI 2026.1. |
The three GPU images carry no vendor toolchain: no nvcc, hipcc or Intel runtime tree under /opt/intel/oneapi (ADR-1517). The ROCm runtime files are in /usr/local/lib/rocm, the Intel ones in /usr/local/lib/intel; each image's LD_LIBRARY_PATH names them.
oneAPI tag names¶
Releases up to v1.0.0-rc.2 published the oneAPI image only as -oneapi2025. Later releases publish the same image under both -oneapi2026 and -oneapi2025, so scripts that name the old suffix keep working. Use -oneapi2026 in new scripts: the older suffix is kept for compatibility and will be retired only by a release that announces a breaking change.
Recovering a published image set¶
Manual publication is an idempotent recovery path for an existing published release (final or candidate), not a way to mint an arbitrary image tag from a branch. Run the workflow at the same immutable tag passed as input:
The preflight rejects, before granting package-write or OIDC permissions:
- an unpublished tag;
- a prerelease flag that disagrees with the tag;
- a dispatch ref other than
refs/tags/$tagormaster; - a source SHA mismatch;
- coordinated version drift.
A dispatch on master is the recovery for a broken build recipe: it builds the tag's source with master's build recipe (docker/, Dockerfile.go-server, ffmpeg-patches/) and signs as master; see Recovering a release's container images.
GPU variants¶
vmaf --version never touches the GPU, so it does not show that an image can use one. Check with a scoring run that forces the backend: with --backend cuda, hip or sycl, a backend that cannot initialise makes the CLI exit with code 100 instead of scoring on the CPU (see explicit-backend semantics). The default, --backend auto, falls back to the CPU with only a message on stderr, so a container started without GPU access still prints a score.
The examples score the pair in /path/to/videos with tag set as in the quick start, and pass the model by path, which works in every image.
CUDA 13.4.2¶
docker run --rm --gpus all \
-v /path/to/videos:/data:ro \
ghcr.io/vmafx/vmafx:$tag-cuda13 \
--backend cuda \
--reference /data/ref.yuv --distorted /data/dis.yuv \
--width 576 --height 324 --pixel_format 420 --bitdepth 8 \
--model path=/usr/local/share/vmafx/model/vmaf_v0.6.1.json \
--output /dev/stdout
Requires the NVIDIA Container Toolkit and a host driver compatible with CUDA 13.4.2. The image holds no NVIDIA library: libvmaf loads the host driver's libcuda.so.1, which the toolkit mounts. Without --gpus all the container has no GPU: --backend cuda exits with code 100, and the default auto mode scores on the CPU.
ROCm 10.1.0 (HIP)¶
Pass /dev/kfd and the render node of the GPU to use, found from its PCI address under /dev/dri/by-path/. Passing all of /dev/dri also works, but exposes every GPU in the host.
Add the host's render and video groups by numeric ID:
- The image has no
rendergroup, so--group-add renderfails withunable to find group render. --group-add videoresolves to the image's GID 44 rather than the host'svideogroup.
# The GPU's PCI address; list them with: ls -l /dev/dri/by-path/
render=$(readlink -f /dev/dri/by-path/pci-0000:7d:00.0-render)
docker run --rm \
--device /dev/kfd \
--device "$render" \
--group-add "$(getent group render | cut -d: -f3)" \
--group-add "$(getent group video | cut -d: -f3)" \
-v /path/to/videos:/data:ro \
ghcr.io/vmafx/vmafx:$tag-rocm10 \
--backend hip \
--reference /data/ref.yuv --distorted /data/dis.yuv \
--width 576 --height 324 --pixel_format 420 --bitdepth 8 \
--model path=/usr/local/share/vmafx/model/vmaf_v0.6.1.json \
--output /dev/stdout
Requires: amdgpu kernel module loaded and /dev/kfd + /dev/dri/renderD<N> accessible. The HIP kernels cover every GPU target ROCm 10.1.0 builds its own libraries for (the dist_amdgpu_targets list of ROCm's share/therock/dist_info.json, 25 targets from gfx908 to gfx1250).
oneAPI 2026.1 (SYCL, Intel Arc)¶
The image is built and run on Debian 13, the base of the CPU image. Everything Intel-specific is installed from pinned packages, with the versions set in build-config.env:
| Component | Where it comes from | Pin |
|---|---|---|
| oneAPI DPC++/C++ compiler (builder) | Intel's oneAPI apt repository | ONEAPI_APT_VERSION (2026.1.1-325) |
SYCL runtime: libsycl, the Unified Runtime loader and its Level Zero adapters, the compiler's maths and support libraries, UMF (libumf.so.1) and hwloc (image, /usr/local/lib/intel) | copied from the builder's compiler installation, every compiler file listed in its credist.txt (tools/rc1-tester/image/sycl-runtime.json) | ONEAPI_APT_VERSION |
| GPU compute runtime: Level Zero GPU driver, IGC, gmmlib | the intel/compute-runtime GitHub release | INTEL_NEO_VERSION (26.35.39758.10) |
Level Zero loader (libze_loader.so.1) | the oneapi-src/level-zero GitHub release | LEVEL_ZERO_VERSION |
SYCL reaches the GPU through Level Zero only: the compute runtime's OpenCL ICD and offline compiler are removed again after installation, as in the Intel GPU tester image, so ONEAPI_DEVICE_SELECTOR=opencl:* finds no device.
The GPU compute runtime is the part the host does not provide: the host supplies only the kernel driver (i915 or xe) and the device node.
Run it¶
Pass the render node and the host's render group by numeric ID, as for ROCm:
# The GPU's PCI address; list them with: ls -l /dev/dri/by-path/
render=$(readlink -f /dev/dri/by-path/pci-0000:03:00.0-render)
docker run --rm \
--device "$render" \
--group-add "$(getent group render | cut -d: -f3)" \
-v /path/to/videos:/data:ro \
ghcr.io/vmafx/vmafx:$tag-oneapi2026 \
--backend sycl \
--reference /data/ref.yuv --distorted /data/dis.yuv \
--width 576 --height 324 --pixel_format 420 --bitdepth 8 \
--model path=/usr/local/share/vmafx/model/vmaf_v0.6.1.json \
--output /dev/stdout
Requires: i915 or xe kernel module loaded and /dev/dri/renderD<N> accessible. With more than one Intel GPU, pick one with ONEAPI_DEVICE_SELECTOR, for example -e ONEAPI_DEVICE_SELECTOR=level_zero:0.
Windows (WSL 2)¶
On Windows, Docker Desktop's WSL 2 backend exposes the GPUs through /dev/dxg instead of a render node, and the GPU driver's user-space half lives in the host's /usr/lib/wsl/lib, which the image's library path already names. Pass both:
docker run --rm \
--device /dev/dxg \
-v /usr/lib/wsl:/usr/lib/wsl:ro \
-e ONEAPI_DEVICE_SELECTOR=level_zero:0 \
-v /path/to/videos:/data:ro \
ghcr.io/vmafx/vmafx:$tag-oneapi2026 \
--backend sycl \
--reference /data/ref.yuv --distorted /data/dis.yuv \
--width 576 --height 324 --pixel_format 420 --bitdepth 8 \
--output /dev/stdout
Note
vmaf --version loads only the libraries vmaf links directly. It does not load the oneAPI Unified Runtime adapters, which SYCL opens with dlopen() when it looks for a device. The image build and the publication smoke test check the adapters with ldd; a forced --backend sycl score is the only check that exercises the device.
MCP server variant¶
The -server tag starts the Python vmaf-mcp JSON-RPC server on port 8080 (entry point /venv/bin/vmaf-mcp --transport http). The Go server vmafx-mcp, which ADR-1229 made the MCP server in the dev container, is not in this image.
docker run --rm -p 8080:8080 \
-e VMAFX_MCP_HTTP_TOKEN='replace-with-a-secret' \
ghcr.io/vmafx/vmafx:vX.Y.Z-server
The image explicitly binds 0.0.0.0 so its published port is reachable; the HTTP transport otherwise defaults to loopback. Authentication remains fail-closed. Include the configured bearer token in health, metrics, and score requests. For a local-only disposable smoke, VMAFX_MCP_HTTP_NO_AUTH=1 is the explicit opt-out.
To override the port or run the stdio transport:
docker run --rm -p 8080:8080 \
-e VMAFX_MCP_HTTP_TOKEN='replace-with-a-secret' \
ghcr.io/vmafx/vmafx:vX.Y.Z-server \
--transport http --port 8080
docker run --rm -i \
--entrypoint /venv/bin/vmaf-mcp \
ghcr.io/vmafx/vmafx:vX.Y.Z-server \
--transport stdio
For the full vmaf-mcp environment variable reference see docs/mcp/.
Environment variables¶
| Variable | Default | Description |
|---|---|---|
VMAF_MODEL_PATH | /usr/local/share/vmafx/model | Directory searched for .json model files |
LD_LIBRARY_PATH | /usr/local/lib | Path containing libvmaf.so |
VMAF_BINARY | /usr/local/bin/vmaf | (server only) vmaf binary path for vmaf-mcp |
VMAFX_MCP_HTTP_BIND | 0.0.0.0 in the server image | HTTP bind address; host installs default to 127.0.0.1 |
VMAFX_MCP_HTTP_TOKEN | unset (fail closed) | Bearer token required by HTTP requests |
Verifying image provenance¶
Every image is signed via Sigstore keyless cosign and carries a CycloneDX SBOM attestation. Verify before deploying in a security-sensitive context:
tag=vX.Y.Z
# The signing identity is the workflow at the ref it ran on: refs/tags/$tag for
# a normal publish, refs/heads/master for a recovered image (every
# v1.0.0-rc.1 image; see release.md). Pin the one that applies.
identity="https://github.com/VMAFx/vmafx/.github/workflows/docker-publish-production.yml@refs/heads/master"
# Verify the cosign signature
cosign verify \
--certificate-identity "$identity" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/vmafx/vmafx:$tag
# Verify and print the SBOM attestation
cosign verify-attestation \
--certificate-identity "$identity" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--type cyclonedx \
ghcr.io/vmafx/vmafx:$tag \
| jq '.payload | @base64d | fromjson'
The CPU and server images also carry an SPDX SBOM of each platform image, attested with GitHub's attestation store (ADR-1513):
gh attestation verify oci://ghcr.io/vmafx/vmafx:$tag --repo VMAFx/vmafx \
--predicate-type https://spdx.dev/Document/v2.3
Licences and corresponding source¶
Every published target writes its notices into the image and cannot be built without passing the licence check (ADR-1513, the rules of ADR-1503; GPU images ADR-1517):
| Path or tag | What it holds |
|---|---|
/usr/local/share/vmafx/licenses/THIRD_PARTY_NOTICES.txt | every component of the image: VMAFx's compiled files with their licences and copyright lines, the models, CPython and every Python package (server), every Debian package with its source package |
/usr/local/share/vmafx/licenses/texts/ | the licence texts the notices name |
/usr/local/share/vmafx/licenses/vmafx-compiled-sources.json | the licence of every repository file the build compiled |
/usr/local/share/vmafx/licence-check.json | the receipt of the licence check |
ghcr.io/vmafx/vmafx:<tag>-source, <tag>-server-source, <tag>-cuda13-source, <tag>-rocm10-source, <tag>-oneapi2026-source | the corresponding source of the copyleft parts: Debian source packages of every installed package at the installed version, (server) the GCC source RPMs of the runtimes grafted into the numpy and scipy wheels, and (ROCm) the elfutils and numactl archives and the TheRock tree that built the LGPL libraries of the ROCm runtime; SOURCES.txt is the index |
How the gate works, per stage of docker/Dockerfile.production:
builderrunslicensing.py scan-build, which readsninja -t depsand the SPDX headers (orREUSE.toml) of every compiled repository file.licence-textsdownloads the recorded texts that are not in the repository (CPython'sDoc/license.rst, the pinnedfetched_texts), each by SHA-256.cli-notices(on a copy of the distroless tree, which has no interpreter) andserver-assembledwrite the notices withlicensing.py notices.cli-licence-check/server-licence-checkrunlicensing.py checkon the finished tree: a file no component oftools/rc1-tester/image/licensing.jsonclaims, a Debian package without its copyright file, a dist-info without a licence file, a copyleft wheel graft without recorded source, or a missing text fails the build.cliandservercopy the check's receipt, so they cannot be built without it.cli-source-export/server-source-exportfetch the corresponding source (licensing.py sources,fetch-sources); the release workflow pushes them as the-sourcetags through.github/actions/image-licence-artifacts.
A base-image or lock bump that brings a new package, wheel library or licence fails the release build until licensing.json records it. Run the check locally the same way the release does:
docker buildx build --target cli -f docker/Dockerfile.production -t vmafx:test-cli .
docker buildx build --target cli-source-export -f docker/Dockerfile.production \
--output type=local,dest=./cli-source .
GPU images¶
docker/Dockerfile.production-gpu follows the same pattern per variant (ADR-1517): builder-<variant> runs scan-build and stages the vendor files the image ships into /stage (prepare_build.py rocm-runtime / intel-runtime with the tester images' hip-runtime.json / sycl-runtime.json; for CUDA only the EULA text and the nv-codec-headers notices); <variant>-notices writes the notices on a copy of the assembled tree; <variant>-licence-check runs the check (artifact kinds production-cuda-image, production-rocm-image, production-oneapi-image) and final-<variant> copies its receipt; <variant>-source-export holds the source, published as <tag>-<variant>-source. The variants are cuda13, rocm10 and oneapi2026. The CUDA build also fails when a binary links an NVIDIA library or an NVIDIA file is in the image. The three records take the vendor components of the tester records by reference, so a vendor runtime is recorded once for both images.
Go service and node images¶
docker/Dockerfile.operator, Dockerfile.go-server and docker/Dockerfile.node (node-cpu) follow the same pattern (ADR-1514): the go-builder stage runs licensing.py scan-go (the licences of our own Go files the program compiles) and licensing.py go-licences, which reads the module list from the binary's build information and copies every module's LICENSE*, COPYING*, NOTICE* and PATENTS* files into /usr/local/share/vmafx/licenses/go/. The licence check fails on a module without a text or with a licence it cannot classify (go_module_licences in licensing.json records exceptions, such as a nested module that shares its repository's LICENSE). The source-export / node-source-export stages hold the module zips of every copyleft module, checked against the binary's h1: sums, and the Debian sources of the base.
The node image adds:
- FFmpeg built with
--enable-gpl --enable-version3(never--enable-nonfree), its licence files in/usr/local/share/vmafx/ffmpeg/, and in the source image the patched tree exactly as compiled withCONFIGURE.txtand the patch series; - the libraries copied out of Debian packages for FFmpeg, recorded by
scripts/ci/record-copied-debian-libs.shin/usr/local/share/vmafx/copied-packages/packages.listwith each package's copyright file (the source image holds their Debian sources); - for rclone's mount mode, the setuid
fusermount3(Debianfuse3, GPL-2.0) and the util-linuxmountandumountit runs, with their libraries at their Debian paths, recorded the same way in/usr/local/share/vmafx/fuse-tools/packages.list(ADR-1593); - rclone built from its release's module source at
RCLONE_VERSION(build-config.env), so the source image can hold the exact source of it and of every module it links (it links an LGPL-3.0 module).
Images published before these rules¶
The images of 1.0.0-rc.1 and rc.2 were published without notices or source (ADR-1578). The images that stay are listed under keep in tools/rc1-tester/image/published-rc/artifacts.json, each with its digest and licence record (published-rc-* in licensing.json). The manual workflow .github/workflows/published-rc-licence-companions.yml completes them:
- It refuses an image whose tag no longer names the recorded digest.
- It unpacks every platform of that digest (
docker export) and writes its notices withlicensing.py notices. The licence scan of the release tag's build is recorded inpublished-rc/scans/<release>/<build>.json, so the workflow compiles nothing. - It fetches the source of every installed package at its installed version. Debian packages come from the archive or snapshot.debian.org, Ubuntu packages from Launchpad. It also fetches the recorded archives of the grafted GCC runtimes and the copyleft Go modules.
- With
publishset, it pushes the sources as<tag>-sourcethrough.github/actions/image-licence-artifacts, which also attests an SPDX SBOM on the published digest. It attaches the notices to the release page and writes the release page's licence section.
Without publish, the workflow keeps the notices and source lists as a workflow artifact, for review. Run a step locally:
python3 scripts/release/published_rc_companion.py export --release v1.0.0-rc.2 --artifact operator --work /tmp/op
python3 scripts/release/published_rc_companion.py licence --release v1.0.0-rc.2 --artifact operator \
--work /tmp/op --source-tree <checkout of v1.0.0-rc.2>
Regenerating a scan builds the tag's configuration and needs its toolchain (nvcc for cuda, icx / icpx for sycl, go for the Go images): python3 scripts/release/published_rc_companion.py scan --release v1.0.0-rc.2 --build cuda.
Building locally¶
# CPU CLI (default)
docker buildx build \
--platform linux/amd64 \
--target cli \
-f docker/Dockerfile.production \
-t vmafx:test-cli \
.
# Server
docker buildx build \
--platform linux/amd64 \
--target server \
-f docker/Dockerfile.production \
-t vmafx:test-server \
.
# GPU variant (CUDA example), and its corresponding source
docker buildx build \
--platform linux/amd64 \
--target final-cuda13 \
-f docker/Dockerfile.production-gpu \
-t vmafx:test-cuda13 \
.
docker buildx build --target cuda13-source-export -f docker/Dockerfile.production-gpu \
--output type=local,dest=./cuda13-source .
# oneAPI variant. Its build looks up the Intel compute-runtime and Level Zero
# releases through the GitHub API; the optional secret lifts the anonymous rate
# limit. `final-oneapi2025` still names the same stage.
GITHUB_TOKEN=$(gh auth token) docker buildx build \
--platform linux/amd64 \
--target final-oneapi2026 \
--secret id=github_token,env=GITHUB_TOKEN \
-f docker/Dockerfile.production-gpu \
-t vmafx:test-oneapi2026 \
.
Architecture notes¶
Both Dockerfiles use a multi-stage build:
- CPU builder (
debian:13-slim): compiles libvmaf + vmaf CLI with Meson/Ninja as a stripped release build. - Python dependency builder (
python:3.14-slim, Debian 13): installsvmaf-mcpandvmaf-tuneinto/venv. - CPU CLI runtime (
gcr.io/distroless/cc-debian13:nonroot): carries only the compiled binary, shared libraries, and model files. - Server runtime (the same pinned
python:3.14-slimimage): provides the interpreter to which/venv/bin/pythonlinks. It runs as UID/GID 65532. - GPU builders and runtimes:
debian:13-slimfor every builder and runtime (ADR-1517); the runtimes carry only the vendor filesvmafloads.
| Variant | Builder toolchain | Vendor files in the image |
|---|---|---|
| CUDA 13.4.2 | nvcc from NVIDIA's debian13 repository at exact versions (scripts/ci/install-cuda-toolkit.sh --mode=builder) | None; the host driver provides libcuda.so.1 |
| ROCm 10.1.0 | /opt/rocm streamed out of AMD's pinned rocm/dev-ubuntu-26.04:10.1.0-full (scripts/ci/install-rocm-from-image.sh) | The HIP runtime files of tools/rc1-tester/image/hip-runtime.json |
| Intel oneAPI 2026.1 | oneAPI compiler at one exact apt build (ADR-1368) | The SYCL runtime files of tools/rc1-tester/image/sycl-runtime.json, the pinned Intel GPU compute runtime and Level Zero loader |
Every base-image reference is digest-pinned.
Release publishing and smoke checks¶
Publishing a GitHub release drives the two Docker workflows through the release.published event. Each workflow checks out github.event.release.tag_name and uses that same value for every image tag, so a release cannot accidentally publish a branch tip under a release tag.
After each GPU image is signed and receives its SBOM and provenance, the workflow verifies the digest-pinned signature before pulling the image and runs vmaf --version, which needs no accelerator hardware. That proves only that the libraries vmaf links directly are present. Runtime plugins opened with dlopen() are not loaded until a backend initialises, so for the oneAPI image the smoke also runs ldd on the Unified Runtime adapters. Neither check exercises a GPU; run a forced-backend score from GPU variants on the target hardware for that.
See ADR-0698 for the full rationale, alternatives considered, and tag matrix design decisions.
History¶
-
GPU images before 1.0.0-rc.3. Up to v1.0.0-rc.2 the ROCm image was AMD's whole
rocm/devimage (about 29 GB, with compilers, a GPL debugger and a profiler library whose licence forbids redistribution), the CUDA image an Ubuntu 26.04 base withlibcudartthat nothing loaded, and the oneAPI image Intel's full runtime set; none carried notices or published source (Research-2140). Since ADR-1517 they are Debian 13 images with only the vendor filesvmafloads. -
oneAPI compute runtime. Releases up to v1.0.0-rc.2 shipped the compute runtime of Intel's
oneapi-runtime:2025.3.1image (version 25.18). On an Arc B580 it crashed every--backend syclrun with a segmentation fault (exit code 139) right after device selection, while an Arc A380 and a UHD 770 worked. The image now carries the same compute runtime as the development container. libumf.so.1missing in v1.0.0-rc.1. Thev1.0.0-rc.1oneAPI image passedvmaf --versionwhile every Unified Runtime adapter failed to load for want oflibumf.so.1: SYCL reported "No device of requested type available" and--backend syclexited with code100. The image build and the publication smoke test now check the adapters withldd.