diff options
author | jeschli <jeschli@gmail.com> | 2018-03-20 15:37:44 +0100 |
---|---|---|
committer | jeschli <jeschli@gmail.com> | 2018-03-20 15:37:44 +0100 |
commit | 01358d3947b46c2d9cceb7f6c53855cb536d6efe (patch) | |
tree | 194c3c5e346327774603f8948a0fa301a082be90 /makefu | |
parent | 390375cd8a0c745eb6b4df93f3f6f3e5f2985c90 (diff) | |
parent | 6267aa42509a4f56dc95dfc2db7773c33ca12522 (diff) |
Merge branch 'staging/jeschli' of prism.r:stockholm into staging/jeschli
Diffstat (limited to 'makefu')
38 files changed, 481 insertions, 534 deletions
diff --git a/makefu/1systems/gum/config.nix b/makefu/1systems/gum/config.nix index a656fdce3..b859efc94 100644 --- a/makefu/1systems/gum/config.nix +++ b/makefu/1systems/gum/config.nix @@ -148,6 +148,11 @@ in { allowedIPs = [ "10.244.0.5/32" ]; publicKey = "QJMwwYu/92koCASbHnR/vqe/rN00EV6/o7BGwLockDw="; } + { + # workr + allowedIPs = [ "10.244.0.6/32" ]; + publicKey = "OFhCF56BrV9tjqW1sxqXEKH/GdqamUT1SqZYSADl5GA="; + } ]; }; } diff --git a/makefu/1systems/omo/config.nix b/makefu/1systems/omo/config.nix index ce3ffbcf3..01438397e 100644 --- a/makefu/1systems/omo/config.nix +++ b/makefu/1systems/omo/config.nix @@ -19,22 +19,24 @@ let # __FRONT_ # |* d0 | # | | - # |* d3 | + # |* d1 | # | | # |* d3 | # | | # |* | # |* d2 | - # | * r0 | + # | * | + # | * | # |_______| cryptDisk0 = byid "ata-ST2000DM001-1CH164_Z240XTT6"; cryptDisk1 = byid "ata-TP02000GB_TPW151006050068"; cryptDisk2 = byid "ata-ST4000DM000-1F2168_Z303HVSG"; + cryptDisk3 = byid "ata-ST8000DM004-2CX188_ZCT01SG4"; # cryptDisk3 = byid "ata-WDC_WD20EARS-00MVWB0_WD-WMAZA1786907"; # all physical disks # TODO callPackage ../3modules/MonitorDisks { disks = allDisks } - dataDisks = [ cryptDisk0 cryptDisk1 cryptDisk2 ]; + dataDisks = [ cryptDisk0 cryptDisk1 cryptDisk2 cryptDisk3 ]; allDisks = [ rootDisk ] ++ dataDisks; in { imports = @@ -68,6 +70,8 @@ in { <stockholm/makefu/2configs/syncthing.nix> <stockholm/makefu/2configs/mqtt.nix> <stockholm/makefu/2configs/remote-build/slave.nix> + <stockholm/makefu/2configs/deployment/google-muell.nix> + <stockholm/makefu/2configs/virtualisation/docker.nix> # security @@ -116,7 +120,6 @@ in { services.sabnzbd.enable = true; systemd.services.sabnzbd.environment.SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - virtualisation.docker.enable = true; makefu.ps3netsrv = { enable = true; servedir = "/media/cryptX/emu/ps3"; @@ -126,6 +129,7 @@ in { makefu.snapraid = { enable = true; + # TODO: 3 is not protected disks = map toMapper [ 0 1 ]; parity = toMapper 2; }; @@ -138,7 +142,7 @@ in { ''; environment.systemPackages = with pkgs;[ mergerfs # hard requirement for mount - wol # wake up filepimp + wol # wake up filepimp f3 ]; fileSystems = let @@ -150,6 +154,7 @@ in { in cryptMount "crypt0" // cryptMount "crypt1" // cryptMount "crypt2" + // cryptMount "crypt3" // { "/media/cryptX" = { device = (lib.concatMapStringsSep ":" (d: (toMapper d)) [ 0 1 2 ]); fsType = "mergerfs"; @@ -178,6 +183,7 @@ in { (usbkey "crypt0" cryptDisk0) (usbkey "crypt1" cryptDisk1) (usbkey "crypt2" cryptDisk2) + (usbkey "crypt3" cryptDisk3) ]; }; loader.grub.device = lib.mkForce rootDisk; diff --git a/makefu/1systems/sdev/config.nix b/makefu/1systems/sdev/config.nix index 38c044be4..c2cd23d1e 100644 --- a/makefu/1systems/sdev/config.nix +++ b/makefu/1systems/sdev/config.nix @@ -5,32 +5,35 @@ imports = [ # Include the results of the hardware scan. <stockholm/makefu> - (toString <nixpkgs/nixos/modules/virtualisation/virtualbox-image.nix>) - (toString <nixpkgs/nixos/modules/virtualisation/virtualbox-guest.nix>) + + # <stockholm/makefu/2configs/hw/vbox-guest.nix> + { # until virtualbox-image is fixed + imports = [ + <stockholm/makefu/2configs/fs/single-partition-ext4.nix> + ]; + boot.loader.grub.device = "/dev/sda"; + } <stockholm/makefu/2configs/main-laptop.nix> # <secrets/extra-hosts.nix> # environment <stockholm/makefu/2configs/tinc/retiolum.nix> + <stockholm/makefu/2configs/virtualisation/docker.nix> ]; - # workaround for https://github.com/NixOS/nixpkgs/issues/16641 - services.xserver.videoDrivers = lib.mkOverride 45 [ "virtualbox" "modesetting" ]; - - nixpkgs.config.allowUnfree = true; - # allow sdev to deploy self users.extraUsers = { root = { openssh.authorizedKeys.keys = [ config.krebs.users.makefu-vbob.pubkey ]; }; }; + # corefonts + nixpkgs.config.allowUnfree = true; environment.systemPackages = with pkgs;[ ppp xclip get passwdqc-utils - docker gnupg populate (pkgs.writeScriptBin "tor-browser" '' @@ -39,18 +42,11 @@ '') ]; - virtualisation.docker.enable = true; - networking.firewall.allowedTCPPorts = [ 25 80 8010 ]; - fileSystems."/media/share" = { - fsType = "vboxsf"; - device = "share"; - options = [ "rw" "uid=9001" "gid=9001" ]; - }; } diff --git a/makefu/1systems/vbob/config.nix b/makefu/1systems/vbob/config.nix index ffd9deaee..208dd1ff7 100644 --- a/makefu/1systems/vbob/config.nix +++ b/makefu/1systems/vbob/config.nix @@ -8,30 +8,9 @@ { imports = [<stockholm/makefu/2configs/fs/single-partition-ext4.nix> ]; boot.loader.grub.device = "/dev/sda"; - virtualisation.virtualbox.guest.enable = true; } - # { - # imports = [ - # <nixpkgs/nixos/modules/virtualisation/virtualbox-image.nix> - # ]; - # virtualbox.baseImageSize = 35 * 1024; - # fileSystems."/media/share" = { - # fsType = "vboxsf"; - # device = "share"; - # options = [ "rw" "uid=9001" "gid=9001" ]; - # }; - # } - - # { - # imports = [ - # <nixpkgs/nixos/modules/virtualisation/qemu-vm.nix> - # ]; - # fileSystems."/nix" = { - # device ="/dev/disk/by-label/nixstore"; - # fsType = "ext4"; - # }; - # } - + # <stockholm/makefu/2configs/hw/vbox-guest.nix> + # <nixpkgs/nixos/modules/virtualisation/qemu-vm.nix> # base gui # <stockholm/makefu/2configs/main-laptop.nix> @@ -75,14 +54,8 @@ ]; networking.extraHosts = import (toString <secrets/extra-hosts.nix>); - nixpkgs.config.allowUnfree = true; - # allow vbob to deploy self - users.extraUsers = { - root = { - openssh.authorizedKeys.keys = [ config.krebs.users.makefu-vbob.pubkey ]; - }; - }; + users.extraUsers.root.openssh.authorizedKeys.keys = [ config.krebs.users.makefu-vbob.pubkey ]; environment.shellAliases = { forti = "cat ~/vpn/pw.txt | xclip; sudo forticlientsslvpn"; @@ -94,16 +67,18 @@ ln -fs ${pkgs.ppp}/bin/pppd /usr/sbin/pppd ln -fs ${pkgs.coreutils}/bin/tail /usr/bin/tail ''; + + # for forticlient + nixpkgs.config.allowUnfree = true; + environment.systemPackages = with pkgs;[ fortclientsslvpn ppp xclip get logstash - # docker #devpi-web #devpi-client ansible ]; - # virtualisation.docker.enable = true; networking.firewall.allowedTCPPorts = [ @@ -111,6 +86,6 @@ 80 8010 ]; - + # required for qemu systemd.services."serial-getty@ttyS0".enable = true; } diff --git a/makefu/1systems/wbob/config.nix b/makefu/1systems/wbob/config.nix index f44211b93..637d8e2d8 100644 --- a/makefu/1systems/wbob/config.nix +++ b/makefu/1systems/wbob/config.nix @@ -18,7 +18,7 @@ in { <stockholm/makefu/2configs/virtualisation/libvirt.nix> <stockholm/makefu/2configs/tinc/retiolum.nix> <stockholm/makefu/2configs/mqtt.nix> - # <stockholm/makefu/2configs/gui/wbob-kiosk.nix> + <stockholm/makefu/2configs/gui/wbob-kiosk.nix> <stockholm/makefu/2configs/stats/client.nix> @@ -29,8 +29,69 @@ in { # <stockholm/makefu/2configs/vncserver.nix> # Services - <stockholm/makefu/2configs/remote-build/slave.nix> + <stockholm/makefu/2configs/hydra/stockholm.nix> + <stockholm/makefu/2configs/share/wbob.nix> + (let + musicDirectory = "/data/music"; + in { + services.mpd = { + enable = true; + inherit musicDirectory; + # dataDir = "/home/anders/.mpd"; + network.listenAddress = "any"; + extraConfig = '' + audio_output { + type "pulse" + name "Local MPD" + server "127.0.0.1" + } + ''; + }; + # open because of truestedInterfaces + # networking.firewall.allowedTCPPorts = [ 6600 4713 ]; + services.samba.shares.music = { + path = musicDirectory; + "read only" = "no"; + browseable = "yes"; + "guest ok" = "yes"; + }; + + sound.enable = true; + hardware.pulseaudio = { + enable = true; + package = pkgs.pulseaudioFull; + # systemWide = true; + support32Bit = true; + zeroconf.discovery.enable = true; + zeroconf.publish.enable = true; + tcp = { + enable = true; + anonymousClients.allowAll = true; + anonymousClients.allowedIpRanges = [ "127.0.0.1" "192.168.8.0/24" ]; + }; + configFile = pkgs.writeText "default.pa" '' + load-module module-udev-detect + load-module module-bluetooth-policy + load-module module-bluetooth-discover + load-module module-native-protocol-unix + load-module module-always-sink + load-module module-console-kit + load-module module-systemd-login + load-module module-intended-roles + load-module module-position-event-sounds + load-module module-filter-heuristics + load-module module-filter-apply + load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 + load-module module-switch-on-connect + # may be required for "system-wide" pulse to connect to bluetooth + #module-bluez5-device + #module-bluez5-discover + ''; + }; + # connect via https://nixos.wiki/wiki/Bluetooth#Using_Bluetooth_headsets_with_PulseAudio + hardware.bluetooth.enable = true; + }) # Sensors <stockholm/makefu/2configs/stats/telegraf> @@ -147,7 +208,10 @@ in { boot.loader.grub.device = rootdisk; hardware.cpu.intel.updateMicrocode = true; boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; - boot.kernelModules = [ "kvm-intel" ]; + + boot.kernelModules = [ "kvm-intel" + "snd-seq" "snd-rawmidi" + ]; fileSystems = { "/" = { device = rootdisk + "-part1"; @@ -174,66 +238,4 @@ in { serverAddress = "x.r"; }; }; - security.wrappers.fping = { - source = "${pkgs.fping}/bin/fping"; - setuid = true; - }; - services.smokeping = { - enable = true; - targetConfig = '' - probe = FPing - menu = Top - title = Network Latency Grapher - remark = Welcome to this SmokePing website. - - + network - menu = Net latency - title = Network latency (ICMP pings) - - ++ google - probe = FPing - host = google.de - ++ webde - probe = FPing - host = web.de - - + services - menu = Service latency - title = Service latency (DNS, HTTP) - - ++ HTTP - menu = HTTP latency - title = Service latency (HTTP) - - +++ webdeping - probe = EchoPingHttp - host = web.de - - +++ googwebping - probe = EchoPingHttp - host = google.de - - #+++ webwww - #probe = Curl - #host = web.de - - #+++ googwebwww - #probe = Curl - #host = google.de - ''; - probeConfig = '' - + FPing - binary = /run/wrappers/bin/fping - + EchoPingHttp - pings = 5 - url = / - - #+ Curl - ## probe-specific variables - #binary = ${pkgs.curl}/bin/curl - #step = 60 - ## a default for this target-specific variable - #urlformat = http://%host%/ - ''; - }; } diff --git a/makefu/1systems/x/config.nix b/makefu/1systems/x/config.nix index a32db91e1..ad2ad8779 100644 --- a/makefu/1systems/x/config.nix +++ b/makefu/1systems/x/config.nix @@ -40,7 +40,7 @@ with import <stockholm/lib>; # Virtualization <stockholm/makefu/2configs/virtualisation/libvirt.nix> <stockholm/makefu/2configs/virtualisation/docker.nix> - <stockholm/makefu/2configs/virtualisation/virtualbox.nix> + # <stockholm/makefu/2configs/virtualisation/virtualbox.nix> { networking.firewall.allowedTCPPorts = [ 8080 ]; networking.nat = { @@ -59,8 +59,9 @@ with import <stockholm/lib>; # Hardware <stockholm/makefu/2configs/hw/tp-x230.nix> - <stockholm/makefu/2configs/hw/rtl8812au.nix> - <stockholm/makefu/2configs/hw/wwan.nix> + # <stockholm/makefu/2configs/hw/tpm.nix> + # <stockholm/makefu/2configs/hw/rtl8812au.nix> + <stockholm/makefu/2configs/hw/network-manager.nix> <stockholm/makefu/2configs/hw/stk1160.nix> # <stockholm/makefu/2configs/rad1o.nix> @@ -77,18 +78,82 @@ with import <stockholm/lib>; # <stockholm/makefu/2configs/lanparty/lancache-dns.nix> # <stockholm/makefu/2configs/lanparty/samba.nix> # <stockholm/makefu/2configs/lanparty/mumble-server.nix> + # <stockholm/makefu/2configs/deployment/photostore.krebsco.de.nix> + + { + networking.wireguard.interfaces.wg0 = { + ips = [ "10.244.0.2/24" ]; + privateKeyFile = (toString <secrets>) + "/wireguard.key"; + allowedIPsAsRoutes = true; + peers = [ + { + # gum + endpoint = "${config.krebs.hosts.gum.nets.internet.ip4.addr}:51820"; + allowedIPs = [ "10.244.0.0/24" ]; + publicKey = "yAKvxTvcEVdn+MeKsmptZkR3XSEue+wSyLxwcjBYxxo="; + } + #{ + # # vbob + # allowedIPs = [ "10.244.0.3/32" ]; + # publicKey = "Lju7EsCu1OWXhkhdNR7c/uiN60nr0TUPHQ+s8ULPQTw="; + #} + ]; + }; + } + { # bluetooth+pulse config + # for blueman-applet + users.users.makefu.packages = [ + pkgs.blueman + ]; + hardware.pulseaudio = { + enable = true; + package = pkgs.pulseaudioFull; + # systemWide = true; + support32Bit = true; + configFile = pkgs.writeText "default.pa" '' + load-module module-udev-detect + load-module module-bluetooth-policy + load-module module-bluetooth-discover + load-module module-native-protocol-unix + load-module module-always-sink + load-module module-console-kit + load-module module-systemd-login + load-module module-intended-roles + load-module module-position-event-sounds + load-module module-filter-heuristics + load-module module-filter-apply + load-module module-switch-on-connect + ''; + }; + + # presumably a2dp Sink + # Enable profile: + ## pacmd set-card-profile "$(pactl list cards short | egrep -o bluez_card[[:alnum:]._]+)" a2dp_sink + hardware.bluetooth.extraConfig = ''; + [general] + Enable=Source,Sink,Media,Socket + ''; + + # connect via https://nixos.wiki/wiki/Bluetooth#Using_Bluetooth_headsets_with_PulseAudio + hardware.bluetooth.enable = true; + } + { # auto-mounting + services.udisks2.enable = true; + services.devmon.enable = true; + # services.gnome3.gvfs.enable = true; + users.users.makefu.packages = with pkgs;[ + gvfs pcmanfm lxmenu-data + ]; + environment.variables.GIO_EXTRA_MODULES = [ "${pkgs.gvfs}/lib/gio/modules" ]; + } ]; makefu.server.primary-itf = "wlp3s0"; makefu.full-populate = true; - makefu.umts.apn = "web.vodafone.de"; nixpkgs.config.allowUnfree = true; - environment.systemPackages = [ pkgs.passwdqc-utils ]; - - # configure pulseAudio to provide a HDMI sink as well networking.firewall.enable = true; networking.firewall.allowedTCPPorts = [ 80 24800 26061 8000 3000 ]; @@ -100,8 +165,15 @@ with import <stockholm/lib>; krebs.tinc.retiolum.connectTo = [ "omo" "gum" "prism" ]; networking.extraHosts = '' - 192.168.1.11 omo.local + 192.168.1.11 omo.local ''; # hard dependency because otherwise the device will not be unlocked boot.initrd.luks.devices = [ { name = "luksroot"; device = "/dev/sda2"; allowDiscards=true; }]; + + nix.package = pkgs.nixUnstable; + environment.systemPackages = [ pkgs.passwdqc-utils pkgs.nixUnstable ]; + nixpkgs.overlays = [ (import <python/overlay.nix>) ]; + + # environment.variables = { GOROOT = [ "${pkgs.go.out}/share/go" ]; }; + } diff --git a/makefu/2configs/deployment/google-muell.nix b/makefu/2configs/deployment/google-muell.nix new file mode 100644 index 000000000..f23789ee5 --- /dev/null +++ b/makefu/2configs/deployment/google-muell.nix @@ -0,0 +1,34 @@ +{ config, lib, pkgs, buildPythonPackage, ... }: +with import <stockholm/lib>; +let + pkg = pkgs.ampel; + home = "/var/lib/ampel"; + sec = "${toString <secrets>}/google-muell.json"; + ampelsec = "${home}/google-muell.json"; + esp = "192.168.1.23"; + sleepval = "1800"; +in { + users.users.ampel = { + uid = genid "ampel"; + createHome = true; + isSystemUser = true; + inherit home; + }; + systemd.services.google-muell-ampel = { + description = "Send led change to rgb cubes"; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = "ampel"; + ExecStartPre = pkgs.writeDash "copy-ampel-secrets" '' + cp ${sec} ${ampelsec} + chown ampel ${ampelsec} + ''; + ExecStart = "${pkg}/bin/google-muell --esp=${esp} --client-secrets=${ampelsec} --credential-path=${home}/google-muell-creds.json --sleepval=${sleepval}"; + PermissionsStartOnly = true; + Restart = "always"; + RestartSec = 10; + PrivateTmp = true; + }; + }; +} diff --git a/makefu/2configs/deployment/led-fader.nix b/makefu/2configs/deployment/led-fader.nix index 292b6679d..d34b66125 100644 --- a/makefu/2configs/deployment/led-fader.nix +++ b/makefu/2configs/deployment/led-fader.nix @@ -2,25 +2,7 @@ let mq = "192.168.8.11"; - - pkg = pkgs.python3Packages.buildPythonPackage { - name = "ampel-master"; - - src = pkgs.fetchgit { - url = "http://cgit.euer.krebsco.de/ampel"; - rev = "531741b"; - sha256 = "110yij53jz074zbswylbzcd8jy7z49r9fg6i3j1gk2y3vl91g81c"; - }; - propagatedBuildInputs = with pkgs.python3Packages; [ - docopt - paho-mqtt - requests - pytz - influxdb - httplib2 - google_api_python_client - ]; - }; + pkg = pkgs.ampel; in { systemd.services.led-fader = { description = "Send led change to message queue"; diff --git a/makefu/2configs/deployment/owncloud.nix b/makefu/2configs/deployment/owncloud.nix index 3a9d57dbb..e9d4b18e0 100644 --- a/makefu/2configs/deployment/owncloud.nix +++ b/makefu/2configs/deployment/owncloud.nix @@ -1,6 +1,18 @@ { lib, pkgs, config, ... }: with lib; +# imperative in config.php: +# #local memcache: +# 'memcache.local' => '\\OC\\Memcache\\APCu', +# #local locking: +# 'memcache.locking' => '\\OC\\Memcache\\Redis', +# 'redis' => +# array ( +# 'host' => 'localhost', +# 'port' => 6379, +# ), + + let # TODO: copy-paste from lass/2/websites/util.nix serveCloud = domains: @@ -124,20 +136,48 @@ let env[PATH] = ${lib.makeBinPath [ pkgs.php ]} catch_workers_output = yes ''; + services.phpfpm.phpOptions = '' + opcache.enable=1 + opcache.enable_cli=1 + opcache.interned_strings_buffer=8 + opcache.max_accelerated_files=10000 + opcache.memory_consumption=128 + opcache.save_comments=1 + opcache.revalidate_freq=1 + + display_errors = on + display_startup_errors = on + always_populate_raw_post_data = -1 + error_reporting = E_ALL | E_STRICT + html_errors = On + date.timezone = "Europe/Berlin" + # extension=${pkgs.phpPackages.memcached}/lib/php/extensions/memcached.so + extension=${pkgs.phpPackages.redis}/lib/php/extensions/redis.so + extension=${pkgs.phpPackages.apcu}/lib/php/extensions/apcu.so + ''; }; in { imports = [ ( serveCloud [ "o.euer.krebsco.de" ] ) ]; - services.mysql = { # TODO: currently nextcloud uses sqlite + services.redis.enable = true; + services.mysql = { enable = false; package = pkgs.mariadb; rootPassword = config.krebs.secret.files.mysql_rootPassword.path; - }; - services.mysqlBackup = { - enable = false; - databases = [ "nextcloud" ]; + initialDatabases = [ + # Or use writeText instead of literalExample? + #{ name = "nextcloud"; schema = literalExample "./nextcloud.sql"; } + { + name = "nextcloud"; + schema = pkgs.writeText "nextcloud.sql" + '' + create user if not exists 'nextcloud'@'localhost' identified by 'password'; + grant all privileges on nextcloud.* to 'nextcloud'@'localhost' identified by 'password'; + ''; + } + ]; }; # dataDir is only defined after mysql is enabled # krebs.secret.files.mysql_rootPassword = { diff --git a/makefu/2configs/git/cgit-retiolum.nix b/makefu/2configs/git/cgit-retiolum.nix index eacbd99cf..1109e2519 100644 --- a/makefu/2configs/git/cgit-retiolum.nix +++ b/makefu/2configs/git/cgit-retiolum.nix @@ -28,6 +28,7 @@ let init-stockholm = { cgit.desc = "Init stuff for stockholm"; }; + hydra-stockholm = { }; }; priv-repos = mapAttrs make-priv-repo { diff --git a/makefu/2configs/gui/base.nix b/makefu/2configs/gui/base.nix index daa0282b8..861a9327e 100644 --- a/makefu/2configs/gui/base.nix +++ b/makefu/2configs/gui/base.nix @@ -48,13 +48,14 @@ in fonts = [ pkgs.terminus_font ]; }; - environment.systemPackages = with pkgs;[ - pavucontrol - xlockmore - rxvt_unicode-with-plugins - firefox - ]; - users.extraUsers.${mainUser}.extraGroups = [ "audio" ]; + users.users.${mainUser} = { + extraGroups = [ "audio" ]; + packages = with pkgs;[ + pavucontrol + xlockmore + rxvt_unicode-with-plugins + ]; + }; hardware.pulseaudio = { enable = true; diff --git a/makefu/2configs/gui/wbob-kiosk.nix b/makefu/2configs/gui/wbob-kiosk.nix index 4b7a0c333..7db749227 100644 --- a/makefu/2configs/gui/wbob-kiosk.nix +++ b/makefu/2configs/gui/wbob-kiosk.nix @@ -1,11 +1,13 @@ - |