Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
Hibernation permanently refused: setup writes an empty resume= and never refreshes a stale resume_offset=
Reported by developercrocodiles · filed Oct 6, 2026 · open at source
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. So far: matches no known issue — decided by arbitration; partly in the audited area (menu) — decided by arbitration. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.
Original report
Hibernation permanently refused: omarchy-hibernation-setup writes an empty resume= and never refreshes a stale resume_offset=
Omarchy version: 4.0.4-1 (stable)
Kernel: 7.2.5-3-omarchy
systemd: 261.2-1-arch
Bootloader: Limine 12.8.0 (UKI)
Install media / machine: generic x86_64 installer, AMD A10-8700P, 7.2 GiB RAM, single btrfs / on LUKS (/dev/mapper/root), swapfile hibernation
Scope: this does not happen on a fresh install
A fresh install is unaffected. I only reproduced this after omarchy setup factory reset. The
reset path is omarchy-system-factory-reset, which clones the @factory snapshot, re-keys LUKS,
destroys and recreates the hibernation swapfile (/swap is a nested subvolume, and btrfs
snapshots don't recurse into it, so the factory root carries only an empty /swap directory),
restores the snapshot, and hands the machine to first-boot setup.
That reset is what turns both defects into a permanently broken hibernation setup — see
"Factory reset already works around half of this" below.
Summary
omarchy-hibernation-setup can leave /etc/limine-entry-tool.d/resume.conf with an empty `resume=` and/or a stale `resume_offset=`, and it never re-validates an existing file on later runs. systemd-logind then refuses every hibernation attempt with a misleading error, and there is no warning from the setup script.
On my machine:
KERNEL_CMDLINE[default]+=" resume= resume_offset=4838916"resume= is empty, and resume_offset=4838916 is not even page-aligned — it is not the current swapfile offset (btrfs inspect-internal map-swapfile -r /swap/swapfile → 4203776).
Timeline on my machine
10:30:00 /etc/limine-entry-tool.d/resume.conf written — "resume= resume_offset=4838916"
10:45:25 btrfs snapshot #1 auto-created, capturing that broken cmdline
11:46:42 /swap subvolume + /swap/swapfile created (fresh offset 4203776)The resume.conf timestamp is from the factory-reset run, not from the original install
(the installed @factory snapshot is dated Sep 15). So the empty resume= was written by the
reset's rebuild_next_boot → chroot … omarchy-hibernation-setup --force --no-rebuild, and a
later setup run recreated the swapfile without refreshing the drop-in.
Why the empty `resume=` is reset-specific (inference, not verified by reproduction — I could
not reproduce it in isolation): rebuild_next_boot runs the setup script via chroot with the
host's /proc, /sys, /dev rbind-mounted over the staged root. RESUME_DEVICE comes from
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')findmnt resolves -T against /proc/self/mountinfo, which inside that chroot is the host's
mount table — it has no mountpoint for the staged root, so the lookup yields nothing andRESUME_DEVICE is empty. On a normal run the path is on the live / mount and resolves to/dev/mapper/root fine. The [[ -n $RESUME_OFFSET ]] guard checks only the offset, so the empty
device sails through.
Symptoms
- Selecting hibernate (menu,
loginctl hibernate, Hyprland keybind) fails with:
Call to Hibernate failed: Invalid resume config: resume= is not populated yet resume_offset= isbusctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanHibernatereturnss "na", andCanSuspendThenHibernatereturnss "na".
omarchy-hibernation-setupreports "Hibernation is already set up" and exits 0 — no re-check, no warning.
The setup script checks exactly one thing here (the "already set up" branch):
# /usr/bin/omarchy-hibernation-setup:63
if [[ -f $MKINITCPIO_CONF ]] && grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
# Fix empty resume_offset if btrfs map-swapfile failed during initial setup
if [[ -f $RESUME_DROP_IN ]] && grep -q 'resume_offset="$' "$RESUME_DROP_IN" && [[ -f $SWAP_FILE ]]; thenAn empty `resume=` is not part of that check, and a non-empty but wrong resume_offset= is not part of it either.
Two distinct defects
A. resume= can be written empty, with no validation
# /usr/bin/omarchy-hibernation-setup:131
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
RESUME_OFFSET=$(sudo btrfs inspect-internal map-swapfile -r "$SWAP_FILE")
if [[ -n $RESUME_OFFSET ]]; then
echo "KERNEL_CMDLINE[default]+=\" resume=$RESUME_DEVICE resume_offset=$RESUME_OFFSET\"" | sudo tee "$RESUME_DROP_IN"
else
echo "Warning: Could not determine resume offset for $SWAP_FILE" >&2
fiOnly the offset is validated. If findmnt prints nothing (e.g. $SWAP_FILE does not exist yet at that point, or the command fails), the drop-in is still written with resume= empty, and setup exits 0. The initramfs then never learns where the hibernation image is, and logind's read_resume_config() (src/shared/hibernate-util.c) hits the "resume= not populated yet resume_offset= is" case on every subsequent boot, permanently.
B. Later runs never refresh the drop-in, so a recreated swapfile leaves a stale offset
# /usr/bin/omarchy-hibernation-setup:131
if [[ ! -f $RESUME_DROP_IN ]]; thenOnce the file exists it is never rewritten. In my case the swapfile was created (or recreated) by a later run:
-rw------- 1 root root 7754670080 2026-10-06 11:46:42 /swap/swapfilebut /etc/limine-entry-tool.d/resume.conf still carries the offset from the earlier swapfile. The mismatch is fatal in a second way: find_suitable_hibernation_device_full() matches /sys/power/resume + /sys/power/resume_offset against the swap entries from /proc/swaps, so a stale offset yields SLEEP_RESUME_DEVICE_MISSING — a different logind error for the same underlying misconfiguration.
Factory reset already works around half of this
omarchy-system-factory-reset (rebuild_next_boot) contains a workaround that confirms defect B
is real and known:
# Btrfs snapshots do not recurse into nested subvolumes, so the factory
# root carries only an empty /swap directory where the hibernation swapfile
# lived. Recreate it and refresh the resume offset before the UKI build
# bakes the cmdline; …
# The resume-offset drop-in especially: hibernation-setup only recomputes the
# physical offset when it is absent, so a surviving one bakes the old swapfile's
# offset into the rebuilt UKI and breaks resume.
if [[ ! -f $next/swap/swapfile ]]; then
rm -f "$next/etc/mkinitcpio.conf.d/omarchy_resume.conf" \
"$next/etc/limine-entry-tool.d/resume.conf"
fi
chroot "$next" … omarchy-hibernation-setup --force --no-rebuildSo the reset path has to delete the drop-in to coax omarchy-hibernation-setup into recomputing
the offset. That is a workaround for the wrong layer: the setup script should re-derive and validateresume=/resume_offset= on every run, and the rm -f above should be able to go away.
Note that this workaround is gated on grep -q "/swap/swapfile" "$next/etc/fstab" and on[[ ! -f $next/swap/swapfile ]]. When the reset runs a setup pass that recreates the swapfile, the
drop-in the script wrote in that same pass is correct at the time — but any subsequent run that
recreates the swapfile again silently leaves the previous drop-in in place, which is exactly the
stale-offset state reported here.
Steps to reproduce
Scope: reproduce after a factory reset, not on a fresh install.
- Boot an Omarchy Quattro install with swapfile hibernation, then run
omarchy setup factory reset
and complete first-boot setup.
2. Observe the drop-in the reset wrote:
cat /etc/limine-entry-tool.d/resume.conf
# KERNEL_CMDLINE[default]+=" resume= resume_offset=…"- Try to hibernate → "Invalid resume config: resume= is not populated yet resume_offset= is".
For defect A in isolation, the mechanism to aim at is the chroot + rbind-mounted /proc inrebuild_next_boot, which is why findmnt -no SOURCE -T comes back empty there.
For the stale-offset variant, run setup again after the swapfile has been recreated (newbtrfs inspect-internal map-swapfile value) and observe that resume.conf is not updated.
Re-running omarchy-hibernation-setup prints "Hibernation is already set up" and exits 0.
Diagnosis / bisect (observed on my machine)
$ cat /proc/cmdline
... resume= resume_offset=4838916 ...
$ cat /sys/power/resume
0:0
$ cat /sys/power/resume_offset
4838916
$ btrfs inspect-internal map-swapfile -r /swap/swapfile
4203776Applying the correct values at runtime flips the verdict immediately:
# /sys/power/resume only (offset left stale):
$ echo /dev/mapper/root > /sys/power/resume
$ busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanHibernate
s "na" # offset mismatch -> SLEEP_RESUME_DEVICE_MISSING
# both values corrected:
$ echo 4203776 > /sys/power/resume_offset
$ busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanHibernate
s "yes"
$ busctl call … Manager CanSuspendThenHibernate
s "yes"Which confirms both the empty resume= and the stale resume_offset= independently break hibernation.
Suggested fix
In /usr/bin/omarchy-hibernation-setup:
- Treat an unresolvable resume device as fatal for setup (or skip writing the drop-in and report it), instead of writing
resume=empty:
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
if [[ -z $RESUME_DEVICE ]]; then
echo "Warning: Could not determine resume device for $SWAP_FILE" >&2
exit 1
fi- Extend the "already set up" branch to detect and repair both halves of a bad drop-in, not just an empty
resume_offset=— an emptyresume=, or aresume_offset=that no longer matchesbtrfs inspect-internal map-swapfile -r "$SWAP_FILE".
- Drop the
[[ ! -f $RESUME_DROP_IN ]]one-shot guard (or make it idempotent): re-deriveresume=/resume_offset=from the live swapfile on every run so a recreated swapfile cannot leave the bootloader permanently misconfigured.
A cheap safety net for #3: also verify /sys/power/resume is set on a machine where the kernel consumed the cmdline, and warn loudly if not.
With #3 in place, omarchy-system-factory-reset's rm -f … resume.conf workaround (quoted above)
becomes unnecessary and can be dropped, so the reset path stops having to know about this.
Because the reset path runs the setup script inside a chroot where findmnt -T cannot resolve the
staged root, #1 should be paired with a fallback that does not depend on the mount table — e.g.
derive the device from /dev/mapper/root the way findmnt -no SOURCE / would, or from theroot=/cryptdevice= kernel parameters — otherwise fix #1 alone would turn the reset into a hard
failure instead of silently writing resume=.
Workaround I used
OFFSET=$(sudo btrfs inspect-internal map-swapfile -r /swap/swapfile)
echo "KERNEL_CMDLINE[default]+=\" resume=$(findmnt -no SOURCE -T /swap/swapfile | sed 's/\[.*\]//') resume_offset=$OFFSET\"" \
| sudo tee /etc/limine-entry-tool.d/resume.conf
sudo limine-mkinitcpioNote: /boot/limine.conf snapshot entries carry a per-snapshot cmdline copied from `/proc/cmdline` at snapshot creation time, so entries created before the fix keep the broken values and need the same correction.
View raw text
# Hibernation permanently refused: `omarchy-hibernation-setup` writes an empty `resume=` and never refreshes a stale `resume_offset=`
**Omarchy version:** 4.0.4-1 (stable)
**Kernel:** 7.2.5-3-omarchy
**systemd:** 261.2-1-arch
**Bootloader:** Limine 12.8.0 (UKI)
**Install media / machine:** generic x86_64 installer, AMD A10-8700P, 7.2 GiB RAM, single btrfs `/` on LUKS (`/dev/mapper/root`), swapfile hibernation
## Scope: this does not happen on a fresh install
**A fresh install is unaffected.** I only reproduced this after `omarchy setup factory reset`. The
reset path is `omarchy-system-factory-reset`, which clones the `@factory` snapshot, **re-keys LUKS**,
**destroys and recreates the hibernation swapfile** (`/swap` is a nested subvolume, and btrfs
snapshots don't recurse into it, so the factory root carries only an empty `/swap` directory),
restores the snapshot, and hands the machine to first-boot setup.
That reset is what turns both defects into a permanently broken hibernation setup — see
"Factory reset already works around half of this" below.
## Summary
`omarchy-hibernation-setup` can leave `/etc/limine-entry-tool.d/resume.conf` with an **empty `resume=`** and/or a **stale `resume_offset=`**, and it never re-validates an existing file on later runs. systemd-logind then refuses every hibernation attempt with a misleading error, and there is no warning from the setup script.
On my machine:
```
KERNEL_CMDLINE[default]+=" resume= resume_offset=4838916"
```
`resume=` is empty, and `resume_offset=4838916` is not even page-aligned — it is not the current swapfile offset (`btrfs inspect-internal map-swapfile -r /swap/swapfile` → `4203776`).
### Timeline on my machine
```
10:30:00 /etc/limine-entry-tool.d/resume.conf written — "resume= resume_offset=4838916"
10:45:25 btrfs snapshot #1 auto-created, capturing that broken cmdline
11:46:42 /swap subvolume + /swap/swapfile created (fresh offset 4203776)
```
The `resume.conf` timestamp is from the factory-reset run, not from the original install
(the installed `@factory` snapshot is dated Sep 15). So the empty `resume=` was written by the
reset's `rebuild_next_boot` → `chroot … omarchy-hibernation-setup --force --no-rebuild`, and a
later setup run recreated the swapfile without refreshing the drop-in.
**Why the empty `resume=` is reset-specific** (inference, not verified by reproduction — I could
not reproduce it in isolation): `rebuild_next_boot` runs the setup script via `chroot` with the
host's `/proc`, `/sys`, `/dev` rbind-mounted over the staged root. `RESUME_DEVICE` comes from
```bash
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
```
`findmnt` resolves `-T` against `/proc/self/mountinfo`, which inside that chroot is the **host's**
mount table — it has no mountpoint for the staged root, so the lookup yields nothing and
`RESUME_DEVICE` is empty. On a normal run the path is on the live `/` mount and resolves to
`/dev/mapper/root` fine. The `[[ -n $RESUME_OFFSET ]]` guard checks only the offset, so the empty
device sails through.
## Symptoms
1. Selecting hibernate (menu, `loginctl hibernate`, Hyprland keybind) fails with:
```
Call to Hibernate failed: Invalid resume config: resume= is not populated yet resume_offset= is
```
2. `busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanHibernate` returns `s "na"`, and `CanSuspendThenHibernate` returns `s "na"`.
3. `omarchy-hibernation-setup` reports **"Hibernation is already set up"** and exits 0 — no re-check, no warning.
The setup script checks exactly one thing here (the "already set up" branch):
```bash
# /usr/bin/omarchy-hibernation-setup:63
if [[ -f $MKINITCPIO_CONF ]] && grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
# Fix empty resume_offset if btrfs map-swapfile failed during initial setup
if [[ -f $RESUME_DROP_IN ]] && grep -q 'resume_offset="$' "$RESUME_DROP_IN" && [[ -f $SWAP_FILE ]]; then
```
An **empty `resume=`** is not part of that check, and a **non-empty but wrong** `resume_offset=` is not part of it either.
## Two distinct defects
### A. `resume=` can be written empty, with no validation
```bash
# /usr/bin/omarchy-hibernation-setup:131
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
RESUME_OFFSET=$(sudo btrfs inspect-internal map-swapfile -r "$SWAP_FILE")
if [[ -n $RESUME_OFFSET ]]; then
echo "KERNEL_CMDLINE[default]+=\" resume=$RESUME_DEVICE resume_offset=$RESUME_OFFSET\"" | sudo tee "$RESUME_DROP_IN"
else
echo "Warning: Could not determine resume offset for $SWAP_FILE" >&2
fi
```
Only the **offset** is validated. If `findmnt` prints nothing (e.g. `$SWAP_FILE` does not exist yet at that point, or the command fails), the drop-in is still written with `resume=` empty, and setup exits 0. The initramfs then never learns where the hibernation image is, and logind's `read_resume_config()` (`src/shared/hibernate-util.c`) hits the "resume= not populated yet resume_offset= is" case on every subsequent boot, permanently.
### B. Later runs never refresh the drop-in, so a recreated swapfile leaves a stale offset
```bash
# /usr/bin/omarchy-hibernation-setup:131
if [[ ! -f $RESUME_DROP_IN ]]; then
```
Once the file exists it is never rewritten. In my case the swapfile was created (or recreated) by a later run:
```
-rw------- 1 root root 7754670080 2026-10-06 11:46:42 /swap/swapfile
```
but `/etc/limine-entry-tool.d/resume.conf` still carries the offset from the earlier swapfile. The mismatch is fatal in a second way: `find_suitable_hibernation_device_full()` matches `/sys/power/resume` + `/sys/power/resume_offset` against the swap entries from `/proc/swaps`, so a stale offset yields `SLEEP_RESUME_DEVICE_MISSING` — a *different* logind error for the same underlying misconfiguration.
### Factory reset already works around half of this
`omarchy-system-factory-reset` (`rebuild_next_boot`) contains a workaround that confirms defect B
is real and known:
```bash
# Btrfs snapshots do not recurse into nested subvolumes, so the factory
# root carries only an empty /swap directory where the hibernation swapfile
# lived. Recreate it and refresh the resume offset before the UKI build
# bakes the cmdline; …
# The resume-offset drop-in especially: hibernation-setup only recomputes the
# physical offset when it is absent, so a surviving one bakes the old swapfile's
# offset into the rebuilt UKI and breaks resume.
if [[ ! -f $next/swap/swapfile ]]; then
rm -f "$next/etc/mkinitcpio.conf.d/omarchy_resume.conf" \
"$next/etc/limine-entry-tool.d/resume.conf"
fi
chroot "$next" … omarchy-hibernation-setup --force --no-rebuild
```
So the reset path has to *delete* the drop-in to coax `omarchy-hibernation-setup` into recomputing
the offset. That is a workaround for the wrong layer: the setup script should re-derive and validate
`resume=`/`resume_offset=` on every run, and the `rm -f` above should be able to go away.
Note that this workaround is gated on `grep -q "/swap/swapfile" "$next/etc/fstab"` and on
`[[ ! -f $next/swap/swapfile ]]`. When the reset runs a setup pass that *recreates* the swapfile, the
drop-in the script wrote in that same pass is correct at the time — but any **subsequent** run that
recreates the swapfile again silently leaves the previous drop-in in place, which is exactly the
stale-offset state reported here.
## Steps to reproduce
Scope: reproduce after a factory reset, not on a fresh install.
1. Boot an Omarchy Quattro install with swapfile hibernation, then run `omarchy setup factory reset`
and complete first-boot setup.
2. Observe the drop-in the reset wrote:
```bash
cat /etc/limine-entry-tool.d/resume.conf
# KERNEL_CMDLINE[default]+=" resume= resume_offset=…"
```
3. Try to hibernate → *"Invalid resume config: resume= is not populated yet resume_offset= is"*.
For defect A in isolation, the mechanism to aim at is the `chroot` + rbind-mounted `/proc` in
`rebuild_next_boot`, which is why `findmnt -no SOURCE -T` comes back empty there.
For the stale-offset variant, run setup again after the swapfile has been recreated (new
`btrfs inspect-internal map-swapfile` value) and observe that `resume.conf` is not updated.
Re-running `omarchy-hibernation-setup` prints *"Hibernation is already set up"* and exits 0.
## Diagnosis / bisect (observed on my machine)
```
$ cat /proc/cmdline
... resume= resume_offset=4838916 ...
$ cat /sys/power/resume
0:0
$ cat /sys/power/resume_offset
4838916
$ btrfs inspect-internal map-swapfile -r /swap/swapfile
4203776
```
Applying the correct values at runtime flips the verdict immediately:
```
# /sys/power/resume only (offset left stale):
$ echo /dev/mapper/root > /sys/power/resume
$ busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanHibernate
s "na" # offset mismatch -> SLEEP_RESUME_DEVICE_MISSING
# both values corrected:
$ echo 4203776 > /sys/power/resume_offset
$ busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanHibernate
s "yes"
$ busctl call … Manager CanSuspendThenHibernate
s "yes"
```
Which confirms both the empty `resume=` and the stale `resume_offset=` independently break hibernation.
## Suggested fix
In `/usr/bin/omarchy-hibernation-setup`:
1. Treat an unresolvable resume device as fatal for setup (or skip writing the drop-in and report it), instead of writing `resume=` empty:
```bash
RESUME_DEVICE=$(findmnt -no SOURCE -T "$SWAP_FILE" | sed 's/\[.*\]//')
if [[ -z $RESUME_DEVICE ]]; then
echo "Warning: Could not determine resume device for $SWAP_FILE" >&2
exit 1
fi
```
2. Extend the "already set up" branch to detect and repair *both* halves of a bad drop-in, not just an empty `resume_offset=` — an empty `resume=`, or a `resume_offset=` that no longer matches `btrfs inspect-internal map-swapfile -r "$SWAP_FILE"`.
3. Drop the `[[ ! -f $RESUME_DROP_IN ]]` one-shot guard (or make it idempotent): re-derive `resume=`/`resume_offset=` from the live swapfile on every run so a recreated swapfile cannot leave the bootloader permanently misconfigured.
A cheap safety net for #3: also verify `/sys/power/resume` is set on a machine where the kernel consumed the cmdline, and warn loudly if not.
With #3 in place, `omarchy-system-factory-reset`'s `rm -f … resume.conf` workaround (quoted above)
becomes unnecessary and can be dropped, so the reset path stops having to know about this.
Because the reset path runs the setup script inside a `chroot` where `findmnt -T` cannot resolve the
staged root, #1 should be paired with a fallback that does not depend on the mount table — e.g.
derive the device from `/dev/mapper/root` the way `findmnt -no SOURCE /` would, or from the
`root=`/`cryptdevice=` kernel parameters — otherwise fix #1 alone would turn the reset into a hard
failure instead of silently writing `resume=`.
## Workaround I used
```bash
OFFSET=$(sudo btrfs inspect-internal map-swapfile -r /swap/swapfile)
echo "KERNEL_CMDLINE[default]+=\" resume=$(findmnt -no SOURCE -T /swap/swapfile | sed 's/\[.*\]//') resume_offset=$OFFSET\"" \
| sudo tee /etc/limine-entry-tool.d/resume.conf
sudo limine-mkinitcpio
```
Note: `/boot/limine.conf` snapshot entries carry a **per-snapshot cmdline copied from `/proc/cmdline` at snapshot creation time**, so entries created before the fix keep the broken values and need the same correction.Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
Not linked to any known issue, other report or change yet.
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
- Decided by arbitration: matches no known issue
- Decided by arbitration: partly in the audited area (menu)
The outcome (valid, duplicate, not a bug, …) is not decided yet.