9487c3bef7
Per local/docs/REDBEAR-FIRST-CLASS-CITIZEN-POLICY.md (added in the previous commit), every redbear-* recipe is a first-class citizen of redbear-mini. Before this commit: 24 redbear-* recipes explicitly listed in config/redbear-mini.toml [packages]. 24 were missing (the 13 fully-orphaned recipes + 11 recipes that were only in redbear-full). After this commit: ALL 48 redbear-* recipes explicitly listed in config/redbear-mini.toml [packages]. config/redbear-full.toml inherits from redbear-mini.toml via the include chain, so all 48 reach the full ISO transitively (verified via grep of [packages] sections in both configs). The wiring also enables first-class building of: - 4 driver recipes (redbear-btusb, redbear-hid-core, redbear-input-headers, redbear-iwlwifi) - 5 firmware recipes (redbear-firmware + 4 named subsets) - 11 system services (scheme daemons, D-Bus daemons, login/greeter stack, IME, accessibility, keymapd) - 4 USB class drivers (acmd, ecmd, ftdi, usbaudiod) - 5 D-Bus daemons (sessiond, polkit, udisks, upower, notifications, statusnotifierwatcher) - 1 Wayland compositor (redbear-compositor) - 4 library-only recipes (hid-core, login-protocol, tui-theme, passwd) - 1 meta-package (redbear-meta) - 1 ufw prototype (redbear-ufw, with REDBEAR-UFW-STATUS.md explaining its intentionally-orphaned lifecycle) Also: redbear-input-headers added as a build dep of libinput. The recipe at recipes/libs/libinput/recipe.toml previously only depended on libevdev + libudev. The Linux input header definitions are needed by libinput's meson build (per AGENTS.md 'linux-input-headers' policy, redbear-input-headers is the canonical reference implementation). libevdev already declared redbear-input-headers as a dep; libinput now declares it explicitly too. Verified: 'for r in $(find local/recipes -maxdepth 3 -type d -name "redbear-*" -not -path "*/target/*"); do grep -q $r config/redbear-mini.toml; done' returns 48/48 ✓. sync-versions.sh --check passes (75 Cat 1 crates, 0 drift).
673 lines
14 KiB
TOML
673 lines
14 KiB
TOML
# Red Bear OS Mini Configuration
|
|
# Text-only ISO for console/recovery/install on bare metal.
|
|
#
|
|
# Build: make live CONFIG_NAME=redbear-mini
|
|
#
|
|
# Target contract:
|
|
# - text-login live/recovery/install surface
|
|
# - boot framebuffer for VT text consoles via vesad + fbcond
|
|
|
|
include = ["minimal.toml", "redbear-legacy-base.toml", "redbear-netctl.toml", "redbear-device-services.toml", "redbear-boot-stages.toml"]
|
|
|
|
[general]
|
|
filesystem_size = 512
|
|
|
|
[users.messagebus]
|
|
uid = 100
|
|
gid = 100
|
|
name = "messagebus"
|
|
home = "/nonexistent"
|
|
shell = "/usr/bin/zsh"
|
|
|
|
[packages]
|
|
# Red Bear OS branding and host utilities.
|
|
redbear-release = {}
|
|
redbear-hwutils = {}
|
|
redbear-quirks = {}
|
|
|
|
# Device driver infrastructure (driver-manager owns the boot-time PCI
|
|
# match/claim/spawn path; pcid-spawner is retired and removed)
|
|
redbear-driver-policy = {}
|
|
ehcid = {}
|
|
ohcid = {}
|
|
uhcid = {}
|
|
redbear-hid-core = {}
|
|
redbear-input-headers = {}
|
|
redbear-btusb = {}
|
|
redbear-iwlwifi = {}
|
|
redbear-firmware-iwlwifi = {}
|
|
|
|
# Redox-native netctl tooling.
|
|
redbear-netctl = {}
|
|
redbear-netctl-console = {}
|
|
redbear-netstat = {}
|
|
redbear-traceroute = {}
|
|
redbear-mtr = {}
|
|
redbear-nmap = {}
|
|
|
|
# Caching DNS daemon (loopback listener + scheme:dns). Wired as a service
|
|
# below; see [init] section. Provides positive + negative caching and an
|
|
# mDNS responder so the loopback resolver hits cache before upstream.
|
|
redbear-dnsd = {}
|
|
redbear-firmware = {}
|
|
redbear-firmware-amdgpu = {}
|
|
redbear-firmware-bluetooth = {}
|
|
redbear-firmware-intel = {}
|
|
firmware-loader = {}
|
|
redbear-wifictl = {}
|
|
redbear-btctl = {}
|
|
redbear-ufw = {}
|
|
|
|
# Diagnostics and shell-side utilities.
|
|
tlc = {}
|
|
#mc = {}
|
|
redbear-info = {}
|
|
redbear-passwd = {}
|
|
|
|
# brush: Rust shell, candidate default login shell (validated in-image before
|
|
# switching the [users.*] shell over from zsh).
|
|
brush = {}
|
|
|
|
# Keep package builder utility in live environment.
|
|
cub = {}
|
|
cpufreqd = {}
|
|
thermald = {}
|
|
redbear-power = {}
|
|
hwrngd = {}
|
|
redbear-acmd = {}
|
|
redbear-ftdi = {}
|
|
redbear-ecmd = {}
|
|
redbear-usbaudiod = {}
|
|
redbear-usb-hotplugd = {}
|
|
driver-params = {}
|
|
redbear-login-protocol = {}
|
|
redbear-tui-theme = {}
|
|
redbear-meta = {}
|
|
redbear-accessibility = {}
|
|
redbear-ime = {}
|
|
redbear-keymapd = {}
|
|
redbear-authd = {}
|
|
redbear-greeter = {}
|
|
redbear-session-launch = {}
|
|
redbear-compositor = {}
|
|
redbear-statusnotifierwatcher = {}
|
|
|
|
# ── PCI device database (critical for PCI driver matching) ──
|
|
pciids = {}
|
|
|
|
# ── Filesystem support ──
|
|
ext4d = {}
|
|
fatd = {}
|
|
redoxfs = {}
|
|
|
|
# ── System installer ──
|
|
installer = {}
|
|
|
|
# ── Input / device management ──
|
|
evdevd = {}
|
|
udev-shim = {}
|
|
|
|
# ── D-Bus IPC and session services ──
|
|
dbus = {}
|
|
redbear-sessiond = {}
|
|
redbear-dbus-services = {}
|
|
redbear-notifications = {}
|
|
redbear-upower = {}
|
|
redbear-udisks = {}
|
|
redbear-polkit = {}
|
|
|
|
# ── IOMMU DMA remapping ──
|
|
iommu = {}
|
|
|
|
# ── Standard CLI tools (from server profile) ──
|
|
bash = {}
|
|
bottom = {}
|
|
curl = {}
|
|
diffutils = {}
|
|
findutils = {}
|
|
uutils-tar = {}
|
|
bison = {}
|
|
flex = {}
|
|
meson = {}
|
|
ninja-build = {}
|
|
m4 = {}
|
|
#git = {} # suppressed: cascading rebuild; git not needed for boot/recovery
|
|
htop = {}
|
|
|
|
# ── Build / packaging utilities ──
|
|
# patchelf = {} # requires strtold which is missing in relibc
|
|
shared-mime-info = {}
|
|
|
|
# VT/getty/login chain: initfs starts inputd + vesad + fbcond in phase 1,
|
|
# then minimal.toml legacy 30_console runs inputd -A 2 + getty 2 + getty debug.
|
|
|
|
[[files]]
|
|
path = "/etc/netctl/active"
|
|
data = "wired-dhcp\n"
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/10_smolnetd.service"
|
|
data = """
|
|
[unit]
|
|
description = "Network stack (non-blocking on live-mini)"
|
|
requires_weak = [
|
|
"00_driver-manager.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "netstack"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/10_dhcpd.service"
|
|
data = """
|
|
[unit]
|
|
description = "DHCP client daemon (non-blocking on live-mini)"
|
|
requires_weak = [
|
|
"10_smolnetd.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "dhcpd"
|
|
args = ["-f"]
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/11_dnsd.service"
|
|
data = """
|
|
[unit]
|
|
description = "Caching DNS daemon (loopback listener + scheme:dns)"
|
|
requires_weak = [
|
|
"10_dhcpd.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "redbear-dnsd"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/issue"
|
|
data = """
|
|
########## Red Bear OS #########
|
|
# Login with the following: #
|
|
# `user` #
|
|
# `root`:`password` #
|
|
################################
|
|
"""
|
|
|
|
# motd is provided by the redbear-release recipe (generated from motd.in
|
|
# template with the current git-branch version). Do NOT add a static
|
|
# motd [[files]] override here — it creates a collision with recipe
|
|
# staging and goes stale when the version bumps.
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/20_audiod.service"
|
|
data = """
|
|
[unit]
|
|
description = "Audio multiplexer (non-blocking on live-mini)"
|
|
requires_weak = [
|
|
"00_base.target",
|
|
]
|
|
|
|
[service]
|
|
cmd = "audiod"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/02_usb_hotplug.service"
|
|
data = """
|
|
[unit]
|
|
description = "USB device hotplug daemon (auto-spawns class drivers)"
|
|
requires_weak = [
|
|
"00_base.target",
|
|
"00_driver-manager.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "redbear-usb-hotplugd"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/02_serial_probe.service"
|
|
data = """
|
|
[unit]
|
|
description = "Serial boot probe marker"
|
|
requires_weak = [
|
|
"00_base.target",
|
|
]
|
|
|
|
[service]
|
|
cmd = "echo"
|
|
args = ["RB_SERIAL_PROBE_OK"]
|
|
type = "oneshot"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_gpiod.service"
|
|
data = """
|
|
[unit]
|
|
description = "GPIO controller registry"
|
|
requires_weak = [
|
|
"00_base.target",
|
|
]
|
|
|
|
[service]
|
|
cmd = "gpiod"
|
|
type = { scheme = "gpio" }
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_i2cd.service"
|
|
data = """
|
|
[unit]
|
|
description = "I2C adapter registry"
|
|
requires_weak = [
|
|
"00_base.target",
|
|
]
|
|
|
|
[service]
|
|
cmd = "i2cd"
|
|
type = { scheme = "i2c" }
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_intel-lpss-i2cd.service"
|
|
data = """
|
|
[unit]
|
|
description = "Intel LPSS I2C controller (PCI + ACPI discovery, DesignWare engine)"
|
|
requires_weak = [
|
|
"00_i2cd.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "/usr/lib/drivers/intel-lpss-i2cd"
|
|
type = { scheme = "i2c-lpss" }
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_i2c-dw-acpi.service"
|
|
data = """
|
|
[unit]
|
|
description = "DesignWare ACPI I2C controller"
|
|
requires_weak = [
|
|
"00_i2cd.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "dw-acpi-i2cd"
|
|
type = { scheme = "dw-acpi-i2c" }
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_intel-gpiod.service"
|
|
data = """
|
|
[unit]
|
|
description = "Intel ACPI GPIO registrar"
|
|
requires_weak = [
|
|
"00_gpiod.service",
|
|
"00_i2cd.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "intel-gpiod"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_i2c-gpio-expanderd.service"
|
|
data = """
|
|
[unit]
|
|
description = "I2C GPIO expander companion bridge"
|
|
requires_weak = [
|
|
"00_i2cd.service",
|
|
"00_gpiod.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "i2c-gpio-expanderd"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_i2c-hidd.service"
|
|
data = """
|
|
[unit]
|
|
description = "ACPI I2C HID bring-up daemon"
|
|
requires_weak = [
|
|
"00_i2cd.service",
|
|
"00_intel-lpss-i2cd.service",
|
|
"00_i2c-dw-acpi.service",
|
|
"00_intel-gpiod.service",
|
|
"00_i2c-gpio-expanderd.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "i2c-hidd"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_ucsid.service"
|
|
data = """
|
|
[unit]
|
|
description = "USB-C UCSI topology detector"
|
|
requires_weak = [
|
|
"00_base.target",
|
|
"00_i2cd.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "ucsid"
|
|
type = { scheme = "ucsi" }
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/12_boot-late.target"
|
|
data = """
|
|
[unit]
|
|
description = "Late boot services target"
|
|
requires_weak = [
|
|
"00_base.target",
|
|
]
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/11_udev.service"
|
|
data = """
|
|
[unit]
|
|
description = "udev compatibility shim"
|
|
requires_weak = [
|
|
"12_boot-late.target",
|
|
"00_driver-manager.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "udev-shim"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/10_evdevd.service"
|
|
data = """
|
|
[unit]
|
|
description = "Evdev input daemon"
|
|
requires_weak = [
|
|
"12_boot-late.target",
|
|
"00_driver-manager.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "evdevd"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/11_wifictl.service"
|
|
data = """
|
|
[unit]
|
|
description = "Wi-Fi control daemon"
|
|
requires_weak = [
|
|
"12_boot-late.target",
|
|
"00_driver-manager.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "redbear-wifictl"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/12_dbus.service"
|
|
data = """
|
|
[unit]
|
|
description = "D-Bus system bus"
|
|
requires_weak = [
|
|
"12_boot-late.target",
|
|
]
|
|
|
|
[service]
|
|
cmd = "dbus-daemon"
|
|
args = ["--system", "--nopidfile", "--address=unix:path=/run/dbus/system_bus_socket"]
|
|
envs = { DBUS_SYSTEM_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket" }
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/13_seatd.service"
|
|
data = """
|
|
[unit]
|
|
description = "seatd seat management (no-op on live-mini)"
|
|
|
|
[service]
|
|
cmd = "echo"
|
|
args = ["seatd: skipped on live-mini"]
|
|
type = "oneshot"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/13_redbear-sessiond.service"
|
|
data = """
|
|
[unit]
|
|
description = "Red Bear session broker (org.freedesktop.login1)"
|
|
requires_weak = [
|
|
"12_dbus.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "redbear-sessiond"
|
|
envs = { DBUS_SYSTEM_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket" }
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/13_iommu.service"
|
|
data = """
|
|
[unit]
|
|
description = "IOMMU DMA remapping daemon"
|
|
requires_weak = [
|
|
"12_boot-late.target",
|
|
"00_driver-manager.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "/usr/bin/iommu"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/14_redbear-upower.service"
|
|
data = """
|
|
[unit]
|
|
description = "UPower D-Bus service (org.freedesktop.UPower)"
|
|
requires_weak = [
|
|
"12_dbus.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "redbear-upower"
|
|
envs = { DBUS_SYSTEM_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket" }
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/14_redbear-udisks.service"
|
|
data = """
|
|
[unit]
|
|
description = "UDisks2 D-Bus service (org.freedesktop.UDisks2)"
|
|
requires_weak = [
|
|
"12_dbus.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "redbear-udisks"
|
|
envs = { DBUS_SYSTEM_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket" }
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/14_redbear-polkit.service"
|
|
data = """
|
|
[unit]
|
|
description = "PolicyKit1 D-Bus service (org.freedesktop.PolicyKit1)"
|
|
requires_weak = [
|
|
"12_dbus.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "redbear-polkit"
|
|
envs = { DBUS_SYSTEM_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket" }
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/polkit-1/policy.toml"
|
|
data = """
|
|
# Red Bear OS polkit policy (v0.2 — comprehensive syntax)
|
|
#
|
|
# Format: action_id = uid, @group, *, !uid, !@group
|
|
#
|
|
# Specifiers:
|
|
# 1000 - explicit UID
|
|
# @wheel - any user in the named group (primary or supplementary)
|
|
# * - wildcard (allow any user)
|
|
# !1000 - explicit deny (overrides allows)
|
|
# !@restricted - explicit deny for users in 'restricted'
|
|
#
|
|
# UID 0 (root) is implicitly authorized for every action.
|
|
|
|
# -------- Power management (login1) --------
|
|
org.freedesktop.login1.power-off = *
|
|
org.freedesktop.login1.reboot = *
|
|
org.freedesktop.login1.suspend = *
|
|
org.freedesktop.login1.set-user-linger = 0
|
|
|
|
# -------- Storage (UDisks2) --------
|
|
org.freedesktop.udisks2.filesystem-mount = @wheel, 1000
|
|
org.freedesktop.udisks2.filesystem-mount-system = 0
|
|
|
|
# -------- NetworkManager --------
|
|
org.freedesktop.NetworkManager.settings.modify.system = 0
|
|
org.freedesktop.NetworkManager.enable-disable-wifi = @wheel, 1000
|
|
org.freedesktop.NetworkManager.enable-disable-wifi = !@restricted
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/var/lib/dbus"
|
|
data = ""
|
|
directory = true
|
|
mode = 0o755
|
|
|
|
[[files]]
|
|
path = "/run/dbus"
|
|
data = ""
|
|
directory = true
|
|
mode = 0o755
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/29_activate_console.service"
|
|
data = """
|
|
[unit]
|
|
description = "Activate console VT"
|
|
requires_weak = ["00_base.target"]
|
|
|
|
[service]
|
|
cmd = "inputd"
|
|
args = ["-A", "2", "-K", "us"]
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
# NOTE: cpufreqd is already started earlier by 15_cpufreqd.service (from
|
|
# redbear-device-services.toml). A second 30_cpufreqd instance used to live here
|
|
# and (a) ran cpufreqd twice — double MSR probing + a duplicate 16-line P-state
|
|
# dump — and (b) fired at getty time, burying the login banner/prompt under its
|
|
# output. Removed; the 15_ instance covers it with settle time before the prompt.
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/30_console.service"
|
|
data = """
|
|
[unit]
|
|
description = "Console terminals"
|
|
requires_weak = [
|
|
"29_activate_console.service",
|
|
"00_ptyd.service",
|
|
]
|
|
|
|
[service]
|
|
cmd = "getty"
|
|
args = ["2"]
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/31_debug_console.service"
|
|
# Serial/debug console handled by fbcond's serial mirror (see minimal.toml).
|
|
data = """
|
|
[unit]
|
|
description = "Debug console (handled by fbcond serial mirror)"
|
|
|
|
[service]
|
|
cmd = "true"
|
|
type = "oneshot"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_driver-manager.service"
|
|
data = """
|
|
[unit]
|
|
description = "Driver manager (non-blocking on live-mini)"
|
|
|
|
[service]
|
|
cmd = "driver-manager"
|
|
args = ["--hotplug"]
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_ipcd.service"
|
|
data = """
|
|
[unit]
|
|
description = "Inter-process communication daemon (non-blocking on live-mini)"
|
|
|
|
[service]
|
|
cmd = "ipcd"
|
|
type = "oneshot_async"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/13_ftdi-probe.service"
|
|
data = """
|
|
[unit]
|
|
description = "FTDI USB serial probe (non-blocking on redbear-mini)"
|
|
requires_weak = [
|
|
"00_base.target",
|
|
]
|
|
|
|
[service]
|
|
cmd = "echo"
|
|
args = ["RB_FTDI_PROBE_OK"]
|
|
type = "oneshot"
|
|
"""
|
|
|
|
[[files]]
|
|
path = "/etc/init.d/00_ptyd.service"
|
|
data = """
|
|
[unit]
|
|
description = "Pseudo-terminal daemon"
|
|
|
|
[service]
|
|
cmd = "ptyd"
|
|
# ptyd registers the "pty" scheme and signals readiness by sending its scheme
|
|
# cap fd back to init (redox_scheme ready_sync_scheme / ready_with_fd). init's
|
|
# scheme-service startup does a call_ro(FD) to receive that fd and register the
|
|
# scheme. It MUST therefore be type={scheme="pty"} — NOT "notify". With "notify"
|
|
# init does a plain readiness-byte read_exact that ptyd never sends, so init
|
|
# blocks forever here (the observed post-switchroot boot hang before the console
|
|
# stack). See ptyd/src/main.rs: it is on the SchemeDaemon/ready_with_fd path.
|
|
type = { scheme = "pty" }
|
|
"""
|