summaryrefslogtreecommitdiffstats
path: root/lass/2configs
diff options
context:
space:
mode:
Diffstat (limited to 'lass/2configs')
-rw-r--r--lass/2configs/IM.nix33
-rw-r--r--lass/2configs/alacritty.nix130
-rw-r--r--lass/2configs/baseX.nix29
-rw-r--r--lass/2configs/bgt-bot/bgt-check.sh57
-rw-r--r--lass/2configs/bgt-bot/default.nix44
-rw-r--r--lass/2configs/bitcoin.nix1
-rw-r--r--lass/2configs/bitlbee.nix2
-rw-r--r--lass/2configs/blue.nix1
-rw-r--r--lass/2configs/br.nix2
-rw-r--r--lass/2configs/codimd.nix5
-rw-r--r--lass/2configs/default.nix5
-rw-r--r--lass/2configs/fysiirc.nix18
-rw-r--r--lass/2configs/games.nix2
-rw-r--r--lass/2configs/git-brain.nix2
-rw-r--r--lass/2configs/git.nix6
-rw-r--r--lass/2configs/hass/default.nix1
-rw-r--r--lass/2configs/hass/pyscript/.gitignore1
-rw-r--r--lass/2configs/hass/pyscript/default.nix26
-rw-r--r--lass/2configs/hass/pyscript/shell.nix51
-rw-r--r--lass/2configs/home-media.nix4
-rw-r--r--lass/2configs/jitsi.nix3
-rw-r--r--lass/2configs/mail.nix10
-rw-r--r--lass/2configs/minecraft.nix1
-rw-r--r--lass/2configs/mpv.nix30
-rw-r--r--lass/2configs/network-manager.nix1
-rw-r--r--lass/2configs/paste.nix4
-rw-r--r--lass/2configs/pipewire.nix13
-rw-r--r--lass/2configs/print.nix2
-rw-r--r--lass/2configs/programs.nix35
-rw-r--r--lass/2configs/radio/controls.html83
-rw-r--r--lass/2configs/radio/default.nix (renamed from lass/2configs/radio.nix)110
-rw-r--r--lass/2configs/radio/news.nix (renamed from lass/2configs/radio-news.nix)64
-rw-r--r--lass/2configs/radio/weather.nix55
-rw-r--r--lass/2configs/radio/weather_for_ips.py33
-rw-r--r--lass/2configs/realwallpaper.nix4
-rw-r--r--lass/2configs/retiolum.nix1
-rw-r--r--lass/2configs/ssh-cryptsetup.nix2
-rw-r--r--lass/2configs/sync/decsync.nix9
-rw-r--r--lass/2configs/sync/sync.nix11
-rw-r--r--lass/2configs/sync/weechat.nix8
-rw-r--r--lass/2configs/tests/dummy-secrets/ssh-tor.priv0
-rw-r--r--lass/2configs/themes.nix66
-rw-r--r--lass/2configs/tmux.nix29
-rw-r--r--lass/2configs/tor-ssh.nix14
-rw-r--r--lass/2configs/vim.nix62
-rw-r--r--lass/2configs/websites/domsen.nix56
-rw-r--r--lass/2configs/websites/lassulus.nix32
-rw-r--r--lass/2configs/websites/ref.ptkk.de/default.nix89
-rw-r--r--lass/2configs/websites/util.nix1
-rw-r--r--lass/2configs/wiregrill.nix4
-rw-r--r--lass/2configs/xmonad.nix51
-rw-r--r--lass/2configs/yubikey.nix2
52 files changed, 956 insertions, 349 deletions
diff --git a/lass/2configs/IM.nix b/lass/2configs/IM.nix
index 5b8cebf5c..8567def02 100644
--- a/lass/2configs/IM.nix
+++ b/lass/2configs/IM.nix
@@ -1,38 +1,23 @@
with (import <stockholm/lib>);
{ config, lib, pkgs, ... }: let
weechat = pkgs.weechat.override {
- configure = { availablePlugins, ... }: with pkgs.weechatScripts; {
- plugins = lib.attrValues (availablePlugins // {
- python = availablePlugins.python.withPackages (_: [ weechat-matrix ]);
- });
- scripts = [ weechat-matrix ];
+ configure = { availablePlugins, ... }: {
+ scripts = with pkgs.weechatScripts; [
+ weechat-matrix
+ ];
};
};
- tmux = pkgs.writeDashBin "tmux" ''
- exec ${pkgs.tmux}/bin/tmux -f ${pkgs.writeText "tmux.conf" ''
- set-option -g prefix `
- unbind-key C-b
- bind ` send-prefix
-
- set-option -g status off
- set-option -g default-terminal screen-256color
-
- #use session instead of windows
- bind-key c new-session
- bind-key p switch-client -p
- bind-key n switch-client -n
- bind-key C-s switch-client -l
- ''} "$@"
- '';
+ tmux = "/run/current-system/sw/bin/tmux";
in {
imports = [
./bitlbee.nix
];
- environment.systemPackages = [ tmux weechat ];
+ environment.systemPackages = [ weechat ];
systemd.services.chat = {
description = "chat environment setup";
+ environment.WEECHAT_HOME = "\$HOME/.weechat";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
@@ -46,8 +31,8 @@ in {
User = "lass";
RemainAfterExit = true;
Type = "oneshot";
- ExecStart = "${tmux}/bin/tmux -2 new-session -d -s IM ${weechat}/bin/weechat";
- ExecStop = "${tmux}/bin/tmux kill-session -t IM"; # TODO run save in weechat
+ ExecStart = "${tmux} -2 new-session -d -s IM ${weechat}/bin/weechat";
+ ExecStop = "${tmux} kill-session -t IM"; # TODO run save in weechat
};
};
}
diff --git a/lass/2configs/alacritty.nix b/lass/2configs/alacritty.nix
new file mode 100644
index 000000000..903ddf6cc
--- /dev/null
+++ b/lass/2configs/alacritty.nix
@@ -0,0 +1,130 @@
+{ config, lib, pkgs, ... }: let
+
+ alacritty-cfg = extrVals: builtins.toJSON ({
+ font = {
+ normal = {
+ family = "Inconsolata";
+ style = "Regular";
+ };
+ bold = {
+ family = "Inconsolata";
+ style = "Bold";
+ };
+ italic = {
+ family = "Inconsolata";
+ style = "Italic";
+ };
+ bold_italic = {
+ family = "Inconsolata";
+ style = "Bold Italic";
+ };
+ size = 8;
+ };
+ live_config_reload = true;
+ window.dimensions = {
+ columns = 80;
+ lines = 20;
+ };
+ # window.opacity = 0;
+ hints.enabled = [
+ {
+ regex = ''(mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)[^\u0000-\u001F\u007F-\u009F<>"\s{-}\^⟨⟩`]+'';
+ command = "/run/current-system/sw/bin/xdg-open";
+ post_processing = true;
+ mouse.enabled = true;
+ binding = {
+ key = "U";
+ mods = "Alt";
+ };
+ }
+ ];
+ } // extrVals);
+
+ alacritty = pkgs.symlinkJoin {
+ name = "alacritty";
+ paths = [
+ (pkgs.writeDashBin "alacritty" ''
+ ${pkgs.alacritty}/bin/alacritty --config-file /var/theme/config/alacritty.yaml "$@"
+ '')
+ pkgs.alacritty
+ ];
+ };
+
+in {
+ environment.etc = {
+ "themes/light/alacritty.yaml".text = alacritty-cfg {
+ colors = {
+ # Default colors
+ primary = {
+ # hard contrast: background = '#f9f5d7'
+ # background = "#fbf1c7";
+ background = "#f9f5d7";
+ # soft contrast: background = '#f2e5bc'
+ foreground = "#3c3836";
+ };
+
+ # Normal colors
+ normal = {
+ black = "#fbf1c7";
+ red = "#cc241d";
+ green = "#98971a";
+ yellow = "#d79921";
+ blue = "#458588";
+ magenta = "#b16286";
+ cyan = "#689d6a";
+ white = "#7c6f64";
+ };
+
+ # Bright colors
+ bright = {
+ black = "#928374";
+ red = "#9d0006";
+ green = "#79740e";
+ yellow = "#b57614";
+ blue = "#076678";
+ magenta = "#8f3f71";
+ cyan = "#427b58";
+ white = "#3c3836";
+ };
+ };
+ };
+ "themes/dark/alacritty.yaml".text = alacritty-cfg {
+ colors = {
+ # Default colors
+ primary = {
+ background = "0x000000";
+ foreground = "0xffffff";
+ };
+ cursor = {
+ text = "0xF81CE5";
+ cursor = "0xffffff";
+ };
+
+ # Normal colors
+ normal = {
+ black = "0x000000";
+ red = "0xfe0100";
+ green = "0x33ff00";
+ yellow = "0xfeff00";
+ blue = "0x0066ff";
+ magenta = "0xcc00ff";
+ cyan = "0x00ffff";
+ white = "0xd0d0d0";
+ };
+
+ # Bright colors
+ bright = {
+ black = "0x808080";
+ red = "0xfe0100";
+ green = "0x33ff00";
+ yellow = "0xfeff00";
+ blue = "0x0066ff";
+ magenta = "0xcc00ff";
+ cyan = "0x00ffff";
+ white = "0xFFFFFF";
+ };
+ };
+ };
+ };
+ environment.systemPackages = [ alacritty ];
+}
diff --git a/lass/2configs/baseX.nix b/lass/2configs/baseX.nix
index 59d1e0182..e94cbbd2c 100644
--- a/lass/2configs/baseX.nix
+++ b/lass/2configs/baseX.nix
@@ -4,6 +4,7 @@ let
user = config.krebs.build.user;
in {
imports = [
+ ./alacritty.nix
./mpv.nix
./power-action.nix
./copyq.nix
@@ -13,8 +14,9 @@ in {
./pipewire.nix
./tmux.nix
./xmonad.nix
+ ./themes.nix
{
- krebs.per-user.lass.packages = [
+ users.users.mainUser.packages = [
pkgs.sshuttle
];
security.sudo.extraConfig = ''
@@ -44,7 +46,7 @@ in {
}
];
- users.users.mainUser.extraGroups = [ "audio" "video" ];
+ users.users.mainUser.extraGroups = [ "audio" "pipewire" "video" ];
time.timeZone = "Europe/Berlin";
@@ -55,14 +57,14 @@ in {
environment.systemPackages = with pkgs; [
acpi
acpilight
- ag
+ ripgrep
cabal2nix
dic
dmenu
font-size
fzfmenu
gimp
- gitAndTools.hub
+ gitAndTools.gh
git-crypt
git-preview
dconf
@@ -77,11 +79,13 @@ in {
ponymix
powertop
rxvt_unicode-with-plugins
+ sshvnc
sxiv
taskwarrior
termite
transgui
wirelesstools
+ x11vnc
xclip
xephyrify
xorg.xhost
@@ -96,12 +100,17 @@ in {
'')
];
- fonts.fonts = with pkgs; [
- hack-font
- hasklig
- symbola
- xlibs.fontschumachermisc
- ];
+ fonts = {
+ fontDir.enable = true;
+ enableGhostscriptFonts = true;
+
+ fonts = with pkgs; [
+ hack-font
+ xorg.fontschumachermisc
+ terminus_font_ttf
+ inconsolata
+ ];
+ };
services.udev.extraRules = ''
SUBSYSTEM=="backlight", ACTION=="add", \
diff --git a/lass/2configs/bgt-bot/bgt-check.sh b/lass/2configs/bgt-bot/bgt-check.sh
new file mode 100644
index 000000000..30185ba18
--- /dev/null
+++ b/lass/2configs/bgt-bot/bgt-check.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+# needs in path:
+# curl gnugrep jq
+# creates and manages $PWD/state
+set -xeuf
+
+send_reaktor(){
+ # usage: send_reaktor "text"
+ echo "send_reaktor: $1"
+ curl -fsS "http://localhost:$REAKTOR_PORT" \
+ -H content-type:application/json \
+ -d "$(jq -n \
+ --arg text "$1" \
+ --arg channel "$IRC_CHANNEL" \
+ '{
+ command:"PRIVMSG",
+ params:[$channel,$text]
+ }'
+ )"
+}
+
+live=$(shuf -n1 <<EOF
+Binärgewitter Liveshow hat begonnen! http://stream.radiotux.de:8000/binaergewitter.mp3
+EOF
+)
+
+offline=$(shuf -n1 <<EOF
+Live stream vorbei
+EOF
+)
+error=$(shuf -n1 <<EOF
+something went wrong
+EOF
+)
+
+if curl -Ss http://stream.radiotux.de:8000 | grep -q 'Mount Point /binaergewitter'; then
+ state='live'
+else
+ state='offline'
+fi
+prevstate=$(cat state ||:)
+
+if test "$state" == "$(cat state)";then
+ #echo "current and last state is the same ($state), doing nothing"
+ :
+else
+ echo "API state and last state differ ( '$state' != '$prevstate')"
+ if test "$state" == 'live';then
+ send_reaktor "$live"
+ elif test "$state" == 'offline';then
+ send_reaktor "$offline"
+ else
+ send_reaktor "$error"
+ fi
+ echo 'updating state'
+ printf "%s" "$state" > state
+fi
diff --git a/lass/2configs/bgt-bot/default.nix b/lass/2configs/bgt-bot/default.nix
new file mode 100644
index 000000000..6f9e33704
--- /dev/null
+++ b/lass/2configs/bgt-bot/default.nix
@@ -0,0 +1,44 @@
+{ config, lib, pkgs, ... }:
+let
+
+ bot_port = "7654";
+ irc_channel = "#binaergewitter";
+in
+{
+ krebs.reaktor2.bgt-announce = {
+ hostname = "irc.libera.chat";
+ port = "6697";
+ nick = "bgt-announce";
+ API.listen = "inet://127.0.0.1:${bot_port}";
+ plugins = [
+ {
+ plugin = "register";
+ config = {
+ channels = [
+ irc_channel
+ ];
+ };
+ }
+ ];
+ };
+ systemd.services.check_bgt_show = {
+ startAt = "*:0/5";
+ environment = {
+ IRC_CHANNEL = irc_channel;
+ REAKTOR_PORT = bot_port;
+ };
+ path = with pkgs; [
+ curl
+ gnugrep
+ jq
+ ];
+ script = builtins.readFile ./bgt-check.sh;
+ serviceConfig = {
+ DynamicUser = true;
+ StateDirectory = "bgt-announce";
+ WorkingDirectory = "/var/lib/bgt-announce";
+ PrivateTmp = true;
+ };
+ };
+}
+
diff --git a/lass/2configs/bitcoin.nix b/lass/2configs/bitcoin.nix
index de6562cbc..e9dd055f9 100644
--- a/lass/2configs/bitcoin.nix
+++ b/lass/2configs/bitcoin.nix
@@ -28,7 +28,6 @@ in {
};
};
security.sudo.extraConfig = ''
- ${mainUser.name} ALL=(bch) ALL
${mainUser.name} ALL=(bitcoin) ALL
${mainUser.name} ALL=(monero) ALL
'';
diff --git a/lass/2configs/bitlbee.nix b/lass/2configs/bitlbee.nix
index b84221155..84f06e587 100644
--- a/lass/2configs/bitlbee.nix
+++ b/lass/2configs/bitlbee.nix
@@ -11,7 +11,7 @@ with (import <stockholm/lib>);
pkgs.bitlbee-discord
];
libpurple_plugins = [
- pkgs.telegram-purple
+ # pkgs.telegram-purple
# pkgs.tdlib-purple
# pkgs.purple-gowhatsapp
];
diff --git a/lass/2configs/blue.nix b/lass/2configs/blue.nix
index 28c7d640d..2698f67e0 100644
--- a/lass/2configs/blue.nix
+++ b/lass/2configs/blue.nix
@@ -8,7 +8,6 @@ with (import <stockholm/lib>);
];
environment.systemPackages = with pkgs; [
- ag
dic
nmap
git-preview
diff --git a/lass/2configs/br.nix b/lass/2configs/br.nix
index 6e0a2385c..273a9c963 100644
--- a/lass/2configs/br.nix
+++ b/lass/2configs/br.nix
@@ -46,4 +46,6 @@ with import <stockholm/lib>;
];
};
+ users.users.mainUser.extraGroups = [ "scanner" "lp" ];
+
}
diff --git a/lass/2configs/codimd.nix b/lass/2configs/codimd.nix
index 271dcfca4..b3bf1b761 100644
--- a/lass/2configs/codimd.nix
+++ b/lass/2configs/codimd.nix
@@ -28,6 +28,10 @@ in {
params.hedgedoc = {};
};
+ systemd.services.hedgedoc.environment = {
+ CMD_COOKIE_POLICY = "none";
+ CMD_CSP_ALLOW_FRAMING = "true";
+ };
services.hedgedoc = {
enable = true;
configuration.allowOrigin = [ domain ];
@@ -47,6 +51,7 @@ in {
sslCertPath = "/var/lib/acme/${domain}/cert.pem";
sslKeyPath = "/var/lib/acme/${domain}/key.pem";
dhParamPath = config.security.dhparams.params.hedgedoc.path;
+
};
};
}
diff --git a/lass/2configs/default.nix b/lass/2configs/default.nix
index f03d8b568..e8ac55988 100644
--- a/lass/2configs/default.nix
+++ b/lass/2configs/default.nix
@@ -10,6 +10,8 @@ with import <stockholm/lib>;
./htop.nix
<stockholm/krebs/2configs/security-workarounds.nix>
./wiregrill.nix
+ ./tmux.nix
+ ./tor-ssh.nix
{
users.extraUsers =
mapAttrs (_: h: { hashedPassword = h; })
@@ -122,6 +124,9 @@ with import <stockholm/lib>;
q
rs
untilport
+ (pkgs.writeDashBin "urgent" ''
+ printf '\a'
+ '')
usbutils
logify
goify
diff --git a/lass/2configs/fysiirc.nix b/lass/2configs/fysiirc.nix
index f3c1d5b7c..e12eda42e 100644
--- a/lass/2configs/fysiirc.nix
+++ b/lass/2configs/fysiirc.nix
@@ -54,14 +54,20 @@ in {
name = "reaktor2-fysiweb-github";
};
script = ''. ${pkgs.writeDash "github-irc" ''
- set -efu
+ set -xefu
case "$Method $Request_URI" in
"POST /")
- payload=$(head -c "$req_content_length" \
- | sed 's/+/ /g;s/%\(..\)/\\x\1/g;' \
- | xargs -0 echo -e \
- )
- echo "$payload" | ${format-github-message}/bin/format-github-message
+ payload=$(head -c "$req_content_length")
+ echo "$payload" >&2
+ payload2=$payload
+ payload2=$(echo "$payload" | tr '\n' ' ' | tr -d '\r')
+ if [ "$payload" != "$payload2" ]; then
+ echo "payload has been mangled" >&2
+ else
+ echo "payload not mangled" >&2
+ fi
+ echo "$payload2" > /tmp/last_fysi_payload
+ echo "$payload2" | ${format-github-message}/bin/format-github-message
printf 'HTTP/1.1 200 OK\r\n'
printf 'Connection: close\r\n'
printf '\r\n'
diff --git a/lass/2configs/games.nix b/lass/2configs/games.nix
index 829773b87..26707f1f0 100644
--- a/lass/2configs/games.nix
+++ b/lass/2configs/games.nix
@@ -61,7 +61,7 @@ in {
name = "games";
description = "user playing games";
home = "/home/games";
- extraGroups = [ "audio" "video" "input" "loot" ];
+ extraGroups = [ "audio" "video" "input" "loot" "pipewire" ];
createHome = true;
useDefaultShell = true;
packages = with pkgs; [
diff --git a/lass/2configs/git-brain.nix b/lass/2configs/git-brain.nix
index 1c6f92fcd..f4d1a27cd 100644
--- a/lass/2configs/git-brain.nix
+++ b/lass/2configs/git-brain.nix
@@ -28,7 +28,7 @@ let
# TODO: get the list of all krebsministers
- krebsminister = with config.krebs.users; [ makefu tv ];
+ krebsminister = with config.krebs.users; [ makefu tv kmein ];
krebs-rules = repo:
set-owners repo [ config.krebs.users.lass ] ++ set-ro-access repo krebsminister;
diff --git a/lass/2configs/git.nix b/lass/2configs/git.nix
index e6c77f64b..891aefcfd 100644
--- a/lass/2configs/git.nix
+++ b/lass/2configs/git.nix
@@ -122,12 +122,6 @@ let
cgit.section = "configuration";
};
} // mapAttrs make-public-repo-silent {
- nixos-aws = {
- collaborators = [ {
- name = "fabio";
- pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDFst8DvnfOu4pQJYxcwdf//jWTvP+jj0iSrOdt59c9Gbujm/8K1mBXhcSQhHj/GBRC1Qc1wipf9qZsWnEHMI+SRwq6tDr8gqlAcdWmHAs1bU96jJtc8EgmUKbXTFG/VmympMPi4cEbNUtH93v6NUjQKwq9szvDhhqSW4Y8zE32xLkySwobQapNaUrGAtQp3eTxu5Lkx+cEaaartaAspt8wSosXjUHUJktg0O5/XOP+CiWAx89AXxbQCy4XTQvUExoRGdw9sdu0lF0/A0dF4lFF/dDUS7+avY8MrKEcQ8Fwk8NcW1XrKMmCdNdpvou0whL9aHCdTJ+522dsSB1zZWh63Si4CrLKlc1TiGKCXdvzmCYrD+6WxbPJdRpMM4dFNtpAwhCm/dM+CBXfDkP0s5veFiYvp1ri+3hUqV/sep9r5/+d+5/R1gQs8WDNjWqcshveFbD5LxE6APEySB4QByGxIrw7gFbozE+PNxtlVP7bq4MyE6yIzL6ofQgO1e4THquPcqSCfCvyib5M2Q1phi5DETlMemWp84AsNkqbhRa4BGRycuOXXrBzE+RgQokcIY7t3xcu3q0xJo2+HxW/Lqi72zYU1NdT4nJMETEaG49FfIAnUuoVaQWWvOz8mQuVEmmdw2Yzo2ikILYSUdHTp1VPOeo6aNPvESkPw1eM0xDRlQ== ada";
- } ];
- };
};
restricted-repos = mapAttrs make-restricted-repo (
diff --git a/lass/2configs/hass/default.nix b/lass/2configs/hass/default.nix
index 8f93e0cec..cc8189f51 100644
--- a/lass/2configs/hass/default.nix
+++ b/lass/2configs/hass/default.nix
@@ -19,6 +19,7 @@ let
in {
imports = [
+ ./pyscript
./zigbee.nix
./rooms/bett.nix
./rooms/essen.nix
diff --git a/lass/2configs/hass/pyscript/.gitignore b/lass/2configs/hass/pyscript/.gitignore
new file mode 100644
index 000000000..282debf56
--- /dev/null
+++ b/lass/2configs/hass/pyscript/.gitignore
@@ -0,0 +1 @@
+hass_token
diff --git a/lass/2configs/hass/pyscript/default.nix b/lass/2configs/hass/pyscript/default.nix
new file mode 100644
index 000000000..c56967e4b
--- /dev/null
+++ b/lass/2configs/hass/pyscript/default.nix
@@ -0,0 +1,26 @@
+{ config, lib, pkgs, ... }:
+{
+ systemd.tmpfiles.rules = [
+ "L+ /var/lib/hass/custom_components/pyscript - - - - ${pkgs.fetchzip {
+ url = "https://github.com/custom-components/pyscript/releases/download/1.3.2/hass-custom-pyscript.zip";
+ sha256 = "0cqdjj46s5xp4mqxb0ic790jm1xp3z0zr2n9f7bsfl5zpvdshl8z";
+ stripRoot = false;
+ }}"
+ ];
+
+ services.home-assistant = {
+ package = (pkgs.home-assistant.overrideAttrs (old: {
+ doInstallCheck = false;
+ })).override {
+ extraPackages = pp: [ pp.croniter ];
+ };
+ config.pyscript = {
+ allow_all_imports = true;
+ hass_is_global = true;
+ };
+ };
+
+ networking.firewall.interfaces.retiolum.allowedTCPPortRanges = [
+ { from = 50321; to = 50341; } # for ipython interactive debugging
+ ];
+}
diff --git a/lass/2configs/hass/pyscript/shell.nix b/lass/2configs/hass/pyscript/shell.nix
new file mode 100644
index 000000000..3cfac0275
--- /dev/null
+++ b/lass/2configs/hass/pyscript/shell.nix
@@ -0,0 +1,51 @@
+{ pkgs ? import <nixpkgs> {} }: let
+
+ hass_host = "styx.r";
+ h