diff options
Diffstat (limited to '')
175 files changed, 7690 insertions, 6031 deletions
diff --git a/flake.lock b/flake.lock index b11793a4..41ac27dc 100644 --- a/flake.lock +++ b/flake.lock @@ -16,11 +16,11 @@ ] }, "locked": { - "lastModified": 1745630506, - "narHash": "sha256-bHCFgGeu8XjWlVuaWzi3QONjDW3coZDqSHvnd4l7xus=", + "lastModified": 1750173260, + "narHash": "sha256-9P1FziAwl5+3edkfFcr5HeGtQUtrSdk/MksX39GieoA=", "owner": "ryantm", "repo": "agenix", - "rev": "96e078c646b711aee04b82ba01aefbff87004ded", + "rev": "531beac616433bac6f9e2a19feb8e99a22a66baf", "type": "github" }, "original": { @@ -29,32 +29,6 @@ "type": "github" } }, - "arkenfox-nixos": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "nixpkgs": [ - "nixpkgs" - ], - "pre-commit": [ - "pre-commit-hooks" - ] - }, - "locked": { - "lastModified": 1744011341, - "narHash": "sha256-ZwyAdfXgfigchDLMZ/UqSjLc5YKk2xnchGHuWaNfqmQ=", - "owner": "dwarfmaster", - "repo": "arkenfox-nixos", - "rev": "57eefe49b80ea5e02f42199db531292de34a4350", - "type": "github" - }, - "original": { - "owner": "dwarfmaster", - "repo": "arkenfox-nixos", - "type": "github" - } - }, "beautysh": { "inputs": { "nixpkgs": [ @@ -83,11 +57,11 @@ }, "crane": { "locked": { - "lastModified": 1747260204, - "narHash": "sha256-KUb6MFWc2DYeTCmcEkrBrrqhxAgO6NHZh5qQKwsjG6I=", + "lastModified": 1751562746, + "narHash": "sha256-smpugNIkmDeicNz301Ll1bD7nFOty97T79m4GUMUczA=", "owner": "ipetkov", "repo": "crane", - "rev": "7f85510df37247c86a0c44032f49aa18292ee11f", + "rev": "aed2020fd3dc26e1e857d4107a5a67a33ab6c1fd", "type": "github" }, "original": { @@ -123,11 +97,11 @@ ] }, "locked": { - "lastModified": 1747274630, - "narHash": "sha256-87RJwXbfOHyzTB9LYagAQ6vOZhszCvd8Gvudu+gf3qo=", + "lastModified": 1751607816, + "narHash": "sha256-5PtrwjqCIJ4DKQhzYdm8RFePBuwb+yTzjV52wWoGSt4=", "owner": "nix-community", "repo": "disko", - "rev": "ec7c109a4f794fce09aad87239eab7f66540b888", + "rev": "da6109c917b48abc1f76dd5c9bf3901c8c80f662", "type": "github" }, "original": { @@ -159,11 +133,11 @@ ] }, "locked": { - "lastModified": 1743550720, - "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "lastModified": 1751413152, + "narHash": "sha256-Tyw1RjYEsp5scoigs1384gIg6e0GoBVjms4aXFfRssQ=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "rev": "77826244401ea9de6e3bac47c2db46005e1f30b5", "type": "github" }, "original": { @@ -205,11 +179,11 @@ ] }, "locked": { - "lastModified": 1747372754, - "narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=", + "lastModified": 1750779888, + "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46", + "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", "type": "github" }, "original": { @@ -265,11 +239,11 @@ ] }, "locked": { - "lastModified": 1747374689, - "narHash": "sha256-JT/aBZqmK1LbExzwT9cPkvxKc0IC4i6tZKOPjsSWFbI=", + "lastModified": 1751638848, + "narHash": "sha256-7HiC6w4ROEbMmKtj5pilnLOJej9HkkfU9wEd5QSTyNo=", "owner": "nix-community", "repo": "home-manager", - "rev": "d2263ce5f4c251c0f7608330e8fdb7d1f01f0667", + "rev": "7d9e3c35f0d46f82bac791d76260f15f53d83529", "type": "github" }, "original": { @@ -306,16 +280,16 @@ ] }, "locked": { - "lastModified": 1737371634, - "narHash": "sha256-fTVAWzT1UMm1lT+YxHuVPtH+DATrhYfea3B0MxG/cGw=", + "lastModified": 1748294338, + "narHash": "sha256-FVO01jdmUNArzBS7NmaktLdGA5qA3lUMJ4B7a05Iynw=", "owner": "NuschtOS", "repo": "ixx", - "rev": "a1176e2a10ce745ff8f63e4af124ece8fe0b1648", + "rev": "cc5f390f7caf265461d4aab37e98d2292ebbdb85", "type": "github" }, "original": { "owner": "NuschtOS", - "ref": "v0.0.7", + "ref": "v0.0.8", "repo": "ixx", "type": "github" } @@ -379,11 +353,11 @@ ] }, "locked": { - "lastModified": 1747365160, - "narHash": "sha256-4ZVr0x+ry6ybym/VhVYACj0HlJo44YxAaPGOxiS88Hg=", + "lastModified": 1751313918, + "narHash": "sha256-HsJM3XLa43WpG+665aGEh8iS8AfEwOIQWk3Mke3e7nk=", "owner": "lnl7", "repo": "nix-darwin", - "rev": "8817b00b0011750381d0d44bb94d61087349b6ba", + "rev": "e04a388232d9a6ba56967ce5b53a8a6f713cdfcf", "type": "github" }, "original": { @@ -420,11 +394,11 @@ ] }, "locked": { - "lastModified": 1746934494, - "narHash": "sha256-3n6i+F0sDASjkhbvgFDpPDZGp7z19IrRtjfF9TwJpCA=", + "lastModified": 1751170039, + "narHash": "sha256-3EKpUmyGmHYA/RuhZjINTZPU+OFWko0eDwazUOW64nw=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "e9b21b01e4307176b9718a29ac514838e7f6f4ff", + "rev": "9c932ae632d6b5150515e5749b198c175d8565db", "type": "github" }, "original": { @@ -443,11 +417,11 @@ ] }, "locked": { - "lastModified": 1742568034, - "narHash": "sha256-QaMEhcnscfF2MqB7flZr+sLJMMYZPnvqO4NYf9B4G38=", + "lastModified": 1747663185, + "narHash": "sha256-Obh50J+O9jhUM/FgXtI3he/QRNiV9+J53+l+RlKSaAk=", "owner": "nix-community", "repo": "nixos-generators", - "rev": "42ee229088490e3777ed7d1162cb9e9d8c3dbb11", + "rev": "ee07ba0d36c38e9915c55d2ac5a8fb0f05f2afcc", "type": "github" }, "original": { @@ -458,27 +432,27 @@ }, "nixpkgs": { "locked": { - "lastModified": 1747179050, - "narHash": "sha256-qhFMmDkeJX9KJwr5H32f1r7Prs7XbQWtO0h3V0a0rFY=", + "lastModified": 1751619433, + "narHash": "sha256-5aZFBHQNQzrfCisewtYBDNbiKcHbxPYChiP4dkEcSXQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "adaa24fbf46737f3f1b5497bf64bae750f82942e", + "rev": "a2867cc3f8acc944cb19fe0b73c840e9fa1ba589", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-unstable", + "ref": "nixos-unstable-small", "repo": "nixpkgs", "type": "github" } }, "nixpkgs-lib": { "locked": { - "lastModified": 1746925973, - "narHash": "sha256-03BE0+8MEQ5hSU5+8OI24X7Rhn5GruYZr18KWAZ5Rzk=", + "lastModified": 1751159883, + "narHash": "sha256-urW/Ylk9FIfvXfliA1ywh75yszAbiTEVgpPeinFyVZo=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "f9077b977f4c06f04afdfcac722fa942dd25818c", + "rev": "14a40a1d7fb9afa4739275ac642ed7301a9ba1ab", "type": "github" }, "original": { @@ -489,16 +463,16 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1747209494, - "narHash": "sha256-fLise+ys+bpyjuUUkbwqo5W/UyIELvRz9lPBPoB0fbM=", + "lastModified": 1751479989, + "narHash": "sha256-M5KgdpVBVcW4HRVq9/OSRbrxlwsQ1ogEKqnvzsClDqU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5d736263df906c5da72ab0f372427814de2f52f8", + "rev": "34627c90f062da515ea358360f448da57769236e", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-24.11", + "ref": "nixos-25.05", "repo": "nixpkgs", "type": "github" } @@ -519,11 +493,11 @@ ] }, "locked": { - "lastModified": 1747224967, - "narHash": "sha256-we27kbNAAEeT0+PxJ2aUNVFXlJ7uvh4pxTc3R8RUqxA=", + "lastModified": 1751492444, + "narHash": "sha256-26NgRXwhNM2x4hrok0C3CqSf2v0vi9byONNON5PzbHQ=", "owner": "nix-community", "repo": "nixvim", - "rev": "95ca65c8d1adee5594bd14f527c68d564fb68879", + "rev": "239d331bb48673dfd00d7187654892471cd60d44", "type": "github" }, "original": { @@ -543,11 +517,11 @@ ] }, "locked": { - "lastModified": 1745046075, - "narHash": "sha256-8v4y6k16Ra/fiecb4DxhsoOGtzLKgKlS+9/XJ9z0T2I=", + "lastModified": 1749730855, + "narHash": "sha256-L3x2nSlFkXkM6tQPLJP3oCBMIsRifhIDPMQQdHO5xWo=", "owner": "NuschtOS", "repo": "search", - "rev": "066afe8643274470f4a294442aadd988356a478f", + "rev": "8dfe5879dd009ff4742b668d9c699bc4b9761742", "type": "github" }, "original": { @@ -599,11 +573,11 @@ ] }, "locked": { - "lastModified": 1747372754, - "narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=", + "lastModified": 1750779888, + "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46", + "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", "type": "github" }, "original": { @@ -645,7 +619,6 @@ "root": { "inputs": { "agenix": "agenix", - "arkenfox-nixos": "arkenfox-nixos", "beautysh": "beautysh", "crane": "crane", "devshell": "devshell", @@ -685,11 +658,11 @@ ] }, "locked": { - "lastModified": 1747363019, - "narHash": "sha256-N4dwkRBmpOosa4gfFkFf/LTD8oOcNkAyvZ07JvRDEf0=", + "lastModified": 1751596734, + "narHash": "sha256-1tQOwmn3jEUQjH0WDJyklC+hR7Bj+iqx6ChtRX2QiPA=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "0e624f2b1972a34be1a9b35290ed18ea4b419b6f", + "rev": "e28ba067a9368286a8bc88b68dc2ca92181a09f0", "type": "github" }, "original": { @@ -784,11 +757,11 @@ ] }, "locked": { - "lastModified": 1747417311, - "narHash": "sha256-/DaiYxJ3s/2rpQrzuI8JLQHo4QQGmzuq0X+D4jBJJmE=", + "lastModified": 1750931469, + "narHash": "sha256-0IEdQB1nS+uViQw4k3VGUXntjkDp7aAlqcxdewb/hAc=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "2faace5cefca955da79be88df944b1c02ac6102d", + "rev": "ac8e6f32e11e9c7f153823abc3ab007f2a65d3e1", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 30c0394c..9c5a2963 100644 --- a/flake.nix +++ b/flake.nix @@ -13,8 +13,8 @@ inputs = { # base - nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-24.11"; - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.05"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small"; # open nixpkgs prs @@ -191,14 +191,6 @@ nixpkgs.follows = "nixpkgs"; }; }; - arkenfox-nixos = { - url = "github:dwarfmaster/arkenfox-nixos"; - inputs = { - nixpkgs.follows = "nixpkgs"; - pre-commit.follows = "pre-commit-hooks"; - flake-compat.follows = "flake-compat"; - }; - }; # my configs templates = { @@ -247,7 +239,6 @@ lanzaboote, nixvim, nix-index-database, - arkenfox-nixos, # external dependencies treefmt-nix, templates, @@ -284,7 +275,6 @@ disko lanzaboote nix-index-database - arkenfox-nixos ; }; diff --git a/flake/default.nix b/flake/default.nix index 1170efa3..e80e6ead 100644 --- a/flake/default.nix +++ b/flake/default.nix @@ -106,10 +106,6 @@ in { # nix pkgs.alejandra pkgs.deadnix - - # update - packageSets.soispha.generate_moz_extension # needed for the firefox extension update script - packageSets.soispha.lf-make-map # needed to generate the lf cd mappings ]; }; }; diff --git a/hosts/by-name/apzu/configuration.nix b/hosts/by-name/apzu/configuration.nix index 69af3f2d..4464011e 100644 --- a/hosts/by-name/apzu/configuration.nix +++ b/hosts/by-name/apzu/configuration.nix @@ -39,78 +39,6 @@ river.init = { mappings = { layout = "dvorak-modified"; - keymap = - { - # Focus change - "<Meta-T>" = {command = ["focus-view" "next"];}; - "<Meta-N>" = {command = ["focus-view" "previous"];}; - "<Meta+Ctrl-T>" = {command = ["focus-output" "next"];}; - "<Meta+Ctrl-N>" = {command = ["focus-output" "previous"];}; - - # Standard programs - "<Meta-<ENTER>>" = {command = ["spawn" "${lib.getExe pkgs.alacritty}"];}; - "<Meta+Shift-q>" = {command = ["exit"];}; - "<Meta-L>" = {command = ["spawn" "${lib.getExe pkgs.lock}"];}; - - # Screenshot - "<PRINTSCREEN>" = {command = ["spawn" "${lib.getExe pkgs.screenshot_persistent}"];}; - - # Audio - "<MEDIA_RAISEVOLUME>" = { - command = ["spawn" "${lib.getExe' pkgs.wireplumber "wpctl"} set-volume @DEFAULT_SINK@ 5%+"]; - modes = ["normal" "locked"]; - }; - "<MEDIA_LOWERVOLUME>" = { - command = ["spawn" "${lib.getExe' pkgs.wireplumber "wpctl"} set-volume @DEFAULT_SINK@ 5%-"]; - modes = ["normal" "locked"]; - }; - "<MEDIA_MUTEVOLUME>" = { - command = ["spawn" "${lib.getExe pkgs.mpc} toggle"]; - modes = ["normal" "locked"]; - }; - - # Launcher - "<Meta-R>" = {command = ["spawn" "${lib.getExe pkgs.rofi} -show combi -modes combi -combi-modes 'window, drun, run' -show-icons"];}; - "<Meta-<F1>>" = {command = ["spawn" "${lib.getExe pkgs.tskm} open select"];}; - "<Meta-<F2>>" = {command = ["spawn" "${lib.getExe pkgs.keepassxc}"];}; - "<Meta-<F3>>" = {command = ["spawn" "${lib.getExe pkgs.signal-desktop}"];}; - # "<Meta-<F4>>" = {command = ["spawn" "${lib.getExe pkgs.steam}"];}; - - # Client - "<Meta-f>" = {command = ["toggle-fullscreen"];}; - "<Meta+Shift-c>" = {command = ["close"];}; - "<Meta+Ctrl- >" = {command = ["toggle-float"];}; - "<Meta+Ctrl-<ENTER>>" = {command = ["zoom"];}; - "<Meta-o>" = {command = ["send-to-output" "next"];}; - "<Meta+Shift-T>" = {command = ["swap" "next"];}; - "<Meta+Shift-N>" = {command = ["swap" "previous"];}; - - # Toggle all tags - "<Meta-0>" = {command = ["set-focused-tags" (builtins.toString ((baseLib.pow 2 32) - 1))];}; - "<Meta+Shift-0>" = {command = ["set-view-tags" (builtins.toString ((baseLib.pow 2 32) - 1))];}; - - # Mouse - "<Meta-<MOUSE_LEFT>>" = { - command = ["move-view"]; - map_mode = "MapMouse"; - }; - "<Meta-<MOUSE_RIGHT>>" = { - command = ["resize-view"]; - map_mode = "MapMouse"; - }; - } - // ( - builtins.foldl' (acc: elem: acc // elem) {} ( - builtins.map (index: let - num = builtins.toString index; - index2tag = input: builtins.toString (baseLib.pow 2 (input - 1)); - in { - "<Meta-${num}>" = {command = ["set-focused-tags" (index2tag index)];}; - "<Meta+Shift-${num}>" = {command = ["set-view-tags" (index2tag index)];}; - "<Meta+Shift+Ctrl-${num}>" = {command = ["toggle-view-tags" (index2tag index)];}; - }) (builtins.genList (i: i + 1) 9) - ) - ); }; screenSetupCode = {}; }; diff --git a/hosts/by-name/tiamat/configuration.nix b/hosts/by-name/tiamat/configuration.nix index 3e7349ce..18393543 100644 --- a/hosts/by-name/tiamat/configuration.nix +++ b/hosts/by-name/tiamat/configuration.nix @@ -46,91 +46,13 @@ init = { mappings = { layout = "us"; - keymap = let - map = key: "<Alt+Ctrl+Meta+Shift-${key}>"; - in - (lib.mapAttrs' (name: value: lib.nameValuePair (map name) value) { - # Movement - "A" = {command = ["exit"];}; - "B" = {command = ["close"];}; - - "C" = {command = ["focus-view" "previous"];}; - "D" = {command = ["focus-view" "next"];}; - - "E" = {command = ["swap" "previous"];}; - "F" = {command = ["swap" "next"];}; - - "G" = {command = ["zoom"];}; - - "H" = {command = ["toggle-fullscreen"];}; - "I" = {command = ["toggle-float"];}; - - "J" = {command = ["send-to-output" "next"];}; - - "K" = {command = ["spawn" "${lib.getExe pkgs.alacritty}"];}; - "L" = {command = ["spawn" "${lib.getExe pkgs.screenshot_persistent}"];}; - - # Audio - # "M" = {command = ["spawn" "video-pause toggle"]; modes = ["normal" "locked"]; }; - "N" = { - command = ["spawn" "${lib.getExe pkgs.mpc} toggle"]; - modes = ["normal" "locked"]; - }; - - # Launcher - "O" = {command = ["spawn" "${lib.getExe pkgs.rofi} -show combi -modes combi -combi-modes 'window,drun,run' -show-icons"];}; - "P" = {command = ["spawn" "${lib.getExe pkgs.tskm} open select"];}; - "Q" = {command = ["spawn" "${lib.getExe pkgs.keepassxc}"];}; - # "R" = {command = ["spawn" "nheko"];}; - "S" = {command = ["spawn" "${lib.getExe pkgs.signal-desktop}"];}; - "T" = {command = ["spawn" "${lib.getExe pkgs.lock}"];}; - - "U" = {command = ["focus-output" "next"];}; - "V" = {command = ["focus-previous-tags"];}; - "W" = {command = ["send-to-previous-tags"];}; - # "X" = {command = ["spawn" "bemenu-run"];}; - # "Y" = {command = ["spawn" "bemenu-run"];}; - - # Toggle all tags - "0" = {command = ["set-focused-tags" "${builtins.toString ((libraries.base.pow 2 32) - 1)}"];}; - - # Support Unicode input - "Z" = {command = ["spawn" "${lib.getExe externalBinaries.qmk_firmware.packages.${system}.qmk_unicode_type} 106 65377"];}; - }) - // ({ - # TODO: add toggle-focus mapping - - # Toggle all tags - "<Alt+Ctrl+Shift-0>" = { - command = [ - "set-view-tags" - "${builtins.toString - ((libraries.base.pow 2 32) - 1)}" - ]; - }; - - # Mouse - "<Meta-<MOUSE_LEFT>>" = { - command = ["move-view"]; - map_mode = "MapMouse"; - }; - "<Meta-<MOUSE_RIGHT>>" = { - command = ["resize-view"]; - map_mode = "MapMouse"; - }; - } - // ( - builtins.foldl' (acc: elem: acc // elem) {} ( - builtins.map (index: let - num = builtins.toString index; - index2tag = input: builtins.toString (libraries.base.pow 2 (input - 1)); - in { - "${map num}" = {command = ["set-focused-tags" (index2tag index)];}; - "<Alt+Ctrl+Shift-${num}>" = {command = ["set-view-tags" (index2tag index)];}; - # "<Super+Shift+Ctrl-${num}>" = {command = ["toggle-view-tags" (index2tag index)];}; - }) (builtins.genList (i: i + 1) 9) - ) - )); + keymap = { + # Support Unicode input + "<Alt+Ctrl+Meta+Shift-Z>" = [ + "spawn" + "${lib.getExe externalBinaries.qmk_firmware.packages.${system}.qmk_unicode_type} 106 65377" + ]; + }; }; screenSetupCode = { "DP-2" = {pos = "2560,0";}; diff --git a/hosts/default.nix b/hosts/default.nix index 35b2d08b..64768074 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -29,6 +29,7 @@ inherit libraries modules + self ; }; modules = [ @@ -41,7 +42,6 @@ # extra information system # nix registry - self externalDependencies # bins # TODO: Integrate these into `pkgs/by-name` <2024-05-22> diff --git a/lib/default.nix b/lib/default.nix index d84ac5e2..1cdbf936 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -7,7 +7,7 @@ # # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{lib}: let +{lib}: rec { /* Converts `number` from a binary number to a decimal one. @@ -101,6 +101,26 @@ else if power > 0 then (base * (pow base (power - 1))) else builtins.throw "Negative powers are not supported"; -in { - inherit binaryToDecimal idFromString pow; + + options = { + /* + Generate an enable option definition, that defaults to true. + + This conveniently allows the composition of a “common” module set. + + # Type + + mkEnable :: String -> AttrSet + + # Arguments + + name + : The name to use in the option description. + */ + mkEnable = name: + (lib.mkEnableOption name) + // { + default = true; + }; + }; } diff --git a/modules/by-name/bo/boot/module.nix b/modules/by-name/bo/boot/module.nix index 404352ac..dfcd14b7 100644 --- a/modules/by-name/bo/boot/module.nix +++ b/modules/by-name/bo/boot/module.nix @@ -84,7 +84,7 @@ in { # This should only be necessary for `lanzaboote`, but that is the current default in # this module. soispha.impermanence.directories = [ - "/etc/secureboot" + "/var/lib/sbctl" ]; boot = { @@ -96,7 +96,7 @@ in { lanzaboote = { enable = true; - pkiBundle = "/etc/secureboot"; + pkiBundle = "/var/lib/sbctl"; settings = { # Disable editing the kernel command line (which could allow someone to become root) diff --git a/modules/by-name/di/disks/module.nix b/modules/by-name/di/disks/module.nix index d88fa3df..d5746ecf 100644 --- a/modules/by-name/di/disks/module.nix +++ b/modules/by-name/di/disks/module.nix @@ -109,11 +109,20 @@ in { nodev = { "/" = { fsType = "tmpfs"; - mountOptions = ["defaults" "size=4G" "mode=755"]; + mountOptions = ["defaults" "size=25%" "mode=0755"]; }; "/tmp" = { fsType = "tmpfs"; - mountOptions = ["defaults" "size=16G" "mode=755"]; + mountOptions = ["defaults" "size=50%" "mode=0755"]; + }; + "/nix/var/nix/builds" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "noswap" # Otherwise, we might run into io-based slowdowns + "size=75%" + "mode=0755" + ]; }; }; }; diff --git a/modules/by-name/fi/firefox/extensions.json b/modules/by-name/fi/firefox/extensions.json deleted file mode 100644 index cc098acd..00000000 --- a/modules/by-name/fi/firefox/extensions.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "darkreader": { - "addonId": "addon@darkreader.org", - "default_area": "navbar", - "pname": "darkreader", - "sha256": "sha256:23c94085063aa6b57fae40ca9111ab049fffca5476c29e9990db3aa1a3fe1f10", - "url": "https://addons.mozilla.org/firefox/downloads/file/4488139/darkreader-4.9.106.xpi", - "version": "4.9.106" - }, - "keepassxc-browser": { - "addonId": "keepassxc-browser@keepassxc.org", - "default_area": "navbar", - "pname": "keepassxc-browser", - "sha256": "sha256:7629ee8fe6a8bace5d0f12c3aef41803c2ab01407a22ad8803633992a6c4eda2", - "url": "https://addons.mozilla.org/firefox/downloads/file/4477789/keepassxc_browser-1.9.8.xpi", - "version": "1.9.8" - }, - "torproject-snowflake": { - "addonId": "{b11bea1f-a888-4332-8d8a-cec2be7d24b9}", - "default_area": "navbar", - "pname": "torproject-snowflake", - "sha256": "sha256:615c0d570f41e721a91fc4f334377a61732171b65eb1a4429d78681e85bc8878", - "url": "https://addons.mozilla.org/firefox/downloads/file/4458115/torproject_snowflake-0.9.3.xpi", - "version": "0.9.3" - }, - "tridactyl-vim": { - "addonId": "tridactyl.vim@cmcaine.co.uk", - "default_area": "menupanel", - "pname": "tridactyl-vim", - "sha256": "sha256:807925f26aab56ab19a28e663ade73743a033e3b77aa09edd3f77bf92e5fb36e", - "url": "https://addons.mozilla.org/firefox/downloads/file/4405615/tridactyl_vim-1.24.2.xpi", - "version": "1.24.2" - }, - "ublock-origin": { - "addonId": "uBlock0@raymondhill.net", - "default_area": "menupanel", - "pname": "ublock-origin", - "sha256": "sha256:b9e1c868bd1ac1defcabf2e01776d1a90effba34b07fe6a21350d45f022e0e9f", - "url": "https://addons.mozilla.org/firefox/downloads/file/4492375/ublock_origin-1.64.0.xpi", - "version": "1.64.0" - }, - "vhack-libredirect": { - "addonId": "vhack-libredirect@addons.vhack.eu", - "default_area": "navbar", - "pname": "vhack-libredirect", - "sha256": "sha256:08ccfd4b32ba15b357252208da7f383099ed5aefb9e92ffb5b9ae33f9146caf6", - "url": "https://addons.mozilla.org/firefox/downloads/file/4427811/vhack_libredirect-3.0.2.xpi", - "version": "3.0.2" - } -} diff --git a/modules/by-name/fi/firefox/extensions.json.license b/modules/by-name/fi/firefox/extensions.json.license deleted file mode 100644 index eae6a84c..00000000 --- a/modules/by-name/fi/firefox/extensions.json.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/modules/by-name/fi/firefox/module.nix b/modules/by-name/fi/firefox/module.nix deleted file mode 100644 index b5c1ff9a..00000000 --- a/modules/by-name/fi/firefox/module.nix +++ /dev/null @@ -1,248 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - lib, - config, - pkgs, - modules, - ... -}: let - cfg = config.soispha.programs.firefox; - - mkAllowedExtension = extension: - lib.attrsets.nameValuePair extension.addonId { - installation_mode = "normal_installed"; - updates_disabled = true; - inherit (extension) default_area; - install_url = "file://${builtins.fetchurl { - inherit - (extension) - url - sha256 - ; - }}"; - }; - - allowedExtensions = - builtins.listToAttrs - (builtins.map mkAllowedExtension (builtins.attrValues - cfg.extensions)); - - mkBlockedExtension = id: - lib.attrsets.nameValuePair id { - install_mode = "blocked"; - }; - blockedExtensions = builtins.listToAttrs (builtins.map mkBlockedExtension [ - # these are the default search engines - "addons-search-detection@mozilla.com" - "amazon@search.mozilla.org" - "bing@search.mozilla.org" - "ddg@search.mozilla.org" - "google@search.mozilla.org" - "wikipedia@search.mozilla.org" - ]); - - mkProfile = import ./profile.nix {inherit config pkgs;}; -in { - options.soispha.programs.firefox = { - enable = lib.mkEnableOption "firefox"; - - profiles = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule { - options = { - id = lib.mkOption { - type = lib.types.int; - description = "The id of this profile."; - }; - name = lib.mkOption { - type = lib.types.str; - description = "The name of this profile"; - }; - }; - }); - description = "A list of profies to create besides the default `default` profile."; - default = {}; - apply = value: - lib.attrsets.mapAttrs' (name: value: lib.attrsets.nameValuePair name (mkProfile value)) - value; - }; - - extensions = lib.mkOption { - type = lib.types.attrsOf ( - lib.types.submodule { - options = { - addonId = lib.mkOption { - type = lib.types.str; - example = "addon@darkreader.org"; - description = "The addon id of this extension"; - }; - default_area = lib.mkOption { - type = lib.types.enum ["navbar" "menupanel"]; - example = "navbar"; - description = '' - Where to put this extension by default. - `navbar` means into the top-left bar as icon. - `menupanel` means hidden behind a “all extensions” button. - ''; - }; - pname = lib.mkOption { - type = lib.types.str; - example = "darkreader"; - description = "The package name of this extension"; - }; - sha256 = lib.mkOption { - type = lib.types.str; - example = "sha256:f565b2263a71626a0310380915b7aef90be8cc6fe16ea43ac1a0846efedc2e4c"; - description = "The fetchurl copatible hash of this extension"; - }; - url = lib.mkOption { - type = lib.types.str; - example = "https://addons.mozilla.org/firefox/downloads/file/4439735/darkreader-4.9.103.xpi"; - description = "The download url of this extension."; - }; - version = lib.mkOption { - type = lib.types.str; - example = "4.9.103"; - description = "The version of this extension"; - }; - }; - } - ); - - default = builtins.fromJSON (builtins.readFile ./extensions.json); - - description = '' - A list of the extensions that should be installed. - You can use a tool like `generate_extensions` to generate this config. - ''; - }; - }; - - config = lib.mkIf cfg.enable { - programs.firefox = { - enable = true; - preferencesStatus = "locked"; - - languagePacks = ["en-CA" "de" "sv-SE"]; - - nativeMessagingHosts.packages = [ - pkgs.tridactyl-native - pkgs.keepassxc - ]; - - # NOTE: See https://mozilla.github.io/policy-templates for documentation <2023-10-21> - policies = { - # NixOS manages this already - DisableAppUpdate = true; - - DisableFirefoxAccounts = true; - DisableFirefoxScreenshots = true; - - # KeepassXC does this for me - DisableMasterPasswordCreation = true; - - # I use a self-hosted services for that - DisablePocket = true; - - # I don't want to lose my data - DisableProfileRefresh = true; - - DisableDeveloperTools = false; - - DisplayBookmarksToolbar = "newtab"; - DisplayMenuBar = "default-off"; - - DNSOverHTTPS = { - Enabled = true; - Locked = false; - }; - # The concept of a "default browser" does not apply to my NixOS config - DontCheckDefaultBrowser = true; - - ExtensionSettings = - { - "*" = { - # Blocking the extension install here, also blocks the 'about:debugging' page - - # blocked_install_message = '' - # You can't install a extension manually, - # please specify it in your NixOS configuration - # ''; - installation_mode = "allowed"; - }; - } - // allowedExtensions - // blockedExtensions; - RequestedLocales = config.programs.firefox.languagePacks; - - ExtensionUpdate = false; - - HardwareAcceleration = true; - - # KeepassXC and such things - OfferToSaveLogins = false; - PasswordManagerEnabled = false; - - PDFjs = { - Enabled = true; - # Don't honor documents right to be un-copy-able - EnablePermissions = false; - }; - - SearchBar = "unified"; - }; - - # Beware, that we already set them per-profile in the home-manager config. - preferences = {}; - }; - - home-manager.users.soispha = { - imports = [ - modules.arkenfox-nixos.hmModules.arkenfox - ]; - - home.sessionVariables = { - # Improve touch input and make scrolling smother - MOZ_USE_XINPUT2 = "1"; - - # Tell Firefox to use Wayland - MOZ_ENABLE_WAYLAND = 1; - - # Tell GTK to use portals - GTK_USE_PORTAL = 1; - - BROWSER = "firefox"; - }; - - programs.firefox = { - enable = true; - arkenfox = { - enable = true; - version = "133.0"; - }; - - # We use the NixOS module to provide us a package. - # HACK: Extract the package from the system-path to get a version for - # arkenfox-nixos to compare to. <2025-04-02> - package = lib.lists.findSingle (x: builtins.hasAttr "pname" x && x.pname == "firefox") "none" "multiple" config.environment.systemPackages; - - profiles = - { - default = mkProfile { - isDefault = true; - id = 0; - name = "default"; - }; - } - // cfg.profiles; - }; - }; - }; -} diff --git a/modules/by-name/fi/firefox/profile.nix b/modules/by-name/fi/firefox/profile.nix deleted file mode 100644 index d82bfafa..00000000 --- a/modules/by-name/fi/firefox/profile.nix +++ /dev/null @@ -1,189 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - config, - pkgs, -}: preConfig: ({ - userChrome = ./userChrome.css; - - bookmarks = { - force = true; - settings = []; - }; - - search = { - default = "brave-search"; - privateDefault = "brave-search"; - force = true; - engines = import ./search_engines {inherit pkgs;}; - - order = [ - # DEFAULT - "brave-search" - - # NIX - "nix-packages" - "nix-options" - "nixpkgs-issues" - "homemanager-options" - "nixos-wiki" - "nixpkgs-pull-request-tracker" - - # RUST - "rust-std" - "rust-tokio" - - # OTHER - "google-scholar" - "wikipedia" - "arch-wiki" - ]; - }; - - settings = { - "browser.download.dir" = "${config.home-manager.users.soispha.xdg.userDirs.download}"; - # "browser.download.useDownloadDir" = true; - # "browser.download.folderList" = 2; - - # QoL - "general.autoScroll" = false; - "browser.tabs.insertAfterCurrent" = true; - "browser.tabs.loadInBackground" = true; - "browser.ctrlTab.recentlyUsedOrder" = false; - "browser.search.widget.inNavBar" = true; - "findbar.highlightAll" = true; - - "devtools.toolbox.host" = "right"; - "devtools.toolsidebar-width.inspector" = 700; - - # Keep translations useful - "browser.translations.automaticallyPopup" = true; - "browser.translations.neverTranslateLanguages" = "de"; - - # Improve Tab UI - "browser.tabs.inTitlebar" = 1; - "browser.toolbars.bookmarks.visibility" = "never"; - "browser.places.importBookmarksHTML" = true; - - # Theme - "extensions.activeThemeID" = "firefox-alpenglow@mozilla.org"; - "extensions.extensions.activeThemeID" = "firefox-alpenglow@mozilla.org"; - - # disable updates (pretty pointless with nix) - "extensions.update.autoUpdateDefault" = false; - "extensions.update.enabled" = false; - "app.update.channel" = "default"; - "browser.shell.checkDefaultBrowser" = false; - - # Allow my custom css - "toolkit.legacyUserProfileCustomizations.stylesheets" = true; - }; - - arkenfox = { - enable = true; - "0000".enable = true; - "0100" = { - enable = true; - "0102"."browser.startup.page".value = 3; - "0103"."browser.startup.homepage".value = "file:///home/dt/home.html"; - "0104"."browser.newtabpage.enabled".value = true; - }; - "0200" = { - enable = true; - }; - "0300" = { - enable = true; - }; - "0400" = { - enable = false; - }; - "0600" = { - enable = true; - }; - "0700" = { - enable = true; - "0710"."network.trr.mode" = { - enable = true; - value = 3; - }; - }; - "0800" = { - enable = true; - }; - "0900" = { - enable = true; - }; - "1000" = { - enable = true; - "1001"."browser.cache.disk.enable".value = true; - "1003"."browser.sessionstore.privacy_level".value = 0; - }; - "1200" = { - enable = true; - "1241"."security.mixed_content.block_display_content".enable = true; - }; - "1600" = { - enable = true; - }; - "1700" = { - enable = true; - }; - "2000" = { - enable = true; - }; - "2400" = { - enable = true; - }; - "2600" = { - enable = true; - "2603" = { - "browser.download.start_downloads_in_tmp_dir".value = false; - "browser.helperApps.deleteTempFileOnExit".value = false; - }; - "2615"."permissions.default.shortcuts" = { - value = 2; - enable = true; - }; - }; - "2700" = { - enable = true; - }; - "2800" = { - enable = false; - "2810"."privacy.sanitize.sanitizeOnShutdown".value = false; - }; - "4000" = { - enable = true; - }; - "4500" = { - enable = true; - }; - "5000" = { - enable = true; - "5003"."signon.rememberSignons" = { - enable = true; - value = false; - }; - }; - "6000" = { - enable = true; - }; - "7000" = { - enable = true; - }; - "8000" = { - enable = true; - }; - "9000" = { - enable = true; - }; - }; - } - // preConfig) diff --git a/modules/by-name/fi/firefox/search_engines/default.nix b/modules/by-name/fi/firefox/search_engines/default.nix deleted file mode 100644 index f36be0a7..00000000 --- a/modules/by-name/fi/firefox/search_engines/default.nix +++ /dev/null @@ -1,113 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{pkgs, ...}: { - # DEFAULT - brave-search = { - name = "Brave Search"; - urls = [{template = "https://search.brave.com/search?q={searchTerms}";}]; - icon = ./logos/brave.svg; - definedAliases = ["@bs"]; - }; - - # NIX - nix-packages = { - name = "Nix packages"; - urls = [{template = "https://search.nixos.org/packages?type=packages&query={searchTerms}";}]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@np"]; - }; - - nix-functions = { - name = "Nix functions"; - urls = [{template = "https://noogle.dev/q?term={searchTerms}";}]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@ng"]; - }; - - nixos-options = { - name = "NixOS options"; - urls = [{template = "https://search.nixos.org/options?type=options&query={searchTerms}";}]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@no"]; - }; - homemanager-options = { - name = "Home-Manager options"; - urls = [{template = "https://home-manager-options.extranix.com/?query={searchTerms}&release=master";}]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@nh"]; - }; - - nixpkgs-issues = { - name = "Nixpkgs issues"; - urls = [{template = "https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+{searchTerms}";}]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@ni"]; - }; - nixpkgs-pull-requests = { - name = "Nixpkgs pull requests"; - urls = [{template = "https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+{searchTerms}";}]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@nr"]; - }; - - nixpkgs-pull-requests-tracker = { - name = "Nixpkgs pull requests tracker"; - urls = [{template = "https://nixpk.gs/pr-tracker.html?pr={searchTerms}";}]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@nt"]; - }; - nixos-wiki = { - name = "NixOS Wiki"; - urls = [{template = "https://wiki.nixos.org/w/index.php?search={searchTerms}";}]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@nw"]; - }; - - # RUST - rust-std = { - name = "Rust std"; - urls = [{template = "https://doc.rust-lang.org/std/?search={searchTerms}";}]; - icon = ./logos/rust_std.svg; - definedAliases = ["@rs"]; - }; - rust-tokio = { - name = "Rust tokio"; - urls = [{template = "https://docs.rs/tokio/latest/tokio/index.html?search={searchTerms}";}]; - icon = ./logos/rust_tokio.png; - definedAliases = ["@rt"]; - }; - - # OTHER - google-scholar = { - name = "Google Scholar"; - urls = [{template = "https://scholar.google.com/scholar?hl=en&q={searchTerms}";}]; - icon = ./logos/google_scholar.ico; - definedAliases = ["@gs"]; - }; - wikipedia = { - name = "Wikipedia"; - urls = [{template = "https://en.wikipedia.org/wiki/{searchTerms}";}]; - icon = ./logos/wikipedia.svg; - definedAliases = ["@wp"]; - }; - arch-wiki = { - name = "Arch Wiki"; - urls = [{template = "https://wiki.archlinux.org/index.php?search={searchTerms}";}]; - icon = ./logos/arch_linux.svg; - definedAliases = ["@aw"]; - }; - - "wikipedia".metaData.hidden = true; - "ddg".metaData.hidden = true; - "bing".metaData.hidden = true; - "google".metaData.hidden = true; - "Amazon.de".metaData.hidden = true; - "ebay".metaData.hidden = true; -} diff --git a/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg b/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg deleted file mode 100644 index 949b5c5f..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M31.994-.006c-2.85 6.985-4.568 11.554-7.74 18.332 1.945 2.062 4.332 4.462 8.2 7.174-4.168-1.715-7-3.437-9.136-5.224-4.06 8.47-10.42 20.538-23.327 43.73C10.145 58.15 18 54.54 25.338 53.16c-.315-1.354-.494-2.818-.48-4.345l.012-.325c.16-6.5 3.542-11.498 7.547-11.158s7.118 5.886 6.957 12.386a18.36 18.36 0 0 1-.409 3.491c7.25 1.418 15.03 5.02 25.037 10.797l-5.42-10.026c-2.65-2.053-5.413-4.726-11.05-7.62 3.875 1.007 6.65 2.168 8.8 3.467-17.1-31.84-18.486-36.07-24.35-49.833z" fill="#1793d1" fill-rule="evenodd"/></svg> \ No newline at end of file diff --git a/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg.license b/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg.license deleted file mode 100644 index eae6a84c..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/arch_linux.svg.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/modules/by-name/fi/firefox/search_engines/logos/brave.svg b/modules/by-name/fi/firefox/search_engines/logos/brave.svg deleted file mode 100644 index 09dd2e42..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/brave.svg +++ /dev/null @@ -1,25 +0,0 @@ -<svg width='100' height='129' xmlns='http://www.w3.org/2000/svg'> - <style> - @keyframes bounce{to{transform:translateY(5%)}} - </style> - <defs> - <linearGradient x1='0%' y1='50.706%' y2='50.706%' id='a'> - <stop stop-color='#F50' offset='0%'/> - <stop stop-color='#FF2000' offset='100%'/> - </linearGradient> - <linearGradient x1='2.148%' y1='50.706%' y2='50.706%' id='b'> - <stop stop-color='#FA3F2E' offset='0%'/> - <stop stop-color='#FF2000' offset='46.132%'/> - <stop stop-color='#FF2000' offset='100%'/> - </linearGradient> - <linearGradient x1='50%' y1='100%' x2='96.767%' y2='100%' id='c'> - <stop stop-color='#FFF' offset='0%'/> - <stop stop-color='#F4F4F4' offset='100%'/> - </linearGradient> - </defs> - <g fill='none' fill-rule='evenodd' style='animation:bounce 1s infinite alternate ease-in-out'> - <path d='M99.914 37.337l-3.616-9.848 2.512-5.657a1.941 1.941 0 0 0-.391-2.148l-6.835-6.936a11.014 11.014 0 0 0-11.464-2.676l-1.91.665L68.226.014H31.524L21.67 10.876l-1.858-.656a11.04 11.04 0 0 0-11.574 2.7l-6.956 7.067a1.541 1.541 0 0 0-.309 1.711l2.625 5.872L0 37.413l2.329 8.875 10.605 40.45a20.6 20.6 0 0 0 7.949 11.545s12.876 9.11 25.583 17.384c1.117.729 2.286 1.26 3.54 1.241 1.254.017 2.422-.512 3.537-1.244 14.271-9.384 25.562-17.417 25.562-17.417a20.61 20.61 0 0 0 7.936-11.556l10.555-40.467 2.318-8.887z' fill='url(#a)'/> - <path d='M31.565.033l-9.73 10.987-.803-.554c-6.463-2.01-9.277-.647-13.447 3.23l-.923.996 5.093-.996c1.407 0 5.342.133 6.167.416 3.473 1.195 4.437 2.593 6.662 4.059l1.069.359 10.385 2.083a4.21 4.21 0 0 0 1.96-.096l4.879-1.602c4.416-1.711 9.227-1.79 14.238 0l4.786 1.622a4.645 4.645 0 0 0 2.272.14l.859-.162 10.493-2.344.17-.422.723-.583c4.463-3.249 8.017-4.822 14.867-4.152h.527l-.315-.424c-5.711-4.543-9.193-3.178-12.401-2.124l-.877.3L68.281.033H31.565z' fill='url(#b)'/> - <path d='M53.472 72.856l1.388.576c1.496.62 3.903 1.73 5.346 2.464l4.096 2.085c1.444.733 1.548 2.106.23 3.05l-3.493 2.505a73.241 73.241 0 0 0-4.602 3.644l-4.406 3.853c-1.21 1.059-3.17 1.064-4.356.014a605.63 605.63 0 0 0-4.368-3.823 71.635 71.635 0 0 0-4.614-3.612l-3.481-2.465c-1.324-.937-1.23-2.317.207-3.066l4.118-2.148a80.664 80.664 0 0 1 5.33-2.495l1.388-.579c1.495-.621 2.835-1.131 2.979-1.131h1.258c.142 0 1.484.506 2.98 1.128zm34.992-33.039l-.263.946c-.703.878-2.184 2.563-3.293 3.746L74.713 55.38c-1.11 1.182-1.735 2.665-1.102 4.159l1.375 3.399c.632 1.492.694 3.962.088 5.62a10.013 10.013 0 0 1-3.065 4.315l-1.064.87c-1.255 1.026-3.478 1.296-4.941.598l-4.696-2.234c-1.462-.695-3.643-2.153-4.848-3.24l-4.443-4.005a2.07 2.07 0 0 1-.109-2.968l10.82-7.32c1.342-.908 2.052-2.587 1.29-4.018l-3.847-7.02c-.763-1.432-1.068-3.334-.679-4.228.39-.894 1.948-2.095 3.464-2.67l12.559-4.68c1.514-.575 1.433-1.169-.179-1.32l-8.025-.6c-1.613-.151-2.796.084-4.355.52l-6.074 1.508c-1.56.436-1.89 2.1-1.597 3.695l2.506 13.626c.294 1.596.437 3.202.32 3.571-.118.37-1.506.964-3.086 1.323l-2.077.473c-1.58.359-4.167.375-5.75.038l-2.514-.537c-1.584-.339-2.976-.918-3.094-1.286-.118-.369.024-1.978.317-3.572l2.49-13.629c.292-1.595-.04-3.257-1.6-3.692l-6.076-1.5c-1.56-.436-2.743-.666-4.355-.514l-8.025.606c-1.613.153-1.692.747-.178 1.32l12.567 4.665c1.514.574 3.074 1.774 3.464 2.668.392.892.088 2.794-.672 4.227l-3.84 7.021c-.76 1.433-.048 3.112 1.295 4.018l10.83 7.31a2.07 2.07 0 0 1-.106 2.967l-4.439 4.012c-1.202 1.087-3.382 2.547-4.844 3.246l-4.693 2.24c-1.461.698-3.686.432-4.94-.592L27.72 72.9c-1.392-1.136-2.455-2.626-3.122-4.447-.558-1.524-.5-3.992.13-5.486l1.372-3.4c.63-1.494.003-2.977-1.108-4.158L14.786 44.552c-1.11-1.18-2.593-2.864-3.296-3.74l-.265-.947-.166-.527c-.015-.607.201-2.542.447-3.066.246-.521 1.189-2.049 2.096-3.393l2.184-3.239a91.717 91.717 0 0 1 3.484-4.75l3.201-4.023c1.01-1.268 1.87-2.3 2-2.292.006-.008 1.312.236 2.902.541l4.85.933c1.59.306 3.344.642 3.898.746.554.105 2.267-.218 3.809-.719l3.487-1.131c1.54-.502 3.879-1.162 5.195-1.468l1.219.018 1.22-.02c1.315.305 3.654.962 5.195 1.46l3.49 1.13c1.541.498 3.255.82 3.808.714.555-.105 2.308-.445 3.898-.753l4.848-.937c1.59-.308 2.897-.553 2.99-.545.042-.008.903 1.021 1.914 2.29l3.206 4.019a90.663 90.663 0 0 1 3.49 4.746l2.188 3.235c.909 1.342 2.328 3.786 2.416 4.342.09.556.15 1.507.136 2.114l-.166.527z' fill='url(#c)'/> - </g> -</svg> diff --git a/modules/by-name/fi/firefox/search_engines/logos/brave.svg.license b/modules/by-name/fi/firefox/search_engines/logos/brave.svg.license deleted file mode 100644 index eae6a84c..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/brave.svg.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico b/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico deleted file mode 100644 index 85d0c664..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico +++ /dev/null Binary files differdiff --git a/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico.license b/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico.license deleted file mode 100644 index eae6a84c..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/google_scholar.ico.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg b/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg deleted file mode 100644 index 0091b5a8..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg width="100%" height="100%" viewBox="0 0 1200 800" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"> - <g id="Layer-1" serif:id="Layer 1"> - <g transform="matrix(1,0,0,1,597.344,637.02)"> - <path d="M0,-279.559C-121.238,-279.559 -231.39,-264.983 -312.939,-241.23L-312.939,-38.329C-231.39,-14.575 -121.238,0 0,0C138.76,0 262.987,-19.092 346.431,-49.186L346.431,-230.37C262.987,-260.465 138.76,-279.559 0,-279.559" style="fill:rgb(165,43,0);fill-rule:nonzero;"/> - </g> - <g transform="matrix(1,0,0,1,1068.75,575.642)"> - <path d="M0,-53.32L-14.211,-82.761C-14.138,-83.879 -14.08,-84.998 -14.08,-86.121C-14.08,-119.496 -48.786,-150.256 -107.177,-174.883L-107.177,2.643C-79.932,-8.849 -57.829,-21.674 -42.021,-35.482C-46.673,-16.775 -62.585,21.071 -75.271,47.686C-96.121,85.752 -103.671,118.889 -102.703,120.53C-102.086,121.563 -94.973,110.59 -84.484,92.809C-60.074,58.028 -13.82,-8.373 -4.575,-25.287C5.897,-44.461 0,-53.32 0,-53.32" style="fill:rgb(165,43,0);fill-rule:nonzero;"/> - </g> - <g transform="matrix(1,0,0,1,149.064,591.421)"> - <path d="M0,-99.954C0,-93.526 1.293,-87.194 3.788,-80.985L-4.723,-65.835C-4.723,-65.835 -11.541,-56.989 0.465,-38.327C11.055,-21.872 64.1,42.54 92.097,76.271C104.123,93.564 112.276,104.216 112.99,103.187C114.114,101.554 105.514,69.087 81.631,32.046C70.487,12.151 57.177,-14.206 49.189,-33.675C71.492,-19.559 100.672,-6.755 135.341,4.265L135.341,-204.17C51.797,-177.622 0,-140.737 0,-99.954" style="fill:rgb(165,43,0);fill-rule:nonzero;"/> - </g> - <g transform="matrix(-65.8097,-752.207,-752.207,65.8097,621.707,796.312)"> - <path d="M0.991,-0.034L0.933,0.008C0.933,0.014 0.933,0.02 0.933,0.026L0.99,0.069C0.996,0.073 0.999,0.08 0.998,0.087C0.997,0.094 0.992,0.1 0.986,0.103L0.92,0.133C0.919,0.139 0.918,0.145 0.916,0.15L0.964,0.203C0.968,0.208 0.97,0.216 0.968,0.222C0.965,0.229 0.96,0.234 0.953,0.236L0.882,0.254C0.88,0.259 0.877,0.264 0.875,0.27L0.91,0.33C0.914,0.336 0.914,0.344 0.91,0.35C0.907,0.356 0.9,0.36 0.893,0.361L0.82,0.365C0.817,0.369 0.813,0.374 0.81,0.379L0.832,0.445C0.835,0.452 0.833,0.459 0.828,0.465C0.824,0.47 0.816,0.473 0.809,0.472L0.737,0.462C0.733,0.466 0.729,0.47 0.724,0.474L0.733,0.544C0.734,0.551 0.731,0.558 0.725,0.562C0.719,0.566 0.711,0.568 0.704,0.565L0.636,0.542C0.631,0.546 0.626,0.549 0.621,0.552L0.615,0.621C0.615,0.629 0.61,0.635 0.604,0.638C0.597,0.641 0.589,0.641 0.583,0.638L0.521,0.602C0.52,0.603 0.519,0.603 0.518,0.603L0.406,0.729C0.406,0.729 0.394,0.747 0.359,0.725C0.329,0.705 0.206,0.599 0.141,0.543C0.109,0.52 0.089,0.504 0.09,0.502C0.093,0.499 0.149,0.509 0.217,0.554C0.278,0.588 0.371,0.631 0.38,0.619C0.38,0.619 0.396,0.604 0.406,0.575C0.406,0.575 0.406,0.575 0.406,0.575C0.407,0.576 0.407,0.576 0.406,0.575C0.406,0.575 0.091,0.024 0.305,-0.531C0.311,-0.593 0.275,-0.627 0.275,-0.627C0.266,-0.639 0.178,-0.598 0.12,-0.566C0.055,-0.523 0.002,-0.513 0,-0.516C-0.001,-0.518 0.018,-0.533 0.049,-0.555C0.11,-0.608 0.227,-0.707 0.256,-0.726C0.289,-0.748 0.301,-0.73 0.301,-0.73L0.402,-0.615C0.406,-0.614 0.41,-0.613 0.415,-0.613L0.47,-0.658C0.475,-0.663 0.483,-0.664 0.49,-0.662C0.497,-0.66 0.502,-0.655 0.504,-0.648L0.522,-0.58C0.527,-0.578 0.533,-0.576 0.538,-0.574L0.602,-0.608C0.608,-0.612 0.616,-0.612 0.623,-0.608C0.629,-0.605 0.633,-0.599 0.633,-0.592L0.637,-0.522C0.642,-0.519 0.647,-0.515 0.652,-0.512L0.721,-0.534C0.728,-0.536 0.736,-0.535 0.741,-0.531C0.747,-0.526 0.75,-0.519 0.749,-0.512L0.738,-0.443C0.742,-0.439 0.746,-0.435 0.751,-0.431L0.823,-0.439C0.83,-0.44 0.837,-0.437 0.842,-0.432C0.847,-0.426 0.848,-0.419 0.845,-0.412L0.821,-0.347C0.824,-0.342 0.828,-0.337 0.831,-0.332L0.903,-0.327C0.911,-0.327 0.917,-0.322 0.92,-0.316C0.924,-0.31 0.924,-0.302 0.92,-0.296L0.883,-0.236C0.885,-0.231 0.887,-0.226 0.889,-0.22L0.959,-0.202C0.966,-0.2 0.972,-0.195 0.974,-0.188C0.976,-0.181 0.974,-0.174 0.969,-0.168L0.92,-0.116C0.921,-0.111 0.923,-0.105 0.924,-0.099L0.988,-0.068C0.995,-0.065 0.999,-0.059 1,-0.052C1.001,-0.045 0.997,-0.038 0.991,-0.034ZM0.406,0.575C0.406,0.575 0.406,0.575 0.406,0.575C0.406,0.575 0.406,0.575 0.406,0.575Z" style="fill:url(#_Linear1);fill-rule:nonzero;"/> - </g> - <g transform="matrix(1,0,0,1,450.328,483.629)"> - <path d="M0,167.33C-1.664,165.91 -2.536,165.068 -2.536,165.068L140.006,153.391C23.733,0 -69.418,122.193 -79.333,135.855L-79.333,167.33L0,167.33Z" style="fill-rule:nonzero;"/> - </g> - <g transform="matrix(1,0,0,1,747.12,477.333)"> - <path d="M0,171.974C1.663,170.554 2.536,169.71 2.536,169.71L-134.448,159.687C-18.12,0 69.421,126.835 79.335,140.497L79.335,171.974L0,171.974Z" style="fill-rule:nonzero;"/> - </g> - <g transform="matrix(-1.53e-05,-267.211,-267.211,1.53e-05,809.465,764.23)"> - <path d="M1,-0.586C1,-0.586 0.768,-0.528 0.524,-0.165L0.5,-0.064C0.5,-0.064 1.1,0.265 0.424,0.731C0.424,0.731 0.508,0.586 0.405,0.197C0.405,0.197 0.131,0.376 0.14,0.736C0.14,0.736 -0.275,0.391 0.324,-0.135C0.324,-0.135 0.539,-0.691 1,-0.736L1,-0.586Z" style="fill:url(#_Linear2);fill-rule:nonzero;"/> - </g> - <g transform="matrix(1,0,0,1,677.392,509.61)"> - <path d="M0,-92.063C0,-92.063 43.486,-139.678 86.974,-92.063C86.974,-92.063 121.144,-28.571 86.974,3.171C86.974,3.171 31.062,47.615 0,3.171C0,3.171 -37.275,-31.75 0,-92.063" style="fill-rule:nonzero;"/> - </g> - <g transform="matrix(1,0,0,1,727.738,435.209)"> - <path d="M0,0.002C0,18.543 -10.93,33.574 -24.408,33.574C-37.885,33.574 -48.814,18.543 -48.814,0.002C-48.814,-18.539 -37.885,-33.572 -24.408,-33.572C-10.93,-33.572 0,-18.539 0,0.002" style="fill:white;fill-rule:nonzero;"/> - </g> - <g transform="matrix(1,0,0,1,483.3,502.984)"> - <path d="M0,-98.439C0,-98.439 74.596,-131.467 94.956,-57.748C94.956,-57.748 116.283,28.178 33.697,33.028C33.697,33.028 -71.613,12.745 0,-98.439" style="fill-rule:nonzero;"/> - </g> - <g transform="matrix(1,0,0,1,520.766,436.428)"> - <path d="M0,0C0,19.119 -11.27,34.627 -25.173,34.627C-39.071,34.627 -50.344,19.119 -50.344,0C-50.344,-19.124 -39.071,-34.627 -25.173,-34.627C-11.27,-34.627 0,-19.124 0,0" style="fill:white;fill-rule:nonzero;"/> - </g> - <g transform="matrix(-1.53e-05,-239.021,-239.021,1.53e-05,402.161,775.388)"> - <path d="M0.367,0.129C-0.364,-0.441 0.223,-0.711 0.223,-0.711C0.259,-0.391 0.472,-0.164 0.472,-0.164C0.521,-0.548 0.525,-0.77 0.525,-0.77C1.203,-0.256 0.589,0.161 0.589,0.161C0.627,0.265 0.772,0.372 0.906,0.451L1,0.77C0.376,0.403 0.367,0.129 0.367,0.129Z" style="fill:url(#_Linear3);fill-rule:nonzero;"/> - </g> - </g> - <defs> - <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,1.38778e-17,-1,0,-0.000650515)"><stop offset="0" style="stop-color:rgb(247,76,0);stop-opacity:1"/><stop offset="0.33" style="stop-color:rgb(247,76,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(244,150,0);stop-opacity:1"/></linearGradient> - <linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,-1,0,1.23438e-06)"><stop offset="0" style="stop-color:rgb(204,58,0);stop-opacity:1"/><stop offset="0.15" style="stop-color:rgb(204,58,0);stop-opacity:1"/><stop offset="0.74" style="stop-color:rgb(247,76,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(247,76,0);stop-opacity:1"/></linearGradient> - <linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,1.32349e-23,1.32349e-23,-1,0,-9.1568e-07)"><stop offset="0" style="stop-color:rgb(204,58,0);stop-opacity:1"/><stop offset="0.15" style="stop-color:rgb(204,58,0);stop-opacity:1"/><stop offset="0.74" style="stop-color:rgb(247,76,0);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(247,76,0);stop-opacity:1"/></linearGradient> - </defs> -</svg> diff --git a/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg.license b/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg.license deleted file mode 100644 index eae6a84c..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/rust_std.svg.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png b/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png deleted file mode 100644 index f1de55ff..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png +++ /dev/null Binary files differdiff --git a/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png.license b/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png.license deleted file mode 100644 index eae6a84c..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/rust_tokio.png.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg b/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg deleted file mode 100644 index dc32f984..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [<!ENTITY st0 "opacity:.22;fill:#231F20;"><!ENTITY st1 "opacity:.34;fill:url(#SVGID_25_);"><!ENTITY st2 "opacity:.19;fill:#231F20;"><!ENTITY st3 "opacity:.18;fill:url(#SVGID_42_);"><!ENTITY st4 "opacity:.73;fill:#FFF;"><!ENTITY st5 "opacity:.35;fill:url(#SVGID_6_);"><!ENTITY st6 "opacity:.53;fill:#FFF;"><!ENTITY st7 "opacity:.43;fill:url(#SVGID_23_);"><!ENTITY st8 "opacity:.25;fill:#231F20;"><!ENTITY st9 "opacity:.53;fill:url(#SVGID_9_);"><!ENTITY st10 "opacity:.88;fill:#231F20;"><!ENTITY st11 "opacity:.31;fill:url(#SVGID_24_);"><!ENTITY st12 "fill:#232323;"><!ENTITY st13 "opacity:.68;fill:url(#SVGID_22_);"><!ENTITY st14 "opacity:.28;fill:#231F20;"><!ENTITY st15 "opacity:.38;fill:url(#SVGID_43_);"><!ENTITY st16 "fill:url(#SVGID_1_);"><!ENTITY st17 "fill:url(#SVGID_2_);"><!ENTITY st18 "fill:url(#SVGID_4_);"><!ENTITY st19 "opacity:.45;fill:url(#SVGID_5_);"><!ENTITY st20 "opacity:.17;fill:#FFF;"><!ENTITY st21 "opacity:.3;fill:#505050;"><!ENTITY st22 "fill:#616161;"><!ENTITY st23 "fill:#FFF;"><!ENTITY st24 "opacity:.2;fill:url(#SVGID_41_);"><!ENTITY st25 "opacity:.69;fill:url(#SVGID_3_);"><!ENTITY st26 "opacity:.45;fill:url(#SVGID_39_);"><!ENTITY st27 "opacity:.96;fill:url(#SVGID_10_);"><!ENTITY st28 "opacity:.3;fill:#FFF;"><!ENTITY st29 "fill:#9FA2A3;"><!ENTITY st30 "opacity:.73;fill:url(#SVGID_8_);"><!ENTITY st31 "fill:#6B6B6B;"><!ENTITY st32 "opacity:.36;fill:#231F20;"><!ENTITY st33 "opacity:.5;fill:url(#SVGID_7_);"><!ENTITY st34 "opacity:.1;fill:#232323;"><!ENTITY st35 "fill:url(#SVGID_11_);"><!ENTITY st36 "fill:url(#SVGID_12_);"><!ENTITY st37 "fill:url(#SVGID_13_);"><!ENTITY st38 "fill:url(#SVGID_14_);"><!ENTITY st39 "fill:url(#SVGID_15_);"><!ENTITY st40 "fill:url(#SVGID_16_);"><!ENTITY st41 "fill:url(#SVGID_17_);"><!ENTITY st42 "fill:url(#SVGID_18_);"><!ENTITY st43 "fill:url(#SVGID_19_);"><!ENTITY st44 "fill:url(#SVGID_20_);"><!ENTITY st45 "fill:url(#SVGID_21_);"><!ENTITY st46 "fill:url(#SVGID_26_);"><!ENTITY st47 "fill:url(#SVGID_27_);"><!ENTITY st48 "fill:url(#SVGID_28_);"><!ENTITY st49 "fill:url(#SVGID_29_);"><!ENTITY st50 "fill:url(#SVGID_30_);"><!ENTITY st51 "fill:url(#SVGID_31_);"><!ENTITY st52 "fill:url(#SVGID_33_);"><!ENTITY st53 "fill:url(#SVGID_34_);"><!ENTITY st54 "fill:url(#SVGID_35_);"><!ENTITY st55 "fill:url(#SVGID_36_);"><!ENTITY st56 "fill:url(#SVGID_37_);"><!ENTITY st57 "fill:url(#SVGID_38_);"><!ENTITY st58 "fill:url(#SVGID_40_);"><!ENTITY st59 "opacity:.1;fill:#231F20;"><!ENTITY st60 "opacity:.5;fill:#141414;"><!ENTITY st61 "opacity:.38;fill:#231F20;"><!ENTITY st62 "opacity:.83;fill:url(#SVGID_32_);">]><svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="103px" height="94px" viewBox="0 0 103 94"><title>Wikipedia logo version 2</title><radialGradient id="SVGID_1_" cx="244.5713" cy="-427.1392" r="68.6868" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#FFF"/><stop offset=".4835" stop-color="#EAEAEB"/><stop offset=".9451" stop-color="#A9ABAE"/><stop offset="1" stop-color="#999B9E"/></radialGradient><path style="&st16;" d="M49.85,17.003c0.014-0.606-0.392-1.27-0.392-1.27l-0.025-0.058c0,0-0.487-0.949-1.301-1.228c-0.815-0.278-1.478,0.342-1.478,0.342s-0.114,0.131-0.428,0.494c-0.313,0.364-0.507,0.666-1.198,0.938c-0.692,0.271-1.379,0.204-1.743,0.033c-0.365-0.172-0.457-0.537-0.457-0.537s-0.229-0.722-0.313-1.049c-0.086-0.331-0.308-1.694-0.308-1.694s-0.492-2.747-0.535-3.304c0,0,1.475-0.126,3.686-0.775c2.3-0.673,3.043-1.206,3.043-1.206s-0.432-0.156-0.484-0.662c-0.051-0.507-0.089-1.19-0.089-1.19s-0.089-0.5,0.483-1.139c0.572-0.64,1.354-0.863,1.763-0.953c0.41-0.089,1.281-0.17,2.092-0.134c0.813,0.038,1.266,0.112,1.594,0.291c0.327,0.178,0.356,0.61,0.356,0.61l-0.009,1.146c0,0-0.035,0.402,0.262,0.529c0,0,0.505,0.305,2.197,0.133c0,0,0.719-0.126,1.845-0.46c1.125-0.335,4.129-1.229,4.554-1.341c0.426-0.111,0.953-0.291,1.645-0.469c0.693-0.179,2.041-0.626,2.309-0.73c0.27-0.104,1.811-0.618,2.928-0.81c1.114-0.195,2.226-0.186,2.813,0.149c0,0,0.357,0.304,0.521,0.662c0.162,0.358,0.476,0.863,0.92,1.088c0.457,0.227,0.754,0.371,1.877,0.273c0,0,0.021-0.096-0.396-0.37c-0.417-0.277-0.991-0.701-0.991-0.701s-0.334-0.245-0.408-0.447c-0.072-0.202-0.043-0.306-0.043-0.306l0.877-1.406c0,0,0-0.172,0.506-0.238c0.506-0.067,1.074-0.134,1.742-0.313c0.67-0.178,0.789-0.312,0.789-0.312l0.578,0.178c0,0,3.547,2.853,4.655,3.583l0.198-0.239c0,0,0.437,0.018,0.828,0.172c0.393,0.154,0.979,0.562,0.979,0.562s1.613,1.31,2.072,2.2l0.222,0.679l-0.102,0.161c0,0,0.919,1.307,2.096,2.602c0,0,1.229,1.664,1.689,2.09c0,0-0.108-0.399-0.203-0.849l0.339-0.226l0.2-0.144l0.617,0.259c3.575,4.811,6.435,10.424,8.144,16.328l-0.121,0.484l0.396,0.501c1.129,4.212,1.729,8.643,1.729,13.211c0,1.122-0.038,2.236-0.109,3.339l-0.304,0.511l0.226,0.555C99.95,72.645,78.057,93.131,51.38,93.131c-18.502,0-34.702-9.854-43.637-24.601l-0.102-0.365l-0.205-0.151c-3.387-5.742-5.682-12.205-6.595-19.104l0.212-0.524l-0.336-0.482c-0.213-1.892-0.322-3.812-0.322-5.758c0-2.985,0.255-5.909,0.748-8.755l0.25-0.562l-0.087-0.328C2.463,26.451,4.689,20.783,7.78,15.7l0.684-0.384l0.081,0.032c0,0,0.233-0.169,0.354-0.217l0.076-0.023c0,0,1.179-1.971,1.625-2.601c0,0,0.542-0.348,0.745-0.407c0,0,0.124-0.016,0.189,0.076c0,0,0.496-0.432,1.699-2.054c0.004-0.005,0.007-0.011,0.012-0.017c0,0-0.114-0.076-0.131-0.174c-0.018-0.097,0.108-0.591,0.173-0.717s0.108-0.156,0.108-0.156s1.722-2.032,3.151-3.238c0,0,0.26-0.202,0.678-0.25c0,0,1.472-0.613,3.264-2.184c0,0,0.051-0.289,0.478-0.858c0.428-0.57,1.456-1.163,2.222-1.337c0.764-0.174,0.896-0.038,0.896-0.038l0.064,0.065l0.515,0.766c0,0,0.565-0.316,1.413-0.604c0.847-0.289,0.979-0.262,0.979-0.262l0.823,1.336l-0.987,2c0,0-0.644,1.421-1.655,2.185c0,0-0.472,0.284-1.12,0.127c-0.648-0.157-1.072,0.333-1.072,0.333l-0.17,0.14c0,0,0.14-0.024,0.346-0.103c0,0,0.158,0.065,0.274,0.223c0.114,0.158,0.913,1.175,0.913,1.175s0.005,0.837-0.415,1.938c-0.419,1.1-1.467,2.891-1.467,2.891s-0.733,1.424-1.075,2.253c-0.342,0.829-0.515,1.765-0.488,2.262c0,0,0.187,0.062,0.707-0.202c0.655-0.332,1.083,0.027,1.083,0.027s0.719,0.53,1.041,0.881c0.262,0.289,0.802,1.765,0.209,3.224c0,0-0.402,1.008-1.377,1.724c0,0-0.216,0.332-1.529,0.174c-0.368-0.043-0.585-0.276-1.372-0.2c-0.785,0.077-1.231,0.815-1.231,0.815l0.013-0.024c-0.692,0.999-1.154,2.458-1.154,2.458l-0.057,0.165c0,0-0.241,0.509-0.292,1.752c-0.053,1.284,0.284,3.109,0.284,3.109s7.876-1.387,9.88-0.055l0.58,0.532c0,0,0.046,0.174-0.031,0.376c-0.08,0.204-0.375,0.673-0.987,1.113c-0.611,0.438-1.222,1.583-0.313,2.304c1.034,0.818,1.691,0.766,3.43,0.468c1.74-0.297,2.898-1.269,2.898-1.269s0.972-0.72,0.783-1.628c-0.188-0.908-1.017-1.189-1.017-1.189s-0.658-0.423-0.141-1.238c0,0,0.141-0.689,2.553-1.316c2.414-0.626,6.812-1.52,10.557-1.989c0,0-2.539-8.223-0.738-9.289c0,0,0.438-0.296,1.224-0.408l0.72-0.037c0.131-0.027,0.343,0.005,0.796,0.045c0.453,0.038,1.001,0.076,1.678-0.441c0.676-0.519,0.697-0.819,0.697-0.819"/><radialGradient id="SVGID_2_" cx="197.6416" cy="-371.8613" r="0" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#FFF"/><stop offset=".4835" stop-color="#EAEAEB"/><stop offset=".9451" stop-color="#A9ABAE"/><stop offset="1" stop-color="#999B9E"/></radialGradient><path style="&st17;" d="M-16.122-14.641"/><linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="456.2744" y1="510.1602" x2="502.7757" y2="582.9122" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#8A8A8A"/><stop offset=".5687" stop-color="#606060"/><stop offset=".5914" stop-color="#FFF"/><stop offset=".6116" stop-color="#585858"/><stop offset="1" stop-color="#303030"/></linearGradient><path style="&st25;" d="M82.447,79.307l0.451,0.168c-0.032,0.061-0.067,0.119-0.101,0.179c-0.864,1.573-0.936,1.927-1.36,2.253c-0.424,0.326-0.58,0.539-1.443,0.695c-0.865,0.156-1.771,1.175-1.771,1.175s-0.875,0.835-0.48,0.866c0.396,0.025,1.177-0.609,1.177-0.609s0.497-0.354,0.625-0.255c0.125,0.099-0.539,0.751-0.539,0.751s-1.161,1.176-2.479,1.982l-0.396,0.213c0,0,1.869-1.392,2.764-2.395c0,0,0.185-0.271-0.185,0.057c-0.369,0.325-1.332,0.821-1.741,0.821c-0.41,0,0.016-0.563,0.016-0.563s0.596-0.768,1.812-1.758c1.22-0.994,2.239-0.922,2.239-0.922s0.227,0.043,0.253-0.271c0.028-0.313,0.312-0.863,0.312-0.863s0.453-1.032,1.674-2.749c1.218-1.714,1.77-2.195,1.77-2.195s1.588-1.629,2.423-3.259c0,0,0.581-1.006-0.364-0.255c-0.951,0.753-2.211,1.7-3.44,2.014c-1.233,0.312-1.349-0.836-1.349-0.836s-0.271-1.884,1.049-3.344c1.188-1.316,2.492-1.273,3.684-1.415c1.188-0.144,2.21-1.571,2.21-1.571s0.82-0.922,1.289-3.797c0.218-1.337,0.067-2.244-0.144-2.818l0.021-0.647l-0.368-0.021c-0.078-0.106-0.135-0.153-0.135-0.153s-0.297-0.299-0.607-0.524c-0.313-0.227-0.692-0.649-1.063-1.457c0,0-1.019-2.11-0.792-5.156c0.227-3.047,2.762-2.762,2.762-2.762s1.475,0.143,1.76-0.298c0.283-0.438,0.553-0.993,0.649-2.223c0.101-1.233-0.396-2.408-0.396-2.408s-0.186-0.609-1.049-0.708c-0.863-0.1-1.051,0.169-1.051,0.169s-0.255,0.072-0.723,1.09c-0.471,1.021-0.75,1.488-1.602,1.702c-0.849,0.211-2.023,0.099-2.549-0.992c-0.515-1.072-1.757-3.693-2.351-5.772l0.084-0.735l-0.325-0.471c-0.063-0.396-0.117-0.846-0.13-1.236c-0.026-0.992-0.312-2.097-0.638-3.2c-0.326-1.106-1.459-2.972-1.672-3.399c-0.324-0.667-0.621-0.949-1.021-0.893c-0.396,0.056-0.339,0.056-0.513,0.056c-0.168,0-0.266,0.212-0.311,0.425c-0.042,0.212-0.375,1.315-1.104,1.812c-0.752,0.51-1.147,0.737-2.438,0.85c0,0-1.487,0.099-2.661-2.097C71,29.36,71.301,27.96,71.398,27.45c0.099-0.51,0.539-1.247,1.229-1.388c0.693-0.141,1.119-0.184,1.119-0.184s1.122-0.01,1.603-0.071c0.551-0.071,0.283-1.006,0.283-1.006s-0.361-2.371-2.348-4.318l-0.096-0.487l-0.756-0.381c-1.881-2.04-4.354-5.354-4.354-5.354s-1.105-1.048-0.17-2.493c0,0,0.438-0.963,1.742-0.792c0.419,0.081,0.457,0.123,0.818,0.199c0.481,0.099,1.008,0.225,1.478-0.398c0,0,0.438-0.792-0.271-1.812s-0.923-1.742-1.785-1.687c0,0-0.397-0.055-0.793,0.384C68.702,8.1,67.682,8.378,67.086,8.44c-0.679,0.071-2.252-0.528-3.156-2.082c-0.513-0.874-0.752-1.35-0.865-1.595l0.231-0.34l0.72,0.08c0.186,0.358,0.549,1.056,0.978,1.812c0.552,0.978,1.048,1.118,1.373,1.261c0.325,0.141,1.049-0.071,1.431-0.283c0.385-0.213,0.766-0.695,1.43-0.738c0.668-0.043,1.629,0.071,2.311,0.793c0.682,0.723,1.531,2.224,1.459,2.932c-0.068,0.708-0.111,1.403-1.035,1.699c-0.921,0.298-1.303,0.043-1.884-0.084c-0.581-0.128-0.864-0.072-1.104,0.211c-0.242,0.284-0.512,0.892-0.412,1.162c0.102,0.27,0.186,0.454,0.75,1.262c0.566,0.806,3.474,4.25,4.031,4.766l-0.152,0.698l0.968,0.176c0.625,0.724,1.358,1.668,1.687,2.263c0.493,0.907,0.752,2.337,0.779,3.002c0.025,0.666-0.299,0.963-0.299,0.963s-0.313,0.524-2.012,0.524c-1.517,0-1.614,0.297-1.614,0.297s-0.47,0.467-0.369,1.615c0.103,1.146,0.616,2.344,1.56,3.37c0.778,0.851,2.252-0.006,2.748-0.295c0.51-0.299,0.822-1.264,0.822-1.264s0.102-1.217,1.432-1.217c1.377,0,1.969,1.318,1.969,1.318s0.963,1.295,1.941,4.121c0.481,1.389,0.566,2.281,0.566,2.281l0.126,1.668l-0.513,0.892l0.732,0.312c0.135,0.541,0.348,1.24,0.686,2.044c0,0,1.008,2.381,1.443,3.286c0.44,0.906,0.896,0.766,1.264,0.808c0,0,0.85,0.113,1.16-0.282c0.313-0.398,0.61-1.092,0.61-1.092s0.663-1.812,2.138-1.657c1.475,0.156,1.84,1.092,2.096,2.168c0.256,1.074,0.313,3.229-0.479,4.545c-0.798,1.318-1.688,1.135-1.688,1.135s-1.813-0.17-2.225,0.213c-0.41,0.382-0.623,0.724-0.681,1.613c-0.058,0.894,0.026,2.336,0.751,4.08c0.631,1.523,1.146,1.361,1.432,1.728c0.284,0.368,1.188,1.204,1.104,3.272c-0.082,2.067-0.791,4.149-1.586,5.439c-0.793,1.288-1.997,2.053-1.997,2.053s-0.338,0.211-1.076,0.311c-0.735,0.102-1.784,0.086-2.534,0.513c-0.75,0.426-0.992,1.501-1.063,1.971c-0.069,0.468-0.112,1.529,0.921,1.413c1.034-0.109,2.577-1.4,2.577-1.4s1.486-1.104,1.685-0.752c0.199,0.354-0.636,1.784-0.636,1.784s-1.035,1.562-1.898,2.523c-0.709,0.791-1.641,1.868-2.431,3.102L82.447,79.307L82.447,79.307z"/><linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="425.2861" y1="502.9512" x2="445.7861" y2="598.6606" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#A8A9AB"/><stop offset="1" stop-color="#636668"/></linearGradient><path style="&st18;" d="M23.441,22.732c-0.007,0.008-0.013,0.018-0.021,0.025C23.428,22.75,23.434,22.74,23.441,22.732z"/><linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="421.0684" y1="504.3701" x2="441.068" y2="597.7433" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#A8A9AB"/><stop offset="1" stop-color="#636668"/></linearGradient><path style="&st19;" d="M38.188,89.707l0.163,0.01c-0.163-0.147-0.37-0.281-0.62-0.414c-0.699-0.371-3.731-2.375-4.669-3.009c-0.936-0.633-2.575-1.7-3.297-1.478c-0.554,0.172-0.475,0.394-0.804,0.556c-0.331,0.157-0.687,0.052-1.504-0.384c-0.818-0.434-1.424-0.725-3.02-2.239c-1.245-1.185,1.595-0.118,1.595-0.118s0.619,0.262,0.343-0.385c-0.277-0.646-1.676-2.333-2.994-3.691c-1.068-1.098-1.674-1.86-2.435-2.97l-0.566-0.661l0.007-0.166c-0.018-0.024-0.035-0.054-0.052-0.078c0,0-1.874-3.377-1.676-4.617c0,0,0.068-0.828,1.241-1.188c0.817-0.251,0.71,0.542,3.112,0.975c0,0,2.07,0.559,2.611-0.945c0.539-1.505-0.567-3.393-0.567-3.393s-1.449-2.656-3.244-2.758c-0.95-0.053-0.692,0.586-2.125,0.926c0,0-1.913,0.184-2.519-0.963c-0.734-1.389-1.04-2.969-1.015-4.022c0.022-1,0.054-1.079,0.119-1.371c0.045-0.206,0.192-0.582,0.254-1.128l-0.134-0.667l0.204-0.501c0.002-0.26-0.004-0.535-0.021-0.83c-0.091-1.66-0.213-4.221-0.437-5.71c-0.223-1.491-0.633-3.798-1.991-3.866c0,0-0.671-0.051-1.634,0.885c-0.884,0.856-1.684-0.708-1.728-1.663c-0.053-1.121,0.131-2.254,0.409-2.795c0.277-0.541,1.042-0.567,1.186-0.555c0.146,0.013,0.555,0.171,1.043,0.474c0.488,0.305,1.16,0.305,1.557-0.092c0.395-0.394,0.947-0.856,1.173-2.598c0.224-1.741,0.224-3.547,0.013-5.71l-0.225-0.484l1.339-0.289c-0.001-0.017-0.021-0.126-0.032-0.193c0-0.002,0-0.003,0-0.005c-0.002-0.017-0.005-0.032-0.007-0.049c-0.001-0.003-0.001-0.005-0.001-0.007c-0.003-0.019-0.007-0.038-0.009-0.057c0-0.001-0.001-0.001-0.001-0.003c-0.003-0.02-0.006-0.042-0.009-0.062c0-0.001,0-0.001,0-0.001c-0.004-0.023-0.007-0.045-0.011-0.068c0-0.004-0.001-0.006-0.001-0.008c-0.002-0.022-0.006-0.045-0.008-0.066c-0.001-0.006-0.001-0.01-0.003-0.017c-0.002-0.023-0.005-0.046-0.009-0.069c-0.001-0.004-0.001-0.007-0.002-0.014c-0.003-0.026-0.007-0.05-0.011-0.076c0-0.002,0-0.004,0-0.005c-0.004-0.024-0.008-0.05-0.011-0.076c-0.001-0.007-0.001-0.01-0.003-0.017c-0.002-0.025-0.006-0.052-0.009-0.08c-0.001-0.005-0.001-0.011-0.002-0.021c-0.005-0.027-0.007-0.053-0.011-0.081c-0.001-0.006-0.002-0.013-0.002-0.019c-0.002-0.029-0.006-0.058-0.01-0.087c0-0.004-0.001-0.008-0.003-0.014c-0.002-0.028-0.005-0.056-0.009-0.082c-0.001-0.006-0.001-0.011-0.002-0.016c-0.002-0.031-0.006-0.06-0.01-0.09c0-0.006-0.001-0.015-0.002-0.021c-0.004-0.03-0.006-0.061-0.011-0.09c0-0.007-0.001-0.015-0.002-0.022c-0.003-0.03-0.006-0.062-0.01-0.093c0-0.006-0.002-0.012-0.002-0.019c-0.003-0.032-0.005-0.063-0.009-0.094c0-0.002,0-0.005,0-0.009c-0.004-0.032-0.005-0.066-0.01-0.1c0-0.005,0-0.012-0.001-0.02c-0.002-0.033-0.005-0.065-0.007-0.098c-0.001-0.007-0.001-0.014-0.001-0.021c-0.004-0.033-0.006-0.067-0.008-0.099c0-0.005,0-0.012-0.001-0.02c-0.002-0.033-0.006-0.069-0.007-0.102c0-0.003,0-0.007-0.001-0.01c-0.002-0.033-0.004-0.066-0.006-0.1c-0.001-0.006-0.001-0.011-0.001-0.017c-0.001-0.032-0.003-0.068-0.005-0.1c0-0.008,0-0.014-0.001-0.021c-0.001-0.031-0.002-0.065-0.003-0.099c-0.001-0.006-0.001-0.013-0.001-0.021c-0.002-0.033-0.003-0.066-0.004-0.1c0-0.005,0-0.009,0-0.014c-0.001-0.032-0.001-0.066-0.002-0.099c0-0.003,0-0.005,0-0.009c0-0.034,0-0.067-0.001-0.101c0-0.005,0-0.013,0-0.017c0-0.033,0-0.067,0-0.098c0-0.005,0.001-0.012,0.001-0.019c0-0.032,0-0.065,0.001-0.095c0-0.005,0-0.009,0-0.015c0.001-0.033,0.001-0.065,0.003-0.099c0.052-1.244,0.292-1.752,0.292-1.752l0.057-0.164c0,0,0.46-1.459,1.154-2.459l-0.013,0.024c0,0,0.446-0.738,1.231-0.814c0.785-0.079,1.004,0.156,1.371,0.2c0.04,0.004,0.078,0.008,0.115,0.013c0.013,0.002,0.025,0.002,0.037,0.004c0.025,0.002,0.051,0.004,0.075,0.006c0.014,0.001,0.027,0.003,0.041,0.003c0.021,0.001,0.043,0.003,0.064,0.004c0.014,0.001,0.028,0.002,0.041,0.003c0.02,0.001,0.04,0.001,0.058,0.003c0.014,0,0.026,0,0.042,0c0.019,0.001,0.036,0.002,0.055,0.002c0.013,0.001,0.026,0.001,0.038,0.002c0.017,0,0.034,0,0.051,0c0.011,0,0.023,0,0.034,0c0.017,0,0.033,0,0.05,0c0.011,0,0.02-0.001,0.032-0.001c0.016-0.001,0.031-0.001,0.046-0.001c0.011-0.001,0.02-0.001,0.03-0.002c0.016,0,0.03-0.002,0.045-0.002c0.009,0,0.019,0,0.026-0.001c0.016-0.001,0.03-0.002,0.044-0.004c0.006,0,0.016-0.001,0.023-0.002c0.015-0.001,0.029-0.001,0.044-0.003c0.006-0.001,0.013-0.002,0.02-0.002c0.016-0.002,0.03-0.004,0.045-0.008c0.004,0,0.008,0,0.013-0.001c0.019-0.002,0.036-0.005,0.052-0.008l0,0c0.035-0.006,0.068-0.014,0.098-0.021c0,0,0,0,0.002-0.002c0.012-0.002,0.026-0.005,0.039-0.01c0.002,0,0.004,0,0.008-0.001c0.009-0.003,0.019-0.006,0.028-0.009c0.004,0,0.007-0.002,0.01-0.003c0.009-0.003,0.019-0.007,0.026-0.009c0.002-0.001,0.005-0.002,0.008-0.003c0.008-0.003,0.015-0.006,0.021-0.009c0.004-0.001,0.006-0.003,0.009-0.003c0.007-0.004,0.014-0.005,0.02-0.009c0.003-0.001,0.006-0.003,0.008-0.004c0.005-0.002,0.012-0.005,0.019-0.007c0.001-0.001,0.003-0.002,0.005-0.004c0.005-0.003,0.01-0.005,0.016-0.007c0.002-0.002,0.003-0.002,0.006-0.004c0.004-0.001,0.008-0.005,0.012-0.007c0.002-0.001,0.004-0.001,0.005-0.003c0.004-0.002,0.008-0.006,0.012-0.008c0.001,0,0.003-0.002,0.004-0.003c0.003-0.003,0.007-0.004,0.011-0.007c0.001-0.001,0.001-0.001,0.002-0.003c0.004-0.001,0.006-0.005,0.008-0.008h0.002c0.003-0.002,0.005-0.005,0.008-0.007l0.001-0.001c0.002-0.002,0.004-0.004,0.006-0.006s0.002-0.002,0.003-0.003c0.001,0,0.002-0.002,0.002-0.002c0.001-0.003,0.001-0.003,0.003-0.005c0.003-0.001,0.003-0.004,0.003-0.004c0.328-0.241,0.593-0.516,0.797-0.775c0.014-0.017,0.026-0.033,0.04-0.05c0.002-0.004,0.005-0.009,0.008-0.012c0.013-0.015,0.026-0.031,0.038-0.048c0.002-0.004,0.006-0.008,0.007-0.011c0.012-0.018,0.025-0.033,0.038-0.05c0.001,0,0.001,0,0.001-0.001c0.039-0.054,0.075-0.109,0.109-0.159c0-0.002,0.002-0.004,0.003-0.007c0.01-0.016,0.02-0.029,0.03-0.044c0.001-0.004,0.005-0.007,0.007-0.011c0.008-0.014,0.017-0.029,0.024-0.042c0.003-0.004,0.005-0.009,0.009-0.013c0.008-0.014,0.017-0.028,0.024-0.042l0.001-0.002c0.017-0.027,0.032-0.055,0.046-0.079c0.002-0.003,0.004-0.008,0.007-0.012c0.005-0.009,0.01-0.021,0.016-0.03c0.003-0.007,0.007-0.014,0.012-0.02c0.004-0.008,0.01-0.017,0.014-0.024c0.002-0.008,0.006-0.017,0.011-0.023c0.004-0.007,0.009-0.016,0.012-0.022c0.004-0.007,0.007-0.014,0.011-0.021c0.002-0.006,0.007-0.011,0.01-0.018c0.066-0.13,0.097-0.207,0.097-0.207c0.594-1.459,0.052-2.935-0.21-3.224c-0.32-0.354-1.041-0.883-1.041-0.883s-0.426-0.357-1.08-0.025c-0.521,0.264-0.711,0.201-0.711,0.201c-0.024-0.498,0.149-1.432,0.491-2.263c0.341-0.829,1.075-2.253,1.075-2.253s1.047-1.792,1.467-2.89c0.418-1.102,0.415-1.94,0.415-1.94s-0.795-1.019-0.91-1.177c-0.115-0.158-0.272-0.223-0.272-0.223c-0.205,0.078-0.345,0.103-0.345,0.103l0.169-0.14c0,0,0.424-0.492,1.073-0.334c0.648,0.158,1.119-0.126,1.119-0.126c1.011-0.764,1.654-2.187,1.654-2.187l0.988-1.997L27.059,1.12c0,0-0.131-0.028-0.979,0.259c0,0-0.773,1.905-1.725,3.087c0,0-0.374,0.552-0.664,0.416c-0.289-0.134-0.629-0.144-0.91-0.085c-0.281,0.06-1.156,0.349-1.948,1.413c-0.79,1.064-0.883,1.863-0.458,2.101c0.425,0.238,1.045-0.076,1.42-0.407c0.375-0.333,0.638-0.485,0.757-0.47c0.118,0.02,0.093,0.315,0.068,0.41c-0.026,0.094-0.154,1.364-1.625,3.913c-0.369,0.64-0.845,1.589-1.069,2.046l0.608,0.447l-0.999,0.503c-0.266,0.758-0.605,1.945-0.471,2.61c0.204,1.011,1.158,1.011,1.158,1.011s0.621,0.027,1.344-0.348c0.722-0.375,0.892,1.242,0.892,1.505c0,0.264-0.007,1.726-1.02,2.442c0,0-0.409,0.313-0.985,0.313c-0.579,0-0.954-0.169-0.954-0.169s-0.984-0.272-1.59,0.083c-0.604,0.358-1.326,1.098-1.897,2.17c-0.569,1.072-1.045,2.986-1.019,4.397c0.02,1.111,0.18,2.162,0.291,2.879l0.667,0.435l-0.543,0.623c0.079,1.136,0.168,3.363,0.155,4.109c-0.018,0.911-0.154,2.84-1.115,3.292c0,0-0.324,0.171-0.868-0.238s-1.132-0.426-1.37-0.435c-0.238-0.007-1.285,0.162-1.692,1.311c-0.408,1.145-0.375,2.688-0.29,3.597c0.086,0.91,0.876,2.458,1.872,2.458c0,0,0.484,0.035,1.055-0.553c0.568-0.586,0.902-0.637,1.156-0.629c0.255,0.009,0.749,0.272,1.072,2.851c0.307,2.442,0.437,4.442,0.414,6.668l0.605,0.392l-0.758,0.768c-0.042,0.199-0.089,0.417-0.142,0.626c-0.169,0.682-0.187,1.364-0.024,2.569c0.161,1.21,0.811,3.72,1.754,4.375c1.252,0.871,2.071,0.856,2.916,0.791c0.842-0.067,1.424-0.712,1.424-0.712s0.331-0.342,0.685-0.237c0.356,0.104,1.346,0.66,2.058,2.084c0.713,1.425,0.871,2.992-0.316,3.272c-1.187,0.272-3.231-0.846-3.231-0.846s-1.161-0.647-2.109,0.064c-0.951,0.713-0.977,1.807-0.502,3.15c0.261,0.738,0.782,1.938,1.513,3.188l0.721,0.302l-0.193,0.551c0.492,0.748,1.055,1.479,1.678,2.105c0,0,2.466,2.729,3.838,4.457c0,0,0.08,0.157-0.158,0.016c-0.238-0.146-1.266-0.621-1.82-0.566c-0.555,0.054-0.45,0.395-0.45,0.395s0.238,1.254,4.01,3.365c0,0,1.359,0.766,2.216,0.766c0,0,0.277,0.039,0.619-0.346c0.346-0.381,0.45-0.341,0.688-0.262c0.237,0.076,0.553,0.249,1.741,1.105c1.188,0.857,3.496,2.176,4.325,2.731c0.83,0.555,0.793,0.657,0.621,1.054c-0.171,0.396,0.593,0.619,0.593,0.619s1.899,0.855,2.928,0.846c1.029-0.016,1.464-0.119,2.097,0.012c0.632,0.133,1.28,0.291,1.345,0.346c0.066,0.053-0.315,0.038-0.315,0.038s-2.362-0.276-2.494-0.21c-0.13,0.066,0.014,0.184,0.99,0.436v0.006c1.245,0.217,2.507,0.387,3.782,0.51c-0.489-0.061-2.52-0.322-3.823-0.713c0,0-0.131-0.078,0.173-0.014c0.303,0.065,2.018,0.225,2.466,0.157c0.448-0.065-0.092-0.274-0.092-0.274s-0.897-0.425-2.889-0.582c0,0-0.803-0.055-1.503,0.014c-0.699,0.066-1.41-0.264-1.41-0.264s-1.028-0.317-0.78-0.646c0.126-0.165,0.137-0.336,0.065-0.502L38.188,89.707L38.188,89.707z"/><linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="444.7598" y1="550.8145" x2="473.8418" y2="550.8145" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#231F20"/><stop offset="1" stop-color="#474747"/></linearGradient><path style="&st5;" d="M62.342,86.16l-0.438,0.646c0.096,0.655-0.104,0.875-0.254,1.119c-0.156,0.26-0.59,0.592-0.375,1.185c0.218,0.59,1.687,0.401,2.535,0.144c0.852-0.26,1.569-0.49,2.134-0.693c0.562-0.198,0.719,0.086,0.719,0.086s0.246,0.175-0.574,0.606c-0.821,0.433-2.336,0.634-3.055,0.72c-0.724,0.086-0.506-0.043-1.586,0.33c-1.082,0.377-0.07,0.707-0.07,0.707c2.435,0.635,4.188,0.115,4.188,0.115l0.332-0.097c0.27-0.077,0.535-0.161,0.803-0.244c-2.021,0.456-3.326,0.149-3.739,0.095c-0.431-0.058-0.778-0.145-0.88-0.361c-0.102-0.215,0.479-0.2,0.479-0.2s1.683-0.188,3.24-0.69c1.557-0.506,1.932-0.98,1.871-1.341c-0.057-0.358-0.848-0.332-1.785-0.028c-0.937,0.305-2.334,0.75-2.662,0.821c-0.334,0.07-0.691,0.06-0.812-0.146c-0.114-0.203-0.216-0.53,0.146-0.905c0.36-0.376,0.402-0.694,0.402-0.694c0.055-0.254,0.057-0.523,0.021-0.8L62.342,86.16l0.545-0.118c-0.298-1.124-1.052-2.218-1.279-2.577c-0.314-0.507-0.836-0.793-2.393-0.535c-1.556,0.26-3.386,1.035-3.386,1.035s-1.888,0.997-3.298,0.812c-1.413-0.188-1.703-1.614-1.688-2.063c0.015-0.447,0.304-0.835,1.039-1.123c0.735-0.289,2.465-0.678,4.985-0.808s3.458-1.771,3.458-1.771c0.33-0.478,0.922-1.543-0.489-2.336c-1.41-0.791-1.441-0.593-2.119-1.107c-0.678-0.52-1.412-1.153-1.701-2.033c-0.025-0.084-0.066-0.197-0.104-0.292l-0.849-0.558l0.41-0.371c-0.34-0.67-0.693-1.271-0.693-1.271s-1.281-1.902-0.246-3.703c1.038-1.803,2.736-2.348,2.736-2.348s1.5-0.332,2.996,0.016c1.418,0.324,2.133-0.219,2.133-0.219s0.865-0.374,1.123-2.102c0.264-1.729-0.014-4.943-2.316-5.578c-2.307-0.633-3.527,0.563-3.527,0.563s-1.24,1.369-1.644,1.57c-0.404,0.201-1.022,0.563-1.022,0.563s-0.867,0.519-1.453,0.648c-0.393,0.086-1.791-1.771-1.933-3.201c-0.133-1.316-0.401-2.388-0.306-5.096l-0.485-0.63l0.537-0.533c0.101-2.999-0.417-5.116-1.188-6.461c-0.807-1.412-2.119-2.161-2.766-2.478c-0.648-0.318-2.147-0.462-3.17-0.086c-1.023,0.374-1.239,0.678-1.613,1.326c-0.376,0.648-0.836,0.605-0.836,0.605s-1.427,0.043-1.888-2.133c-0.646-3.049,0.359-4.035,0.359-4.035s0.318-0.476,1.369-0.619c1.053-0.144,1.73,0.115,2.537,0.315c0.806,0.202,1.41,0.116,2.419-0.374c1.008-0.491,1.442-1.297,1.238-2.739c-0.195-1.393-0.255-1.742-1.483-5.964l-0.875-0.46l0.583-0.579C44.87,23.032,44.8,20.35,44.8,20.35c-0.106-0.977,0.049-1.292,0.598-1.54c0.576-0.259,1.116-0.175,1.934-0.123c0.818,0.053,1.425-0.079,1.847-0.316c0.422-0.237,1.581-0.87,1.504-2.162c-0.08-1.292-1.109-2.824-1.953-3.351c-0.843-0.528-1.953-0.316-2.558,0.131c-0.606,0.45-0.845,1.029-1.214,1.214c-0.369,0.183-0.895,0.605-1.45,0.474c-0.554-0.132-0.581-1.371-0.818-2.77c-0.153-0.907-0.271-1.611-0.338-1.989l-0.678-0.254c0.044,0.557,0.535,3.304,0.535,3.304s0.223,1.364,0.308,1.692c0.086,0.329,0.314,1.05,0.314,1.05s0.092,0.364,0.456,0.535c0.365,0.172,1.052,0.24,1.743-0.032c0.692-0.271,0.886-0.572,1.199-0.938c0.315-0.364,0.429-0.493,0.429-0.493s0.663-0.622,1.478-0.343c0.813,0.278,1.299,1.228,1.299,1.228l0.028,0.06c0,0,0.403,0.661,0.392,1.269v-0.057c0,0-0.022,0.301-0.697,0.818c-0.676,0.519-1.226,0.479-1.678,0.442c-0.454-0.04-0.666-0.072-0.797-0.045l-0.719,0.038C45.178,18.303,44.74,18.6,44.74,18.6c-1.8,1.064,0.736,9.288,0.736,9.288l0,0L45.2,28.501c0,0,0.514,2.052,0.904,3.378c0.388,1.326,0.562,2.637,0.62,2.91c0.058,0.274,0.044,0.762-0.317,1.051c-0.359,0.289-1.239,0.534-1.425,0.562c-0.187,0.029-0.535-0.042-0.996-0.201c-0.462-0.158-0.922-0.187-0.922-0.187s-1.11-0.188-2.291,0.173c-1.182,0.359-2.076,1.569-2.148,3.083c-0.071,1.513-0.057,2.278,0.535,3.617c0.59,1.34,1.657,2.104,2.463,2.118c0.808,0.014,1.469-0.403,1.931-1.051c0.459-0.65,0.59-0.751,0.59-0.751c0.548-0.302,1.944-0.433,2.651-0.172c0.708,0.258,2.007,1.073,2.723,2.679c0.579,1.298,0.76,2.75,0.729,5.363l0.584,0.448l-0.61,0.703c-0.007,0.246-0.016,0.498-0.026,0.761c-0.143,3.876,0.72,5.864,0.72,5.864c0.491,1.065,1.023,1.83,1.745,2.318c0.719,0.489,1.699,0.156,2.018,0c0.315-0.158,1.194-0.563,1.943-1.037c0.749-0.477,0.725-0.679,1.629-1.515c0.907-0.833,2.076-0.604,2.076-0.604s1.107,0.028,1.74,1.313c0.637,1.283,0.509,3.109,0.347,3.773c-0.158,0.662-0.444,1.097-1.063,0.979c-0.621-0.114-1.645-0.217-2.019-0.231c-0.375-0.014-1.433-0.049-2.394,0.203c-0.938,0.244-2.205,0.92-3.414,2.883c-0.938,1.52-0.478,3.013-0.262,3.603c0.17,0.462,0.635,1.104,1.043,1.896l0.756,0.252l-0.35,0.656c0.398,0.963,0.701,1.493,1.305,2.151c0.648,0.705,1.672,1.251,2.881,1.714c1.213,0.462,0.662,1.282,0.662,1.282c-0.69,1.497-2.75,1.557-3.354,1.628c-0.604,0.07-1.872,0.188-3.058,0.447c-1.182,0.261-2.291,0.418-2.954,1.182c-0.661,0.764-0.402,1.557-0.013,2.393c0.388,0.834,1.427,1.28,2.853,1.226c1.426-0.058,2.35-0.476,3.214-0.851s2.362-0.809,2.81-0.937c0.445-0.129,1.051-0.39,1.498,0.26c0.482,0.701,0.994,1.697,1.229,2.45L62.342,86.16L62.342,86.16z"/><path style="&st34;" d="M101.566,51.162c0,0,0.347-3.236,0.457-4.392c0.018-0.173,0.031-0.343,0.045-0.513l-0.098-0.241c-0.459,5.815-0.938,7.727-0.938,7.727s0.013-0.037,0.031-0.101c0.189-0.817,0.357-1.646,0.51-2.48C101.568,51.162,101.566,51.162,101.566,51.162L101.566,51.162z"/><path style="&st34;" d="M91.268,12.579l0.328,0.413l0.279,0.5c1.021,1.648,2.846,4.295,2.846,4.295s0.739,0.958,0.905,0.968c0.164,0.01-0.084-0.741-0.084-0.741s-0.271-0.979,0.517,0.298c0.73,1.19,1.207,2.359,1.317,2.72c0.114,0.361,0.042,0.411,0.042,0.411s-0.146,0.072-0.146,0.33c0,0.505,0.496,1.659,0.496,1.659s1.545,3.926,2.07,5.563c0.526,1.641,1.133,4.368,1.133,4.368s0.187,0.804,0.207,1.174c0.021,0.371-0.063,0.381-0.229,0.186c-0.164-0.196-0.329-0.072-0.329-0.072s-0.175,0.072-0.175,0.773c0,0.7,0.085,2.346,0.217,3.615c0.152,1.505,0.616,2.133,0.616,2.133s0.413,0.618,0.526-0.577c0.096-1.028,0.185-0.228,0.185-0.228c0.196,1.557,0.062,4.544,0.03,4.955c-0.019,0.218-0.032,0.433-0.049,0.64l0.133-0.221c0.201-2.971,0.06-5.359,0.06-5.359s-0.144-1.323-0.3-1.311c-0.155,0.01-0.211,0.701-0.211,0.701s-0.065,0.467-0.156,0.456c-0.088-0.011-0.369,0.022-0.566-1.412c-0.199-1.436-0.156-2.949-0.156-2.949s-0.043-0.155,0.048-0.189c0.09-0.034,0.188,0.1,0.188,0.1s0.133,0.189,0.287,0.033c0.156-0.154,0.19-0.622-0.301-3.08c-0.288-1.454-0.711-2.896-1.006-3.832l-0.294-0.333l-0.058-0.718c0,0-0.311-0.913-1.033-2.737c-0.723-1.824-0.846-2.458-0.846-2.458s-0.045-0.2,0.066-0.234c0.111-0.032,0.091-0.178,0.091-0.178s-0.013-0.245-0.278-0.99c-0.268-0.746-0.426-1.281-1.356-2.86c-0.869-1.468-1.124-1.558-1.124-1.558s-0.426-0.234-0.112,0.591c0.313,0.823-0.075,0.232-0.075,0.232c-0.925-1.177-2.838-4.292-2.838-4.292l-0.537-0.373l-0.508-1.261l-0.015,0.01"/><path style="&st34;" d="M1.547,32.696l-0.183,0.37c-0.472,2.495-0.625,5.135-0.62,5.31c0.01,0.208-0.036,0.211-0.075,0.178c-0.042-0.035,0.03-0.16-0.048-0.16c-0.079,0-0.108,0.211-0.108,0.211L0.512,38.6c-0.021,0.288-0.038,0.574-0.053,0.861l0.016-0.003c0.068-0.098,0.097-0.028,0.097-0.028s-0.029,0.126,0.097,0.056c0.126-0.07,0.21-1.379,0.21-1.379s0.014-2.813,0.836-6.14c0.819-3.327,1.281-4.259,1.281-4.259s0.154-0.418,0.138-0.083C3.12,27.958,3.33,27.986,3.33,27.986c0.375-0.054,0.821-1.125,1.267-2.493c0.445-1.363,0.668-2.589,0.668-2.7c0-0.11-0.055-0.194-0.152-0.138c-0.098,0.056-0.125,0.014-0.125,0.014c-0.014-0.208,0.361-1.127,0.361-1.127c1.253-3.202,3.104-5.694,3.104-5.694l0.09-0.504c-0.164,0.254-0.27,0.419-0.421,0.661c-0.056,0.089-0.042,0.297-0.001,0.32c-0.201,0.191-0.365,0.35-0.476,0.456c-2.707,4.473-3.059,6.556-3.059,6.556c-0.017,0.214,0.004,0.311,0.111,0.306c0.065-0.003,0.251-0.349,0.116,0.354c-0.09,0.468-0.524,1.708-0.693,2.212c-0.171,0.505-0.358,0.85-0.495,0.826C3.49,27.01,3.49,26.801,3.49,26.801s-0.042-0.546-0.398,0.245c-0.356,0.791-0.713,1.859-1.425,4.65c-0.031,0.125-0.063,0.251-0.092,0.38L1.547,32.696L1.547,32.696z"/><path style="&st34;" d="M4.841,62.626c-0.15-0.401-0.264-0.722-0.179-0.581c0.085,0.143,0.198,0.432,0.462,0.725c0.263,0.291,0.442-0.226-0.622-3.104s-1.354-3.04-1.402-3.095c-0.046-0.058-0.215-0.237-0.167,0.167c0.045,0.404,0.018,0.656-0.51-1.146c-0.528-1.806-0.996-4.844-1.025-5.089c-0.027-0.243-0.169-1.778-0.396-3.594c-0.226-1.814-0.246-3.743-0.207-4.28c0.039-0.537-0.066-0.828-0.123-0.837c-0.056-0.008-0.094,0.047-0.131,0.284c-0.038,0.234-0.01,0.395-0.067,0.385c-0.057-0.009-0.076-0.471-0.076-0.471H0.391c0,0.05,0,0.1,0,0.151c0,0.174,0.001,0.345,0.002,0.519l0.039,0.402c0.033,0.597,0.129,0.354,0.135,0.246c0.006-0.109,0.03-0.329,0.03-0.329s0.103-0.884,0.084,0.02c-0.019,0.904,0.236,4.563,0.236,4.563c0.019,0.236,0.041,0.479,0.068,0.729l0.063,0.092l-0.042,0.104c0.265,2.425,0.795,5.086,0.795,5.086c0.507,2.417,1.11,3.846,1.308,4.25c0.198,0.405,0.236,0.085,0.17-0.271c-0.066-0.357,0.546,0.688,0.873,1.674c0.332,0.99,0.556,1.815,0.556,1.815s0.254,0.781,0.142,0.828c-0.113,0.046-0.292-0.293-0.292-0.293s-0.473-0.835-0.274-0.228c0.398,1.231,1.6,3.822,1.6,3.822l1.396,2.471C6.282,65.836,4.982,63.004,4.841,62.626L4.841,62.626z"/><path style="&st34;" d="M7.281,67.639c0.069,0.125,0.136,0.246,0.202,0.359L7.281,67.639z"/><path style="&st34;" d="M20.722,2.874C20.51,3.216,20.48,3.388,20.48,3.388s0.112-0.118,0.183-0.237C20.733,3.033,20.722,2.874,20.722,2.874z"/><path style="&st34;" d="M17.216,5.572c-0.417,0.048-0.677,0.25-0.677,0.25S16.889,5.761,17.216,5.572z"/><path style="&st34;" d="M84.005,4.909c0,0,0.247-0.03,0.347,0.02c0.101,0.049,0.066-0.158,0.066-0.158s-0.287-0.406-0.322-0.556c-0.32-0.089-0.611-0.1-0.611-0.1l-0.028,0.034c-0.01,0.075-0.036,0.188-0.012,0.297C83.441,4.448,83.917,4.811,84.005,4.909L84.005,4.909z"/><path style="&st34;" d="M87.487,7.88l0.095-0.152l-0.223-0.679c-0.004-0.012-0.012-0.022-0.021-0.036c-0.007,0.066-0.049,0.125-0.172,0.115c0,0-0.099-0.03-0.011,0.198C87.219,7.469,87.355,7.699,87.487,7.88L87.487,7.88z"/><path style="&st34;" d="M101.566,51.162c0,0,0.347-3.236,0.457-4.392c0.018-0.173,0.031-0.343,0.045-0.513l-0.098-0.241c-0.459,5.815-0.938,7.727-0.938,7.727s0.013-0.037,0.031-0.101c0.189-0.817,0.357-1.646,0.51-2.48C101.568,51.162,101.566,51.162,101.566,51.162L101.566,51.162z"/><linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="266.4922" y1="-395.2783" x2="295.9644" y2="-485.0349" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset=".0094" stop-color="#FCFCFC"/><stop offset=".0655" stop-color="#EEEEEE"/><stop offset=".1342" stop-color="#E5E5E5"/><stop offset=".2515" stop-color="#E3E3E3"/><stop offset=".3357" stop-color="#8A8A8A"/><stop offset=".4422" stop-color="#B8B8B8"/><stop offset="1" stop-color="#3B3B3B"/></linearGradient><path style="&st33;" d="M79.003,84.528c0,0,0.667-0.653,0.539-0.752c-0.128-0.101-0.623,0.256-0.623,0.256s-0.073,0.062-0.185,0.142l0.393-0.252c0,0-0.038,0.238-0.355,0.555c0,0-0.094,0.094-0.258,0.248c-0.957,0.938-2.386,1.998-2.386,1.998l0.396-0.211C77.844,85.703,79.003,84.528,79.003,84.528z"/><linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="460.4629" y1="512.5557" x2="509.5884" y2="573.3062" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#EFF0F0"/><stop offset=".5914" stop-color="#F0F1F2"/><stop offset=".599" stop-color="#787878"/><stop offset=".6456" stop-color="#EEEFF0"/><stop offset="1" stop-color="#D8D9DB"/></linearGradient><path style="&st30;" d="M82.984,39.705l0.51-0.891l-0.127-1.667c0,0-0.085-0.893-0.566-2.28c-0.979-2.828-1.941-4.122-1.941-4.122s-0.592-1.318-1.969-1.318c-1.33,0-1.431,1.219-1.431,1.219s-0.312,0.963-0.821,1.261c-0.5,0.29-1.972,1.146-2.748,0.296c-0.941-1.026-1.461-2.225-1.56-3.372c-0.101-1.146,0.367-1.615,0.367-1.615s0.1-0.296,1.614-0.296c1.703,0,2.014-0.525,2.014-0.525s0.324-0.296,0.297-0.963s-0.284-2.097-0.779-3.001c-0.324-0.596-1.058-1.537-1.684-2.261l-0.967-0.178l0.15-0.699c-0.56-0.514-3.465-3.959-4.031-4.766c-0.564-0.808-0.65-0.993-0.75-1.262c-0.099-0.269,0.17-0.877,0.412-1.161c0.238-0.283,0.521-0.341,1.104-0.212c0.58,0.127,0.961,0.381,1.886,0.084c0.919-0.297,0.962-0.992,1.033-1.699c0.071-0.708-0.78-2.209-1.458-2.932c-0.684-0.721-1.645-0.836-2.311-0.792c-0.664,0.042-1.047,0.523-1.433,0.737c-0.382,0.213-1.103,0.425-1.429,0.284c-0.326-0.142-0.823-0.284-1.375-1.261c-0.43-0.76-0.794-1.459-0.979-1.817L63.299,4.42v0.012c0,0,0.633,1.654,1.633,2.811c0.998,1.157,2.266,0.919,2.266,0.919s0.82-0.089,1.533-0.772c0.711-0.683,1.761-0.148,2.024,0.04c0.269,0.189,0.853,0.911,1.478,2.127c0.621,1.216-0.355,2.058-0.355,2.058s-0.555,0.535-1.691,0.088c-1.14-0.443-1.813,0.259-1.986,0.614c-0.182,0.357-0.508,0.99,0.076,1.73c0.584,0.742,3.178,4.273,4.916,5.945c1.74,1.672,2.314,3.047,2.682,4.342c0.365,1.297,0.079,1.899-0.521,2.018c-0.604,0.118-1.148,0.021-2.086,0.187c-0.94,0.17-1.349,0.367-1.543,1.653c-0.199,1.286,0.562,3.373,1.67,4.361c1.106,0.989,2.334,0.386,2.76,0.228c0.427-0.159,1.352-0.653,1.681-2.027c0.188-0.783,0.851-0.721,0.851-0.721s0.563-0.071,0.854,0.117c0.287,0.19,0.633,0.525,1.402,1.87c0.772,1.346,1.453,3.146,1.724,4.738C82.924,38.35,82.729,38.576,82.984,39.705c0.256,1.128,1.078,3.245,1.466,4.074c0.383,0.832,0.78,1.662,0.989,2.107c0.205,0.445,0.531,0.782,1.443,0.802c0.908,0.02,1.273-0.228,1.541-0.662c0.27-0.435,0.612-1.088,0.713-1.316c0.1-0.228,0.467-0.911,1.146-1.02c0.685-0.108,1.762,0.01,2.106,1.198c0.313,1.071,0.76,2.622-0.158,4.5c-0.65,1.334-1.129,0.859-2.451,0.948c0,0-1.165-0.01-1.781,0.921c-0.611,0.93-0.416,2.61-0.286,3.877s0.988,3.113,1.621,3.563c0.636,0.443,0.86,0.849,1.08,1.256c0.216,0.404,0.534,1.205,0.216,3.313c-0.313,2.106-0.979,3.74-1.867,4.521c-0.024,0.021-0.05,0.043-0.07,0.063c-0.067,0.065-0.141,0.135-0.219,0.201c-0.537,0.521-0.371,0.543-0.889,0.793c-0.594,0.289-0.988,0.207-1.958,0.365c-0.97,0.16-1.583,0.327-2.088,0.821c-0.503,0.495-1.243,1.409-0.979,3.187c0.148,0.986,1.318,0.584,2.229,0.111c-0.274,0.125-0.553,0.221-0.798,0.246c-1.033,0.113-0.991-0.949-0.921-1.415c0.069-0.47,0.313-1.544,1.063-1.97s1.799-0.41,2.533-0.512c0.738-0.101,1.076-0.313,1.076-0.313s1.205-0.766,1.997-2.055c0.793-1.289,1.502-3.371,1.587-5.438c0.084-2.068-0.821-2.902-1.104-3.271c-0.283-0.366-0.799-0.203-1.431-1.729c-0.724-1.74-0.81-3.188-0.751-4.079c0.057-0.892,0.27-1.231,0.682-1.612c0.41-0.383,2.223-0.213,2.223-0.213s0.893,0.185,1.686-1.134c0.793-1.317,0.738-3.471,0.481-4.546c-0.253-1.076-0.623-2.013-2.097-2.168c-1.471-0.152-2.138,1.66-2.138,1.66s-0.297,0.693-0.608,1.092c-0.312,0.395-1.16,0.285-1.16,0.285c-0.37-0.044-0.821,0.099-1.264-0.81c-0.438-0.906-1.442-3.286-1.442-3.286c-0.339-0.809-0.556-1.512-0.688-2.055L82.984,39.705L82.984,39.705z"/><linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="272.8721" y1="-392.8257" x2="302.4699" y2="-482.9646" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st9;" d="M82.487,79.313l0.801-0.479c0.788-1.231,1.72-2.31,2.431-3.103c0.863-0.961,1.896-2.522,1.896-2.522s0.835-1.431,0.638-1.784c-0.13-0.23-0.704,0.02-1.687,0.752c-3.674,2.746-3.971,1.246-3.971,1.246c0.422,2.438,4.729-1.633,5.108-1.375c-0.063,0.563-0.457,1.172-1.25,2.25c0,0-0.388,0.555-0.78,0.953c-0.369,0.432-0.578,0.641-0.578,0.641s-0.088,0.09-0.125,0.125c-0.471,0.541-1.024,1.242-1.595,2.018c-0.019,0.021-0.104,0.113-0.125,0.143c-0.295,0.416-0.491,0.73-0.702,1.062c-0.014,0.022-0.064,0.011-0.076,0.034c0-0.002-0.013,0.014-0.025,0.037c-0.245,0.39-0.373,0.713-0.508,0.959c-0.012,0.029-0.021,0.065-0.03,0.095c0,0-0.319,0.665-0.457,1.067c-0.14,0.405-0.12,0.547-0.623,0.625c-0.504,0.078-0.276-0.053-1.021,0.196c0,0-0.403,0.199-0.938,0.571c-0.027,0.021-0.057,0.042-0.082,0.063c-0.736,0.604-1.247,1.119-1.534,1.436c-0.051,0.063-0.099,0.13-0.146,0.195c0,0-0.157,0.168,0.051,0.188c0.206,0.021,0.633-0.01,1.008-0.169l0.088-0.057c-0.186,0.103-0.373,0.174-0.513,0.162c-0.396-0.026,0.479-0.864,0.479-0.864s0.906-1.019,1.771-1.175c0.862-0.156,1.021-0.371,1.444-0.693c0.426-0.327,0.494-0.682,1.359-2.254c0.03-0.059,0.064-0.115,0.098-0.176L82.487,79.313L82.487,79.313z"/><linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="444.6943" y1="510.9561" x2="469.7246" y2="592.0699" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#FFF"/><stop offset=".7473" stop-color="#F9F9F9"/><stop offset="1" stop-color="#D5D7D8"/></linearGradient><path style="&st27;" d="M55.064,72.686l0.408-0.377c-0.34-0.668-0.693-1.269-0.693-1.269s-1.282-1.901-0.245-3.703c1.036-1.803,2.737-2.348,2.737-2.348s1.5-0.332,2.996,0.017c1.418,0.323,2.133-0.22,2.133-0.22s0.865-0.376,1.123-2.104c0.261-1.729-0.014-4.94-2.317-5.576c-2.306-0.633-3.528,0.563-3.528,0.563s-1.242,1.369-1.644,1.57c-0.404,0.2-1.024,0.562-1.024,0.562s-0.865,0.52-1.453,0.648c-0.39,0.087-1.788-1.771-1.931-3.2c-0.133-1.313-0.4-2.385-0.305-5.084c0-0.005,0-0.01,0-0.017l-0.486-0.629l0.537-0.526c0.102-3-0.418-5.119-1.188-6.463c-0.805-1.414-2.118-2.163-2.766-2.479c-0.647-0.317-2.146-0.461-3.169-0.086c-1.022,0.375-1.237,0.677-1.613,1.325c-0.376,0.65-0.835,0.606-0.835,0.606s-1.427,0.044-1.89-2.132c-0.644-3.049,0.36-4.036,0.36-4.036s0.318-0.475,1.369-0.619c1.053-0.144,1.73,0.115,2.536,0.317c0.807,0.2,1.41,0.114,2.42-0.374c1.009-0.49,1.442-1.298,1.24-2.738c-0.196-1.397-0.249-1.727-1.484-5.966l-0.874-0.458l0.582-0.579c-1.182-4.271-1.257-6.961-1.257-6.961c-0.105-0.975,0.049-1.29,0.598-1.537c0.576-0.261,1.117-0.177,1.934-0.125c0.819,0.052,1.425-0.079,1.847-0.316c0.423-0.236,1.583-0.87,1.503-2.163c-0.078-1.292-1.108-2.823-1.951-3.35c-0.844-0.528-1.952-0.317-2.56,0.132c-0.606,0.447-0.843,1.028-1.213,1.212c-0.368,0.185-0.896,0.607-1.45,0.474c-0.554-0.132-0.581-1.372-0.818-2.77c-0.155-0.915-0.276-1.614-0.342-1.989l-0.674-0.254c0.043,0.557,0.535,3.304,0.535,3.304l0.294,1.624c0,0,0,0.007,0,0.02c0.006,0.018,0.009,0.036,0.013,0.05c0.019,0.079,0.049,0.18,0.082,0.289c0.114,0.215,0.37,0.456,0.942,0.502c1.076,0.089,1.772-0.468,2.025-0.709c0.254-0.239,0.86-0.911,0.86-0.911s0.329-0.632,1.253-0.494c0.922,0.14,1.238,0.773,1.403,1.013c0.167,0.242,1.57,1.961,0.672,2.861c-0.039,0.039-0.093,0.089-0.152,0.146c-0.104,0.111-0.245,0.246-0.446,0.399c-0.675,0.517-1.226,0.48-1.678,0.442c-0.453-0.039-0.665-0.07-0.795-0.043l-0.72,0.038c-0.787,0.11-1.224,0.408-1.224,0.408c-1.8,1.065,0.735,9.287,0.735,9.287s0.671,2.029,0.973,2.979c0.301,0.949,0.496,1.625,0.791,3.264c0.295,1.639-0.231,2.092-0.525,2.251c-0.294,0.158-0.984,0.568-1.77,0.604c-0.783,0.034-1.027-0.368-2.371-0.432c-1.345-0.065-2.246,0.345-2.661,0.906c-0.417,0.561-0.913,1.862-0.675,3.4c0.237,1.541,0.504,2.064,1.092,2.748c0.59,0.681,1.165,0.97,1.978,0.696c0.792-0.266,0.764-0.756,1.173-1.164c0.517-0.519,0.855-0.792,2.063-0.821c1.208-0.029,1.979,0.288,2.594,0.784c0.619,0.496,1.934,1.646,2.294,3.356c0.359,1.713,0.424,2.268,0.424,3.676s-0.101,2.978-0.064,4.381c0.036,1.4,0.187,2.841,0.577,3.795c0.386,0.955,0.926,1.755,1.4,2.18c0.475,0.426,0.896,0.438,1.373,0.252c0.475-0.188,1.511-0.771,2.373-1.324c0.861-0.555,0.797-0.99,1.576-1.502c0.875-0.576,1.799-0.605,2.457-0.486c0.661,0.112,1.676,0.631,2.092,1.889C63.059,60.58,63,61.998,63,61.998s0.035,1.186-0.445,1.876c-0.48,0.688-1.272,0.616-1.625,0.545c-0.354-0.071-1.094-0.136-1.094-0.136s-1.451-0.165-2.563,0.094c-1.105,0.258-2.077,1.085-2.73,1.896c-0.652,0.813-0.941,1.57-0.984,2.158c-0.043,0.59,0.027,1.595,0.642,2.572c0.612,0.979,0.712,1.432,1.409,2.827c0.695,1.396,2.15,2.17,2.201,2.206c0.05,0.037,1.388,0.523,1.89,0.949c0.505,0.425,0.555,0.826,0.411,1.208c-0.145,0.381-0.438,1.094-1.604,1.604c-1.166,0.512-2.591,0.523-3.496,0.617c-0.906,0.094-2.651,0.332-3.697,0.834c-1.043,0.503-0.97,1.454-0.97,1.454s-0.028,1.556,1.337,1.983c1.365,0.434,2.64,0,3.201-0.237c0.562-0.238,1.487-0.583,1.487-0.583s1.791-0.631,2.752-0.848c0.965-0.217,1.533-0.323,2.188,0.832c0.652,1.158,1.014,1.886,1.078,2.625c0.064,0.74-0.209,1.148-0.461,1.432c-0.25,0.279-0.217,0.46-0.217,0.46c-0.105,0.873,1.182,0.763,1.182,0.763s0.041-0.004,0.11-0.018c-0.26,0.021-0.499-0.021-0.59-0.178c-0.116-0.202-0.217-0.531,0.146-0.906c0.359-0.374,0.402-0.693,0.402-0.693c0.305-1.439-1.038-3.371-1.354-3.875c-0.315-0.503-0.836-0.791-2.394-0.531c-1.556,0.26-3.386,1.037-3.386,1.037s-1.891,0.995-3.299,0.809c-1.413-0.188-1.701-1.614-1.687-2.063c0.016-0.444,0.304-0.836,1.038-1.122c0.733-0.289,2.464-0.679,4.984-0.809c2.522-0.128,3.458-1.771,3.458-1.771c0.331-0.478,0.923-1.543-0.489-2.338c-1.412-0.789-1.44-0.589-2.116-1.104c-0.68-0.521-1.412-1.153-1.701-2.034c-0.026-0.084-0.07-0.198-0.108-0.291L55.064,72.686L55.064,72.686z"/><linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="390.042" y1="485.6797" x2="390.042" y2="485.6797" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#FFF"/><stop offset=".7473" stop-color="#F9F9F9"/><stop offset="1" stop-color="#D5D7D8"/></linearGradient><path style="&st35;" d="M-16.122-14.641"/><linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="390.042" y1="485.6797" x2="390.042" y2="485.6797" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#FFF"/><stop offset=".7473" stop-color="#F9F9F9"/><stop offset="1" stop-color="#D5D7D8"/></linearGradient><path style="&st36;" d="M-16.122-14.641"/><path style="&st34;" d="M92.002,13.363c1.021,1.649,2.844,4.295,2.844,4.295s0.256,0.332,0.5,0.605l0.01-0.011c0.011-0.375-0.051-0.571-0.06-0.621l-0.091-0.274c-0.021-0.367,0.438,0.095,0.611,0.288c-0.498-0.754-0.659-0.811-0.659-0.811s-0.423-0.234-0.111,0.59c0.312,0.824-0.075,0.233-0.075,0.233c-0.924-1.177-2.838-4.293-2.838-4.293l-0.553-0.383L92.002,13.363L92.002,13.363z"/><path style="&st34;" d="M101.539,51.352c0.014-0.063,0.023-0.125,0.034-0.188c-0.004,0-0.009,0-0.009,0s0.005-0.03,0.013-0.089C101.563,51.17,101.551,51.262,101.539,51.352L101.539,51.352z"/><path style="&st34;" d="M100.822,35.679c0.088-0.033,0.188,0.1,0.188,0.1s0.135,0.189,0.289,0.033c0.107-0.104,0.155-0.353,0.025-1.257c-0.004,0.229-0.053,0.409-0.137,0.59c-0.139,0.296-0.314,0.02-0.441-0.081c-0.129-0.098-0.168,0.07-0.168,0.07l-0.004,0.162c0,0.7,0.087,2.346,0.217,3.617c0.063,0.605,0.173,1.071,0.287,1.408l0.041,0.076c0.089,0.148,0.188,0.343,0.307,0.255c0.116-0.089,0.274-0.582,0.274-0.582l0.128-0.591c0.191,0.113,0.291,0.529,0.341,0.962c-0.002-0.037-0.004-0.056-0.004-0.056s-0.144-1.324-0.3-1.313c-0.155,0.01-0.21,0.701-0.21,0.701s-0.066,0.468-0.157,0.456c-0.088-0.011-0.365,0.022-0.564-1.412c-0.201-1.436-0.158-2.949-0.158-2.949S100.732,35.713,100.822,35.679L100.822,35.679z"/><path style="&st34;" d="M99.696,28.566l0.298,0.341c0.479,1.494,0.996,3.843,1.092,4.264c-0.027-0.139-0.056-0.286-0.088-0.441c-0.288-1.454-0.711-2.896-1.006-3.832L99.696,28.566l-0.05-0.702c-0.004-0.01-0.006-0.016-0.006-0.016s-0.312-0.913-1.033-2.737c-0.725-1.824-0.848-2.458-0.848-2.458s-0.043-0.2,0.066-0.234c0.109-0.032,0.09-0.178,0.09-0.178s-0.013-0.245-0.277-0.99c-0.182-0.503-0.312-0.911-0.662-1.607c0.281,0.585,0.463,1.052,0.524,1.259l0.028,0.068c0,0,0.099,0.148,0.066,0.552c-0.027,0.403-0.146,0.452-0.146,0.452l0.022,0.14c0.141,0.538,0.418,1.187,0.418,1.187s1.065,2.709,1.748,4.54L99.696,28.566L99.696,28.566z"/><linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="274.5342" y1="-396.1577" x2="255.2091" y2="-490.1944" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st37;" d="M42.958,91.536c0.938,0.177,1.723,0.358,1.889,0.396C44.514,91.822,43.895,91.653,42.958,91.536z"/><linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="422.5586" y1="518.7568" x2="427.2878" y2="578.1768" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset=".2198" stop-color="#989A9C"/><stop offset=".2527" stop-color="#FFF"/></linearGradient><path style="&st38;" d="M20.381,74.92l0.007-0.164l-0.052-0.08c0,0-1.874-3.375-1.676-4.615c0,0,0.069-0.827,1.241-1.187c0.817-0.25,0.71,0.538,3.112,0.976c0,0,2.07,0.557,2.611-0.946c0.539-1.507-0.566-3.394-0.566-3.394s-1.45-2.656-3.244-2.756c-0.95-0.055-0.692,0.583-2.125,0.924c0,0-1.913,0.185-2.519-0.963c-0.733-1.389-1.015-2.968-1.015-4.021c0-1.058,0.045-1.001,0.126-1.405c0.045-0.219,0.186-0.548,0.248-1.09l-0.134-0.675l0.204-0.499c0.002-0.26-0.004-0.535-0.021-0.83c-0.092-1.661-0.211-4.221-0.436-5.711c-0.223-1.491-0.633-3.799-1.991-3.865c0,0-0.671-0.052-1.636,0.885c-0.882,0.856-1.682-0.708-1.726-1.663c-0.052-1.121,0.131-2.255,0.409-2.795c0.277-0.541,1.042-0.566,1.186-0.554c0.146,0.012,0.555,0.17,1.042,0.474c0.489,0.304,1.161,0.304,1.558-0.092c0.395-0.395,0.948-0.856,1.173-2.598c0.225-1.741,0.225-3.547,0.013-5.71l-0.224-0.485l1.339-0.288c-0.001-0.016-0.021-0.125-0.032-0.195c0,0,0-0.001-0.001-0.002c-0.001-0.017-0.004-0.033-0.007-0.052c0-0.002,0-0.004,0-0.005c-0.003-0.019-0.007-0.038-0.009-0.057c-0.001-0.001-0.001-0.001-0.001-0.003c-0.003-0.022-0.006-0.042-0.009-0.062c0-0.001,0-0.001,0-0.001c-0.004-0.022-0.006-0.045-0.011-0.067c0-0.003-0.001-0.006-0.001-0.007c-0.002-0.022-0.006-0.045-0.008-0.068c-0.001-0.005-0.001-0.01-0.003-0.015c-0.002-0.023-0.005-0.047-0.009-0.069c-0.001-0.004-0.002-0.01-0.002-0.014c-0.003-0.026-0.007-0.05-0.012-0.076c0-0.002,0-0.005,0-0.005c-0.004-0.025-0.008-0.05-0.012-0.076c0-0.007-0.001-0.012-0.002-0.018c-0.002-0.024-0.006-0.052-0.009-0.079c-0.001-0.005-0.001-0.011-0.003-0.021c-0.004-0.027-0.006-0.053-0.01-0.081c-0.001-0.007-0.002-0.013-0.003-0.02c-0.003-0.028-0.005-0.057-0.009-0.087c-0.001-0.003-0.001-0.008-0.003-0.013c-0.003-0.028-0.005-0.056-0.009-0.082c-0.001-0.006-0.001-0.011-0.002-0.017c-0.003-0.031-0.006-0.06-0.01-0.091c-0.001-0.007-0.001-0.014-0.002-0.02c-0.004-0.03-0.006-0.062-0.011-0.09c0-0.007-0.001-0.015-0.002-0.022c-0.003-0.031-0.006-0.063-0.01-0.094c-0.001-0.006-0.002-0.011-0.002-0.018c-0.003-0.032-0.005-0.063-0.009-0.094c0-0.003,0-0.005-0.001-0.009c-0.003-0.033-0.004-0.068-0.009-0.1c0-0.005,0-0.013-0.001-0.02c-0.002-0.035-0.005-0.065-0.007-0.099c-0.001-0.008-0.001-0.015-0.002-0.021c-0.003-0.032-0.005-0.066-0.007-0.099c0-0.005-0.001-0.011-0.001-0.02c-0.002-0.033-0.006-0.068-0.007-0.101c0-0.003-0.001-0.008-0.001-0.009c-0.002-0.033-0.004-0.066-0.007-0.1c0-0.006,0-0.012,0-0.017c-0.001-0.032-0.003-0.068-0.005-0.1c0-0.008,0-0.014-0.001-0.022c-0.001-0.033-0.004-0.067-0.005-0.098c0-0.006,0-0.013,0-0.021c-0.002-0.033-0.003-0.066-0.004-0.101c0-0.005,0-0.008,0-0.013c-0.001-0.032-0.002-0.066-0.002-0.099c0-0.003,0-0.005,0-0.009c0-0.034-0.001-0.067-0.001-0.102c0-0.005,0-0.012,0-0.016c0-0.033,0-0.067,0-0.098c0-0.005,0-0.012,0-0.019c0.001-0.032,0.001-0.065,0.001-0.096c0-0.004,0.001-0.009,0.001-0.014c0-0.033,0.001-0.066,0.003-0.1c0.052-1.243,0.291-1.751,0.291-1.751l0.058-0.166c0,0,0.46-1.458,1.152-2.458l-0.011,0.024c0,0,0.446-0.738,1.231-0.816c0.785-0.077,1.003,0.158,1.371,0.202c0.04,0.004,0.078,0.008,0.115,0.013c0.013,0.001,0.025,0.002,0.037,0.004c0.025,0.002,0.051,0.003,0.074,0.006c0.014,0.001,0.028,0.002,0.042,0.003c0.021,0.001,0.043,0.002,0.064,0.004c0.014,0.001,0.028,0.001,0.041,0.002c0.02,0.001,0.04,0.002,0.058,0.002c0.013,0.002,0.026,0.002,0.04,0.002c0.021,0.001,0.037,0.002,0.055,0.002c0.014,0,0.026,0.001,0.039,0.001c0.016,0,0.034,0.001,0.051,0.001c0.011,0,0.023,0,0.034,0c0.017,0,0.032,0,0.05-0.001c0.01,0,0.02,0,0.032-0.001c0.016,0,0.031,0,0.046-0.001c0.011,0,0.02-0.001,0.03-0.001c0.015,0,0.03-0.002,0.045-0.002c0.009,0,0.017-0.001,0.026-0.001c0.015-0.001,0.03-0.003,0.044-0.004c0.006-0.001,0.016-0.002,0.022-0.002c0.016-0.001,0.03-0.002,0.044-0.004c0.007-0.001,0.014-0.001,0.019-0.002c0.016-0.002,0.03-0.004,0.045-0.007c0.006,0,0.009,0,0.014-0.001c0.019-0.002,0.036-0.006,0.052-0.008l0,0c0.035-0.008,0.068-0.014,0.098-0.021c0,0,0-0.002,0.002-0.002c0.012-0.002,0.025-0.005,0.039-0.01c0.002,0,0.004-0.001,0.007-0.001c0.01-0.003,0.02-0.006,0.029-0.009c0.003-0.001,0.007-0.002,0.01-0.004c0.009-0.002,0.018-0.006,0.026-0.008c0.002-0.002,0.005-0.003,0.008-0.003c0.008-0.003,0.015-0.006,0.021-0.009c0.003-0.001,0.006-0.003,0.009-0.004c0.006-0.003,0.014-0.004,0.02-0.009c0.003-0.001,0.006-0.002,0.008-0.003c0.005-0.002,0.012-0.005,0.019-0.007c0.001-0.002,0.003-0.003,0.005-0.004c0.005-0.004,0.01-0.005,0.015-0.008c0.003-0.001,0.004-0.003,0.008-0.003c0.004-0.002,0.008-0.005,0.012-0.008c0,0,0.004,0,0.005-0.002c0.004-0.003,0.008-0.006,0.012-0.008c0.001-0.002,0.002-0.002,0.004-0.003c0.003-0.003,0.007-0.004,0.01-0.008c0.002,0,0.002,0,0.002-0.002c0.003-0.001,0.007-0.005,0.011-0.008c0,0,0.001,0,0.001-0.001c0.004-0.002,0.005-0.004,0.009-0.007h0.001c0.002-0.002,0.004-0.004,0.006-0.007c0.001-0.001,0.002-0.001,0.003-0.002s0.002-0.002,0.002-0.002c0.001-0.003,0.001-0.003,0.003-0.005c0.002-0.002,0.004-0.004,0.004-0.004c0.328-0.241,0.591-0.516,0.797-0.775c0.014-0.017,0.026-0.034,0.04-0.05c0.002-0.004,0.005-0.009,0.008-0.012c0.013-0.016,0.026-0.032,0.038-0.05c0.002-0.003,0.006-0.006,0.007-0.01c0.012-0.018,0.025-0.032,0.038-0.05c0,0,0,0,0.001,0c0.039-0.055,0.075-0.109,0.109-0.159c0-0.003,0.002-0.006,0.003-0.008c0.01-0.015,0.021-0.028,0.03-0.044c0.001-0.003,0.004-0.007,0.007-0.01c0.008-0.016,0.017-0.029,0.024-0.042c0.002-0.004,0.005-0.009,0.009-0.013c0.008-0.014,0.017-0.028,0.023-0.042c0.001-0.001,0.001-0.002,0.002-0.002c0.017-0.028,0.032-0.055,0.046-0.079c0.002-0.003,0.004-0.008,0.006-0.013c0.006-0.01,0.01-0.021,0.017-0.029c0.003-0.007,0.007-0.014,0.012-0.02c0.004-0.008,0.009-0.017,0.014-0.024c0.002-0.008,0.006-0.017,0.01-0.023c0.004-0.007,0.009-0.016,0.012-0.023c0.004-0.006,0.006-0.014,0.011-0.021c0.002-0.006,0.007-0.013,0.01-0.021c0.066-0.128,0.097-0.205,0.097-0.205c0.593-1.459,0.052-2.936-0.21-3.225c-0.32-0.353-1.041-0.882-1.041-0.882s-0.288-0.241-0.751-0.144c0.349-0.049,0.791,0.091,0.966,0.558c0.277,0.734,0.376,1.335,0.212,2.33c0,0-0.26,1.387-1.384,2.233c-1.125,0.848-1.923,0.096-2.885,0.13c-0.962,0.032-1.516,0.701-1.809,1.157c-0.293,0.457-1.417,2.2-1.319,5.067c0.097,2.868,0.291,4.301,0.325,5.558c0.033,1.205,0.178,3.976-0.635,5.278c-0.815,1.303-1.628,0.65-2.2,0.309c-0.571-0.341-1.223-0.245-1.744,0.131c-0.521,0.375-0.833,1.124-0.848,3.324c-0.016,2.364,1.532,2.606,1.532,2.606s0.293,0.146,0.945-0.537c0,0,0.651-0.685,1.253-0.603c0.604,0.082,0.995,0.716,1.255,1.808c0.261,1.092,0.796,5.621,0.717,8.668c-0.034,1.271-0.62,1.286-0.36,3.617c0,0,0.409,3.13,1.401,4.089c0.995,0.962,2.378,0.781,2.706,0.75c0.324-0.032,0.7-0.26,0.7-0.26s0.309-0.197,0.537-0.374c0.23-0.182,0.522-0.428,1.011-0.277c0.489,0.146,1.645,0.896,2.557,2.571c0.915,1.678,0.496,3.317-0.26,3.521c-0.668,0.182-0.848,0.229-1.971-0.05c-1.124-0.274-1.451-0.567-1.957-0.766c-0.504-0.196-1.043-0.263-1.547,0.114c-0.505,0.373-1.345,1.057-0.343,3.32c0.961,2.174,1.692,3.797,3.518,5.623c-0.522-0.607-0.956-1.188-1.427-1.871L20.381,74.92L20.381,74.92z"/><linearGradient id="SVGID_15_" gradientUnits="userSpaceOnUse" x1="237.3721" y1="-388.3604" x2="218.8474" y2="-478.5023" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st39;" d="M22.494,7.387l-0.05,0.025C22.45,7.41,22.469,7.401,22.494,7.387z"/><linearGradient id="SVGID_16_" gradientUnits="userSpaceOnUse" x1="259.9063" y1="-479.3379" x2="259.8987" y2="-479.3752" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st40;" d="M46.028,92.85c0.13,0.014,0.26,0.026,0.391,0.041c-0.114-0.016-0.31-0.039-0.561-0.074C45.916,92.828,45.972,92.838,46.028,92.85L46.028,92.85z"/><path style="&st29;" d="M24.089,5.489c-0.649,0.36-0.7-0.016-1.141,0.017c-0.439,0.033-1.026,0.212-1.596,1.043c-0.571,0.831-0.586,1.89,0.326,1.417c0,0,0.436-0.428,0.815-0.579c0.081-0.043,0.24-0.126,0.406-0.174l0.144-0.117c0,0,0.424-0.491,1.073-0.333c0.648,0.156,1.119-0.129,1.119-0.129c1.01-0.761,1.655-2.184,1.655-2.184l0.987-1.998l-0.826-1.336c0,0-0.698,1.489-1.383,2.53C24.986,4.692,25.033,4.972,24.089,5.489L24.089,5.489z"/><path style="&st29;" d="M19.871,16.292c0,0-0.424,1.89,1.156,1.597c0,0,0.006-0.002,0.022-0.007c-0.062,0.003-0.089-0.006-0.089-0.006c-0.025-0.497,0.149-1.432,0.49-2.261c0.341-0.83,1.075-2.254,1.075-2.254s1.047-1.791,1.467-2.89c0.42-1.102,0.416-1.939,0.416-1.939s-0.8-1.019-0.915-1.176c-0.115-0.157-0.272-0.223-0.272-0.223c-0.054,0.019-0.103,0.036-0.146,0.051c0.115-0.007,0.221,0.021,0.283,0.114c0.213,0.31-0.39,2.036-0.39,2.036s-0.522,1.238-1.548,3.03C20.393,14.157,19.871,16.292,19.871,16.292L19.871,16.292z"/><linearGradient id="SVGID_17_" gradientUnits="userSpaceOnUse" x1="268.9033" y1="-394.6382" x2="249.4966" y2="-489.0725" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st41;" d="M38.185,89.697l0.166,0.02c-0.134-0.119-0.305-0.236-0.497-0.347c0.184,0.113,0.489,0.358,0.312,0.665c-0.245,0.424-0.048,0.457,0.489,0.863c0,0,0.022,0.013,0.061,0.033c-0.156-0.107-0.253-0.234-0.156-0.362c0.125-0.166,0.136-0.334,0.065-0.499L38.185,89.697L38.185,89.697z"/><linearGradient id="SVGID_18_" gradientUnits="userSpaceOnUse" x1="254.4561" y1="-391.5991" x2="235.0337" y2="-486.1104" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st42;" d="M24.437,82.749c-1.245-1.185,1.595-0.118,1.595-0.118s0.619,0.262,0.343-0.385c-0.246-0.57-1.373-1.963-2.543-3.219l0.144,0.156c0,0,2.346,2.721,2.183,2.966c-0.164,0.245-1.108-0.325-1.108-0.325s-1.401-0.539-1.206,0.13c0.143,0.491,1.059,1.271,1.536,1.649C25.109,83.372,24.798,83.09,24.437,82.749z"/><linearGradient id="SVGID_19_" gradientUnits="userSpaceOnUse" x1="262.6514" y1="-392.9692" x2="243.1559" y2="-487.8355" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st43;" d="M26.977,84.73c0.424,0.256,0.903,0.513,1.365,0.676c0,0,0.831,0.293,1.337-0.114c0.503-0.403,0.503-0.601,1.238-0.243c0,0,1.388,0.696,2.382,1.444c0.98,0.735,3.557,2.336,4.396,2.791c-0.764-0.417-3.712-2.365-4.633-2.99c-0.936-0.633-2.574-1.698-3.297-1.476c-0.554,0.172-0.474,0.396-0.804,0.555c-0.331,0.158-0.688,0.055-1.504-0.383C27.291,84.9,27.134,84.818,26.977,84.73L26.977,84.73z"/><linearGradient id="SVGID_20_" gradientUnits="userSpaceOnUse" x1="271.5479" y1="-390.9575" x2="251.1904" y2="-490.0176" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st44;" d="M39.903,91.448c0.37,0.104,0.672,0.06,0.787,0.035c-0.678,0.04-1.35-0.269-1.35-0.269s-0.067-0.021-0.165-0.061C39.413,91.268,39.689,91.385,39.903,91.448z"/><linearGradient id="SVGID_21_" gradientUnits="userSpaceOnUse" x1="274.6582" y1="-395.8442" x2="255.2559" y2="-490.2569" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset="1" stop-color="#E4E5E6"/></linearGradient><path style="&st45;" d="M44.293,92.169c0,0-1.344-0.163-1.939-0.163c0,0-0.037,0.064,0.226,0.158c-0.021-0.021-0.031-0.049,0.189,0c0.304,0.064,2.018,0.225,2.465,0.158c0.448-0.068-0.091-0.278-0.091-0.278s-0.088-0.041-0.267-0.102C44.553,92.201,44.293,92.169,44.293,92.169L44.293,92.169z"/><path style="&st34;" d="M4.662,62.045c0.085,0.143,0.198,0.432,0.462,0.725c0.146,0.16,0.266,0.072,0.162-0.525c-0.253-0.182-0.407-0.318-0.464-0.371c-0.113-0.013-0.263-0.297-0.263-0.297s-0.471-0.835-0.274-0.227c0.398,1.23,1.6,3.821,1.6,3.821l1.396,2.47c-0.999-1.803-2.299-4.633-2.44-5.013C4.691,62.223,4.577,61.904,4.662,62.045L4.662,62.045z"/><path style="&st34;" d="M1.547,32.696l0.032-0.643c0.027-0.122,0.057-0.241,0.087-0.36c0.712-2.789,1.069-3.858,1.425-4.649c0.356-0.792,0.398-0.245,0.398-0.245s0,0.209,0.136,0.234c0.135,0.023,0.324-0.32,0.494-0.826c0.17-0.504,0.604-1.745,0.693-2.212c0.135-0.704-0.051-0.358-0.115-0.354c-0.108,0.005-0.126-0.091-0.113-0.306c0,0,0.382-2.122,3.064-6.563c0.18-0.17,0.321-0.307,0.47-0.449c-0.055-0.052-0.033-0.265,0.001-0.32c0.136-0.214,0.275-0.435,0.422-0.661l-0.09,0.504c0,0-1.85,2.492-3.104,5.694c0,0-0.342,0.835-0.359,1.094c-0.025,0.154-0.104,0.739,0.152,0.582l0.065-0.048c-0.093,0.484-0.295,1.37-0.607,2.325c-0.288,0.878-0.573,1.633-0.841,2.078l-0.002-0.004c-0.08,0.067-0.098-0.016-0.146-0.21c-0.048-0.198-0.113-0.198-0.113-0.198c-0.179,0-0.324,0.202-0.41,0.359c-0.04,0.056-0.089,0.19-0.089,0.19s-0.461,0.934-1.281,4.26c-0.822,3.328-0.836,6.14-0.836,6.14s-0.084,1.309-0.21,1.379c-0.126,0.07-0.097-0.056-0.097-0.056s-0.045-0.052-0.114,0.045c0,0,0.02-0.76,0.044-0.875c0,0,0.041-0.206,0.119-0.206s0.006,0.125,0.048,0.16c0.039,0.032,0.084,0.03,0.075-0.178c-0.005-0.176,0.147-2.816,0.621-5.312L1.547,32.696L1.547,32.696z"/><path style="&st34;" d="M0.392,41.994c0-0.002,0-0.004,0-0.005c0,0,0.018,0.217,0.042,0.356l-0.003,0.01c0.078,0.357,0.187,0.357,0.187,0.357c0.008-0.096,0.087-0.273,0.183-0.458c0.007,0.106,0.007,0.231-0.004,0.375c-0.037,0.537-0.019,2.466,0.209,4.28c0.225,1.815,0.367,3.349,0.394,3.594c0.029,0.245,0.498,3.283,1.025,5.089c0.285,0.967,0.422,1.344,0.483,1.424l0.008,0.049c0,0,0.097,0.184,0.348,0.32c0,0,0.111-0.097,0.112-0.412c0.018,0.031,0.037,0.065,0.057,0.105c-0.083,0.262-0.105,0.426-0.105,0.426l0,0c-0.042-0.043-0.06-0.031-0.046,0.045c0.067,0.357,0.027,0.68-0.169,0.272c-0.198-0.403-0.8-1.832-1.307-4.251c0,0-0.531-2.659-0.795-5.084l0.042-0.105L0.989,48.29c-0.027-0.248-0.048-0.491-0.067-0.729c0,0-0.255-3.657-0.237-4.562c0.019-0.904-0.085-0.02-0.085-0.02s-0.021,0.219-0.028,0.329c-0.008,0.109-0.103,0.352-0.136-0.246C0.459,43.322,0.392,42.261,0.392,41.994L0.392,41.994z"/><path style="&st34;" d="M24.672,1.974l-0.53-0.753l-0.066-0.065c0,0-0.131-0.136-0.896,0.038l-0.11,0.022c0,0,0.38-0.094,0.168,0.191c-0.212,0.285-0.56,0.496-1.172,1.15c-0.612,0.655-0.411,0.803-0.01,0.668c0.401-0.138,1.188-0.499,2.606-1.243L24.672,1.974z"/><path style="&st34;" d="M23.106,1.21c-0.022,0.003-0.036,0.006-0.036,0.006L23.106,1.21z"/><path style="&st34;" d="M23.637,1.811c0.31-0.272,0.429-0.484,0.454-0.641l-0.015-0.014c0,0-0.131-0.136-0.896,0.038l-0.075,0.015c0.09-0.015,0.303-0.032,0.133,0.198c-0.212,0.285-0.56,0.496-1.172,1.151c-0.612,0.656-0.411,0.803-0.01,0.667c0.106-0.038,0.239-0.088,0.4-0.157C22.599,2.755,23.046,2.325,23.637,1.811z"/><path style="&st34;" d="M83.482,4.115l-0.2,0.235c0,0,0.136,0.081,0.208,0.141c0.008,0.005,0.014,0.01,0.021,0.012c-0.043-0.034-0.07-0.056-0.07-0.056c-0.023-0.109,0.004-0.223,0.014-0.297L83.482,4.115c0,0,0.055,0.002,0.143,0.011L83.482,4.115L83.482,4.115z"/><path style="&st6;" d="M62.559,90.319c0,0,1.686-0.187,3.239-0.691c1.558-0.504,1.935-0.981,1.874-1.341c-0.037-0.238-0.396-0.305-0.906-0.238c0.271-0.021,0.514,0.032,0.354,0.332c-0.313,0.582-0.861,0.782-0.861,0.782s-0.267,0.19-0.89,0.371c-0.806,0.245-1.794,0.375-2.335,0.438c-0.691,0.082-0.521-0.033-1.465,0.291c-0.023,0.016-0.047,0.025-0.065,0.043c-0.289,0.237,1.071,0.514,1.071,0.514s1.302,0.361,3.257,0.23l0.067-0.021c0.267-0.078,0.533-0.161,0.8-0.245c-2.021,0.457-3.324,0.149-3.737,0.095c-0.434-0.058-0.777-0.144-0.88-0.359C61.98,90.305,62.559,90.319,62.559,90.319L62.559,90.319z"/><path style="&st34;" d="M63.301,4.417l0.717,0.076c1.429-0.405,2.651-0.776,2.651-0.776s1.265-0.41,1.901-0.636c0.635-0.227,1.09-0.313,1.656-0.41c0.563-0.096,1.309-0.14,1.709-0.131c0.398,0.007,0.528,0.122,0.528,0.122s0.166,0.131,0.245,0.27c0.077,0.138,0.74,1.891,2.975,2.005c2.231,0.112,2.261-1.096,2.063-1.464c-0.226-0.427-0.896-0.863-0.896-0.863s-0.898-0.575-1.09-0.846c-0.192-0.271,0.033-0.358,0.104-0.376c0.066-0.018,2.433-0.497,2.729-0.608l0.021-0.02l-0.563-0.174c0,0-0.119,0.134-0.789,0.312c-0.67,0.179-1.233,0.246-1.742,0.313c-0.504,0.067-0.504,0.239-0.504,0.239l-0.879,1.406c0,0-0.029,0.104,0.043,0.305c0.073,0.202,0.41,0.448,0.41,0.448s0.573,0.424,0.99,0.699c0.418,0.275,0.395,0.373,0.395,0.373c-1.123,0.095-1.418-0.048-1.875-0.276c-0.445-0.223-0.76-0.729-0.922-1.086c-0.162-0.357-0.521-0.663-0.521-0.663c-0.589-0.336-1.696-0.343-2.813-0.15c-1.115,0.194-2.656,0.707-2.923,0.812c-0.271,0.104-1.616,0.551-2.309,0.729c-0.694,0.179-1.224,0.357-1.646,0.47c-0.426,0.11-3.431,1.005-4.557,1.339c-1.124,0.333-1.848,0.461-1.848,0.461c-1.688,0.171-2.193-0.134-2.193-0.134c-0.297-0.125-0.262-0.527-0.262-0.527l0.009-1.147c0,0-0.029-0.433-0.356-0.611c-0.328-0.179-0.779-0.252-1.593-0.29c-0.811-0.038-1.683,0.044-2.093,0.134c-0.408,0.09-1.19,0.313-1.764,0.952c-0.573,0.641-0.481,1.141-0.481,1.141s0.035,0.683,0.088,1.19c0.052,0.504,0.484,0.662,0.484,0.662s-0.744,0.532-3.045,1.206c-2.209,0.648-3.682,0.774-3.682,0.774l0.678,0.254c0,0,5.468-1.015,7.148-2.616c0,0,0.624-0.293,0.02-0.88c-0.606-0.585-0.897-0.761-0.897-0.761s-0.41-0.224,0.019-0.771c0.43-0.547,0.923-0.795,1.352-0.933c0.429-0.138,1.753-0.25,2.925-0.093c0,0,0.491,0.041,0.459,0.408c-0.034,0.366-0.088,0.872-0.077,1.028c0.008,0.158,0.023,0.515,0.398,0.845c0.378,0.332,1.099,0.453,1.099,0.453s1.257,0.228,2.843-0.217c1.584-0.445,3.642-1.14,5.431-1.629L63.301,4.417L63.301,4.417z"/><path style="&st12;" d="M-16.122-14.641"/><path style="&st22;" d="M48.462,6.628c0.31,0.207,0.476,0.221,0.5,0.421c0.055,0.339-0.56,0.64-0.56,0.64l-0.006-0.011c0,0-0.431-0.157-0.484-0.664c-0.052-0.505-0.088-1.19-0.088-1.19s0.001,0.2,0.046,0.26C48.004,6.256,48.087,6.378,48.462,6.628z"/><path style="&st20;" d="M82.447,79.307l0.451,0.17c1.104-0.617,1.496-0.809,1.759-0.963c1.183-0.703,2.592-1.563,2.963-1.855c0,0,0.761-0.518,0.116,0.195s-0.969,1.007-0.969,1.007s-0.625,0.626-0.471,0.782c0,0,0.166,0.246,1.193-0.687c1.023-0.929,2.15-2.258,2.275-2.44c0.127-0.188,0.146-0.293,0.146-0.293s0.107-0.215,0.273-0.393c0.145-0.15,1.377-1.496,1.994-2.121c0,0,0.002,0.001,0.006,0.003c0.273-0.362,0.541-0.729,0.806-1.102c-0.358,0.379-1.724,1.829-2.483,2.684c0,0-0.713,0.763-0.938,1.056s-0.225,0.47-0.225,0.47s-0.117,0.196-0.392,0.519s-1.24,1.186-1.24,1.186s-0.577,0.47-0.754,0.478c-0.179,0.011,0.431-0.538,0.431-0.538s0.588-0.625,0.967-1.123c0.382-0.498,0.137-0.47,0.137-0.47s-0.186-0.049-0.986,0.459c-0.8,0.508-1.367,0.858-1.367,0.858s-1.722,0.986-2.814,1.623c-1.096,0.636-3.6,1.908-5.021,2.492c-1.43,0.588-2.162,0.715-2.035,0.527c0.127-0.186,0.461-0.459,0.461-0.459s0.399-0.4,0.399-0.803c0,0,0.128-0.586-1.604-0.223c-1.729,0.36-3.293,1.213-3.293,1.213s-2.571,1.182-1.965,1.887c0,0,0.117,0.186,0.635,0.352c0.52,0.166-0.92,0.606-0.92,0.606c-1.365,0.448-2.413,0.651-3.74,0.926c-1.963,0.403-3.564,0.761-4.165,0.894c-0.165,0.035-0.253,0.059-0.253,0.059s-1.212,0.292-3.229,1.072c-2.015,0.783-5.972,1.43-5.972,1.43s-2.542,0.293-2.777,0.627c-0.234,0.331,0.177,0.499,0.177,0.499s0.362,0.224,1.671,0.283c0,0,0.451,0,0.471,0.036c0.018,0.039,0.046,0.068-0.235,0.156c-0.286,0.088-0.854,0.314-2.778,0.558c-1.936,0.245-1.896-0.067-1.896-0.067s-0.01-0.076,0.078-0.216c0.087-0.134,0.009-0.369-0.293-0.535c0,0-0.419-0.272-1.829-0.262c-1.408,0.009-4.212,0.017-6.833-0.14c-2.374-0.143-5.59-0.551-6.099-0.664c0,0-0.117-0.029-0.206-0.117c-0.088-0.09-0.646-0.422-1.164-0.733c-0.517-0.313-2.073-0.907-2.073-0.907s-2.011-0.783-1.945-0.521c0.015,0.063,0.13,0.153,0.268,0.246c0.351,0.188,0.704,0.375,1.06,0.56l0.002-0.002c0,0-0.743-0.402-0.538-0.402s0.438,0.109,0.438,0.109s1.213,0.332,1.966,0.686c0.753,0.353,1.407,0.83,1.407,0.83s0.929,0.549,2.319,0.732c1.346,0.182,3.174,0.389,3.777,0.448l0.594-0.272l0.433,0.354c1.106,0.068,2.575,0.146,2.575,0.146s2.976,0.111,4.605-0.019c0.733-0.063,0.507,0.317,0.507,0.317s-0.214,0.354,0.206,0.529c0,0,0.771,0.439,3.343,0.157c2.573-0.286,3.138-0.862,3.138-0.862s0.299-0.275-0.351-0.398c-0.513-0.1-0.513-0.051-1.175-0.117c-0.665-0.067-0.998-0.205-0.557-0.323c0.441-0.114,1.174-0.175,1.174-0.175s2.249-0.313,4.066-0.783c0,0,1.938-0.458,3.861-1.134c0.756-0.265,1.395-0.459,1.887-0.599l0.438-0.644l0.644,0.372c0.065-0.014,0.103-0.021,0.103-0.021s2.306-0.539,3.274-0.703c0.966-0.168,3.154-0.637,4.087-1.086c0.928-0.448,1.396-0.805,1.505-1.075c0.107-0.272-0.393-0.431-0.393-0.431s-0.588-0.138-0.508-0.34c0.075-0.205,0.293-0.382,1.213-0.793c0.918-0.41,2.07-0.859,3.227-1.144c1.154-0.282,0.732,0.194,0.732,0.194s-0.692,0.705-0.783,0.979c-0.086,0.273,0.029,0.285,0.119,0.333c0.088,0.05,0.646,0.028,1.022-0.067c0.383-0.099,3.464-1.271,5.341-2.347c0.049-0.026,0.094-0.054,0.139-0.08L82.447,79.307z"/><linearGradient id="SVGID_22_" gradientUnits="userSpaceOnUse" x1="221.1826" y1="-454.5649" x2="221.373" y2="-454.5649" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#808080"/><stop offset=".0868" stop-color="#7A7A7A"/><stop offset=".36" stop-color="#6B6B6B"/><stop offset=".5192" stop-color="#686868"/><stop offset=".6377" stop-color="#5F5F5F"/><stop offset=".7431" stop-color="#4E4E4E"/><stop offset=".8408" stop-color="#383838"/><stop offset=".9324" stop-color="#1B1B1B"/><stop offset="1" stop-color="#000"/></linearGradient><path style="&st13;" d="M7.432,68.01l0.178,0.131c-0.105-0.099-0.167-0.155-0.167-0.155s-0.008,0.003-0.024,0.003C7.423,67.993,7.429,68.002,7.432,68.01L7.432,68.01z"/><linearGradient id="SVGID_23_" gradientUnits="userSpaceOnUse" x1="221.4043" y1="-449.8027" x2="316.0254" y2="-449.8027" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#808080"/><stop offset=".0868" stop-color="#7A7A7A"/><stop offset=".3817" stop-color="#828282"/><stop offset=".5185" stop-color="#808080"/><stop offset=".5677" stop-color="#797979"/><stop offset=".6027" stop-color="#6E6E6E"/><stop offset=".608" stop-color="#6B6B6B"/><stop offset="1" stop-color="#4E4E4E"/></linearGradient><path style="&st7;" d="M90.412,59.954l-0.371-0.021c-1.807,1.463-2.342,1.938-3.781,2.955c0,0-1.644,1.228-3.44,2.196c-1.804,0.97-3.919,0.853-3.919,0.853s-0.573-0.062-0.295-0.477c0.275-0.415,0.634-1.425,0.771-1.938c0.141-0.516,0.415-1.82-0.633-2.235s-3.018,0.196-3.018,0.196s-4.525,1.205-6.371,3.23c-1.793,1.969-0.286,2.846-0.286,2.846s0.702,0.49,1.386,0.73c0.645,0.229,0.516,0.436,0.354,0.555c0,0-2.021,1.287-4.408,1.974c0,0-3.268,1.001-6.441,1.206c-3.154,0.203-4.495,0.283-4.495,0.283l-0.399,0.379l-0.758-0.252c-1.283,0.154-3.455,0.463-5.596,0.979c-2.622,0.64-5.123,1.147-6.903,2.296c0,0-1.333,0.887-0.566,1.746c0.765,0.862,1.565,1.23,1.565,1.23s0.472,0.207,0.464,0.336c-0.009,0.164-0.015,0.309-0.367,0.512c0,0-1.394,0.814-4.108,0.859c-2.714,0.045-3.911,0.021-4.707-0.695c-0.658-0.591,0.165-1.844,0.165-1.844s0.33-0.612,0-1.453c-0.33-0.84-2.218-0.854-2.218-0.854l-2.615-0.134c-3.095-0.081-7.182-0.427-9.001-0.653c0,0-0.012-0.002-0.033-0.006l-0.006,0.166l-0.721-0.303c-1.139-0.221-3.243-0.668-4.075-1.084c-0.759-0.38-1.167-0.313-1.066-1.102c0.101-0.769-0.753-1.836-0.753-1.836s-1.188-1.287-2.257-2.086c-1.069-0.804-1.523-0.564-1.523-0.564s-0.484,0.258-0.049,1.296c0.436,1.04,0.86,1.403,0.86,1.403s0.208,0.22,0.089,0.279c-0.118,0.06-0.484-0.219-0.789-0.478c-0.253-0.21-1.885-1.742-2.456-2.276l0.105,0.356c0.019,0.028,0.035,0.062,0.052,0.086c0.184,0.291,0.855,1.269,2.155,2.28c1.549,1.213,1.559,0.729,1.559,0.729s0.061-0.399-0.297-0.84c-0.359-0.44-0.934-1.373-0.791-1.715c0.144-0.339,0.309-0.31,0.309-0.31s0.133-0.051,0.596,0.299c0.462,0.351,1.498,1.076,2.011,1.703c0.513,0.623,0.48,1.181,0.48,1.181s-0.102,0.563,0.453,1.17c0.553,0.604,1.733,1.714,5.859,2.351c0.025,0.004,0.034,0.006,0.059,0.01l0.193-0.551l0.573,0.663c3.598,0.521,5.555,0.563,5.555,0.563s4.709,0.162,5.982,0.162c1.272,0,1.035,0.666,1.035,0.666s-0.072,0.359-0.225,0.646c-0.155,0.287-0.524,1.365-0.144,1.939c0,0,0.585,1.427,4.381,1.527c0,0,3.324,0.268,5.643-0.688c2.319-0.954,0.226-2.275,0.226-2.275s-0.794-0.481-1.13-0.739c-0.308-0.234-0.184-0.481-0.121-0.646c0.06-0.162,0.297-0.359,0.563-0.492c0.266-0.134,1.239-0.654,5.365-1.722c4.124-1.069,6.587-1.183,6.587-1.183s0.02-0.002,0.055-0.004l0.338-0.656l0.854,0.556c0.732-0.06,1.681-0.129,2.526-0.171c1.691-0.082,4.341-0.471,5.879-0.807c1.54-0.343,3.869-1.062,5.592-1.951c1.725-0.895,1.809-1.519,1.809-1.519s0.328-0.475-0.392-0.995c-0.719-0.523-1.036-0.382-1.673-1.027c-0.637-0.646,0.557-1.62,0.557-1.62s0.612-0.861,4.021-2.175c3.403-1.313,3.979-0.873,4.153-0.729s0.195,0.615,0.123,0.935c-0.069,0.317-0.494,1.455-0.721,2.053c-0.227,0.594-0.316,1.406,0.605,1.601c0.923,0.194,2.215-0.008,3.428-0.442c2.893-1.033,3.756-2.295,8.534-5.764c0.012-0.008,0.021-0.017,0.03-0.021L90.412,59.954l0.689,0.108c1.978-1.573,3.869-3.571,3.869-3.571s1.258-1.261,1.889-2.356c0.595-1.026,0.027,0.89,0.027,0.89s-0.32,1.516,0.19,2.077c0.405,0.445,1.563-0.795,1.563-0.795s0.688-0.789,0.965-2.061c0.408-1.875,0.185-2.248,0.185-2.248s-0.246-0.389-0.093-0.852c0.154-0.459,1.158-3.047,1.98-4.01l0.502-0.563c0-0.008,0.002-0.02,0.002-0.027l-0.224-0.557l0.304-0.512c0,0-0.279,0.322-1.404,2.177c-1.266,2.087-1.467,3.771-1.467,3.771s-0.119,0.653-0.054,1.034c0.063,0.355,0.188,0.519,0.192,0.622c0.009,0.104-0.073,0.959-0.508,1.773c-0.438,0.814-0.815,1.031-0.815,1.031s-0.756,0.545-0.86,0.157c-0.104-0.39-0.074-0.72-0.035-0.966c0.035-0.248,0.289-1.579,0.252-2.072c-0.035-0.494-0.479-0.098-0.479-0.098s-0.104,0.119-0.298,0.366s-1.288,1.637-1.705,2.125c-0.988,1.157-1.886,1.989-4.292,3.93c-0.007,0.003-0.015,0.011-0.019,0.015L90.412,59.954L90.412,59.954z"/><linearGradient id="SVGID_24_" gradientUnits="userSpaceOnUse" x1="214.5928" y1="-431.356" x2="314.4043" y2="-431.356" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#555555"/><stop offset="1" stop-color="#231F20"/></linearGradient><path style="&st11;" d="M1.193,48.543l0.104,0.975c0.235,0.285,0.577,0.677,1.071,1.187c1.084,1.121,1.427,0.416,1.427,0.416s0.253-0.705-0.054-1.985C3.434,47.85,3.488,47.09,4.066,47.11c0.578,0.019,2.258,0.361,2.782,1.752c0,0,0.217,0.649,0.018,1.479c-0.2,0.834-0.162,1.57-0.018,2.295c0.145,0.725,0.759,1.407,1.464,1.971c0.706,0.562,2.746,1.535,4.734,1.66c1.987,0.127,2.601,0.021,2.601,0.021l0.746-0.767l0.134,0.668c0.812-0.09,2.116-0.229,3.62-0.393c2.528-0.271,4.227-0.544,5.798-0.308c1.573,0.235,2.079,1.462,2.079,1.462s0.108,0.314-0.253,0.544c-0.349,0.224-0.749,0.547-0.948,0.89c-0.199,0.346-0.411,1.068,0.16,2.035c0.572,0.963,2.142,1.592,3.478,1.432c1.335-0.155,3.335-0.67,4.52-0.979c1.287-0.337,2.424-0.971,2.572-1.98c0.147-1.008-1.534-2.295-1.534-2.295s-0.812-0.609-0.91-0.75c-0.1-0.139,0.099-0.197,0.099-0.197s0.949-0.229,1.357-0.414c0.404-0.189,1.522-0.646,3.353-1.219s5.608-1.248,5.608-1.248s2.084-0.332,4.685-0.543l0.622-0.702l0.485,0.625c0.409-0.024,0.825-0.046,1.243-0.063c3.572-0.129,5.344-0.554,7.242-0.979c1.897-0.427,4.568-1.978,4.965-2.276c0.396-0.295,1.229-0.66,1.396-1.957c0.168-1.295-1.364-2.157-1.364-2.157s-1.218-0.644-1.475-0.93c-0.258-0.287-0.02-0.562-0.02-0.562s0.689-1.485,2.896-2.354c2.205-0.872,3.689-1.107,4.618-1.208c0.932-0.099,1.245,0.237,1.374,0.396c0.128,0.157,0.128,0.485,0.021,0.821c-0.102,0.308-0.444,1.038-0.645,1.395c-0.197,0.356-0.523,1.216-0.316,1.622c0.208,0.405,0.843,0.593,1.662,0.445c0.821-0.149,2.988-0.761,4.888-1.553c1.9-0.792,5.073-2.345,5.073-2.345s0.009-0.004,0.022-0.012l0.086-0.729l0.729,0.295c1.02-0.562,2.764-1.58,4.01-2.631c1.871-1.573,3.699-3.225,4.166-3.639c0.465-0.417,0.892-0.752,1.307-0.732c0.414,0.021,0.732,0.317,0.988,1.434c0.258,1.118,0.308,2.038,0.426,2.582c0.117,0.543,0.285,1.175,0.931,1.304c0.646,0.129,1.513-0.434,1.838-0.713c0.33-0.276,0.92-1.176,0.882-2.382c0,0,0.068-1.604-0.761-3.127c0,0-0.351-0.614-0.479-0.782c-0.088-0.118-0.155-0.238-0.01-0.525c0.148-0.286,0.467-0.821,1.062-1.156c0.448-0.256,0.88-0.316,1.128-0.396c0,0,0.275-0.067,0.626-0.261l-0.126-0.412l0.289,0.316c0.404-0.239,0.652,0.045,0.652,0.045l-0.392-0.501l0.119-0.484c0,0-0.304-0.163-0.685-0.088c-0.383,0.078-0.42,0.362-1.014,0.458c-0.593,0.096-1.275,0.306-1.945,1.319c-0.67,1.011,0,2.271,0,2.271s0.359,0.592,0.533,0.896c0.172,0.306,1.066,2.215,0.037,3.608c0,0-0.552,0.643-1.525,0.86c-0.86,0.19-0.642-0.816-0.729-1.355c0,0-0.129-2.281-1.237-3.588c-0.976-1.146-2.746,0.888-3.629,1.566c-0.822,0.629-3.228,3.112-6.684,4.925l-0.51,0.892l-0.324-0.472c-1.658,0.827-5.418,2.656-7.87,3.514c0,0-1.875,0.762-2.64,0.782c0,0-0.17,0.006-0.034-0.179c0.133-0.185,0.276-0.322,0.507-0.737c0.23-0.418,0.646-1.357,0.646-2.327c0-0.969-1.119-1.917-2.68-1.748c-1.561,0.167-3.052,0.6-4.849,1.292c-1.796,0.692-3.343,2.159-3.55,3.375c-0.209,1.216,1.105,1.92,1.105,1.92s1.484,0.751,1.674,1.157c0.188,0.406,0.049,0.783,0.049,0.783s-0.129,0.406-0.783,0.782c-0.649,0.377-2.42,1.287-2.42,1.287s-2.207,1.217-5.562,1.512c0,0-3.058,0.26-4.817,0.348c-0.022,0.002-0.046,0.002-0.069,0.003l-0.541,0.53l-0.587-0.449c-1.64,0.136-3.54,0.359-3.54,0.359s-4.29,0.609-8.219,1.822c-3.336,1.027-3.971,1.594-3.971,1.594s-0.711,0.596-0.118,1.453c0,0,0.341,0.539,1.03,1.08c0.685,0.541,1.237,1.057,1.159,1.317c-0.08,0.265-0.29,0.382-0.29,0.382s-0.961,0.856-4.894,1.518c0,0-2.531,0.488-3.31-0.275c-0.778-0.766-0.435-1.279-0.435-1.279s0.052-0.173,0.62-0.527c0,0,0.951-0.596,0.647-1.727c-0.303-1.135-2.129-2.545-4.101-2.533c0,0-2.303,0.006-8.196,0.762c0,0-0.008,0-0.027,0.005l-0.204,0.501l-0.605-0.393c-0.324,0.039-0.713,0.076-1.114,0.107c-1.012,0.07-2.477-0.057-4.3-0.596c-1.824-0.543-2.963-1.535-3.126-2.133c-0.114-0.412,0.035-0.996,0.035-0.996S7.62,50.2,7.405,49.115c-0.22-1.083-0.582-1.934-1.631-2.567c-1.048-0.632-1.643-0.522-1.643-0.522s-0.939-0.144-0.904,1.446c0.037,1.59,0.235,2.256,0.235,2.256s0.181,0.562-0.108,0.635c-0.288,0.072-0.74-0.361-0.74-0.361s-1.021-0.924-1.619-1.688l0.048,0.066l-0.214,0.525c0,0,0.067,0.115,0.266,0.375L1.193,48.543L1.193,48.543z"/><linearGradient id="SVGID_25_" gradientUnits="userSpaceOnUse" x1="214.8965" y1="-410.8818" x2="306.501" y2="-410.8818" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#A0A0A0"/><stop offset=".0769" stop-color="#656767"/><stop offset="1" stop-color="#717375"/></linearGradient><path style="&st1;" d="M91.075,11.742l0.183,0.846c0,0-0.563,0.313-1.678,0.613c-1.113,0.3-2.188,0.801-2.188,0.801s-0.89,0.289-0.551,1.013c0.338,0.726,0.838,1.076,0.838,1.076s0.711,0.69,0.736,1.213c0.021,0.526-0.199,0.765-0.764,1.076c-0.563,0.313-1.075,0.375-1.075,0.375s-1.338,0.24-2.001-0.387c-0.663-0.626-0.787-1.663-0.787-1.663s-0.05-0.876-1.148-1.251c-1.102-0.375-2.453,0.425-2.453,0.425s-1.063,0.563-2.2,1.3c-1.14,0.738-3.291,1.64-4.642,2.114l-0.152,0.699l-0.758-0.382c-1.422,0.489-3.271,1.109-3.271,1.109S66.652,21.645,65,21.871c-1.648,0.224-2.016-0.014-2.238-0.238c-0.228-0.224,0.039-1.012,0.039-1.012s0.674-1.376,0.348-2.09c-0.324-0.714-2.451-0.9-2.486-0.9c-0.04,0-2.318-0.265-4.451,0.932c-1.895,1.062-2.143,1.642-2.143,1.642s-0.604,0.938,0.113,1.867c0.807,1.051,1.879,1.146,1.879,1.146s1.021,0.079,1.258,0.38c0.24,0.299,0.076,0.626,0.076,0.626s-0.336,0.925-2.228,1.312c0,0-3.181,0.933-9.113,1.776l-0.582,0.579c-3.743,0.47-8.143,1.363-10.555,1.989c-2.412,0.627-2.553,1.317-2.553,1.317c-0.519,0.813,0.141,1.236,0.141,1.236s0.829,0.283,1.017,1.19c0.19,0.91-0.783,1.629-0.783,1.629s-1.159,0.972-2.898,1.269c-1.739,0.297-2.396,0.35-3.429-0.47c-0.91-0.721-0.298-1.863,0.312-2.301c0.612-0.438,0.909-0.91,0.988-1.112c0.079-0.204,0.032-0.377,0.032-0.377l-0.58-0.534c-2.005-1.33-9.883,0.063-9.883,0.063s0,0.002,0,0l-1.341,0.289l-0.673-0.435c0,0-2.291,0.604-4.876,0.589c-2.712-0.014-1.27-2.128-1.27-2.128s0.638-1.118,0.75-1.764c0,0,0.224-1.745-1.42-1.631c-1.645,0.112-1.968,1.546-1.968,1.546s-0.112,0.801-0.089,1.392c0.021,0.594-0.002,1.847-0.742,2.56c-0.737,0.713-1.529,0.495-1.529,0.495s-1.331-0.582-1.595-0.718c-0.274-0.142-0.517-0.151-0.751-0.066c-0.02,0.007-0.039,0.018-0.057,0.029l-0.175,0.75l0.025-0.623c-0.156,0.176-0.271,0.42-0.271,0.42l0.088,0.327l-0.248,0.565c-0.002,0.012-0.005,0.023-0.006,0.035l0.008,0.003c0,0,0.087-0.196,0.222-0.357l0.182-0.369L1.493,32.94c0.055-0.044,0.112-0.07,0.172-0.074c0.281-0.017,0.629,0.158,0.629,0.158s1.135,0.611,1.642,0.716s0.875-0.065,1.205-0.292c0.527-0.365,1.143-1.121,1.4-1.839c0.229-0.646,0.279-2.394,0.279-2.394l0.004,0.014c0,0,0-0.421-0.011-0.518c-0.012-0.098-0.075-0.553,0.204-0.783c0.278-0.234,0.459-0.347,1.144-0.364c0.68-0.017,0.886,0.38,0.886,0.38S9.28,28.269,9.28,28.48c0,0.21-0.068,0.34-0.068,0.34s-0.371,0.626-0.5,0.934c-0.13,0.307-0.636,1.323-0.489,2.177c0.148,0.852,1.479,1.251,1.479,1.251s1.062,0.25,2.575,0.027l3.12-0.503l0.543-0.624l0.218,0.474c0.805-0.147,2.14-0.369,3.583-0.511c2.326-0.228,4.787-0.262,5.821-0.132c0,0,0.484,0.061,0.405,0.234c-0.062,0.136-0.421,0.415-0.421,0.415s-0.135,0.081-0.654,0.667s-0.671,1.155-0.693,1.661c-0.024,0.505,0.516,1.995,2.415,2.394c1.901,0.397,4.077-0.341,4.077-0.341s1.427-0.314,2.786-1.674c1.41-1.411,0.012-3.108,0.012-3.108s-0.22-0.304-0.647-0.442c0,0-0.187-0.05-0.079-0.17c0.108-0.12,0.37-0.647,1.37-0.905c1-0.257,3.977-1.198,11.065-2.135l0.274-0.617l0.874,0.459c2.708-0.373,4.551-0.694,7.827-1.454c0,0,3.04-0.539,3.675-1.651c0.368-0.65,1.032-1.539-0.045-2.434c0,0-0.125-0.161-0.791-0.312c-0.666-0.151-1.179-0.252-1.738-0.653c-0.563-0.403-0.551-0.869-0.551-0.869s-0.047-0.445,0.862-0.958c0,0,0.851-0.623,2.54-1.158c1.691-0.533,3.648-0.296,3.648-0.296s0.82,0.089,0.685,0.643c-0.14,0.555-0.604,1.482-0.622,1.959c-0.021,0.474,0.012,1.027,0.938,1.414c0.931,0.386,2.267,0.266,2.267,0.266s1.386-0.069,3.647-0.801c2.265-0.731,4.594-1.573,4.594-1.573l-0.094-0.483l0.971,0.173c0.591-0.22,1.406-0.539,2.285-0.936c1.801-0.81,2.656-1.488,3.48-1.958c0,0,1.815-1.118,2.887-1.088c0,0,0.25-0.009,0.272,0.32c0.022,0.329,0.104,0.814,0.218,1.096c0.111,0.281,0.734,1.822,2.729,2.048c1.993,0.228,2.846-1.118,2.846-1.118s0.683-1.049-0.493-2.296c0,0-0.961-1.028-0.99-1.107c0,0-0.104-0.155,0.168-0.233c0.269-0.078,3.152-0.884,4.268-1.398c0,0,0.012-0.005,0.036-0.015l-0.271-0.485l0.535,0.365c0.202-0.101,0.449-0.246,0.544-0.395c0.171-0.271-0.054-0.797-0.054-0.797l0.006-0.007c-0.133-0.184-0.266-0.366-0.4-0.546l-0.606-0.256l-0.06,0.033L91.075,11.742"/><path style="&st34;" d="M8.12,16.324l-0.291,0.435c0.134-0.023,0.244-0.056,0.244-0.056s0.404-0.066,1.112,0.12c0.917,0.244,2.067-0.496,2.067-0.496s0.872-0.523,1.274-1.381l0.361-1.005c0,0,0.291-0.972,1.105-1.281c0,0,0.317-0.171,0.831-0.177c0.513-0.005,0.392,0.354,0.392,0.354s-0.056,0.233-0.586,0.912c-0.529,0.677-0.671,1.196-0.671,1.196s-0.318,0.722,0.193,0.957c0,0,0.24,0.141,0.939-0.091c0.7-0.233,3.02-0.843,4.438-1.06l0.993-0.506c-0.313-0.23-0.602-0.444-0.602-0.444c-2.388,0.442-4.168,0.995-4.775,1.226c-0.609,0.23-0.62,0.082-0.62,0.082c-0.211-0.248,0.435-1.022,0.435-1.022s0.655-0.894,0.913-1.715c0.259-0.82-0.892-0.707-0.892-0.707c-0.758,0.121-1.303,0.48-1.93,1.236c-0.486,0.586-0.782,1.389-0.893,1.814c-0.071,0.267-0.193,0.515-0.193,0.515s-0.091,0.165-0.45,0.322c-0.416,0.182-1.228,0.396-1.228,0.396s-0.54,0.045-0.931-0.15c-0.24-0.118-0.901,0.05-0.901,0.05l0.091-0.504l-0.082-0.032l-0.683,0.383c-0.115,0.189-0.228,0.379-0.341,0.569c-0.063,0.146-0.179,0.475,0.044,0.51c0.05,0.008,0.113,0.008,0.164,0.008L8.12,16.324L8.12,16.324z"/><path style="&st34;" d="M13.295,9.19c0,0,0.342-0.271,0.342-0.026c0,0.248-0.333,0.69-0.333,0.69s-0.107,0.134-0.172,0.134C13.068,9.987,13.15,9.516,13.295,9.19L13.295,9.19z"/><path style="&st12;" d="M-16.122-14.641"/><path style="&st34;" d="M10.595,12.501c0,0-0.388,0.46,0,0.52l0.838-0.828c-0.037-0.037-0.054-0.055-0.157-0.112C11.277,12.081,10.752,12.343,10.595,12.501L10.595,12.501z"/><path style="&st28;" d="M77.807,85.745c0,0-1.75,0.806-3.396,1.603c-1.647,0.803-2.25,1.14-2.25,1.14s-0.088,0.049-0.031,0.082c0.056,0.028-0.008,0.063-0.008,0.063c-0.847,0.409-2.703,1.07-2.703,1.07s-0.167,0.057-0.157,0.02c0.006-0.041,0.199-0.105,0.199-0.105s0.381-0.146,0.283-0.217c-0.098-0.072-1.21,0.305-1.21,0.305s-1.949,0.621-2.894,0.887c-0.941,0.269-2.75,0.735-2.75,0.735c-1.201,0.298-3.75,0.798-4.315,0.901c-0.562,0.104-0.417,0.064-0.417,0.064s0.492-0.189-0.411-0.226c-1.146-0.05-2.362,0.112-3.612,0.288c-1.25,0.18-1.178,0.324-1.178,0.324s-0.04,0.154,0.708,0.14c0.752-0.019,0.534,0.046,0.534,0.046c-1.396,0.202-4.2,0.238-4.2,0.238l0.005,0.01c0.456,0.014,0.916,0.018,1.376,0.018c0.608,0,1.218-0.01,1.822-0.031c0.241-0.021,1.483-0.15,1.925-0.244c0.486-0.105-0.093-0.105-0.093-0.105l-0.74-0.023c0,0-0.776-0.026-0.052-0.158c0.729-0.133,1.834-0.192,2.388-0.252c0.83-0.094,0.541,0.105,0.541,0.105l-0.04,0.023c0,0,0.014,0.094,0.528,0.066c0.515-0.024,4.721-0.804,7.069-1.487c2.347-0.688,4.102-1.255,4.102-1.255s0.157-0.055,0.066,0.025c-0.094,0.078-0.463,0.2-0.463,0.2s-0.595,0.3,0.844-0.108c0.066-0.02,0.134-0.039,0.197-0.06c1.234-0.469,2.446-0.983,3.635-1.543c0.029-0.028,0.131-0.146-0.021-0.101c-0.172,0.056,0-0.065,0.187-0.131c0.184-0.066,2.267-1.162,3.363-1.608l0.002,0.003c0.394-0.227,0.781-0.455,1.17-0.691L77.807,85.745L77.807,85.745z"/><linearGradient id="SVGID_26_" gradientUnits="userSpaceOnUse" x1="217.6563" y1="-436.751" x2="217.6563" y2="-436.751" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset=".078" stop-color="#F4F4F4"/><stop offset=".3807" stop-color="#CECECE"/><stop offset=".5396" stop-color="#BFBFBF"/><stop offset=".8357" stop-color="#7C7C7C"/><stop offset=".8996" stop-color="#A8A8A8"/><stop offset=".9093" stop-color="#9A9A9A"/><stop offset=".9327" stop-color="#7D7D7D"/><stop offset=".9558" stop-color="#686868"/><stop offset=".9785" stop-color="#5B5B5B"/><stop offset="1" stop-color="#575757"/></linearGradient><path style="&st46;" d="M3.893,50.249L3.893,50.249L3.893,50.249z"/><linearGradient id="SVGID_27_" gradientUnits="userSpaceOnUse" x1="214.3262" y1="-436.5107" x2="322.8717" y2="-424.4851" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset=".078" stop-color="#F4F4F4"/><stop offset=".3807" stop-color="#CECECE"/><stop offset=".5396" stop-color="#BFBFBF"/><stop offset=".8357" stop-color="#7C7C7C"/><stop offset=".8996" stop-color="#A8A8A8"/><stop offset=".9093" stop-color="#9A9A9A"/><stop offset=".9327" stop-color="#7D7D7D"/><stop offset=".9558" stop-color="#686868"/><stop offset=".9785" stop-color="#5B5B5B"/><stop offset="1" stop-color="#575757"/></linearGradient><path style="&st47;" d="M1.193,48.543l0.107,0.98c0.236,0.285,0.579,0.675,1.067,1.181c1.084,1.121,1.428,0.416,1.428,0.416s0.072-0.201,0.092-0.586c-0.042,0.216-0.209,0.403-0.788-0.056c-0.298-0.237-0.688-0.627-1.076-1.049c-0.326-0.326-0.723-0.742-1.021-1.117l0.048,0.065l-0.213,0.526c0,0,0.069,0.115,0.268,0.376L1.193,48.543L1.193,48.543z"/><linearGradient id="SVGID_28_" gradientUnits="userSpaceOnUse" x1="213.8887" y1="-436.4771" x2="336.8819" y2="-422.851" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#FFF"/><stop offset=".078" stop-color="#F4F4F4"/><stop offset=".3807" stop-color="#CECECE"/><stop offset=".5396" stop-color="#BFBFBF"/><stop offset=".8357" stop-color="#7C7C7C"/><stop offset=".8996" stop-color="#A8A8A8"/><stop offset=".9093" stop-color="#9A9A9A"/><stop offset=".9327" stop-color="#7D7D7D"/><stop offset=".9558" stop-color="#686868"/><stop offset=".9785" stop-color="#5B5B5B"/><stop offset="1" stop-color="#575757"/></linearGradient><path style="&st48;" d="M3.741,49.133c-0.006-0.027-0.013-0.054-0.02-0.078c0.012,0.088,0.028,0.179,0.043,0.272c0,0,0.094,0.394,0.12,0.753C3.87,49.813,3.83,49.498,3.741,49.133z"/><linearGradient id="SVGID_29_" gradientUnits="userSpaceOnUse" x1="411.2539" y1="557.002" x2="507.2363" y2="537.6277" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#EDEDEE"/><stop offset=".4176" stop-color="#FFF"/><stop offset=".6264" stop-color="#F8F9F9"/><stop offset="1" stop-color="#BFC0C2"/></linearGradient><path style="&st49;" d="M99.696,28.566l0.29,0.316c0.406-0.238,0.654,0.045,0.654,0.045l-0.386-0.494c-0.383,0.082-1.093,0.256-2.233,0.61c0,0-1.353,0.594-1.59,1.532c-0.016,0.332,0.049,0.641,0.116,0.876c0.753,1.429,0.913,1.666,0.913,1.666c0.499,1.091,0.422,1.993,0.25,2.824c-0.188,0.921-1.188,1.668-1.794,1.842c-0.608,0.171-0.953,0-1.14-0.483c-0.188-0.485-0.157-0.845-0.438-2.34c-0.28-1.499-0.653-2.2-1.216-2.372c-0.563-0.173-1.313,0.468-1.749,0.811c-0.438,0.344-2.417,2.152-2.417,2.152s-2.324,2.091-5.743,4.026c-3.417,1.935-7.69,3.418-7.69,3.418s-2.842,1.092-3.525,0.998c-0.688-0.093-0.516-0.718-0.297-1.076c0.219-0.36,0.516-0.937,0.766-1.545c0.313-0.756,0.201-1.654-0.359-1.967c-0.562-0.311-1.248-0.468-3.523,0.094s-3.197,1.076-3.838,1.451c-0.643,0.376-1.576,1.233-1.842,1.716c-0.266,0.484-0.563,0.983,0.126,1.576c0.688,0.594,0.763,0.485,1.56,1.046c0.797,0.562,0.922,0.64,0.969,1.466c0.045,0.827-0.766,1.341-0.766,1.341s-3.123,2.082-6.602,2.777c-2.34,0.469-6.833,0.639-6.833,0.639s-1.327-0.045-5.384,0.547c-4.056,0.594-6.787,1.514-7.738,1.856c-0.952,0.343-2.34,0.81-3.136,1.17c-0.795,0.358-0.375,0.89-0.203,1.015c0.172,0.123,1.185,1.074,1.498,1.354c0.312,0.282,1.466,1.279,0.108,2.108c-1.356,0.826-3.603,1.264-3.603,1.264s-3.121,0.654-4.119,0.234c-1.001-0.422-1.2-0.778-1.452-1.358c-0.313-0.718-0.016-1.263,0.794-1.78c0.77-0.486,0.469-1.199,0.469-1.199c-0.983-1.9-3.058-2.058-4.774-1.936c-2.72,0.198-5.358,0.471-7.425,0.734c-3.059,0.39-4.541-0.063-5.992-0.516c-1.452-0.453-2.997-1.529-3.154-2.498c-0.027-0.097-0.039-0.199-0.042-0.307c-0.078-0.758,0.074-1.146,0.184-1.784c0.108-0.625-0.043-1.532-0.084-1.758c-0.008-0.026-0.016-0.058-0.023-0.085c-0.507-1.304-1.725-1.903-2.668-2.058c-0.953-0.157-0.983,0.857-0.983,0.857s-0.002,0.012-0.006,0.04c0.078-0.208,0.222-0.315,0.444-0.31c0.577,0.02,2.259,0.361,2.781,1.754c0,0,0.218,0.648,0.019,1.479c-0.199,0.832-0.162,1.571-0.019,2.295c0.145,0.725,0.759,1.408,1.465,1.969c0.704,0.562,2.745,1.535,4.734,1.66c1.814,0.117,2.483,0.037,2.587,0.023l0.759-0.768l0.135,0.666c0.81-0.088,2.115-0.229,3.619-0.394c2.529-0.271,4.227-0.541,5.8-0.306c1.572,0.232,2.078,1.463,2.078,1.463s0.107,0.313-0.253,0.542c-0.349,0.226-0.75,0.548-0.947,0.891c-0.2,0.345-0.411,1.066,0.159,2.033c0.572,0.965,2.142,1.595,3.478,1.435c1.336-0.158,3.336-0.672,4.521-0.98c1.286-0.336,2.424-0.969,2.572-1.979c0.148-1.009-1.534-2.297-1.534-2.297s-0.81-0.611-0.909-0.75c-0.1-0.14,0.099-0.197,0.099-0.197s0.95-0.229,1.356-0.416c0.403-0.19,1.523-0.644,3.353-1.217c1.831-0.572,5.609-1.248,5.609-1.248s2.09-0.332,4.694-0.543l0.612-0.705l0.493,0.627c0.406-0.023,0.819-0.045,1.235-0.061c3.572-0.129,5.343-0.555,7.24-0.979c1.897-0.426,4.569-1.979,4.965-2.276c0.396-0.296,1.229-0.662,1.395-1.958c0.17-1.294-1.363-2.157-1.363-2.157s-1.218-0.643-1.476-0.929c-0.256-0.288-0.019-0.562-0.019-0.562s0.689-1.485,2.896-2.355c2.207-0.872,3.69-1.106,4.619-1.207c0.931-0.099,1.247,0.237,1.375,0.395c0.128,0.158,0.128,0.485,0.021,0.821c-0.101,0.308-0.443,1.039-0.644,1.396c-0.199,0.356-0.522,1.216-0.317,1.622c0.211,0.405,0.842,0.592,1.662,0.444c0.822-0.147,2.987-0.761,4.889-1.553c1.897-0.793,5.074-2.344,5.074-2.344s0.01-0.005,0.021-0.013l0.086-0.729l0.729,0.296c1.021-0.562,2.764-1.582,4.01-2.63c1.871-1.574,3.699-3.225,4.166-3.641c0.465-0.415,0.89-0.751,1.305-0.732c0.416,0.021,0.734,0.318,0.99,1.434c0.258,1.119,0.306,2.038,0.426,2.583c0.117,0.542,0.285,1.176,0.929,1.305c0.644,0.128,1.513-0.436,1.841-0.713c0.326-0.277,0.918-1.176,0.879-2.383c0,0,0.068-1.605-0.762-3.127c0,0-0.348-0.614-0.477-0.782c-0.088-0.119-0.155-0.238-0.008-0.523c0.146-0.288,0.465-0.821,1.059-1.157c0.449-0.256,0.881-0.316,1.128-0.396c0,0,0.28-0.069,0.636-0.266L99.696,28.566L99.696,28.566z"/><path style="&st23;" d="M1.547,32.696l-0.05,0.239c0.053-0.041,0.111-0.068,0.17-0.072c0.281-0.018,0.629,0.158,0.629,0.158s1.135,0.61,1.642,0.716c0.507,0.105,0.875-0.065,1.205-0.292c0.25-0.174,0.521-0.434,0.763-0.737c-0.29,0.29-0.725,0.548-1.365,0.595c0,0-0.571-0.049-1.419-0.587c-0.846-0.537-1.327-0.231-1.729,0.105l0,0l-0.249,0.564c-0.001,0.013-0.003,0.023-0.006,0.036l0.009,0.001c0,0,0.087-0.192,0.217-0.352L1.547,32.696L1.547,32.696z"/><path style="&st4;" d="M6.387,31.961c0.059-0.12,0.112-0.238,0.155-0.354c0.05-0.14,0.09-0.334,0.125-0.55c-0.096,0.44-0.223,0.73-0.223,0.73S6.428,31.853,6.387,31.961L6.387,31.961z"/><path style="&st4;" d="M6.807,28.654c-0.038,0.439-0.038,0.987-0.038,1.493l0,0c0.04-0.509,0.052-0.935,0.052-0.935l0.004,0.014c0,0,0-0.421-0.011-0.518C6.811,28.695,6.809,28.677,6.807,28.654z"/><linearGradient id="SVGID_30_" gradientUnits="userSpaceOnUse" x1="413.5137" y1="516.4121" x2="417.999" y2="516.4121" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#E2E3E4"/><stop offset=".5055" stop-color="#FFF"/></linearGradient><path style="&st50;" d="M8.12,16.324l-0.291,0.435c0.087-0.014,0.089-0.007,0.244-0.056c0,0,0.404-0.066,1.112,0.12c0.917,0.244,2.067-0.496,2.067-0.496s0.272-0.164,0.583-0.458c-0.4,0.24-1.385,0.762-2.132,0.585c-0.961-0.229-0.994-0.017-1.336-0.049c-0.292-0.028-0.292-0.11-0.275-0.314c0.002-0.032,0.023-0.054,0.03-0.092c0.05-0.261,0.339-0.689,0.339-0.689l-0.684,0.383c-0.115,0.189-0.227,0.378-0.34,0.569c-0.063,0.146-0.179,0.475,0.044,0.509c0.055,0.009,0.11,0.011,0.163,0.009L8.12,16.324L8.12,16.324z"/><path style="&st23;" d="M17.019,15.036c-1.027,0.278-1.972,0.734-2.494,0.604c-0.438-0.109-0.084-0.76,0.042-0.965c0.069-0.146,0.167-0.292,0.249-0.406c0.31-0.506,0.833-1.351,0.833-1.351s0,0,0-0.002c0.017-0.032,0.033-0.067,0.049-0.102c0.067-0.18,0.12-0.537-0.472-0.597c-0.799-0.082-1.613,0.619-1.613,0.619s-0.547,0.301-0.838,1.417l0.112-0.313c0,0,0.291-0.973,1.105-1.281c0,0,0.317-0.171,0.831-0.177c0.513-0.005,0.392,0.354,0.392,0.354s-0.056,0.233-0.586,0.912c-0.529,0.677-0.671,1.195-0.671,1.195s-0.319,0.723,0.193,0.957c0,0,0.238,0.141,0.939-0.091c0.7-0.233,3.02-0.843,4.438-1.06l0.993-0.506C19.849,14.299,18.012,14.769,17.019,15.036L17.019,15.036z"/><path style="&st23;" d="M-16.122-14.641"/><path style="&st23;" d="M-16.122-14.641"/><path style="&st59;" d="M90.578,74.217c0.006-0.004,0.009-0.008,0.014-0.013C90.587,74.21,90.582,74.213,90.578,74.217z"/><path style="&st59;" d="M90.821,73.951c0.001-0.002,0.002-0.004,0.003-0.004C90.823,73.947,90.822,73.949,90.821,73.951z"/><path style="&st59;" d="M90.738,74.042c0.003-0.004,0.008-0.009,0.011-0.013C90.746,74.033,90.741,74.038,90.738,74.042z"/><path style="&st8;" d="M87.9,76.68l-0.164,0.174c-0.646,0.716-0.969,1.007-0.969,1.007l-0.242,0.269l0,0c-0.002,0.006-0.006,0.012-0.012,0.014c0.008,0.002,0.018,0.004,0.041,0.004c0,0,0.229-0.002,0.588-0.219c-0.072,0.041-0.139,0.068-0.181,0.07c-0.177,0.012,0.431-0.538,0.431-0.538s0.588-0.626,0.967-1.125c0.382-0.497,0.138-0.468,0.138-0.468s-0.087-0.021-0.397,0.125C88.125,76.018,88.268,76.223,87.9,76.68L87.9,76.68z"/><path style="&st59;" d="M90.657,74.133c0.003-0.006,0.007-0.013,0.013-0.017C90.664,74.121,90.662,74.128,90.657,74.133z"/><path style="&st0;" d="M72.945,81.21c0,0,2.215-0.931,3.402-0.79c0,0,0.611,0.059-0.062,0.711c-0.672,0.652-0.892,1.168,0.396,0.752c0,0,0.094-0.033,0.244-0.086c-0.504,0.143-0.734,0.143-0.658,0.033c0.127-0.188,0.461-0.461,0.461-0.461s0.399-0.4,0.399-0.801c0,0,0.128-0.588-1.604-0.225c-1.01,0.209-1.969,0.59-2.588,0.867C72.941,81.211,72.943,81.211,72.945,81.21L72.945,81.21z"/><path style="&st59;" d="M72.234,81.555l-0.004,0.002C72.232,81.557,72.234,81.555,72.234,81.555z"/><path style="&st59;" d="M88.057,76.014c-0.014,0.008-0.026,0.015-0.043,0.021C88.028,76.027,88.043,76.021,88.057,76.014z"/><path style="&st14;" d="M78.305,81.299c1.448-0.521,3.93-1.854,5.023-2.492C82.232,79.442,79.73,80.717,78.305,81.299z"/><path style="&st59;" d="M87.512,76.325c0.026-0.017,0.055-0.032,0.08-0.049C87.566,76.293,87.538,76.309,87.512,76.325z"/><path style="&st59;" d="M91.618,73.084c0.008-0.011,0.019-0.023,0.026-0.029C91.637,73.061,91.626,73.073,91.618,73.084z"/><path style="&st59;" d="M91.434,73.281c0.01-0.012,0.019-0.02,0.023-0.027C91.451,73.264,91.441,73.27,91.434,73.281z"/><path style="&st59;" d="M91.521,73.188c0.01-0.012,0.02-0.022,0.029-0.032C91.539,73.165,91.53,73.178,91.521,73.188z"/><path style="&st59;" d="M90.9,73.863c0.003-0.006,0.007-0.01,0.012-0.016C90.907,73.854,90.903,73.857,90.9,73.863z"/><path style="&st59;" d="M71.246,82.088c-0.014,0.008-0.023,0.018-0.036,0.022C71.221,82.105,71.232,82.096,71.246,82.088z"/><path style="&st59;" d="M91.346,73.375c0.008-0.008,0.014-0.015,0.021-0.021C91.359,73.36,91.354,73.367,91.346,73.375z"/><path style="&st59;" d="M91.077,73.669c0.006-0.006,0.01-0.011,0.013-0.015C91.087,73.659,91.083,73.663,91.077,73.669z"/><path style="&st59;" d="M91.251,73.479c0.007-0.006,0.015-0.012,0.021-0.021C91.266,73.463,91.255,73.473,91.251,73.479z"/><path style="&st59;" d="M90.987,73.768c0.004-0.006,0.01-0.012,0.016-0.021C90.997,73.756,90.991,73.762,90.987,73.768z"/><path style="&st59;" d="M91.161,73.578c0.006-0.006,0.011-0.014,0.017-0.02C91.172,73.564,91.165,73.572,91.161,73.578z"/><path style="&st59;" d="M71.816,81.764c-0.008,0.006-0.02,0.012-0.026,0.017C71.799,81.774,71.809,81.77,71.816,81.764z"/><path style="&st59;" d="M72.044,81.646c-0.006,0.004-0.012,0.006-0.019,0.009C72.032,81.652,72.038,81.649,72.044,81.646z"/><path style="&st59;" d="M71.305,82.055c-0.011,0.008-0.021,0.014-0.031,0.021C71.283,82.067,71.294,82.063,71.305,82.055z"/><path style="&st59;" d="M71.969,81.684c-0.008,0.004-0.015,0.009-0.021,0.014C71.953,81.692,71.961,81.688,71.969,81.684z"/><path style="&st59;" d="M72.109,81.613c-0.004,0.005-0.01,0.006-0.016,0.01C72.102,81.619,72.105,81.617,72.109,81.613z"/><path style="&st59;" d="M72.008,81.665c-0.007,0.004-0.013,0.007-0.021,0.011C71.994,81.672,72.001,81.669,72.008,81.665z"/><path style="&st59;" d="M72.206,81.566c-0.003,0.002-0.005,0.003-0.007,0.004C72.201,81.569,72.203,81.568,72.206,81.566z"/><path style="&st59;" d="M72.148,81.594c-0.008,0.004-0.016,0.01-0.024,0.015C72.135,81.604,72.141,81.598,72.148,81.594z"/><path style="&st59;" d="M71.928,81.707c-0.01,0.003-0.02,0.01-0.027,0.016C71.908,81.715,71.918,81.711,71.928,81.707z"/><path style="&st59;" d="M72.193,81.575c-0.006,0.001-0.01,0.003-0.014,0.004C72.184,81.578,72.189,81.575,72.193,81.575z"/><path style="&st59;" d="M72.172,81.585c-0.004,0.003-0.008,0.005-0.015,0.007C72.164,81.59,72.168,81.585,72.172,81.585z"/><path style="&st59;" d="M72.079,81.631c-0.008,0.002-0.013,0.004-0.019,0.006C72.066,81.635,72.071,81.633,72.079,81.631z"/><path style="&st59;" d="M71.866,81.739c-0.011,0.002-0.021,0.008-0.027,0.013C71.848,81.747,71.857,81.741,71.866,81.739z"/><path style="&st59;" d="M71.555,81.906c-0.018,0.012-0.033,0.02-0.052,0.029C71.521,81.924,71.539,81.918,71.555,81.906z"/><path style="&st59;" d="M72.219,81.561c0,0.002-0.002,0.002-0.002,0.004C72.217,81.563,72.219,81.563,72.219,81.561z"/><path style="&st59;" d="M71.421,81.986c-0.011,0.006-0.022,0.01-0.03,0.02C71.398,81.996,71.41,81.992,71.421,81.986z"/><path style="&st59;" d="M71.363,82.02c-0.012,0.005-0.021,0.013-0.032,0.021C71.342,82.032,71.354,82.024,71.363,82.02z"/><path style="&st59;" d="M71.482,81.948c-0.014,0.006-0.023,0.015-0.036,0.021C71.458,81.963,71.471,81.956,71.482,81.948z"/><path style="&st59;" d="M71.768,81.79c-0.01,0.004-0.018,0.009-0.024,0.017C71.751,81.799,71.758,81.794,71.768,81.79z"/><path style="&st59;" d="M91.708,72.984c0.013-0.014,0.024-0.028,0.04-0.042C91.734,72.956,91.723,72.971,91.708,72.984z"/><path style="&st59;" d="M71.717,81.818c-0.01,0.004-0.019,0.009-0.027,0.015C71.698,81.827,71.707,81.822,71.717,81.818z"/><path style="&st59;" d="M71.665,81.846c-0.011,0.006-0.021,0.014-0.028,0.018C71.645,81.858,71.654,81.852,71.665,81.846z"/><path style="&st59;" d="M71.609,81.875c-0.01,0.008-0.021,0.014-0.03,0.02C71.589,81.889,71.602,81.881,71.609,81.875z"/><path style="&st59;" d="M92.443,72.197c-0.021,0.021-0.037,0.039-0.055,0.061C92.406,72.238,92.423,72.217,92.443,72.197z"/><path style="&st59;" d="M92.359,72.287c-0.021,0.021-0.041,0.044-0.061,0.066C92.318,72.331,92.339,72.309,92.359,72.287z"/><path style="&st59;" d="M92.501,72.135c-0.011,0.015-0.021,0.023-0.028,0.033C92.48,72.157,92.49,72.148,92.501,72.135z"/><path style="&st59;" d="M91.786,72.899c0.022-0.021,0.042-0.042,0.062-0.063C91.828,72.857,91.807,72.878,91.786,72.899z"/><path style="&st59;" d="M92.273,72.379c-0.014,0.016-0.025,0.029-0.041,0.045C92.245,72.409,92.26,72.395,92.273,72.379z"/><path style="&st59;" d="M92.579,72.053c-0.013,0.012-0.021,0.021-0.03,0.032C92.559,72.074,92.569,72.063,92.579,72.053z"/><path style="&st59;" d="M92.762,71.858c-0.002,0-0.002,0-0.002,0.001C92.76,71.858,92.76,71.858,92.762,71.858z"/><path style="&st59;" d="M92.703,71.919c-0.004,0.005-0.01,0.013-0.014,0.017C92.693,71.928,92.699,71.924,92.703,71.919z"/><path style="&st59;" d="M87.938,76.074c-0.017,0.008-0.027,0.016-0.043,0.023C87.907,76.09,87.922,76.082,87.938,76.074z"/><path style="&st59;" d="M92.648,71.98c-0.012,0.011-0.021,0.021-0.029,0.029C92.629,72,92.637,71.991,92.648,71.98z"/><path style="&st59;" d="M87.666,76.229c-0.018,0.013-0.031,0.021-0.051,0.031C87.633,76.25,87.648,76.241,87.666,76.229z"/><path style="&st59;" d="M48.204,91.026c0,0-0.001,0-0.003,0.002C48.203,91.026,48.203,91.026,48.204,91.026z"/><path style="&st59;" d="M48.073,91.03c-0.007,0-0.013,0-0.021,0C48.06,91.03,48.066,91.03,48.073,91.03z"/><path style="&st59;" d="M48.136,91.028c-0.007,0.002-0.013,0.002-0.02,0.002C48.123,91.03,48.129,91.03,48.136,91.028z"/><path style="&st59;" d="M48.005,91.032c-0.003,0-0.007,0-0.012,0C47.998,91.032,48.002,91.032,48.005,91.032z"/><path style="&st59;" d="M47.94,91.035c-0.004,0-0.009,0-0.015,0C47.93,91.035,47.935,91.035,47.94,91.035z"/><path style="&st59;" d="M87.869,76.111c-0.014,0.006-0.021,0.015-0.039,0.021C87.848,76.126,87.857,76.117,87.869,76.111z"/><path style="&st59;" d="M87.807,76.146c-0.014,0.009-0.025,0.018-0.041,0.021C87.779,76.164,87.793,76.155,87.807,76.146z"/><path style="&st59;" d="M87.738,76.186c-0.016,0.011-0.028,0.018-0.044,0.024C87.71,76.203,87.723,76.196,87.738,76.186z"/><path style="&st59;" d="M87.951,76.067c0.02-0.011,0.035-0.021,0.054-0.027C87.986,76.047,87.971,76.057,87.951,76.067z"/><path style="&st59;" d="M87.719,77.52c0,0-0.082,0.064-0.193,0.147C87.592,77.621,87.664,77.566,87.719,77.52z"/><path style="&st59;" d="M92.205,72.452c-0.021,0.022-0.042,0.046-0.064,0.067C92.163,72.498,92.186,72.475,92.205,72.452z"/><path style="&st59;" d="M28.05,87.006c-0.019-0.007-0.037-0.016-0.056-0.021C28.013,86.991,28.031,86.999,28.05,87.006z"/><path style="&st59;" d="M71.051,82.217c-0.013,0.008-0.021,0.017-0.037,0.021C71.027,82.23,71.038,82.223,71.051,82.217z"/><path style="&st59;" d="M45.854,89.871c-0.024,0-0.049-0.004-0.074-0.004C45.806,89.867,45.831,89.871,45.854,89.871z"/><path style="&st59;" d="M27.678,86.883c0.02,0.004,0.039,0.01,0.058,0.019C27.717,86.893,27.696,86.887,27.678,86.883z"/><path style="&st59;" d="M27.555,86.844c0.038,0.012,0.078,0.022,0.119,0.037C27.633,86.869,27.593,86.854,27.555,86.844z"/><path style="&st59;" d="M27.862,86.941c-0.041-0.014-0.082-0.026-0.123-0.04C27.78,86.913,27.82,86.928,27.862,86.941z"/><path style="&st59;" d="M91.88,72.799c0.015-0.016,0.026-0.027,0.04-0.043C91.907,72.771,91.895,72.784,91.88,72.799z"/><path style="&st59;" d="M28.058,87.006c0.04,0.016,0.079,0.026,0.116,0.041C28.137,87.033,28.098,87.021,28.058,87.006z"/><path style="&st59;" d="M91.977,72.695c0.014-0.016,0.026-0.027,0.041-0.044C92.002,72.668,91.989,72.68,91.977,72.695z"/><path style="&st59;" d="M92.057,72.612c0.021-0.022,0.039-0.041,0.061-0.062C92.096,72.571,92.076,72.59,92.057,72.612z"/><path style="&st59;" d="M27.991,86.985c-0.021-0.009-0.041-0.017-0.062-0.022C27.95,86.969,27.97,86.977,27.991,86.985z"/><path style="&st59;" d="M71.133,82.162c0.021-0.013,0.037-0.021,0.055-0.036C71.17,82.139,71.152,82.149,71.133,82.162z"/><path style="&st59;" d="M46.361,89.926c-0.016-0.002-0.035-0.004-0.053-0.008C46.325,89.922,46.345,89.924,46.361,89.926z"/><path style="&st59;" d="M71.122,82.17c-0.019,0.012-0.034,0.021-0.049,0.032C71.088,82.191,71.105,82.18,71.122,82.17z"/><path style="&st59;" d="M46.439,89.939c-0.017-0.002-0.032-0.006-0.049-0.008C46.407,89.934,46.422,89.938,46.439,89.939z"/><path style="&st59;" d="M46.513,89.953c-0.016-0.005-0.031-0.007-0.047-0.011C46.481,89.946,46.497,89.948,46.513,89.953z"/><path style="&st59;" d="M46.096,89.891c-0.031-0.002-0.065-0.006-0.1-0.01C46.031,89.885,46.065,89.889,46.096,89.891z"/><path style="&st59;" d="M46.278,89.913c-0.02-0.002-0.041-0.004-0.061-0.006C46.237,89.909,46.259,89.911,46.278,89.913z"/><path style="&st59;" d="M46.19,89.904c-0.028-0.005-0.054-0.008-0.084-0.012C46.136,89.896,46.163,89.899,46.19,89.904z"/><path style="&st59;" d="M45.971,89.881c-0.025-0.005-0.051-0.006-0.079-0.009C45.92,89.875,45.945,89.877,45.971,89.881z"/><path style="&st59;" d="M27.926,86.961c-0.02-0.004-0.039-0.011-0.058-0.019C27.888,86.953,27.908,86.957,27.926,86.961z"/><path style="&st59;" d="M47.395,90.975c0.001,0.004,0.003,0.004,0.004,0.004C47.398,90.979,47.396,90.979,47.395,90.975z"/><path style="&st59;" d="M47.375,90.969c0.001,0,0.002,0,0.003,0C47.378,90.969,47.376,90.969,47.375,90.969z"/><path style="&st59;" d="M47.418,90.982L47.418,90.982L47.418,90.982z"/><path style="&st59;" d="M47.465,90.996c0.003,0,0.004,0.001,0.006,0.001C47.47,90.997,47.468,90.996,47.465,90.996z"/><path style="&st59;" d="M47.442,90.988c0.001,0,0.002,0.002,0.002,0.002L47.442,90.988z"/><path style="&st59;" d="M47.342,90.955L47.342,90.955L47.342,90.955z"/><path style="&st59;" d="M46.589,89.967c-0.02-0.002-0.036-0.009-0.054-0.013C46.553,89.959,46.57,89.965,46.589,89.967z"/><path style="&st59;" d="M46.764,90.012c-0.011-0.004-0.021-0.008-0.033-0.012C46.742,90.006,46.753,90.008,46.764,90.012z"/><path style="&st59;" d="M49.049,90.953c-0.01,0.001-0.021,0.002-0.032,0.004C49.028,90.955,49.038,90.954,49.049,90.953z"/><path style="&st59;" d="M46.659,89.984c-0.021-0.006-0.039-0.01-0.061-0.014C46.619,89.975,46.639,89.979,46.659,89.984z"/><path style="&st59;" d="M47.767,91.028c0.003,0,0.003,0,0.006,0C47.773,91.028,47.77,91.028,47.767,91.028z"/><path style="&st59;" d="M47.821,91.03c0.003,0,0.007,0,0.013,0C47.828,91.03,47.824,91.03,47.821,91.03z"/><path style="&st59;" d="M45.214,89.855c0.047,0,0.092,0,0.139,0C45.308,89.855,45.261,89.855,45.214,89.855z"/><path style="&st59;" d="M47.716,91.026c0.005,0,0.009,0,0.013,0.002C47.727,91.026,47.722,91.026,47.716,91.026z"/><path style="&st32;" d="M46.772,90.014c0,0,0.158,0.021,0.059,0.338c-0.1,0.313,0.06,0.451,0.475,0.594l0.023,0.006c0,0,0.001,0,0.002,0c-0.079-0.04-0.074-0.08-0.074-0.08s-0.01-0.078,0.078-0.216c0.087-0.136,0.009-0.369-0.293-0.536C47.044,90.118,46.967,90.07,46.772,90.014L46.772,90.014L46.772,90.014z"/><path style="&st59;" d="M47.869,91.032c0.006,0,0.012,0,0.018,0C47.881,91.032,47.875,91.032,47.869,91.032z"/><path style="&st59;" d="M47.495,91.002c0.001,0,0.004,0,0.004,0C47.497,91.002,47.496,91.002,47.495,91.002z"/><path style="&st59;" d="M47.677,91.024c0.004,0,0.007,0,0.01,0C47.684,91.024,47.681,91.024,47.677,91.024z"/><path style="&st59;" d="M47.529,91.006c0.001,0,0.002,0,0.002,0S47.53,91.006,47.529,91.006z"/><path style="&st59;" d="M47.559,91.01c0.002,0.002,0.005,0.002,0.008,0.002C47.566,91.012,47.561,91.01,47.559,91.01z"/><path style="&st59;" d="M47.594,91.016c0.002,0,0.004,0,0.008,0C47.599,91.016,47.596,91.016,47.594,91.016z"/><path style="&st59;" d="M46.711,89.997c-0.011-0.002-0.026-0.007-0.043-0.011C46.685,89.99,46.701,89.995,46.711,89.997z"/><path style="&st59;" d="M28.748,87.256c-0.008-0.003-0.018-0.007-0.025-0.01C28.731,87.25,28.739,87.254,28.748,87.256z"/><path style="&st59;" d="M28.776,87.27c-0.007-0.002-0.016-0.008-0.024-0.012C28.761,87.262,28.769,87.268,28.776,87.27z"/><path style="&st59;" d="M28.681,87.23c-0.008-0.004-0.021-0.006-0.03-0.01C28.66,87.225,28.672,87.227,28.681,87.23z"/><path style="&st59;" d="M45.66,89.862c0.026,0,0.052,0.005,0.074,0.005C45.711,89.865,45.686,89.865,45.66,89.862z"/><path style="&st59;" d="M28.797,87.275c-0.005-0.002-0.013-0.006-0.021-0.008C28.784,87.271,28.792,87.273,28.797,87.275z"/><path style="&st59;" d="M27.38,86.794c0.038,0.011,0.074,0.022,0.112,0.031C27.453,86.816,27.417,86.803,27.38,86.794z"/><path style="&st59;" d="M27.492,86.825c0.021,0.004,0.039,0.011,0.058,0.019C27.53,86.836,27.512,86.829,27.492,86.825z"/><path style="&st59;" d="M28.814,87.284c-0.003-0.002-0.006-0.005-0.012-0.007C28.808,87.279,28.811,87.282,28.814,87.284z"/><path style="&st59;" d="M28.64,87.219c-0.011-0.006-0.021-0.01-0.03-0.014C28.621,87.21,28.629,87.213,28.64,87.219z"/><path style="&st61;" d="M27.687,87.239c-0.014-0.013-0.023-0.022-0.03-0.032c-0.263-0.197-0.343-0.418-0.343-0.418l0.009-0.011c0.017,0.007,0.034,0.011,0.052,0.014c-0.291-0.075-0.5-0.104-0.479-0.018c0.015,0.061,0.131,0.153,0.269,0.245c0.174,0.094,0.346,0.187,0.522,0.279V87.239L27.687,87.239z"/><path style="&st59;" d="M28.716,87.245c-0.009-0.003-0.018-0.006-0.027-0.01C28.699,87.239,28.708,87.242,28.716,87.245z"/><path style="&st59;" d="M28.602,87.202c-0.013-0.004-0.027-0.01-0.042-0.015C28.574,87.192,28.59,87.198,28.602,87.202z"/><path style="&st59;" d="M28.841,87.293c0,0-0.006-0.004-0.022-0.009C28.835,87.29,28.841,87.293,28.841,87.293z"/><path style="&st59;" d="M28.232,87.068c-0.018-0.006-0.031-0.014-0.047-0.018C28.201,87.055,28.215,87.063,28.232,87.068z"/><path style="&st59;" d="M45.534,89.858c0.028,0,0.054,0.002,0.081,0.002C45.587,89.858,45.562,89.858,45.534,89.858z"/><path style="&st59;" d="M45.397,89.855c0.029,0,0.06,0,0.089,0C45.457,89.855,45.427,89.855,45.397,89.855z"/><path style="&st59;" d="M28.348,87.11c-0.034-0.013-0.07-0.025-0.106-0.039C28.278,87.085,28.314,87.098,28.348,87.11z"/><path style="&st59;" d="M28.506,87.168c-0.013-0.005-0.025-0.01-0.037-0.015C28.481,87.158,28.494,87.162,28.506,87.168z"/><path style="&st59;" d="M28.401,87.129c-0.013-0.006-0.028-0.011-0.043-0.015C28.373,87.118,28.388,87.123,28.401,87.129z"/><path style="&st59;" d="M28.557,87.186c-0.013-0.004-0.025-0.012-0.04-0.017C28.531,87.176,28.544,87.182,28.557,87.186z"/><path style="&st59;" d="M28.458,87.15c-0.016-0.008-0.031-0.014-0.047-0.018C28.427,87.137,28.442,87.143,28.458,87.15z"/><path style="&st59;" d="M70.02,84.389c0.004,0,0.006,0,0.006,0C70.023,84.389,70.023,84.389,70.02,84.389z"/><path style="&st59;" d="M70.789,84.087c-0.001,0.003-0.003,0.005-0.004,0.005C70.786,84.09,70.788,84.088,70.789,84.087z"/><path style="&st59;" d="M70.762,84.102c-0.002,0.002-0.004,0.002-0.006,0.004C70.758,84.104,70.76,84.104,70.762,84.102z"/><path style="&st59;" d="M70.732,84.116c-0.002,0.002-0.004,0.003-0.006,0.004C70.729,84.119,70.73,84.118,70.732,84.116z"/><path style="&st59;" d="M70.697,84.133c-0.001,0-0.002,0-0.002,0.002C70.695,84.133,70.696,84.133,70.697,84.133z"/><path style="&st59;" d="M70.417,84.249c0.006-0.001,0.009-0.002,0.011-0.002C70.426,84.247,70.423,84.248,70.417,84.249z"/><path style="&st59;" d="M70.389,84.262h0.002H70.389z"/><path style="&st59;" d="M70.662,84.146L70.662,84.146L70.662,84.146z"/><path style="&st59;" d="M70.316,84.289c0.002-0.002,0.007-0.003,0.009-0.003C70.321,84.286,70.318,84.287,70.316,84.289z"/><path style="&st59;" d="M70.285,84.299c0.003,0,0.005-0.002,0.009-0.004C70.29,84.297,70.288,84.299,70.285,84.299z"/><path style="&st59;" d="M70.354,84.275c0.002-0.002,0.002-0.002,0.002-0.002S70.354,84.273,70.354,84.275z"/><path style="&st59;" d="M48.946,90.965c-0.011,0-0.022,0.004-0.033,0.004C48.924,90.969,48.935,90.965,48.946,90.965z"/><path style="&st59;" d="M70.256,84.311c0.002,0,0.004,0,0.006-0.002C70.26,84.311,70.258,84.311,70.256,84.311z"/><path style="&st59;" d="M70.78,82.41c0.013-0.009,0.026-0.021,0.042-0.032C70.809,82.389,70.793,82.401,70.78,82.41z"/><path style="&st59;" d="M70.956,82.279c0.013-0.008,0.022-0.016,0.033-0.023C70.98,82.264,70.969,82.271,70.956,82.279z"/><path style="&st59;" d="M70.898,82.321c0.012-0.009,0.022-0.017,0.033-0.022C70.923,82.305,70.91,82.313,70.898,82.321z"/><path style="&st2;" d="M70.903,83.794c0.2,0.064,0.106,0.171-0.087,0.278l0.089-0.033c0,0,0.793-0.436,0.458-0.633c-0.338-0.198-1.129-0.275-0.613-0.969l0.02-0.02c-0.442,0.344-0.756,0.727-0.498,1.021C70.27,83.443,70.387,83.629,70.903,83.794z"/><path style="&st59;" d="M70.566,84.191c-0.002,0-0.006,0.002-0.008,0.003C70.561,84.193,70.564,84.191,70.566,84.191z"/><path style="&st59;" d="M70.631,84.163c-0.002,0.001-0.004,0.002-0.006,0.003C70.627,84.165,70.629,84.164,70.631,84.163z"/><path style="&st59;" d="M70.598,84.176c0,0.002-0.004,0.004-0.006,0.004C70.594,84.18,70.598,84.178,70.598,84.176z"/><path style="&st59;" d="M70.493,84.223c-0.003,0-0.003,0-0.007,0.002C70.49,84.223,70.49,84.223,70.493,84.223z"/><path style="&st59;" d="M70.459,84.233c-0.002,0-0.004,0.002-0.008,0.004C70.455,84.235,70.457,84.233,70.459,84.233z"/><path style="&st59;" d="M70.842,82.363c0.012-0.01,0.024-0.018,0.034-0.025C70.866,82.346,70.854,82.354,70.842,82.363z"/><path style="&st59;" d="M48.293,91.024c-0.007,0-0.016,0-0.023,0C48.277,91.024,48.286,91.024,48.293,91.024z"/><path style="&st59;" d="M48.444,91.014c-0.004,0-0.011,0-0.017,0C48.434,91.014,48.44,91.014,48.444,91.014z"/><path style="&st59;" d="M48.369,91.02c-0.009,0-0.017,0-0.027,0C48.352,91.02,48.359,91.02,48.369,91.02z"/><path style="&st8;" d="M50.023,89.904c0,0,0.362,0.225,1.673,0.285c0,0,0.45,0,0.468,0.035c0.016,0.028,0.036,0.056-0.068,0.102l0,0c0.06-0.021,0.793-0.254,0.476-0.391c-0.04-0.019-0.063-0.024-0.074-0.028c-0.006,0-0.013,0-0.019-0.003l0,0c-0.008-0.002-0.016-0.002-0.021-0.004c-0.007,0-0.009-0.001-0.013-0.001c-0.006-0.003-0.014-0.003-0.021-0.005c-0.004,0-0.009,0-0.015-0.002c-0.005,0-0.011-0.002-0.017-0.002c-0.004,0-0.011-0.002-0.017-0.004c-0.005,0-0.012,0-0.015,0c-0.008-0.002-0.014-0.002-0.018-0.004c-0.004,0-0.012,0-0.016-0.002c-0.005,0-0.012,0-0.018,0c-0.002-0.004-0.008-0.004-0.01-0.004c-0.011-0.002-0.015-0.003-0.021-0.003c-0.004,0-0.006-0.001-0.008-0.001c-0.01-0.001-0.021-0.001-0.028-0.002c0,0-0.002,0-0.004-0.002c-0.007,0-0.015,0-0.021,0c-0.005-0.002-0.007-0.002-0.012-0.002s-0.011,0-0.02,0c-0.004,0-0.006,0-0.008,0c-0.008-0.002-0.013-0.002-0.019-0.002c-0.003,0-0.007,0-0.009,0c-0.008,0-0.014-0.002-0.018-0.002c-0.005,0-0.009-0.003-0.012-0.003c-0.006,0-0.014,0-0.021,0c-0.004,0-0.004,0-0.006,0c-0.039-0.004-0.08-0.004-0.128-0.009c-0.002,0-0.004,0-0.004,0c-0.009,0-0.015-0.002-0.022-0.002c-0.002,0-0.007,0-0.011,0c-0.007,0-0.013,0-0.021,0c-0.004-0.002-0.01-0.002-0.014-0.002c-0.006,0-0.013-0.002-0.02-0.002c-0.005,0-0.011,0-0.016-0.002c-0.005,0-0.011,0-0.019,0c-0.01,0-0.02-0.002-0.028-0.004c-0.006,0-0.012,0-0.019,0c-0.008,0-0.018-0.002-0.028-0.002c-0.005,0-0.011-0.002-0.016-0.002c-0.008,0-0.019,0-0.024-0.001c-0.006-0.001-0.013-0.001-0.021-0.001c-0.007-0.002-0.018-0.002-0.026-0.004c-0.005,0-0.013-0.001-0.02-0.001c-0.008-0.001-0.018-0.003-0.026-0.003c-0.007-0.001-0.016-0.001-0.023-0.003c-0.01,0-0.019-0.002-0.027-0.002c-0.007-0.002-0.014-0.002-0.021-0.002c-0.012,0-0.024-0.003-0.035-0.005c-0.007,0-0.014,0-0.02,0c-0.02-0.004-0.037-0.006-0.057-0.006c-0.142-0.019-0.271-0.033-0.378-0.055l-0.187-0.025c0,0-0.47-0.014-0.653-0.316c-0.118-0.197,0.457-0.318,0.457-0.318s0.956-0.193,1.917-0.321c0,0-2.542,0.294-2.777,0.626C49.613,89.737,50.023,89.904,50.023,89.904L50.023,89.904z"/><path style="&st59;" d="M69.986,84.401L69.986,84.401L69.986,84.401z"/><path style="&st59;" d="M69.989,84.399c0.001,0,0.001,0,0.004,0C69.991,84.399,69.99,84.399,69.989,84.399z"/><path style="&st59;" d="M48.839,90.979c-0.007,0-0.015,0.002-0.021,0.002C48.824,90.98,48.831,90.979,48.839,90.979z"/><path style="&st59;" d="M48.727,90.988c-0.009,0-0.017,0.002-0.026,0.002C48.71,90.99,48.718,90.988,48.727,90.988z"/><path style="&st59;" d="M48.637,90.998c-0.009,0-0.019,0.001-0.029,0.003C48.619,90.999,48.628,90.998,48.637,90.998z"/><path style="&st59;" d="M48.55,91.004c-0.009,0-0.018,0.002-0.025,0.004C48.532,91.006,48.54,91.004,48.55,91.004z"/><path style="&st59;" d="M70.139,84.35c0.004,0,0.006-0.002,0.01-0.004C70.145,84.348,70.143,84.35,70.139,84.35z"/><path style="&st59;" d="M70.116,84.359c0.002-0.002,0.004-0.002,0.007-0.002C70.12,84.357,70.118,84.357,70.116,84.359z"/><path style="&st59;" d="M70.193,84.332c0.002,0,0.002-0.002,0.004-0.002C70.195,84.33,70.195,84.332,70.193,84.332z"/><path style="&st59;" d="M70.068,84.374c0.003,0,0.004,0,0.007-0.002C70.072,84.374,70.07,84.374,70.068,84.374z"/><path style="&st59;" d="M70.163,84.342c0.005,0,0.007-0.002,0.011-0.005C70.17,84.34,70.167,84.342,70.163,84.342z"/><path style="&st59;" d="M69.996,84.395c0.002,0,0.002,0,0.004,0C69.998,84.395,69.998,84.395,69.996,84.395z"/><path style="&st59;" d="M70.004,84.395c0.002,0,0.006-0.002,0.008-0.002C70.006,84.395,70.006,84.395,70.004,84.395z"/><path style="&st59;" d="M72.23,81.559c-0.002,0-0.004,0-0.004,0S72.229,81.559,72.23,81.559z"/><path style="&st59;" d="M70.053,84.379c0.002,0,0.002,0,0.004,0C70.053,84.379,70.053,84.379,70.053,84.379z"/><path style="&st59;" d="M70.036,84.385c0.001,0,0.003,0,0.004-0.002C70.039,84.385,70.037,84.385,70.036,84.385z"/><linearGradient id="SVGID_31_" gradientUnits="userSpaceOnUse" x1="414.2451" y1="568.2656" x2="509.0055" y2="545.7273" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#EDEDEE"/><stop offset=".4176" stop-color="#FFF"/><stop offset=".6264" stop-color="#F8F9F9"/><stop offset=".9505" stop-color="#B2B4B6"/></linearGradient><path style="&st51;" d="M7.61,68.141c-0.065-0.062-0.112-0.105-0.139-0.131L7.45,68.021L7.61,68.141L7.61,68.141z"/><linearGradient id="SVGID_32_" gradientUnits="userSpaceOnUse" x1="416.6992" y1="578.5645" x2="511.8228" y2="555.9398" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#EDEDEE"/><stop offset=".4176" stop-color="#FFF"/><stop offset=".6264" stop-color="#F8F9F9"/><stop offset=".9505" stop-color="#B2B4B6"/></linearGradient><path style="&st62;" d="M90.412,59.954l0.689,0.108c1.976-1.573,3.869-3.571,3.869-3.571s1.258-1.261,1.889-2.356c0.22-0.381,0.281-0.356,0.271-0.177c0.023-0.09,0.103-0.456-0.038-0.714c-0.094-0.176-0.381,0.288-0.83,0.861c0,0-2.013,2.926-5.798,5.816c-3.786,2.891-4.776,3.771-8.083,5.655c0,0-2.309,1.021-3.914,0.669c-1.246-0.271,0-1.547,0.271-2.699c0.271-1.146,0.063-1.58-0.225-1.807c-0.287-0.225-0.91-0.385-2.142-0.109c0,0-4.709,1.264-6.819,3.307c-1.918,1.854,0.478,2.619,1.021,2.875c0,0,0.78,0.338,0.719,0.672c-0.063,0.336-0.496,0.623-0.733,0.783c-0.239,0.16-3.338,1.977-8.324,2.764c-4.039,0.641-3.26,0.255-7.143,0.654c-3.881,0.399-4.952,0.72-8.068,1.453c-3.116,0.734-4.945,1.537-5.352,2.349c-0.336,0.671,0.479,1.103,0.991,1.407c0.511,0.304,1.423,0.781,1.119,1.293c-0.305,0.512-1.631,1.277-4.874,1.391c-3.243,0.114-4.569-0.336-5.16-1.04c-0.548-0.649-0.08-1.323,0.096-1.946c0,0,0.382-0.814,0.16-1.215c-0.224-0.398-0.737-0.494-1.278-0.559c-0.544-0.064-3.245-0.158-5.337-0.271c-2.372-0.127-5.208-0.211-8.611-0.928c0,0-2.237-0.441-3.69-1.262c-0.096-0.055-0.18-0.107-0.25-0.156c-0.11-0.059-0.194-0.122-0.25-0.209c-0.41-0.432-0.047-0.748-0.186-1.168c-0.121-0.359-0.352-0.878-0.896-1.501c-0.176-0.183-0.428-0.437-0.72-0.713c-0.08-0.069-0.165-0.144-0.254-0.214c-1.276-1.037-1.422-1.149-1.964-1.166c-0.542-0.019-0.235,0.895-0.129,1.246c0.041,0.136,0.139,0.328,0.242,0.508c-0.2-0.364-0.336-0.729-0.257-0.915c0.144-0.337,0.309-0.308,0.309-0.308s0.133-0.053,0.595,0.297c0.463,0.35,1.499,1.078,2.012,1.705c0.512,0.625,0.481,1.18,0.481,1.18s-0.103,0.563,0.451,1.17c0.555,0.604,1.733,1.714,5.859,2.349c0.021,0.005,0.041,0.005,0.06,0.009l0.193-0.549l0.568,0.663c0.006,0,0.01,0.001,0.016,0.002c3.592,0.519,5.544,0.563,5.544,0.563s4.709,0.164,5.982,0.164c1.271,0,1.035,0.664,1.035,0.664s-0.072,0.361-0.225,0.647c-0.153,0.288-0.524,1.365-0.144,1.94c0,0,0.585,1.426,4.382,1.527c0,0,3.324,0.267,5.643-0.688c2.317-0.954,0.224-2.277,0.224-2.277s-0.794-0.483-1.129-0.737c-0.308-0.233-0.184-0.48-0.122-0.646c0.061-0.163,0.297-0.355,0.564-0.492c0.265-0.134,1.241-0.652,5.365-1.722c4.124-1.067,6.587-1.183,6.587-1.183s0.021-0.004,0.062-0.006l0.334-0.656l0.845,0.559c0.732-0.061,1.686-0.129,2.537-0.17c1.691-0.083,4.341-0.475,5.879-0.811c1.539-0.342,3.869-1.059,5.591-1.951c1.724-0.891,1.808-1.519,1.808-1.519s0.328-0.472-0.391-0.995c-0.719-0.521-1.037-0.38-1.672-1.024c-0.638-0.646,0.553-1.619,0.553-1.619s0.615-0.865,4.021-2.177c3.408-1.313,3.98-0.873,4.156-0.728c0.175,0.142,0.195,0.613,0.123,0.933c-0.072,0.316-0.494,1.455-0.721,2.055c-0.227,0.592-0.316,1.402,0.604,1.6c0.924,0.193,2.215-0.009,3.427-0.443c2.893-1.033,3.757-2.295,8.535-5.764c0.011-0.01,0.021-0.016,0.029-0.023L90.412,59.954L90.412,59.954z"/><linearGradient id="SVGID_33_" gradientUnits="userSpaceOnUse" x1="415.4736" y1="573.4199" x2="510.5869" y2="550.7977" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#EDEDEE"/><stop offset=".4176" stop-color="#FFF"/><stop offset=".6264" stop-color="#F8F9F9"/><stop offset=".9505" stop-color="#B2B4B6"/></linearGradient><path style="&st52;" d="M100.895,47.596c-0.635,1.186-1.164,2.608-1.443,3.5c-0.045,0.213-0.061,0.33-0.061,0.33s-0.119,0.654-0.054,1.036c0.028,0.161,0.069,0.279,0.106,0.375c0.021,0.052,0.039,0.095,0.055,0.134c0.02,0.045,0.031,0.082,0.033,0.111c0.007,0.082-0.044,0.614-0.27,1.23l0,0c0,0,0,0,0,0.002c-0.063,0.176-0.143,0.359-0.24,0.539c-0.024,0.05-0.053,0.095-0.074,0.139c-0.458,0.814-1.098,1.457-1.604,1.532c-0.324,0.049-0.484-0.117-0.557-0.386c0.014,0.369,0.086,0.738,0.289,0.963c0.406,0.441,1.563-0.795,1.563-0.795s0.688-0.789,0.965-2.062c0.406-1.875,0.187-2.248,0.187-2.248s-0.247-0.389-0.093-0.853c0.152-0.461,1.156-3.047,1.979-4.01l0.502-0.562c0-0.009,0.002-0.02,0.002-0.029l-0.211-0.521c-0.129,0.13-0.259,0.284-0.385,0.454C101.405,46.763,101.178,47.129,100.895,47.596L100.895,47.596z"/><linearGradient id="SVGID_34_" gradientUnits="userSpaceOnUse" x1="414.7754" y1="570.4785" x2="509.8697" y2="547.861" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#EDEDEE"/><stop offset=".4176" stop-color="#FFF"/><stop offset=".6264" stop-color="#F8F9F9"/><stop offset=".9505" stop-color="#B2B4B6"/></linearGradient><path style="&st53;" d="M10.564,70.807L10.564,70.807c-0.146-0.092-0.315-0.229-0.469-0.356c-0.133-0.112-0.641-0.585-1.18-1.086c-0.212-0.194-0.411-0.382-0.589-0.55c-0.277-0.262-0.524-0.493-0.688-0.646l0.107,0.358c0.017,0.028,0.034,0.06,0.052,0.089c0.183,0.29,0.854,1.264,2.153,2.277c1.549,1.213,1.559,0.729,1.559,0.729s0.062-0.4-0.296-0.84c-0.063-0.076-0.131-0.167-0.202-0.27v0.002C11.011,70.516,12.023,71.998,10.564,70.807z"/><linearGradient id="SVGID_35_" gradientUnits="userSpaceOnUse" x1="414.915" y1="571.0664" x2="510.04" y2="548.4415" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#EDEDEE"/><stop offset=".4176" stop-color="#FFF"/><stop offset=".6264" stop-color="#F8F9F9"/><stop offset=".9505" stop-color="#B2B4B6"/></linearGradient><path style="&st54;" d="M10.678,69.98c0.103,0.186,0.219,0.371,0.333,0.533C11,70.501,10.833,70.253,10.678,69.98z"/><linearGradient id="SVGID_36_" gradientUnits="userSpaceOnUse" x1="416.1035" y1="576.0654" x2="511.2286" y2="553.4405" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#EDEDEE"/><stop offset=".4176" stop-color="#FFF"/><stop offset=".6264" stop-color="#F8F9F9"/><stop offset=".9505" stop-color="#B2B4B6"/></linearGradient><path style="&st55;" d="M96.887,55.023c0,0,0.227-0.76,0.243-1.066c-0.003,0.014-0.005,0.021-0.005,0.021s-0.513,1.443-0.333,2.16C96.771,55.579,96.887,55.023,96.887,55.023z"/><path style="&st34;" d="M63.301,4.417l0.728,0.072c1.426-0.402,2.643-0.772,2.643-0.772s1.265-0.41,1.901-0.637c0.635-0.226,1.09-0.313,1.654-0.409c0.565-0.096,1.311-0.14,1.709-0.131c0.4,0.007,0.531,0.122,0.531,0.122s0.166,0.131,0.244,0.27c0.077,0.138,0.74,1.891,2.973,2.005c2.233,0.112,2.263-1.096,2.065-1.464c-0.226-0.427-0.896-0.863-0.896-0.863s-0.899-0.575-1.092-0.847c-0.191-0.27,0.034-0.357,0.104-0.375c0.065-0.017,2.435-0.497,2.729-0.609l0.021-0.021l-0.562-0.171c0,0-0.119,0.134-0.789,0.313c-0.67,0.179-1.235,0.246-1.742,0.313c-0.506,0.066-0.506,0.239-0.506,0.239l-0.086,0.136c-0.025,0.075-0.067,0.321,0.375,0.642c0.528,0.387,1.172,0.75,1.438,1.04s0.586,0.783,0.012,1.137C76.48,4.576,76.27,4.64,75.977,4.671c0.002,0.008,0,0.012,0,0.012c-0.248,0.021-0.457,0.03-0.638,0.03c-0.049,0.002-0.102,0.006-0.155,0.009l-0.017-0.013c-0.506-0.024-0.746-0.142-1.067-0.302c-0.442-0.223-0.758-0.73-0.92-1.087s-0.521-0.662-0.521-0.662c-0.588-0.336-1.695-0.343-2.813-0.15c-1.115,0.193-2.656,0.707-2.925,0.812c-0.268,0.104-1.616,0.551-2.307,0.73c-0.693,0.178-1.222,0.357-1.646,0.47c-0.427,0.111-3.432,1.005-4.556,1.339c-1.126,0.334-1.849,0.46-1.849,0.46c-1.688,0.172-2.193-0.134-2.193-0.134c-0.296-0.124-0.261-0.526-0.261-0.526l0.009-1.147c0,0-0.027-0.433-0.357-0.611c-0.328-0.179-0.779-0.252-1.593-0.29c-0.811-0.038-1.683,0.044-2.093,0.134c-0.408,0.09-1.189,0.313-1.764,0.952c-0.572,0.641-0.481,1.139-0.481,1.139s0.004,0.079,0.01,0.201c0.154,0.245,0.416,0.524,0.862,0.739c1.015,0.485-1.137,1.342-1.137,1.342l0,0c-0.479,0.208-1.191,0.478-2.208,0.777c-2.21,0.647-3.684,0.774-3.684,0.774l0.679,0.254c0,0,5.468-1.016,7.148-2.616c0,0,0.625-0.293,0.021-0.88c-0.606-0.585-0.898-0.761-0.898-0.761s-0.41-0.223,0.02-0.772c0.428-0.546,0.922-0.794,1.352-0.933c0.428-0.135,1.754-0.249,2.925-0.093c0,0,0.491,0.042,0.457,0.407c-0.032,0.365-0.087,0.873-0.077,1.028c0.01,0.157,0.025,0.515,0.399,0.845c0.379,0.332,1.098,0.453,1.098,0.453s1.257,0.228,2.845-0.218c1.586-0.444,3.65-1.141,5.438-1.629L63.301,4.417L63.301,4.417z"/><linearGradient id="SVGID_37_" gradientUnits="userSpaceOnUse" x1="412.6152" y1="535.3994" x2="501.5865" y2="514.8846" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#FFF"/><stop offset=".6538" stop-color="#FFF"/><stop offset="1" stop-color="#CBCCCE"/></linearGradient><path style="&st56;" d="M91.596,12.992l0.271,0.486c-0.021,0.01-0.034,0.014-0.034,0.014c-1.114,0.515-3.999,1.32-4.271,1.398c-0.271,0.08-0.166,0.234-0.166,0.234c0.029,0.078,0.988,1.106,0.988,1.106c1.178,1.249,0.494,2.296,0.494,2.296s-0.852,1.347-2.844,1.12c-1.993-0.227-2.618-1.767-2.729-2.049c-0.111-0.282-0.197-0.768-0.22-1.095c-0.022-0.33-0.272-0.32-0.272-0.32c-1.069-0.03-2.887,1.089-2.887,1.089c-0.824,0.47-1.682,1.147-3.479,1.958c-0.879,0.396-1.694,0.716-2.287,0.936l-0.967-0.173l0.091,0.482c-0.042,0.013-0.063,0.021-0.063,0.021s-2.268,0.822-4.529,1.553c-2.268,0.732-3.65,0.8-3.65,0.8s-1.336,0.12-2.266-0.266c-0.93-0.386-0.959-0.94-0.939-1.415c0.021-0.476,0.483-1.404,0.623-1.958c0.139-0.555-0.683-0.644-0.683-0.644s-1.958-0.236-3.65,0.296c-1.69,0.535-2.54,1.159-2.54,1.159c-0.91,0.512-0.863,0.957-0.863,0.957s-0.012,0.467,0.551,0.869s1.072,0.505,1.736,0.654c0.668,0.149,0.791,0.311,0.791,0.311c1.08,0.894,0.416,1.785,0.047,2.434c-0.631,1.113-3.674,1.653-3.674,1.653c-3.276,0.758-5.12,1.08-7.827,1.452l-0.876-0.46l-0.276,0.615c-7.089,0.936-10.065,1.877-11.065,2.135c-1,0.257-1.261,0.784-1.369,0.904c-0.108,0.12,0.079,0.171,0.079,0.171c0.427,0.137,0.647,0.442,0.647,0.442s1.399,1.697-0.012,3.108c-1.359,1.36-2.785,1.674-2.785,1.674s-2.177,0.737-4.077,0.341c-1.899-0.399-2.439-1.889-2.416-2.395c0.024-0.505,0.176-1.075,0.694-1.661c0.517-0.585,0.654-0.667,0.654-0.667s0.358-0.279,0.421-0.415c0.079-0.172-0.404-0.233-0.404-0.233c-1.034-0.13-3.496-0.097-5.822,0.131c-1.439,0.14-2.769,0.374-3.578,0.518l-0.223-0.48l-0.543,0.625l-3.12,0.504c-1.514,0.222-2.576-0.028-2.576-0.028s-1.331-0.397-1.479-1.252c-0.147-0.852,0.359-1.87,0.49-2.177c0.13-0.307,0.5-0.934,0.5-0.934s0.068-0.13,0.068-0.34c0-0.211-0.233-0.536-0.233-0.536s-0.205-0.396-0.886-0.38c-0.682,0.018-0.866,0.131-1.144,0.364c-0.044,0.038-0.079,0.081-0.108,0.127c0.021-0.064,0.045-0.117,0.073-0.158c0.21-0.309,0.65-0.668,1.401-0.7c0.748-0.034,1.041,0.228,1.041,0.228c0.719,0.82,0.115,1.845-0.351,2.76c-0.057,0.095-0.155,0.271-0.229,0.483c-0.032,0.076-0.062,0.153-0.087,0.227c-0.358,1.06,0.292,1.565,0.668,1.661c0.376,0.097,1.141,0.57,4.269-0.031c3.13-0.603,3.587-0.731,3.587-0.731s6.145-1.087,8.96-0.425l0.023,0.004c0,0,1.297,0.367,0.331,1.334c-0.966,0.966-1.729,1.617-1.504,2.377c0.223,0.762,1.267,1.903,3.646,1.603c0,0,0.842-0.113,1.105-0.165c1.733-0.336,2.899-1.268,2.899-1.268s0.972-0.721,0.782-1.631c-0.187-0.908-1.017-1.189-1.017-1.189s-0.659-0.424-0.141-1.237c0,0,0.141-0.69,2.553-1.317c2.412-0.626,6.813-1.518,10.555-1.989c3.49-0.408,9.652-1.575,10.89-2.08c1.235-0.508,1.497-1.4,1.521-1.708c0.024-0.31,0.072-0.83-1.14-1.09c-1.213-0.259-1.758-0.655-1.931-0.79c-0.172-0.138-0.545-0.483-0.545-1.275c0-0.791,1.607-1.745,3.392-2.35c1.78-0.606,3.927-0.34,3.927-0.34c1.948,0.167,0.936,1.963,0.936,1.963c-0.074,0.322-0.946,1.785,0.5,2.169c1.541,0.409,4.175-0.347,5.188-0.669c0.829-0.261,3.141-1.074,4.688-1.62c0.352-0.122,0.66-0.231,0.908-0.318c1.656-0.577,3.019-1.219,3.785-1.681c0.771-0.462,2.144-1.297,2.144-1.297s1.351-0.744,1.799-0.808c0.451-0.064,1.619-0.346,1.771,0.771c0.155,1.115,0.631,1.899,1.4,2.271c0.771,0.371,2.064,0.538,3.246-0.231c1.182-0.771,0.359-1.901,0.359-1.901c-0.021-0.028-0.039-0.057-0.062-0.085c-0.151-0.27-0.369-0.518-0.487-0.646c-0.388-0.47-0.736-0.822-0.736-0.822c-0.295-0.436,0.053-0.692,0.425-0.834c0.373-0.141,2.351-0.758,2.351-0.758c1.155-0.383,1.592-0.551,2.053-0.988c0.445-0.419-0.189-1.34-0.239-1.412l0.004-0.002l0.608,0.256c0.136,0.182,0.27,0.362,0.4,0.547l-0.007,0.005c0,0,0.226,0.527,0.054,0.799c-0.095,0.149-0.343,0.293-0.545,0.395L91.596,12.992L91.596,12.992z"/><linearGradient id="SVGID_38_" gradientUnits="userSpaceOnUse" x1="390.042" y1="485.6797" x2="390.042" y2="485.6797" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#FFF"/><stop offset=".6538" stop-color="#FFF"/><stop offset="1" stop-color="#CBCCCE"/></linearGradient><path style="&st57;" d="M-16.122-14.641"/><path style="&st34;" d="M57.455,92.28c-0.034-0.042-0.042-0.034-0.012-0.063c0.021-0.021,0.086-0.082,0.115-0.137c0,0-1.17-0.063-2.141,0.077c-0.962,0.137-1.933,0.335-1.933,0.335l0.301,0.146c0,0,0.127-0.055,1.047-0.183c0.921-0.128,1.267-0.128,1.267-0.128s0.808-0.063,0.969-0.063c0.162,0,0.061,0.104,0.061,0.104s-0.078,0.136,0.366,0.124c0,0,0.663-0.027,1.313-0.188C58.809,92.309,57.678,92.544,57.455,92.28z"/><path style="&st34;" d="M54.469,92.691c0,0,0.146,0.266-2.923,0.394c0,0,1.788,0.052,3.31-0.198C55.963,92.707,54.469,92.691,54.469,92.691L54.469,92.691z"/><path style="&st34;" d="M13.114,9.856c0,0-0.005,0.096,0.019,0.131c0.024,0.034,0.107,0.112,0.107,0.112s0.328-0.5,0.194-0.438c0,0-0.119,0.187-0.164,0.23c0,0-0.029,0.04-0.088,0.077C13.123,10.006,13.117,9.991,13.114,9.856L13.114,9.856z"/><path style="&st34;" d="M10.595,12.501c0,0-0.388,0.46,0,0.52l0.528-0.527c0,0,0.139-0.234,0.139-0.398C11.263,12.095,10.752,12.343,10.595,12.501L10.595,12.501z"/><path style="&st12;" d="M-16.122-14.641"/><path style="&st31;" d="M21.093,23.707c1.227,0.146,1.499-0.132,1.527-0.172c0.294-0.003,1.475-0.034,2.865-0.207c1.685-0.21,3.564-0.891,3.564-0.891s1.554-0.568,2.096-1.18l0.016-0.002c0,0-0.693-0.6-1.057-1.122c0,0-0.286-0.557,0.027-1.035c0.316-0.479,0.836-1.008,2.344-1.643c1.506-0.636,2.356-0.514,2.356-0.514s0.594-0.006,1.007,0.45c0.415,0.458,0.649,1.006,0.649,1.006s0.029,0.38-0.115,0.63c-0.141,0.251-0.155,0.277-0.155,0.277s0.049,0.017,0.378-0.007c0.329-0.021,1.165-0.142,2.67-0.506c1.508-0.363,3.407-0.972,3.407-0.972s4.9-1.578,5.407-1.714c0.507-0.135,1.357-0.436,1.357-0.436l0.027,0.059c0,0,0.405,0.663,0.392,1.269V16.94c0,0-0.021,0.301-0.698,0.818c-0.674,0.517-1.226,0.479-1.678,0.442c-0.452-0.039-0.665-0.071-0.794-0.045l-0.72,0.04c-0.787,0.111-1.224,0.407-1.224,0.407c-1.804,1.065,0.731,9.287,0.731,9.287c-3.742,0.47-8.143,1.363-10.555,1.989c-2.412,0.627-2.553,1.317-2.553,1.317c-0.519,0.813,0.141,1.236,0.141,1.236s0.829,0.283,1.017,1.19c0.19,0.91-0.783,1.629-0.783,1.629s-1.159,0.97-2.898,1.268c-1.738,0.298-2.396,0.35-3.429-0.47c-0.91-0.721-0.297-1.864,0.312-2.301c0.612-0.438,0.909-0.91,0.988-1.113c0.079-0.203,0.032-0.376,0.032-0.376l-0.58-0.534c-2.005-1.33-9.884,0.063-9.884,0.063c-0.213-1.169-0.362-1.171-0.282-3.117c0.051-1.244,0.291-1.752,0.291-1.752l0.058-0.164c0,0,0.448-1.443,1.141-2.44c0,0,0.602-0.172,1.364-0.349C20.616,23.793,21.093,23.707,21.093,23.707L21.093,23.707z"/><linearGradient id="SVGID_39_" gradientUnits="userSpaceOnUse" x1="231.2324" y1="-407.8711" x2="263.6191" y2="-407.8711" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#696969"/><stop offset=".3702" stop-color="#2E2E2E"/><stop offset=".4554" stop-color="#424242"/><stop offset=".6014" stop-color="#303030"/><stop offset=".6947" stop-color="#4A4A4A"/><stop offset="1" stop-color="#666666"/></linearGradient><path style="&st26;" d="M49.855,16.94c0,0-4.085,1.326-3.891,1.254c0,0-0.39,0.075-0.686,0.161c-0.294,0.086-0.539,0.247-0.539,0.247s-3.288,1.222-6.438,1.848c-3.148,0.627-2.977-0.361-2.708-0.83c0.232-0.409,0.829-1.112-0.188-1.254c-1.019-0.14-1.788,0.251-2.21,0.439c-0.422,0.189-3.162,1.362-1.251,2.254c0,0,1.423,0.642-0.377,1.755c0,0-1.816,1.16-5.355,1.77c0,0-0.565,0.063-1.88,0.111c-1.316,0.046-2.558,0.213-4.12,0.658c-1.378,0.391-1.992,0.579-2.744,1.065l0.194-0.501l0.2-0.462c1.069-0.533,3.719-1.288,5.717-1.378c1.997-0.089,2.908-0.16,4.721-0.624c2.134-0.546,2.702-1.019,2.93-1.163c0.194-0.123,0.771-0.479,0.493-0.633c-0.359-0.199-0.895-0.729-0.895-0.729c-0.217-0.256-0.39-0.373-0.158-1.046c0.356-1.029,2.196-1.644,2.196-1.644s1.028-0.534,2.334-0.514c1.305,0.021,1.287,0.752,1.287,0.752s0.062,0.34-0.268,0.827c0,0-0.503,0.579-0.049,0.656c0.454,0.081,1.622,0.179,5.48-1.028c3.859-1.207,8.085-2.611,8.085-2.611S49.855,16.66,49.855,16.94L49.855,16.94z"/><linearGradient id="SVGID_40_" gradientUnits="userSpaceOnUse" x1="231.623" y1="-407.063" x2="263.4941" y2="-407.063" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#525252"/><stop offset=".1856" stop-color="#333333"/><stop offset=".354" stop-color="#AEAEAE"/><stop offset=".4199" stop-color="#ADADAD"/><stop offset=".4276" stop-color="#9D9D9D"/><stop offset=".4433" stop-color="#818181"/><stop offset=".4611" stop-color="#6A6A6A"/><stop offset=".4814" stop-color="#585858"/><stop offset=".506" stop-color="#4C4C4C"/><stop offset=".539" stop-color="#444444"/><stop offset=".6166" stop-color="#424242"/><stop offset=".6684" stop-color="#454545"/><stop offset="1" stop-color="#BDBDBD"/></linearGradient><path style="&st58;" d="M31.145,21.257c-0.541,0.612-2.096,1.18-2.096,1.18s-1.88,0.68-3.564,0.891c-1.608,0.201-2.777,0.209-2.777,0.209l-0.082-0.002c-0.175,0.145-0.483,0.188-0.728,0.21c-0.244,0.023-0.806-0.039-0.806-0.039s-2.156,0.432-2.603,0.616c0,0-0.253,0.392-0.331,0.539c-0.08,0.146-0.299,0.594-0.299,0.594c1.069-0.534,3.718-1.289,5.717-1.379c1.997-0.089,2.908-0.159,4.721-0.624c2.134-0.546,2.702-1.019,2.929-1.163c0.195-0.123,0.771-0.479,0.493-0.633c-0.358-0.199-0.894-0.729-0.894-0.729c-0.217-0.256-0.391-0.373-0.158-1.046c0.356-1.029,2.196-1.644,2.196-1.644s1.028-0.533,2.333-0.514c1.306,0.021,1.287,0.753,1.287,0.753s0.062,0.34-0.269,0.826c0,0-0.503,0.579-0.049,0.657c0.455,0.08,1.622,0.178,5.48-1.028c3.858-1.208,8.085-2.612,8.085-2.612c-0.098-0.29-0.296-0.652-0.296-0.652s-0.85,0.301-1.358,0.436c-0.506,0.136-5.407,1.714-5.407,1.714s-1.9,0.608-3.407,0.972c-1.506,0.364-2.342,0.485-2.671,0.508c-0.329,0.021-0.378,0.006-0.378,0.006s0.013-0.027,0.156-0.279c0.144-0.248,0.115-0.629,0.115-0.629s-0.235-0.548-0.649-1.006c-0.414-0.457-1.007-0.45-1.007-0.45s-0.849-0.121-2.355,0.514c-1.508,0.636-2.029,1.164-2.346,1.643c-0.312,0.478-0.026,1.035-0.026,1.035c0.365,0.521,1.057,1.122,1.057,1.122"/><linearGradient id="SVGID_41_" gradientUnits="userSpaceOnUse" x1="236.917" y1="-417.333" x2="235.8882" y2="-410.5272" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)"><stop offset="0" stop-color="#969696"/><stop offset="1" stop-color="#000"/></linearGradient><path style="&st24;" d="M21.606,31.241c0,0-0.064-0.328,0.172-0.939c0.234-0.611,0.908-0.595,1.362-0.503c0.455,0.095,0.846,0.298,1.472-0.124c0.627-0.423,0.47-1.583,0.046-2.852c-0.423-1.267-0.328-2.128-0.328-2.128l-0.608-0.649l-0.237,0.696c0.047,1.316,0.657,3.226,0.829,3.759c0.173,0.533,0.297,0.8-0.735,0.517c-1.034-0.282-1.519,0.125-1.519,0.125c-1.332,0.862-1.082,2.161-1.082,2.161L21.606,31.241z"/><path style="&st60;" d="M27.498,36.633c-0.264-1.763-0.917-2.749-0.917-2.749c-0.25,0.188-0.513,0.693-0.513,0.693s0.179,0.208,0.471,1.568c0,0,0.141,0.106,0.438,0.279C27.273,36.597,27.498,36.633,27.498,36.633z"/><path style="&st60;" d="M33.152,32.881c0,0-0.78,0.907-0.378,2.336c0,0,0.454-0.379,0.585-0.68c0,0-0.145-0.458,0.138-1.017C33.5,33.52,33.37,33.1,33.152,32.881L33.152,32.881z"/><linearGradient id="SVGID_42_" gradientUnits="userSpaceOnUse" x1="428.7803" y1="532.0527" x2="429.5303" y2="524.4692" gradientTransform="matrix(1 0 0 1 -406.1641 -500.3203)"><stop offset="0" stop-color="#333333"/><stop offset=".431" stop-color="#000"/><stop offset="1" stop-color="#2E2E2E"/></linearGradient><path style="&st3;" d="M21.2,31.253c0.017-1.299,0.471-1.492,0.905-1.818c0.436-0.328,1.326-0.024,1.326-0.024s0.678,0.218,1.046-0.1c0.369-0.319-0.017-1.467-0.217-2.123c-0.202-0.653-0.41-1.599-0.445-2.262c-0.025-0.489-0.091-0.707-0.125-0.789l-0.205,0.604c0.047,1.316,0.657,3.226,0.829,3.759c0.173,0.533,0.297,0.8-0.735,0.517c-1.035-0.282-1.519,0.125-1.519,0.125c-1.332,0.862-1.082,2.162-1.082,2.162l0.259-0.027L21.2,31.253L21.2,31.253z"/><path style="&st21;" d="M26.239,34.29c0.045,0.06,0.421,0.597,0.736,2.113l0.005,0.025c0.294,0.17,0.519,0.205,0.519,0.205c-0.264-1.763-0.917-2.749-0.917-2.749C26.46,33.977,26.336,34.143,26.239,34.29L26.239,34.29z"/><path style="&st21;" d="M33.152,32.881c0,0-0.78,0.907-0.378,2.336c0,0,0.125-0.104,0.262-0.248l0.021-0.051c-0.304-1.033,0.283-1.763,0.283-1.763l0.004-0.003C33.291,33.053,33.225,32.957,33.152,32.881z"/><path style="&st10;" d="M17.159,8.189h0.117c-0.16,0.481-0.789,1.141-1.068,1.583c-0.156,0.248-0.252,0.572-0.474,0.751c0.038,0.043-0.003,0.003,0.04,0.04c0.088,0.052,0.813-0.139,0.95-0.236c0.082,0.015,0.076,0.011,0.12,0.039c0.042,0.07-0.481,0.991-0.595,1.109v0.04c0.196-0.023,0.502-0.056,0.634-0.16c0.383-0.299,0.47-0.937,0.75-1.346c-0.013-0.066-0.026-0.132-0.04-0.196c-0.222-0.04-0.681,0.02-0.87,0.157h-0.039c0.091-0.473,0.868-1.346,1.146-1.741c0.454-0.647,0.881-1.269,1.345-1.9c0.243-0.331,0.585-0.622,0.831-0.949c0.276-0.367,0.569-0.85,0.949-1.107V4.194h-0.158c-0.186,0.135-0.675,0.218-0.908,0.354c0.032,0.135,0.019,0.101,0.118,0.158c-0.139,0.386-0.598,0.673-0.832,0.991c-0.371,0.5-0.784,0.968-1.147,1.464c-0.123,0.164-0.205,0.421-0.356,0.553c-0.237,0.208-0.913,0.185-1.185,0.396h-0.08c0.056-0.332,0.907-1.392,1.147-1.622v-0.04c-0.408,0.057-0.724,0.273-0.989,0.473c0.044,0.091,0.037,0.073,0.12,0.12c-0.145,0.238-0.361,0.415-0.515,0.633c-0.197,0.275-0.305,0.602-0.514,0.871c0.014,0.04,0.028,0.077,0.04,0.118C15.948,8.641,17.001,8.307,17.159,8.189L17.159,8.189z M51.936,13.534c0.199,0.066,0.396,0.131,0.596,0.197c0.159,0.002,0.327-0.002,0.432-0.04c-0.009-0.654-0.364-0.913-0.593-1.345c-0.113-0.22-0.175-0.523-0.355-0.673c0.069-0.242,0.727-0.308,0.988-0.396c0.643-0.211,1.371-0.422,2.02-0.633c0.305-0.099,0.664-0.077,0.91-0.236c0.146,0.015,0.22,0.029,0.277,0.118c0.143,0.212,0.26,1.667,0.156,2.097c-0.398,1.663-0.896,2.963-1.938,3.958v0.039c0.385-0.062,0.568-0.436,0.83-0.632c1.051-0.794,1.762-1.972,2.137-3.444c0.221-0.865-0.14-1.713,0.199-2.452h-0.039c-0.074-0.188-1.082-0.553-1.388-0.555c-0.164,0.177-0.399,0.416-0.634,0.515c-0.357,0.152-0.838,0.109-1.146,0.315c-0.287-0.024-0.506-0.57-0.315-0.791c-0.011-0.09-0.009-0.112-0.04-0.158c-0.239-0.191-0.85-0.171-1.268-0.158c-0.133,0.125-0.252,0.15-0.314,0.358h-0.039c-0.021,0.076,0.02,0.05,0.039,0.078c0.025,0.016,0.163-0.007,0.236,0.04c0.449,0.047,0.438,0.566,0.675,0.831c-0.027,0.069-0.011,0.04-0.042,0.08c-0.155,0.123-1.301,0.453-1.543,0.515c-0.185,0.046-0.414-0.068-0.553-0.081c-0.336-0.028-0.633,0.16-0.831,0.277c0.107,0.157,0.434,0.118,0.554,0.276C51.368,12.193,51.556,12.913,51.936,13.534L51.936,13.534z M59.807,12.977c0.187,0.093,0.187,0.332,0.278,0.514c0.185,0.371,0.437,0.82,0.554,1.228v0.316c0.092,0.252,0.396,0.284,0.596,0.435c0.156-0.021,0.214-0.061,0.314-0.118c-0.066-0.753-0.525-1.378-0.791-1.979c-0.08-0.188-0.207-0.452-0.236-0.633c-0.021-0.109,0.063-0.169,0-0.276c-0.051-0.123-0.072-0.085-0.156-0.159c-0.059-0.04-0.031-0.016,0-0.078c0.068-0.144,0.213-0.287,0.275-0.436c0.133-0.313,0.127-0.576,0.396-0.751c-0.04-0.41-0.639-0.457-1.107-0.435c-0.057,0.042-0.156,0.064-0.24,0.077c0.05,0.103,0.082,0.124,0.199,0.157c0.113,1.161-0.699,2.225-1.229,2.928c-0.208,0.279-0.556,0.456-0.75,0.754h-0.04v0.038C58.395,14.473,59.54,13.383,59.807,12.977L59.807,12.977z M12.407,22.83c-0.081,0.017-0.076,0.009-0.117,0.039c-0.288,0.148-0.773,1.426-1.346,1.069c-0.292,0.002-0.319-0.055-0.476-0.16c0.02-0.376,0.659-1.063,0.913-1.226c0.031-0.604,0.187-1.252,0.118-1.819c-0.041-0.014-0.08-0.028-0.118-0.039c-0.14-0.046-0.25,0.168-0.357,0.276c-0.29,0.291-0.648,0.597-0.871,0.949c-0.337-0.003-1.414-0.013-1.623,0.119H8.411c0.099-0.256,0.86-1.096,0.633-1.464c-0.013-0.041-0.025-0.08-0.04-0.12c-0.722,0.002-1.592,1.287-1.82,1.82c-0.115,0.266-0.115,0.573-0.276,0.791v0.04c0.54-0.066,1.082-0.133,1.622-0.199c0.205-0.044,0.487,0.052,0.633-0.039h0.554c0.092-0.118,0.184-0.238,0.277-0.356c0.33-0.349,0.768-0.702,1.028-1.106h0.119v0.551c-0.303,0.273-0.773,0.695-0.91,1.108v0.316c-0.203,0.88,0.223,1.329,0.99,1.267c0.5-0.466,1.324-0.848,1.226-1.779C12.405,22.833,12.444,22.873,12.407,22.83L12.407,22.83z M7.819,22.118H7.58c0.109-0.436,0.537-0.935,1.069-0.95v0.197c-0.185,0.239-0.369,0.475-0.554,0.713C7.982,22.076,7.88,22.076,7.819,22.118z M93.044,22.315c-0.164-0.405-0.294-0.722-0.475-1.068c-0.3-0.574-0.613-1.414-1.464-1.425c-0.211,0.179-0.435,0.322-0.555,0.593c-0.777,1.762,0.819,3.747,1.543,4.71c0.256,0.339,0.557,0.712,0.948,0.908c-0.091,1.376-1.269,1.813-2.53,1.267c-0.899-0.386-1.617-1.237-2.179-1.979c-0.188-0.249-0.481-0.457-0.672-0.713c-0.177-0.239-0.304-0.507-0.515-0.713v-0.039h-0.078c0.107,0.426,0.354,0.815,0.514,1.188c0.669,1.538,1.52,2.614,2.811,3.521c0.608,0.428,1.621,1.104,2.494,0.475C94.412,27.942,93.669,23.851,93.044,22.315L93.044,22.315z M92.928,24.216c-0.104,0.1-0.539-0.419-0.635-0.515c-0.441-0.443-1.329-1.221-0.83-1.979h0.197c0.388,0.403,0.746,0.788,0.99,1.344c0.129,0.299,0.152,0.805,0.313,1.069C92.941,24.205,92.958,24.175,92.928,24.216L92.928,24.216z M66.693,32.128v-0.395c0.179-0.801,0.137-1.765,0.314-2.572c0.241-1.088-0.101-2.148,0.99-2.414c0.021-0.106,0.057-0.148,0-0.238c-0.025-0.067-0.009-0.039-0.04-0.079c-0.043-0.031-0.038-0.024-0.116-0.039c-0.305,0.222-1.131,0.373-1.543,0.474c-0.313,0.076-0.639,0.01-0.871,0.158c-0.039,0.013-0.078,0.027-0.119,0.04c0.014,0.079,0.025,0.159,0.041,0.237c0.451,0.147,0.867-0.031,1.067,0.356c0.13,0.252,0.112,1.157,0.039,1.504c-0.251,1.163-0.146,2.491-0.396,3.64c-0.086,0.397,0.022,1.171-0.157,1.463v0.08c-0.241-0.115-0.397-0.426-0.554-0.633c-0.354-0.467-0.875-0.84-1.229-1.305c-0.213-0.281-0.437-0.617-0.712-0.833c0.037-0.761,0.259-1.56,0.438-2.254c0.131-0.522,0.135-1.005,0.395-1.386c0.148-0.217,0.505-0.355,0.751-0.475c-0.002-0.1-0.004-0.146-0.04-0.198c-0.014-0.04-0.023-0.079-0.037-0.119c-0.543,0.081-1.003,0.341-1.505,0.475c-0.454,0.123-0.911,0.092-1.269,0.276c0.012,0.091,0.01,0.112,0.041,0.158c0.014,0.039,0.024,0.08,0.039,0.118c1.391-0.078,1.18,0.678,0.912,1.742c-0.084,0.326-0.029,0.775-0.199,1.028v0.079h-0.039c-0.285-0.433-0.713-0.852-1.067-1.227c-0.146-0.132-0.291-0.264-0.435-0.395c-0.104-0.137-0.16-0.312-0.278-0.436c0.024-0.437,0.38-0.549,0.713-0.672c-0.015-0.183-0.052-0.206-0.118-0.317c-1.031,0.151-1.927,0.73-3.086,0.791v0.041h-0.04c0.004,0.1,0.004,0.146,0.04,0.197v0.079c0.227,0.039,0.564-0.054,0.831,0.04c0.427,0.15,0.81,0.648,1.067,0.99c0.388,0.513,0.996,0.949,1.384,1.463c0.204,0.274,0.434,0.634,0.713,0.832c-0.038,0.696-0.229,1.428-0.396,2.058c-0.086,0.323-0.035,0.735-0.197,0.988c-0.025,0.069-0.01,0.039-0.041,0.08c-0.377-0.718-1.104-1.265-1.582-1.9c-0.918-1.22-1.938-2.319-2.889-3.521c0-0.167,0.01-0.268,0.08-0.356c0.073-0.229,0.359-0.443,0.633-0.476c0.015-0.12,0.033-0.135-0.039-0.238c-0.016-0.038-0.026-0.077-0.041-0.118c-0.803,0.123-1.521,0.497-2.293,0.714c-0.401,0.112-0.928,0.057-1.229,0.276c-0.04,0.013-0.08,0.026-0.117,0.04c0.021,0.152,0.061,0.176,0.117,0.277c0.314-0.005,0.646-0.092,0.949,0c0.793,0.241,1.361,1.137,1.818,1.742c0.201,0.266,0.513,0.483,0.713,0.751c0.849,1.129,1.808,2.146,2.65,3.285c0.328,0.442,0.771,0.825,1.066,1.304c0.179-0.004,0.216-0.025,0.316-0.079c0.213-0.929,0.332-1.866,0.596-2.81c0.119-0.432,0.269-0.942,0.314-1.424c0.327,0.117,0.592,0.607,0.793,0.871c0.618,0.821,1.491,1.502,2.057,2.373c0.164-0.007,0.182-0.026,0.277-0.078C66.352,34.819,66.521,33.473,66.693,32.128L66.693,32.128z M4.297,38.894c-0.013,2.467-0.142,6.269,1.781,6.806c0.7,0.193,1.087-0.271,1.306-0.595c0.786-1.17,0.565-3.446-0.199-4.43c-0.339,0.034-0.825,0.84-0.988,1.106c-0.082-0.016-0.075-0.011-0.119-0.04c-0.091-0.041-0.085-0.066-0.159-0.118c-0.06-0.933,0.127-1.802,0.159-2.691c1.044,0.102,1.941,0.696,3.007,0.751c-0.001-0.185,0-0.434,0.077-0.552c-0.009-0.092-0.007-0.112-0.04-0.16c-0.145-0.115-0.949-0.306-1.186-0.315v-0.04h-0.04c0.146-1.174-0.186-2.082-0.99-2.414c-0.449-0.08-0.897-0.16-1.346-0.239c-0.229-0.083-0.341-0.266-0.514-0.395c-0.058-0.38-0.133-0.806,0.159-1.029c-0.021-0.142-0.032-0.168-0.119-0.238v-0.039h-0.04c-0.133,0.228-0.245,0.493-0.315,0.792c-0.234,0.983,0.309,1.818,0.909,2.018c0.397,0.065,0.792,0.132,1.188,0.197c0.314,0.122,0.453,0.379,0.671,0.595c-0.009,0.512-0.5,0.568-0.91,0.435c-0.64-0.208-1.321-0.353-1.977-0.592c-0.172-0.064-0.333-0.17-0.555-0.199c-0.027,0.25-0.054,0.501-0.08,0.751c0.554,0.171,1.109,0.343,1.662,0.515c-0.023,1.398-0.574,3.074,0.119,4.153c0.084,0.021,0.143,0.037,0.198,0.08c0.78-0.054,0.943-0.68,1.345-1.108c0.342,0.82,0.086,2.253-0.671,2.453c-0.326,0.224-0.803-0.066-0.989-0.237c-0.648-0.599-0.785-1.511-1.027-2.532c-0.083-0.344,0.033-1.042-0.118-1.307c0.006-0.404,0.092-1.134-0.12-1.344v-0.039L4.297,38.894L4.297,38.894z M99.336,45.543c-0.143-0.666,0.055-1.478-0.08-2.097v-0.633c-0.097-0.453-0.059-1.056-0.156-1.502c-0.189-0.882-0.022-1.926-0.355-2.652c-0.197-0.047-0.393-0.084-0.671-0.08c-0.103,0.104-0.179,0.158-0.159,0.278c0.083,0.359,0.547,0.432,0.673,0.792c0.015,0.172,0.026,0.343,0.04,0.514c0.133,0.561,0.111,1.286,0.236,1.86v0.475c0.063,0.289,0.16,1.036,0.078,1.267c-0.139,0.41-0.584,0.78-0.868,1.068c-0.754,0.755-1.64,1.715-2.97,1.859c-0.025,0.068-0.01,0.039-0.041,0.08c0.022,0.494,0.476,0.396,0.793,0.594c0.08-0.014,0.158-0.028,0.236-0.042c0.122-0.074,0.191-0.242,0.276-0.356c0.2-0.261,0.563-0.399,0.751-0.671h0.04c0.002,1.205,0.028,2.561,0.04,3.718h0.117c0.272-1.172,0.252-2.61,0.238-4.039c0.521-0.486,0.853-1.19,1.385-1.66v-0.078h0.041c0.007,1.251,0.037,2.529,0.037,3.797c0,0.407-0.102,1.378,0,1.544v0.237h0.08c0.106-0.425,0.133-1.023,0.236-1.501v-0.674C99.451,47.107,99.45,46.078,99.336,45.543L99.336,45.543z M28.313,48.073c-0.347-0.144-0.776-0.461-0.989-0.751c-0.637-0.875-1.337-2.948-0.87-4.51c0.379-1.266,1.202-2.127,2.532-2.454c0.673-0.163,1.397,0.062,1.821,0.278c1.208,0.622,1.725,1.506,2.096,2.967c0.48,1.887-0.132,3.619-1.385,4.194c0.078,0.764,0.158,1.529,0.237,2.295c0.444-0.013,0.852-0.105,1.227-0.199c0.629-0.155,1.271-0.176,1.86-0.315c0.431-0.104,1.052-0.015,1.384-0.237c0.079-0.17-0.247-1.35-0.315-1.623c-0.057-0.229-0.009-0.461-0.119-0.633v-0.079c-0.091,0.012-0.185,0.025-0.277,0.039c0.018,1.195-0.834,1.032-1.781,1.267c-0.473,0.119-1.049,0.27-1.581,0.276c0-0.17,0-0.343-0.001-0.514c0.045-0.083,0.739-0.386,0.868-0.476c0.461-0.318,0.931-0.826,1.229-1.304c0.202-0.327,0.366-0.764,0.473-1.149c0.138-0.489,0.154-1.17,0.041-1.662c-0.079-0.338-0.048-0.603-0.158-0.91c-0.427-1.187-1.322-2.054-2.453-2.532c-0.513-0.216-1.093-0.224-1.7-0.356c-0.539-0.116-1.509,0.124-1.901,0.238c-1.905,0.562-3.198,1.48-3.799,3.323c-0.236,0.728-0.163,1.736,0.04,2.414c0.467,1.561,1.773,3.02,3.72,3.047v0.039c0.062,0.088,0.06,0.264,0.118,0.355c-0.024,0.067-0.009,0.039-0.04,0.08c-0.164,0.111-0.404,0.061-0.633,0.117c-0.47,0.118-1.986,0.486-2.334,0.158c-0.222-0.072-0.37-0.363-0.396-0.632c-0.099,0.004-0.146,0.004-0.197,0.039h-0.082c0.146,0.767,0.291,1.53,0.435,2.296h0.041v0.04c1.385-0.239,2.77-0.478,4.154-0.713c-0.198-0.728-0.395-1.451-0.593-2.179C28.873,48.139,28.517,48.159,28.313,48.073L28.313,48.073z M96.014,43.682c0.086,0.218,0.254,0.58,0.435,0.712c0.086,0.063,0.132,0.04,0.198,0.119c1.31,0.113,1.842-2.143,1.308-3.442c-0.095-0.225-0.517-0.885-0.911-0.633h-0.08c0.026-0.069,0.01-0.038,0.04-0.08c-0.001-0.188-0.021-0.25-0.077-0.356c-0.08-0.013-0.156-0.026-0.238-0.038c-0.039,0.031-0.01,0.014-0.078,0.038c0.027,0.24,0.111,0.247,0.119,0.514C96.09,41.099,95.545,42.497,96.014,43.682z M96.446,41.585c0.088-0.213,0.265-0.35,0.396-0.515c0.082-0.015,0.075-0.01,0.117-0.04c0.301-0.001,0.385,0.057,0.555,0.159c0.301,0.711,0.346,1.954-0.156,2.494c-0.077,0.085-0.229,0.116-0.315,0.197C96.214,43.817,96.146,42.305,96.446,41.585L96.446,41.585z M78.092,57.168c-0.445-0.273-0.507-1.675-0.673-2.294c-0.327-1.215-0.483-2.489-0.831-3.72c-0.223-0.788-0.523-1.605-0.435-2.572c0.139-0.138,0.231-0.32,0.396-0.436c0.223-0.154,0.58-0.229,0.752-0.436c0.027-0.051-0.019-0.128-0.041-0.238c-0.459,0.074-0.879,0.35-1.267,0.515c-0.792,0.337-1.567,0.536-2.373,0.87c-0.252,0.104-0.515,0.282-0.833,0.315v0.238c0.027,0.014,0.055,0.025,0.08,0.04c0.042,0.045,1.033-0.392,1.346-0.118c0.356,0.125,0.311,0.59,0.514,0.872c-0.061,0.614-0.672,1.558-0.912,2.097c-0.58,1.326-1.17,2.592-1.816,3.836c-0.248,0.477-0.543,1.334-0.871,1.701v0.039c-0.216-0.296-0.199-1.051-0.314-1.462c-0.353-1.235-0.578-2.591-0.951-3.798c-0.068-0.23-0.305-1.279-0.156-1.503c0.051-0.546,0.822-0.785,1.266-0.95c-0.012-0.092-0.024-0.186-0.039-0.277c-0.701,0.105-1.429,0.479-2.058,0.713c-0.595,0.223-1.14,0.313-1.741,0.516c-0.298,0.102-0.636,0.275-0.986,0.314v0.041h-0.041c0.015,0.112,0.025,0.172,0.078,0.237c0.162,0.107,1.03-0.352,1.386-0.077c0.557,0.19,0.573,1.075,0.752,1.66c0.481,1.579,0.728,3.327,1.187,4.947c0.115,0.404,0.391,1.686,0.119,2.018c-0.148,0.439-0.885,0.615-1.306,0.791c0.014,0.08,0.024,0.159,0.036,0.237c0.609-0.09,1.162-0.373,1.707-0.56c1.063-0.354,2.066-0.65,3.089-1.029c-0.017-0.092-0.027-0.186-0.041-0.275c-0.437,0.116-0.773,0.248-1.386,0.236c-0.08-0.068-0.157-0.133-0.235-0.199c-0.067-0.21-0.134-0.422-0.199-0.632c0.043-0.499,0.683-1.421,0.91-1.86c0.673-1.293,1.262-2.6,1.856-3.955c0.229-0.519,0.754-1.275,0.832-1.857c0.184,0.111,0.133,0.438,0.197,0.672c0.135,0.475,0.211,0.98,0.355,1.503c0.281,1,0.391,2.075,0.673,3.126c0.104,0.387,0.261,1.048,0.08,1.464c-0.179,0.404-0.841,0.673-1.267,0.83c0.017,0.084,0.037,0.183,0.08,0.238c0.004,0.007,0.906-0.288,1.064-0.354c1.104-0.471,2.236-0.959,3.361-1.386c-0.015-0.093-0.024-0.187-0.039-0.274C79.117,57.043,78.477,57.407,78.092,57.168L78.092,57.168z M96.803,60.498c-0.143,0.13-0.354,0.163-0.514,0.277c-0.501,0.359-1.025,0.962-1.385,1.463c-0.288,0.402-0.534,0.843-0.791,1.268c-0.112,0.188-0.137,0.402-0.277,0.553v0.08c0.346-0.059,0.549-0.283,0.792-0.436c0.659-0.408,1.249-0.781,1.858-1.225c0.295-0.217,0.515-0.551,0.83-0.754c0.029-0.473,0.125-0.844-0.077-1.188C97.115,60.512,96.975,60.496,96.803,60.498z M96.329,61.921c-0.239,0.177-0.47,0.423-0.712,0.595c-0.208,0.146-0.458,0.224-0.633,0.396h-0.04c0.13-0.408,0.817-1.107,1.146-1.344c0.17-0.124,0.383-0.157,0.557-0.279h0.156c0.036,0.046,0.034,0.044,0.08,0.08C96.846,61.667,96.523,61.774,96.329,61.921L96.329,61.921z M10.825,63.465c-0.166-0.502-0.278-0.99-0.435-1.465c-0.079-0.246-0.062-0.525-0.199-0.713v-0.118c0.269,0.097,0.679,0.087,0.911,0.238h0.201c-0.045-0.206-0.086-0.552-0.201-0.713c-0.12-0.195-0.886-0.197-1.106-0.354c-0.312-0.244-0.607-0.947-0.832-1.307c-0.56-0.887-1.302-1.832-2.137-2.453c-0.443-0.329-0.751-0.671-1.544-0.673c-0.092,0.065-0.185,0.132-0.276,0.198c-0.178,0.789,0.139,2.248,0.592,2.611v0.078c-0.189-0.051-0.393-0.152-0.514-0.275h-0.04c0.007,0.227,0.051,0.522,0.158,0.672c0.046,0.195,0.362,0.354,0.554,0.396c0.248,1.037,0.592,2.101,0.95,3.05c0.289,0.758,0.436,1.48,0.75,2.213c0.155,0.356,0.522,0.617,0.634,0.99h0.117c-0.089-0.334-0.271-0.646-0.394-0.949c-0.364-0.875-0.653-1.804-0.952-2.688C6.868,61.62,6.734,61.057,6.548,60.5c-0.069-0.21-0.049-0.427-0.158-0.595v-0.039c0.269,0.049,0.43,0.188,0.634,0.276c0.461,0.201,0.903,0.277,1.385,0.476c0.353,0.146,0.796,0.347,1.228,0.396c0.048,0.359,0.253,1.301,0.435,1.545v0.117c-0.602-0.412-0.589-1-1.663-0.91c-0.054,0.063-0.128,0.117-0.197,0.158c-0.098,0.244-0.104,0.646,0,0.909c0.257,0.646,1.072,1.991,1.741,2.179c0.257,0.184,0.634-0.043,0.75-0.24c0.242,0.127,0.293,0.682,0.395,0.951c0.212,0.558,0.522,1.289,1.031,1.543v0.041h0.083c-0.066-0.447-0.318-0.851-0.475-1.229C11.387,65.223,11.113,64.324,10.825,63.465L10.825,63.465z M9.678,60.26C9.26,60.23,8.905,60.067,8.57,59.945c-0.894-0.332-1.703-0.615-2.492-0.991c-0.095-0.358-0.76-1.644-0.396-2.095c0.026-0.04,0.053-0.081,0.079-0.12c0.081-0.019,0.077-0.011,0.119-0.039c1.219,0.146,2.442,1.629,3.046,2.452c0.236,0.32,0.43,0.799,0.752,1.029V60.26L9.678,60.26z M10.311,63.701c-0.12,0.146-0.237,0.291-0.356,0.436c-0.105,0.078-0.223,0.109-0.316,0.198c-0.68-0.021-0.704-0.686-0.989-1.108c0.005-0.389,0.152-0.39,0.315-0.594c0.092-0.007,0.112-0.007,0.158-0.037c0.614,0.004,0.753,0.278,1.109,0.515C10.29,63.344,10.327,63.445,10.311,63.701L10.311,63.701z M33.578,69.794c-0.165-0.271-0.49-0.342-0.713-0.554c-0.069-0.023-0.04-0.007-0.079-0.039c0.51-0.264,1.053-0.555,1.583-0.79c0.142,0.158,0.801,0.792,1.029,0.671c0.04-0.012,0.079-0.023,0.118-0.038c-0.013-0.224-0.025-0.448-0.04-0.673c-0.499-0.498-1.234-0.91-2.059-1.066v0.039h-0.039c0.093,0.273,0.398,0.534,0.636,0.672v0.119c-0.469,0.068-0.885,0.295-1.307,0.437c-0.289,0.093-0.638,0.08-0.873,0.235h-0.117c0.171-0.479,0.737-0.871,1.028-1.267c0.576-0.776,1.033-1.728,1.94-2.176c-0.024-0.365-1.076-1.12-1.464-0.871c-0.097,0.051-0.029-0.021-0.079,0.078c-0.059,0.144,0.137,0.321,0.079,0.554c-0.076,0.305-0.831,1.74-1.029,1.9v0.041c-0.408-0.139-0.718-0.523-1.107-0.713c0.069-0.364,0.375-0.644,0.554-0.91c0.453-0.684,0.816-1.335,1.503-1.782c-0.006-0.526-0.855-1.075-1.425-1.065c0.002,0.242,0.125,0.379,0.08,0.592c-0.14,0.646-0.435,1.297-0.672,1.861c-0.156,0.364-0.226,0.799-0.476,1.065c-0.054,0.03-0.492-0.006-0.594-0.077c-0.149-0.002-0.298,0.005-0.394,0.038v0.079c0.666,0.645,1.387,0.865,2.295,1.268c-0.126,0.655-0.786,1.092-1.108,1.584c-0.166,0-0.3-0.011-0.395-0.08c-0.091,0.017-0.098,0.021-0.158,0.041c0.016,0.582,0.5,1.077,0.987,1.188c0.327-0.366,0.737-0.543,1.228-0.751c0.449,0.468,0.578,1.137,0.751,1.897c0.075,0.332-0.047,0.697,0.04,0.988c0.152,0.514,0.426,0.667,0.672,1.027h0.277c0.174-0.93-0.253-1.832-0.475-2.571C33.71,70.43,33.644,70.111,33.578,69.794L33.578,69.794z M96.09,63.108c-0.238,0.202-0.57,0.296-0.83,0.475c-0.4,0.282-0.758,0.659-1.146,0.95c-0.177,0.134-0.435,0.253-0.556,0.436c-0.199,0.299-0.16,0.806-0.396,1.067v0.157c0.314-0.114,0.464-0.483,0.713-0.672c0.307-0.23,0.563-0.536,0.87-0.754c0.192-0.133,0.411-0.207,0.594-0.355c0.125,0.023,0.115,0.037,0.199,0.081c-0.021,1.005-0.549,1.714-0.871,2.454c-0.093,0.215-0.121,0.551-0.276,0.71c-0.074,0.076-0.229,0.094-0.314,0.157c-0.264,0.291-0.528,0.58-0.794,0.873c-0.25,0.344-0.365,0.803-0.632,1.146c-0.002,0.114-0.002,0.216,0.037,0.276c0.041,0.031,0.11,0.059,0.16,0.08c0.51-0.483,1.004-0.887,1.424-1.465c0.658-0.904,0.986-2.047,1.465-3.125c0.3-0.683,0.734-1.354,0.711-2.334c-0.047-0.045-0.084-0.102-0.117-0.158L96.09,63.108L96.09,63.108z M93.32,69.361V69.4h-0.04c0.069-0.475,0.43-0.606,0.596-0.952h0.079C93.904,68.842,93.605,69.194,93.32,69.361L93.32,69.361z M34.171,69.993c-0.08,0.342,0.76,1.106,1.027,1.308c0.133,0.1,0.312,0.328,0.515,0.235c0.104-0.008,0.136-0.019,0.199-0.04c0.046-0.105,0.115-0.24,0.039-0.354C35.93,70.645,34.64,70.088,34.171,69.993z M37.97,73.037c0.067,0.034,0.122,0.021,0.198-0.039c0.139-0.113,0.063-0.313,0.159-0.475c0.222-0.159,0.615-0.118,0.911-0.199c0.809-0.213,1.753-0.198,2.65-0.396c0.425-0.093,1.128,0.16,1.464-0.037c0.04-0.016,0.081-0.026,0.118-0.043c-0.019-0.517-1.009-0.737-1.545-0.588c-0.237,0.066-0.513,0.213-0.751,0.275c-0.185,0.014-0.37,0.027-0.555,0.038c-0.062-0.644-0.38-1.144-0.395-1.817c0.595-0.013,1.341-0.091,1.739-0.316c-0.008-0.2-0.045-0.2-0.118-0.314c-0.453-0.107-1.23-0.126-1.583,0.116c-0.1-0.004-0.147-0.004-0.197-0.039c-0.221-0.28-0.116-0.851-0.316-1.146v-0.158c0.426-0.092,1.122-0.168,1.345-0.475c0.031-0.041,0.014-0.011,0.039-0.078c-0.036-0.035-0.051-0.068-0.079-0.119c-0.619-0.156-0.887-0.049-1.423,0.158c-0.167-0.535,0.034-0.959-0.514-1.108c0.117-0.203,0.506-0.194,0.751-0.276c0.382-0.126,0.817-0.296,1.148-0.474c0.026-0.068,0.007-0.04,0.04-0.08c-0.022-0.2-0.078-0.193-0.159-0.316c-0.571-0.044-1.027,0.011-1.346,0.316h-0.076c0.047-0.295,0.231-0.718,0.394-0.949c0.112-0.162,0.318-0.14,0.396-0.356h0.04V64.1c-0.081-0.104-0.159-0.211-0.238-0.314c-0.186-0.13-0.454-0.143-0.632-0.279c-0.263-0.004-0.515-0.003-0.672,0.079c0.021,0.152,0.089,0.248,0.119,0.356c0.109,0.408-0.284,1.669-0.436,1.859c-0.123,0.154-1.551,0.672-1.939,0.555c-0.092-0.029-0.36-0.164-0.435-0.239c-0.032-0.039-0.015-0.008-0.04-0.077c0.561-0.527,0.965-1.702,1.741-1.939c0.014-0.064,0.027-0.131,0.041-0.196c-0.194-0.2-1.135-1.188-1.622-0.871c-0.04,0.014-0.079,0.022-0.117,0.038c0,0.338,0.168,0.593,0.078,0.949c-0.182,0.711-0.587,1.556-0.95,2.139c-0.218,0.35-0.693,0.729-0.712,1.229c0.646-0.064,0.802-0.731,1.304-0.912c0.146,0.135,0.29,0.267,0.436,0.396c0.207,0.311,0.168,0.778,0.276,1.186c0.185,0.856,0.371,1.715,0.554,2.571c0.025,0.425,0.052,0.845,0.08,1.269C37.246,72.28,37.561,72.945,37.97,73.037L37.97,73.037z M39.233,70.032c0.031,0.368,0.258,1.407,0.436,1.662c0.001,0.024,0.001,0.054,0.001,0.08c-0.477,0.102-0.973,0.239-1.504,0.237c-0.082-0.564-0.352-1.061-0.355-1.662C38.418,70.338,38.731,70.094,39.233,70.032z M36.939,66.75c0.063-0.107,1.113-0.273,1.228-0.199c0.42,0.195,0.27,0.813,0.514,1.188c-0.083,0.194-1.047,0.487-1.345,0.514C37.283,67.834,37.213,66.977,36.939,66.75L36.939,66.75z M38.76,68.253h0.04c0.076,0.36,0.119,0.978,0.317,1.267c-0.142,0.348-1.016,0.317-1.346,0.516c-0.138-0.083-0.32-1.076-0.316-1.346C37.757,68.662,38.541,68.402,38.76,68.253L38.76,68.253z M31.914,70.506c-0.06,0.135-0.053,0.354-0.117,0.514c-0.342,0.84-0.454,1.015,0.079,1.82c0.237,0,0.269-0.037,0.396-0.119C32.429,72.064,32.454,70.814,31.914,70.506L31.914,70.506z M77.023,70.744c-1.154-0.285-2.125,0.285-3.325,0.199c-0.114-0.121-0.2-0.19-0.275-0.356c-0.835,0.024-1.757,1.886-0.909,2.453c0.453,0.308,1.744,0.129,2.295,0c0.306-0.071,0.783-0.139,1.027,0.038c0.332,0.247,0.273,1.182,0.157,1.703c-0.132,0.975-0.265,1.951-0.396,2.929c-0.117,0.593-0.236,1.185-0.356,1.779c0.606-0.003,1.178-0.623,1.349-1.069c0.1-0.258,0.047-0.502,0.119-0.791c0.209-0.83,0.237-1.82,0.436-2.689c0.127-0.563,0.041-1.1,0.156-1.621c0.086-0.393,0.143-1.696,0.041-2.059C77.281,71.059,77.126,70.901,77.023,70.744z M22.857,82.695c-0.135-0.102-0.229-0.283-0.356-0.395c-0.473-0.42-1.029-0.826-1.543-1.188c-0.426-0.298-1.008-0.476-1.387-0.829c-0.01-0.086,0.123-0.296,0.041-0.516c-0.335-0.896-1.589-1.933-2.374-2.412c-0.363-0.225-0.972-0.328-1.305-0.555c-0.246-0.017-0.374-0.025-0.435,0.155c-0.097,0.218,0.209,0.521,0.315,0.675c0.271,0.381,0.581,0.826,0.95,1.104c0.276,0.209,0.591,0.392,0.83,0.635h0.119c-0.154-0.426-0.609-0.657-0.949-0.909c-0.311-0.229-0.449-0.632-0.712-0.909c0.021-0.125,0.035-0.115,0.08-0.199c1.093,0.009,1.802,1.012,2.294,1.662c0.22,0.291,0.571,0.461,0.594,0.951c-0.116,0-0.216,0-0.276-0.041h-0.119c0.188,0.522,0.824,0.479,1.267,0.754c0.888,0.549,1.603,1.409,2.373,2.094c0.262,0.234,0.719,0.466,0.791,0.873c-0.537-0.028-0.917-0.327-1.261-0.555c-0.614-0.4-1.597-1.1-2.019-1.662c-0.08-0.104-0.106-0.263-0.199-0.355c-0.109-0.111-0.261-0.145-0.355-0.275h-0.158c-0.039,0.41,0.407,0.705,0.671,0.948c0.819,0.75,1.696,1.442,2.73,1.979c0.373,0.191,1.053,0.521,1.465,0.275C23.874,83.434,23.227,82.975,22.857,82.695L22.857,82.695z M47.226,85.307c-2.014-1.379-4.985-2.775-8.427-2.689c-0.167,0.104-0.503,0.021-0.711,0.078c-0.288,0.076-0.464,0.223-0.672,0.355c-0.008,0.971,1.446,1.496,2.255,1.698c0.483,0.123,0.909-0.104,1.188-0.198c0.215-0.82-0.776-0.94-1.227-1.347h-0.081v-0.038c3.036-0.119,5.308,0.729,7.043,2.02c0.433,0.322,0.93,0.783,1.148,1.306c0.081,0.194,0.116,0.515,0,0.674c-0.159,0.44-0.685,0.401-1.188,0.515c-1.162,0.267-2.755-0.391-3.285-0.91c-0.108,0.189,0.049,0.48-0.118,0.674c-0.176,0.478-0.788,0.354-1.346,0.474c-0.917,0.199-2.353-0.271-2.888-0.632c-0.149-0.104-0.257-0.286-0.396-0.396c-0.007-0.103-0.018-0.136-0.041-0.199c0.081-0.073,0.177-0.187,0.237-0.275c1.139-0.085,1.718-0.027,2.376,0.596c-0.017,0.078-0.01,0.073-0.041,0.114c-0.074,0.152-0.245,0.17-0.474,0.161v0.074c0.417,0.004,0.593-0.059,0.83-0.197c0.013-0.079,0.027-0.159,0.04-0.236c-0.136-0.141-0.231-0.328-0.396-0.438c-0.65-0.426-1.991-0.641-2.729-0.156c-0.116,0.561,0.232,0.864,0.554,1.105c0.646,0.488,1.191,0.771,2.098,1.029c0.291,0.082,0.55,0.008,0.871,0.076c0.28,0.064,0.765,0.079,1.068,0c0.504-0.128,1.205-0.658,0.632-1.268v-0.037c0.299,0.109,0.544,0.402,0.831,0.556c0.761,0.397,2.021,0.726,3.167,0.476c0.562-0.125,1.143-0.125,1.303-0.635c0.179-0.277-0.068-0.668-0.156-0.826C48.322,86.151,47.836,85.721,47.226,85.307L47.226,85.307z M39.906,83.485c0.14,0.094,0.22,0.291,0.356,0.396c-0.003,0.1-0.004,0.148-0.04,0.199c-0.257,0.697-1.706,0.182-2.058-0.081c-0.11-0.08-0.153-0.248-0.236-0.354c0.015-0.082,0.01-0.076,0.041-0.116c0.108-0.306,0.417-0.203,0.671-0.354C39.142,83.174,39.596,83.274,39.906,83.485z M76.625,83.881h-0.396c-0.262,0.209-0.692,0.236-0.991,0.396c-0.263,0.141-0.581,0.332-0.829,0.515c-0.207,0.148-0.326,0.418-0.516,0.592c0.004,0.197,0.008,0.229,0.16,0.277c0.039,0.029,0.01,0.018,0.075,0.04c0.042-0.047,0.08-0.063,0.12-0.12c0.033-0.023-0.027-0.104-0.04-0.232c0.384-0.386,0.667-0.598,1.228-0.832c0.144-0.059,0.447-0.233,0.634-0.119h0.079c-0.026,0.391-0.916,1.591-1.188,1.781v0.115c0.729-0.188,1.215-1.643,1.702-2.174c-0.013-0.09-0.01-0.111-0.04-0.157L76.625,83.881L76.625,83.881z M73.459,86.809c-0.234,0.209-0.807,0.229-1.066,0.435h-0.041c0.104-0.149,0.291-0.213,0.396-0.354c0.076-0.104,0.107-0.226,0.197-0.315c-0.018-0.081-0.01-0.075-0.039-0.117v-0.08c-1.155-0.212-3.084,0.784-3.68,1.308c-0.155,0.135-0.248,0.336-0.396,0.477c0.003,0.111,0.016,0.168,0.039,0.236c0.701,0.047,2.016-0.383,2.174-0.949c0.031-0.025,0.012-0.002,0-0.04v-0.079c-0.479-0.027-1.124,0.075-1.422,0.355h-0.039c0.26-0.396,1.223-0.746,1.739-0.91c0.172-0.053,0.55-0.149,0.714-0.039c0.037,0.015,0.077,0.025,0.117,0.039c-0.094,0.396-0.657,0.838-1.029,0.949v0.08c0.607-0.141,1.163-0.416,1.7-0.634c0.368-0.149,0.786-0.188,1.108-0.396c0.229-0.149,1.008-1.207,1.068-1.504C74.086,85.409,74.012,86.313,73.459,86.809L73.459,86.809z M70.333,87.6v0.119c-0.075,0.049-0.129,0.156-0.198,0.196c-0.205,0.12-0.479,0.106-0.674,0.238c-0.09-0.011-0.109-0.009-0.156-0.041h-0.039C69.373,87.775,70.025,87.621,70.333,87.6L70.333,87.6z M53.835,91.317c0.015-0.037,0.025-0.078,0.039-0.117c-0.976-0.04-1.953-0.079-2.927-0.119c-0.123,0.082-0.312,0.035-0.475,0.079c-0.202,0.059-0.426,0.15-0.593,0.239c0.026,0.067,0.008,0.038,0.04,0.077c0.238,0.188,1.624,0.199,1.9,0h0.078v-0.077c-0.419-0.134-1.183,0.2-1.503,0h-0.041v-0.041c1.052-0.073,2.23-0.044,3.325-0.04c-0.105,0.072-0.328,0.051-0.436,0.119c-0.039,0.014-0.078,0.027-0.117,0.039v0.08c0.238,0.037,0.475,0.078,0.711,0.117c0.037,0.041-0.004,0.004,0.039,0.037c-0.35,0.233-1.254,0.139-1.581-0.037v-0.08c-0.178-0.082-0.991,0.084-1.148,0.117c-0.133,0.03-0.27-0.014-0.357,0.039c-0.165,0.01-0.181,0.029-0.276,0.079c0.022,0.128,0.035,0.115,0.08,0.198c0.255,0.06,0.696,0.064,0.987,0.156v-0.039h0.04v-0.039c-0.148-0.057-0.559-0.025-0.713-0.115h-0.079c0.132-0.104,1.425-0.278,1.663-0.119c0.067,0.023,0.039,0.007,0.079,0.039c-0.211,0.038-0.424,0.08-0.634,0.117c0.025,0.066,0.009,0.039,0.04,0.078c0.065,0.045,0.193,0.045,0.316,0.039c-0.04,0.074-0.054,0.109-0.119,0.158c0.013,0.023,0.027,0.051,0.04,0.078c0.561,0,1.031-0.057,1.502-0.156c0.28-0.062,0.624,0.052,0.831-0.08h0.317v-0.078c-0.539-0.002-1.885-0.055-2.215,0.158h-0.117c0.033-0.043-0.004-0.004,0.038-0.041c0.155-0.18,0.471-0.09,0.75-0.156c0.44-0.104,1.168-0.284,1.544,0c0.105,0.064,0.04-0.008,0.039,0.117c0.107-0.002,0.181-0.002,0.236-0.036h0.277v-0.081c-0.359-0.088-0.889-0.251-1.188-0.434C54.057,91.488,54.135,91.344,53.835,91.317L53.835,91.317z M13.635,18.359c-0.088,0.32-0.274,0.593-0.395,0.87c-0.268,0.613-0.507,1.225-0.751,1.822c-0.207,0.496-0.335,1.295-0.633,1.699v0.079c0.416-0.074,0.698-0.493,0.949-0.751c0.617-0.634,1.92-2.22,1.9-3.402c-0.062-0.061-0.119-0.162-0.159-0.237C14.3,18.38,13.982,18.353,13.635,18.359z M13.794,20.022c-0.181,0.298-0.281,0.592-0.476,0.871c-0.178,0.255-0.46,0.452-0.633,0.713h-0.041c0.051-0.302,0.214-0.546,0.319-0.792c0.235-0.561,0.396-1.118,0.671-1.621c0.152,0.003,0.268,0.015,0.356,0.078c0.095,0.052,0.028-0.018,0.079,0.08C14.15,19.548,13.89,19.862,13.794,20.022L13.794,20.022z M84.023,7.875c-0.414-0.416-0.729-0.938-1.147-1.346V6.49c-0.205,0.073-0.899,0.688-1.028,0.871c-0.25-0.095-0.391-0.365-0.594-0.514c-0.676-0.508-1.313-1.167-2.49-1.147c-0.148,0.115-0.367,0.118-0.556,0.197c-0.53,0.23-1.083,0.688-1.305,1.227c-0.249,0.602,0.004,1.491,0.196,1.939c0.392,0.904,1.03,1.667,1.582,2.414c0.457,0.615,0.973,1.252,1.819,1.464c0.956,0.238,1.422-0.884,1.781-1.308c0.37-0.435,1.182-0.539,1.464-1.107c0.104-0.207,0.034-0.615-0.039-0.791c-0.18-0.426-1.066-1.622-1.425-1.859c0.024-0.239,0.135-0.247,0.235-0.396c0.248,0.121,0.338,0.471,0.516,0.673c0.227,0.258,0.546,0.396,0.791,0.632c0.378,0.003,0.604-0.094,0.79-0.277h0.041C84.561,8.243,84.212,8.06,84.023,7.875L84.023,7.875z M81.77,12.148c-0.699,0.165-1.047-0.293-1.424-0.673c-0.938-0.935-1.57-2.093-2.298-3.244c-0.247-0.396-0.885-1.134-0.554-1.702h0.156c0.199,0.299,0.539,0.507,0.754,0.792c0.591,0.784,1.313,1.469,1.898,2.255c0.359,0.485,0.758,0.94,1.106,1.424c0.178,0.249,0.315,0.565,0.556,0.751C81.924,11.931,81.848,12.015,81.77,12.148L81.77,12.148z M82.361,9.339c0.32,0.439,0.755,0.688,0.751,1.463c-0.122,0.116-0.157,0.224-0.356,0.276c-0.039,0.032-0.011,0.015-0.078,0.041c-0.56-0.932-1.367-1.711-2.017-2.573c-0.212-0.282-0.541-0.511-0.752-0.791c-0.362-0.48-0.793-0.864-1.188-1.305c-0.113-0.131-0.168-0.257-0.313-0.357c0.033-0.086,0.031-0.057,0.076-0.118c0.672,0.006,0.994,0.458,1.386,0.753C80.837,7.453,81.648,8.354,82.361,9.339L82.361,9.339z"/><radialGradient id="SVGID_43_" cx="251.8086" cy="-408.3613" r="72.7509" gradientTransform="matrix(1 0 0 -1 -213.7637 -386.502)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#000" stop-opacity="0"/><stop offset=".8022" stop-color="#000" stop-opacity=".08"/><stop offset="1" stop-color="#000" stop-opacity=".3882"/></radialGradient><path style="&st15;" d="M49.885,17.037c0.014-0.606-0.392-1.27-0.392-1.27l-0.025-0.058c0,0-0.487-0.949-1.302-1.228c-0.815-0.278-1.478,0.342-1.478,0.342s-0.114,0.131-0.429,0.494c-0.313,0.364-0.507,0.666-1.198,0.938c-0.692,0.271-1.379,0.204-1.743,0.033c-0.364-0.172-0.457-0.537-0.457-0.537s-0.229-0.722-0.313-1.049c-0.086-0.331-0.309-1.694-0.309-1.694s-0.491-2.747-0.534-3.304c0,0,1.475-0.126,3.687-0.775c2.299-0.673,3.043-1.206,3.043-1.206s-0.432-0.156-0.484-0.662c-0.051-0.507-0.089-1.19-0.089-1.19s-0.089-0.5,0.483-1.139c0.571-0.64,1.354-0.863,1.762-0.953c0.41-0.089,1.281-0.17,2.093-0.134c0.812,0.038,1.267,0.112,1.593,0.291c0.328,0.178,0.357,0.61,0.357,0.61l-0.008,1.146c0,0-0.037,0.402,0.261,0.529c0,0,0.505,0.305,2.196,0.133c0,0,0.72-0.126,1.846-0.46c1.125-0.335,4.129-1.229,4.554-1.341c0.425-0.111,0.953-0.291,1.646-0.469c0.691-0.179,2.039-0.626,2.308-0.73c0.271-0.104,1.812-0.618,2.927-0.81c1.115-0.195,2.227-0.186,2.813,0.149c0,0,0.357,0.304,0.521,0.662c0.163,0.358,0.478,0.863,0.923,1.088c0.454,0.227,0.752,0.371,1.875,0.273c0,0,0.022-0.096-0.395-0.37c-0.417-0.277-0.991-0.701-0.991-0.701S74.29,3.4,74.215,3.198c-0.072-0.202-0.043-0.306-0.043-0.306l0.877-1.406c0,0,0-0.172,0.508-0.238c0.506-0.067,1.071-0.134,1.74-0.313c0.67-0.178,0.788-0.312,0.788-0.312l0.58,0.178c0,0,3.546,2.853,4.655,3.583l0.199-0.239c0,0,0.436,0.018,0.826,0.172c0.394,0.154,0.979,0.562,0.979,0.562s1.612,1.31,2.071,2.2l0.223,0.679l-0.102,0.161c0,0,0.918,1.307,2.096,2.602c0,0,1.227,1.664,1.689,2.09c0,0-0.108-0.399-0.201-0.849l0.336-0.226l0.203-0.144l0.617,0.259c3.573,4.811,6.432,10.424,8.141,16.328l-0.12,0.484l0.395,0.501c1.128,4.212,1.728,8.643,1.728,13.211c0,1.122-0.036,2.236-0.107,3.339l-0.304,0.511l0.225,0.555c-2.231,26.1-24.124,46.584-50.801,46.584c-18.502,0-34.702-9.854-43.637-24.6L7.674,68.2l-0.205-0.153c-3.387-5.742-5.682-12.205-6.595-19.103l0.212-0.525L0.75,47.936c-0.213-1.892-0.322-3.812-0.322-5.756c0-2.985,0.255-5.909,0.748-8.755l0.25-0.562l-0.087-0.328c1.157-6.048,3.383-11.716,6.474-16.799l0.684-0.384l0.081,0.032c0,0,0.233-0.169,0.354-0.217l0.076-0.023c0,0,1.179-1.971,1.625-2.601c0,0,0.542-0.348,0.745-0.407c0,0,0.124-0.016,0.189,0.076c0,0,0.496-0.432,1.699-2.054c0.004-0.005,0.007-0.011,0.012-0.017c0,0-0.114-0.076-0.131-0.174c-0.018-0.097,0.108-0.591,0.173-0.717c0.065-0.126,0.108-0.156,0.108-0.156s1.722-2.032,3.151-3.238c0,0,0.26-0.202,0.678-0.25c0,0,1.472-0.613,3.264-2.184c0,0,0.051-0.289,0.478-0.858c0.428-0.57,1.456-1.163,2.222-1.337c0.764-0.174,0.896-0.038,0.896-0.038l0.064,0.065l0.515,0.766c0,0,0.565-0.316,1.413-0.604c0.847-0.289,0.979-0.262,0.979-0.262l0.825,1.336l-0.987,2c0,0-0.644,1.421-1.655,2.185c0,0-0.472,0.284-1.12,0.127c-0.648-0.157-1.072,0.333-1.072,0.333l-0.17,0.14c0,0,0.14-0.024,0.346-0.103c0,0,0.158,0.065,0.274,0.223c0.114,0.158,0.913,1.175,0.913,1.175s0.005,0.837-0.415,1.938c-0.419,1.1-1.467,2.891-1.467,2.891s-0.733,1.424-1.075,2.253c-0.342,0.829-0.515,1.765-0.488,2.262c0,0,0.187,0.062,0.707-0.202c0.655-0.332,1.083,0.027,1.083,0.027s0.719,0.53,1.041,0.881c0.262,0.289,0.802,1.765,0.209,3.224c0,0-0.402,1.008-1.377,1.724c0,0-0.216,0.332-1.529,0.174c-0.368-0.043-0.585-0.276-1.372-0.2c-0.785,0.077-1.231,0.815-1.231,0.815l0.013-0.024c-0.692,0.999-1.154,2.458-1.154,2.458l-0.057,0.165c0,0-0.241,0.509-0.292,1.752c-0.053,1.284,0.284,3.109,0.284,3.109s7.876-1.387,9.88-0.055l0.58,0.532c0,0,0.046,0.174-0.031,0.376c-0.08,0.204-0.375,0.673-0.987,1.113c-0.611,0.438-1.222,1.583-0.313,2.304c1.034,0.818,1.691,0.766,3.43,0.468c1.74-0.297,2.898-1.269,2.898-1.269s0.972-0.72,0.783-1.628c-0.188-0.908-1.017-1.189-1.017-1.189s-0.658-0.423-0.141-1.238c0,0,0.141-0.689,2.553-1.316c2.414-0.626,6.812-1.52,10.556-1.989c0,0-2.539-8.223-0.737-9.289c0,0,0.438-0.296,1.224-0.408l0.721-0.037c0.131-0.027,0.344,0.005,0.796,0.045c0.452,0.038,1.001,0.076,1.678-0.441c0.676-0.519,0.697-0.819,0.697-0.819"/></svg> \ No newline at end of file diff --git a/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg.license b/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg.license deleted file mode 100644 index eae6a84c..00000000 --- a/modules/by-name/fi/firefox/search_engines/logos/wikipedia.svg.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/modules/by-name/fi/firefox/update_extensions.sh b/modules/by-name/fi/firefox/update_extensions.sh deleted file mode 100755 index 588a7530..00000000 --- a/modules/by-name/fi/firefox/update_extensions.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env sh - -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -# The `generate_extensions` binary is provided in the devshell. - -generate_extensions \ - darkreader:navbar \ - keepassxc-browser:navbar \ - vhack-libredirect:navbar \ - torproject-snowflake:navbar \ - tridactyl-vim:menupanel \ - ublock-origin:menupanel \ - >"$(dirname "$0")"/extensions.json diff --git a/modules/by-name/fi/firefox/userChrome.css b/modules/by-name/fi/firefox/userChrome.css deleted file mode 100644 index 6e0d705d..00000000 --- a/modules/by-name/fi/firefox/userChrome.css +++ /dev/null @@ -1,53 +0,0 @@ -/* - * nixos-config - My current NixOS configuration - * - * Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> - * SPDX-License-Identifier: GPL-3.0-or-later - * - * This file is part of my nixos-config. - * - * You should have received a copy of the License along with this program. - * If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - */ - -/* thickness of tab when you have too many open tabs */ -.tabbrowser-tab:not([pinned="true"]) { - min-width: 10px !important; - min-height: 10px !important; -} - -/* tab height -#TabsToolbar .tabbrowser-tabs { -min-height: 10px !important; -} -*/ - -/* -.tabbrowser-tab {min-width: 016px !important;} -.tabbrowser-tab {clip-width: 016px !important;} -*/ - -/* the + button that opens new tabs */ -#TabsToolbar .tabs-newtab-button { - margin-left: 10px !important; - height: Auto !important; -} - -#main-window[privatebrowsingmode="temporary"] #navigator-toolbox { - background-color: #c40944 !important; -} - -/* close button inside a tab */ -.tab-close-button * { - width: 10px !important; - height: 10px !important; -} - -/* bookmark toolbar */ -#personal-bookmarks .bookmark-item > .toolbarbutton-text { - font-size: 10pt !important; -} -#personal-bookmarks .bookmark-item > .toolbarbutton-icon { - height: 12px !important; - width: 12px !important; -} diff --git a/modules/by-name/gp/gpg/module.nix b/modules/by-name/gp/gpg/module.nix index 89d7b356..d5136e92 100644 --- a/modules/by-name/gp/gpg/module.nix +++ b/modules/by-name/gp/gpg/module.nix @@ -22,6 +22,8 @@ in { }; config = lib.mkIf cfg.enable { + soispha.programs.qutebrowser.key = "8321 ED3A 8DB9 99A5 1F3B F80F F268 2914 EA42 DE26"; + home-manager.users.soispha = { programs.gpg = { enable = true; @@ -45,6 +47,7 @@ in { } ]; }; + services = { gpg-agent = { enable = true; diff --git a/modules/by-name/i3/i3bar-river/module.nix b/modules/by-name/i3/i3bar-river/module.nix new file mode 100644 index 00000000..8a2203aa --- /dev/null +++ b/modules/by-name/i3/i3bar-river/module.nix @@ -0,0 +1,197 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.soispha.programs.i3bar-river; + + toColor = color: + if builtins.isString color + then lib.trivial.fromHexString color + else color; + + substractColor = color_a: color_b: let + saturatingSub = a: b: + if a < b + then 0 + else a - b; + in { + red = saturatingSub color_a.red color_b.red; + green = saturatingSub color_a.green color_b.green; + blue = saturatingSub color_a.blue color_b.blue; + alpha = saturatingSub color_a.alpha color_b.alpha; + inherit (color_a) __toString; + }; + + colorOption = red: green: blue: alpha: + lib.mkOption { + type = lib.types.submodule { + options = { + red = lib.mkOption { + type = lib.types.ints.between 0 255; + description = "The amount of red in this color"; + default = toColor red; + }; + green = lib.mkOption { + type = lib.types.ints.between 0 255; + description = "The amount of green in this color"; + default = toColor green; + }; + blue = lib.mkOption { + type = lib.types.ints.between 0 255; + description = "The amount of blue in this color"; + default = toColor blue; + }; + alpha = lib.mkOption { + type = lib.types.ints.between 0 255; + description = "The amount of alpha in this color"; + default = toColor alpha; + }; + + __toString = lib.mkOption { + internal = true; + + default = self: let + tH = num: let + converted = lib.trivial.toHexString num; + in + if builtins.stringLength converted == 1 + then "0${converted}" + else assert (builtins.stringLength converted) == 2; converted; + + output = "#${tH self.red}${tH self.green}${tH self.blue}${tH self.alpha}"; + in + output; + + description = "Convert this type to a string before use"; + }; + }; + }; + + default = { + red = toColor red; + green = toColor green; + blue = toColor blue; + alpha = toColor alpha; + }; + + description = "The specific color to use for this name."; + }; +in { + options.soispha.programs.i3bar-river = { + enable = lib.mkEnableOption "i3bar-river"; + + package = lib.mkPackageOption pkgs "i3bar-river-patched" {}; + + colors = { + none = colorOption 00 00 00 00; + + white = colorOption "ff" "ff" "ff" "ff"; + + blue = colorOption "99" "d1" "db" "ff"; + green = colorOption "a6" "e3" "a1" "dd"; + lavendar = colorOption "b4" "be" "fe" "dd"; + mauve = colorOption "cb" "a6" "f7" "dd"; + normal = colorOption "c6" "ce" "ef" "ff"; + peach = colorOption "fa" "b3" "87" "dd"; + sapphire = colorOption "74" "c7" "ec" "dd"; + teal = colorOption "94" "e2" "d5" "dd"; + + light_gray = colorOption "58" "5b" "70" "ff"; + gray = colorOption "45" "47" "5a" "ff"; + dark_gray = colorOption "30" "34" "46" "ff"; + bright_red = colorOption "e7" "82" "84" "ff"; + + vivid_burgundy = colorOption "9f" "1d" "35" "ff"; + + unfocused_offset = colorOption "33" "33" "33" "00"; + }; + }; + + config = lib.mkIf cfg.enable { + soispha.programs.river.init.backgroundStart = [cfg.package]; + + home-manager.users.soispha = { + programs.i3bar-river = { + enable = true; + inherit (cfg) package; + + settings = { + theme = { + focused = { + # Colors + background = toString cfg.colors.none; + color = toString cfg.colors.white; # Only used, if blocks do not specify one + separator = toString cfg.colors.vivid_burgundy; + + # Tag is set (but not focused or urgent) + tag_fg = toString cfg.colors.white; + tag_bg = toString cfg.colors.light_gray; + + tag_urgent_fg = toString cfg.colors.white; + tag_urgent_bg = toString cfg.colors.bright_red; + + tag_focused_fg = toString cfg.colors.white; + tag_focused_bg = toString cfg.colors.teal; + + tag_inactive_fg = toString cfg.colors.white; + tag_inactive_bg = toString cfg.colors.none; + + # Shop options + blend = true; # whether tags/blocks colors should blend with bar's background + hide_inactive_tags = false; + show_layout_name = false; + show_mode = true; + show_tags = true; + }; + + unfocused = { + hide_inactive_tags = true; + + color = toString (substractColor cfg.colors.white cfg.colors.unfocused_offset); + separator = toString (substractColor cfg.colors.vivid_burgundy cfg.colors.unfocused_offset); + + tag_fg = toString (substractColor cfg.colors.white cfg.colors.unfocused_offset); + tag_bg = toString (substractColor cfg.colors.light_gray cfg.colors.unfocused_offset); + + tag_urgent_fg = toString (substractColor cfg.colors.white cfg.colors.unfocused_offset); + tag_urgent_bg = toString (substractColor cfg.colors.bright_red cfg.colors.unfocused_offset); + + tag_focused_fg = toString (substractColor cfg.colors.white cfg.colors.unfocused_offset); + tag_focused_bg = toString cfg.colors.vivid_burgundy; + + tag_inactive_fg = toString (substractColor cfg.colors.white cfg.colors.unfocused_offset); + tag_inactive_bg = toString (substractColor cfg.colors.none cfg.colors.unfocused_offset); + }; + }; + + # The font and various sizes + font = "SauceCodePro Nerd Font Mono:pixelsize=26"; + height = 24; + margin_top = 10; + margin_bottom = 0; + margin_left = 0; + margin_right = 0; + separator_width = 0; + tags_r = 10.0; + tags_padding = 10.0; + tags_margin = 5.0; + blocks_r = 6.0; + blocks_overlap = 0.0; + + # Misc + position = "top"; # either "top" or "bottom" + layer = "overlay"; # one of "top", "overlay", "bottom" or "background" + invert_touchpad_scrolling = true; + start_hidden = false; # whether the bar is initially in the 'hidden' state + + # WM-specific options + wm.river = { + max_tag = 9; # Show only the first nine tags + }; + }; + }; + }; + }; +} diff --git a/modules/by-name/i3/i3status-rust/module.nix b/modules/by-name/i3/i3status-rust/module.nix new file mode 100644 index 00000000..48bcd5de --- /dev/null +++ b/modules/by-name/i3/i3status-rust/module.nix @@ -0,0 +1,154 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.soispha.programs.i3status-rust; + + mkScript = name: deps: + lib.getExe (pkgs.writeShellApplication { + inherit name; + text = builtins.readFile ./scripts/${name}; + + inheritPath = false; + runtimeInputs = deps; + }); +in { + options.soispha.programs.i3status-rust = { + enable = lib.mkEnableOption "i3status-rust"; + + package = lib.mkPackageOption pkgs "i3status-rust-patched" {}; + }; + + config = lib.mkIf cfg.enable { + home-manager.users.soispha = { + programs.i3status-rust = { + enable = true; + inherit (cfg) package; + + bars.default = { + settings = { + icons = { + icons = "material-nf"; + + overrides = { + cpu = [ + "" # nf-md-memory + ]; + memory_mem = ""; # nf-fa-bars + }; + }; + + theme = { + theme = "slick"; + + overrides = { + separator = "native"; + alternating_tint_bg = "none"; + alternating_tint_fg = "none"; + }; + }; + }; + + blocks = [ + { + block = "time"; + format = " $timestamp.datetime(format:'%d/%m/%y (%a) %H:%M %:z') "; + interval = 60; + } + + { + # TODO(@bpeetz): Switch to “music” when mpd gets mpris support <2025-05-20> + block = "custom"; + interval = "once"; + persistent = true; + command = mkScript "mpd_song_name.sh" [pkgs.mpc pkgs.coreutils]; + hide_when_empty = true; + shell = "${lib.getExe pkgs.dash}"; + format = " $text.str(max_width:60,rot_interval:0.5) "; + } + + { + block = "sound"; + driver = "pulseaudio"; + headphones_indicator = true; + } + + # System info + { + block = "cpu"; + } + { + block = "memory"; + format = " $icon $mem_used_percents{ ($swap_used_percents.eng(range:1..))|} "; + } + { + block = "amd_gpu"; + format = " $icon $utilization (^icon_memory_mem $vram_used_percents) "; + error_format = ""; + } + + { + block = "net"; + format = " ^icon_net_down $speed_down.eng(prefix:Ki) ^icon_net_up $speed_up.eng(prefix:Ki) "; + } + { + block = "privacy"; + driver = [ + {name = "v4l";} + {name = "pipewire";} + ]; + } + + { + block = "disk_space"; + path = "/srv"; + info_type = "used"; + format = " $icon $used.eng(prefix:Gi) ($percentage) "; + backend = "btrfs"; + + # warn if 80 % is used, alert after 90 % used. + warning = 80; + alert = 90; + } + { + block = "backlight"; + missing_format = ""; + } + { + block = "battery"; + format = " $icon $percentage{ $time_remaining.dur(hms:true, min_unit:m)|}{ $power|} "; + missing_format = ""; + } + + # { + # block = "calendar"; + # + # source = { + # calendars = ["user/calendar"]; + # auth = { + # type = "unauthenticated"; + # }; + # }; + # } + # { + # block = "focused_window"; + # driver = "wlr_toplevel_management"; + # } + # { + # block = "maildir"; + # display_type = "new"; + # inboxes = ["~/.local/share/maildir/soispha/*"]; + # interval = 60; + # threshold_critical = 10; + # threshold_warning = 1; + # } + ]; + }; + }; + + programs.i3bar-river.settings.command = "${lib.getExe cfg.package} config-default.toml"; + }; + }; +} diff --git a/modules/by-name/i3/i3status-rust/scripts/mpd_song_name.sh b/modules/by-name/i3/i3status-rust/scripts/mpd_song_name.sh new file mode 100755 index 00000000..28921520 --- /dev/null +++ b/modules/by-name/i3/i3status-rust/scripts/mpd_song_name.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env dash + +# nixos-config - My current NixOS configuration +# +# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> +# SPDX-License-Identifier: GPL-3.0-or-later +# +# This file is part of my nixos-config. +# +# You should have received a copy of the License along with this program. +# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. + +while true; do + state="$(mpc status '%state%')" + + if [ "$state" = "playing" ]; then + song="$(mpc --format '[[%artist% - ]%title%]|[%file%]' current)" + progress="$(mpc status "%currenttime%/%totaltime%")" + + echo "$song :: $progress" + else + # The song has stopped, we are done displaying it. + echo "" + + # Wait for a new song. (Or in this case for a new event.) + mpc idle + fi + + sleep 1 +done + +# vim: ft=sh diff --git a/modules/by-name/im/impermanence/module.nix b/modules/by-name/im/impermanence/module.nix index 4ce86b25..e31cfaaf 100644 --- a/modules/by-name/im/impermanence/module.nix +++ b/modules/by-name/im/impermanence/module.nix @@ -56,7 +56,6 @@ in { ".config/iamb/profiles" ".cache" - ".mozilla/firefox" "media" "repos" diff --git a/modules/by-name/lf/lf/module.nix b/modules/by-name/lf/lf/module.nix index 2e6669e8..ea9970ef 100644 --- a/modules/by-name/lf/lf/module.nix +++ b/modules/by-name/lf/lf/module.nix @@ -19,6 +19,8 @@ commands = import ./commands {inherit pkgs sysLib shell_library system;}; keybindings = import ./keybindings {inherit (cfg.keymaps) uid downloadDir;}; + packages = import ./wrappers {inherit pkgs;}; + cfg = config.soispha.programs.lf; in { imports = [ @@ -58,6 +60,11 @@ in { "lf/colors".source = ./colors; }; + programs.zsh.shellAliases = { + ll = ". ${lib.getExe packages.ll}"; + lm = ". ${lib.getExe packages.lm}"; + }; + programs.lf = { enable = true; diff --git a/modules/by-name/lf/lf/wrappers/default.nix b/modules/by-name/lf/lf/wrappers/default.nix new file mode 100644 index 00000000..7257a66e --- /dev/null +++ b/modules/by-name/lf/lf/wrappers/default.nix @@ -0,0 +1,4 @@ +{pkgs}: { + ll = pkgs.callPackage ./ll {}; + lm = pkgs.callPackage ./lm {}; +} diff --git a/pkgs/by-name/ll/ll/package.nix b/modules/by-name/lf/lf/wrappers/ll/default.nix index 6e4ee336..6e4ee336 100644 --- a/pkgs/by-name/ll/ll/package.nix +++ b/modules/by-name/lf/lf/wrappers/ll/default.nix diff --git a/pkgs/by-name/ll/ll/ll.sh b/modules/by-name/lf/lf/wrappers/ll/ll.sh index e012cffa..e012cffa 100755 --- a/pkgs/by-name/ll/ll/ll.sh +++ b/modules/by-name/lf/lf/wrappers/ll/ll.sh diff --git a/pkgs/by-name/lm/lm/package.nix b/modules/by-name/lf/lf/wrappers/lm/default.nix index 42bdc687..42bdc687 100644 --- a/pkgs/by-name/lm/lm/package.nix +++ b/modules/by-name/lf/lf/wrappers/lm/default.nix diff --git a/pkgs/by-name/lm/lm/lm.sh b/modules/by-name/lf/lf/wrappers/lm/lm.sh index 71213721..71213721 100755 --- a/pkgs/by-name/lm/lm/lm.sh +++ b/modules/by-name/lf/lf/wrappers/lm/lm.sh diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/pylyzer.nix b/modules/by-name/me/mergiraf/module.nix index 47e8de7a..474a0ae3 100644 --- a/modules/by-name/nv/nvim/plgs/lsp/servers/servers/pylyzer.nix +++ b/modules/by-name/me/mergiraf/module.nix @@ -10,19 +10,20 @@ { config, lib, - pkgs, + libraries, ... }: let - cfg = config.soispha.programs.nvim; + cfg = config.soispha.programs.mergiraf; in { - home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable { - extraConfigLuaPost = - /* - lua - */ - '' - require('lspconfig').pylyzer.setup{} - ''; - extraPackages = with pkgs; [pylyzer]; + options.soispha.programs.mergiraf = { + enable = libraries.base.options.mkEnable "mergiraf"; + }; + + config = lib.mkIf cfg.enable { + home-manager.users.soispha = { + programs.mergiraf = { + enable = true; + }; + }; }; } diff --git a/modules/by-name/ni/nix-index/command_not_found.sh b/modules/by-name/ni/nix-index/command_not_found.sh index f650cf7b..e3036797 100644 --- a/modules/by-name/ni/nix-index/command_not_found.sh +++ b/modules/by-name/ni/nix-index/command_not_found.sh @@ -31,7 +31,7 @@ command_not_found_handle() { case "$len" in 0) - eprintln "$cmd: command not found" + printf "%s: command not found\n" "$cmd" >&2 ;; 1) # If only one package provides this, then we can invoke it diff --git a/modules/by-name/ni/nix/module.nix b/modules/by-name/ni/nix/module.nix index 0072164f..2b91f59b 100644 --- a/modules/by-name/ni/nix/module.nix +++ b/modules/by-name/ni/nix/module.nix @@ -18,7 +18,7 @@ # TODO(@bpeetz): Modularize <2025-02-08> nix = { - package = pkgs.lix; + package = pkgs.lixPackageSets.latest.lix; # Disable nix channels (this is a remnant of old days) channel.enable = false; diff --git a/modules/by-name/nv/nvim/mappings/default.nix b/modules/by-name/nv/nvim/mappings/default.nix index 4997f66c..683b0465 100644 --- a/modules/by-name/nv/nvim/mappings/default.nix +++ b/modules/by-name/nv/nvim/mappings/default.nix @@ -189,12 +189,13 @@ in { action = "\"_dP"; options.desc = "keep the cut thing in the base register"; } - { - mode = ["n"]; - key = "<leader>c"; - action = "\"_c"; - options.desc = "change without saving to register"; - } + # Overlaps with the femaco mapping (`<Space>cc`). + # { + # mode = ["n"]; + # key = "<leader>c"; + # action = "\"_c"; + # options.desc = "change without saving to register"; + # } { mode = ["n"]; diff --git a/modules/by-name/nv/nvim/module.nix b/modules/by-name/nv/nvim/module.nix index 819646d6..9b44906a 100644 --- a/modules/by-name/nv/nvim/module.nix +++ b/modules/by-name/nv/nvim/module.nix @@ -12,17 +12,26 @@ lib, config, modules, + libraries, ... }: let cfg = config.soispha.programs.nvim; + + plgs = builtins.attrValues (libraries.extra.mkByName { + useShards = false; + baseDirectory = ./plgs; + fileName = "default.nix"; + }); in { - imports = [ - ./autocmds - ./clipboard - ./mappings - ./options - ./plgs - ]; + imports = + [ + ./autocmds + ./clipboard + ./mappings + ./options + ./performance + ] + ++ plgs; options.soispha.programs.nvim = { enable = lib.mkEnableOption "custom nvim config"; @@ -43,6 +52,7 @@ in { VISUAL = "nvim"; CODEEDITOR = "nvim"; }; + programs.nixvim = { enable = true; diff --git a/modules/by-name/nv/nvim/performance/default.nix b/modules/by-name/nv/nvim/performance/default.nix new file mode 100644 index 00000000..a392a672 --- /dev/null +++ b/modules/by-name/nv/nvim/performance/default.nix @@ -0,0 +1,24 @@ +{ + config, + lib, + ... +}: let + cfg = config.soispha.programs.nvim; +in { + home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable { + performance = { + combinePlugins = { + enable = true; + }; + + byteCompileLua = { + enable = true; + configs = true; + initLua = true; + luaLib = true; + nvimRuntime = true; + plugins = true; + }; + }; + }; +} diff --git a/modules/by-name/nv/nvim/plgs/comment-nvim/default.nix b/modules/by-name/nv/nvim/plgs/comment-nvim/default.nix index b404843e..68a88d32 100644 --- a/modules/by-name/nv/nvim/plgs/comment-nvim/default.nix +++ b/modules/by-name/nv/nvim/plgs/comment-nvim/default.nix @@ -26,6 +26,7 @@ in { }; }; }; + keymaps = [ { key = "gcc"; diff --git a/modules/by-name/nv/nvim/plgs/debugprint/default.nix b/modules/by-name/nv/nvim/plgs/debugprint/default.nix deleted file mode 100644 index 79e557bd..00000000 --- a/modules/by-name/nv/nvim/plgs/debugprint/default.nix +++ /dev/null @@ -1,82 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - pkgs, - lib, - config, - ... -}: let - cfg = config.soispha.programs.nvim; -in { - home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable { - # TODO: package debugprint though a module - extraConfigLuaPost = '' - ${lib.strings.fileContents ./lua/debugprint.lua} - ''; - extraPlugins = [ - pkgs.vimExtraPlugins.debugprint-nvim - ]; - - keymaps = [ - { - key = "g?v"; - mode = ["v" "n"]; - action.__raw = '' - function() - return require('debugprint').debugprint({variable = true;}); - end - ''; - options.expr = true; - options.desc = '' - 'variable' debug line below the current line - ''; - } - { - key = "g?V"; - mode = ["v" "n"]; - action.__raw = '' - function() - return require('debugprint').debugprint({above = true; variable = true;}) ; - end - ''; - options.expr = true; - options.desc = '' - 'variable' debug line above the current line - ''; - } - { - key = "g?p"; - mode = "n"; - action.__raw = '' - function() - return require('debugprint').debugprint(); - end - ''; - options.expr = true; - options.desc = '' - 'plain' debug line below the current line - ''; - } - { - key = "g?P"; - mode = "n"; - action.__raw = '' - function() - return require('debugprint').debugprint({above = true;}); - end - ''; - options.expr = true; - options.desc = '' - 'plain' debug line above the current line - ''; - } - ]; - }; -} diff --git a/modules/by-name/nv/nvim/plgs/debugprint/lua/debugprint.lua b/modules/by-name/nv/nvim/plgs/debugprint/lua/debugprint.lua deleted file mode 100644 index b934d619..00000000 --- a/modules/by-name/nv/nvim/plgs/debugprint/lua/debugprint.lua +++ /dev/null @@ -1,13 +0,0 @@ --- nixos-config - My current NixOS configuration --- --- Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> --- SPDX-License-Identifier: GPL-3.0-or-later --- --- This file is part of my nixos-config. --- --- You should have received a copy of the License along with this program. --- If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -require("debugprint").setup({ - create_keymaps = false, -}) diff --git a/modules/by-name/nv/nvim/plgs/default.nix b/modules/by-name/nv/nvim/plgs/default.nix deleted file mode 100644 index aaebb3b1..00000000 --- a/modules/by-name/nv/nvim/plgs/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{...}: { - imports = - [ - # Plugins not yet packaged in nixpkgs - # ./debugprint - ./lf-nvim - # ./lsp-progress-nvim - ] - ++ [ - # Already packaged in nixpkgs - ./colorscheme - ./comment-nvim - ./femaco - ./flatten-nvim - ./goto-preview - ./harpoon - ./leap - ./lsp - ./lspkind - ./ltex_extra - ./lualine - ./luasnip - ./neorg - ./nvim-cmp - ./nvim-lint - ./raw_plugins - ./telescope - ./todo-comments - ./treesitter - ./vim-tex - ./which-key - ]; -} diff --git a/modules/by-name/nv/nvim/plgs/femaco/default.nix b/modules/by-name/nv/nvim/plgs/femaco/default.nix index a30bb59f..0388844a 100644 --- a/modules/by-name/nv/nvim/plgs/femaco/default.nix +++ b/modules/by-name/nv/nvim/plgs/femaco/default.nix @@ -8,7 +8,6 @@ # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. { - pkgs, lib, config, ... @@ -16,13 +15,14 @@ cfg = config.soispha.programs.nvim; in { home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable { - # TODO: package femaco through a module + plugins.femaco = { + enable = true; + }; + extraConfigLuaPost = '' ${lib.strings.fileContents ./lua/femaco.lua} ''; - extraPlugins = [ - pkgs.vimPlugins.nvim-FeMaco-lua - ]; + keymaps = [ { key = "<leader>cc"; diff --git a/modules/by-name/nv/nvim/plgs/femaco/lua/femaco.lua b/modules/by-name/nv/nvim/plgs/femaco/lua/femaco.lua index 1371a825..50a6cb23 100644 --- a/modules/by-name/nv/nvim/plgs/femaco/lua/femaco.lua +++ b/modules/by-name/nv/nvim/plgs/femaco/lua/femaco.lua @@ -8,7 +8,9 @@ -- You should have received a copy of the License along with this program. -- If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. + local clip_val = require("femaco.utils").clip_val + require("femaco").setup({ -- should prepare a new buffer and return the winid -- by default opens a floating window @@ -17,7 +19,8 @@ require("femaco").setup({ prepare_buffer = function(opts) local buf = vim.api.nvim_create_buf(false, false) return vim.api.nvim_open_win(buf, true, opts) - end, + end; + -- should return options passed to nvim_open_win -- @param code_block: data about the code-block with the keys -- * range @@ -25,30 +28,43 @@ require("femaco").setup({ -- * lang float_opts = function(code_block) return { - relative = "cursor", - width = clip_val(5, 120, vim.api.nvim_win_get_width(0) - 10), -- TODO: how to offset sign column etc? - height = clip_val(5, #code_block.lines, vim.api.nvim_win_get_height(0) - 6), - anchor = "NW", - row = 0, - col = 0, - style = "minimal", - border = "rounded", - zindex = 1, + relative = "cursor"; + width = clip_val(5, 120, vim.api.nvim_win_get_width(0) - 10); -- TODO how to offset sign column etc? + height = clip_val(5, #code_block.lines, vim.api.nvim_win_get_height(0) - 6); + anchor = "NW"; + row = 0; + col = 0; + style = "minimal"; + border = "rounded"; + zindex = 1; } - end, + end; + -- return filetype to use for a given lang -- lang can be nil - ft_from_lang = function(lang) return lang end, + ft_from_lang = function(lang) + return lang + end; + -- what to do after opening the float - post_open_float = function(winnr) vim.wo.signcolumn = "no" end, + post_open_float = function(winnr) + vim.wo.signcolumn = "no" + end; + -- create the path to a temporary file - create_tmp_filepath = function(filetype) return os.tmpname() end, + create_tmp_filepath = function(filetype) + return os.tmpname() + end; + -- if a newline should always be used, useful for multiline injections -- which separators needs to be on separate lines such as markdown, neorg etc -- @param base_filetype: The filetype which FeMaco is called from, not the -- filetype of the injected language (this is the current buffer so you can -- get it from vim.bo.filetyp). - ensure_newline = function(base_filetype) return false end, + ensure_newline = function(base_filetype) + return base_filetype == "nix" + end; + -- Return true if the indentation should be normalized. Useful when the -- injected language inherits indentation from the construction scope (e.g. an -- inline multiline sql string). If true, the leading indentation is detected, @@ -57,5 +73,7 @@ require("femaco").setup({ -- @param base_filetype: The filetype which FeMaco is called from, not the -- filetype of the injected language (this is the current buffer, so you can -- get it from vim.bo.filetype). - normalize_indent = function(base_filetype) return false end, + normalize_indent = function(base_filetype) + return base_filetype == "nix" + end; }) diff --git a/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix b/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix deleted file mode 100644 index 8d61d859..00000000 --- a/modules/by-name/nv/nvim/plgs/flatten-nvim/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - pkgs, - lib, - config, - ... -}: let - cfg = config.soispha.programs.nvim; -in { - # TODO: Get this plugin working again <2025-01-29> - home-manager.users.soispha.programs.nixvim = lib.mkIf false { - # TODO: package flatten-nvim though a module - - extraConfigLuaPre = '' - ${lib.strings.fileContents ./lua/flatten-nvim.lua} - if os.getenv("NVIM") ~= nil then - -- Avoid loading plugins because the host will take control of the instance anyways - return - end - ''; - extraPlugins = [ - pkgs.vimPlugins.flatten-nvim - ]; - }; -} diff --git a/modules/by-name/nv/nvim/plgs/flatten-nvim/lua/flatten-nvim.lua b/modules/by-name/nv/nvim/plgs/flatten-nvim/lua/flatten-nvim.lua deleted file mode 100644 index 0c86cd27..00000000 --- a/modules/by-name/nv/nvim/plgs/flatten-nvim/lua/flatten-nvim.lua +++ /dev/null @@ -1,114 +0,0 @@ --- nixos-config - My current NixOS configuration --- --- Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> --- SPDX-License-Identifier: GPL-3.0-or-later --- --- This file is part of my nixos-config. --- --- You should have received a copy of the License along with this program. --- If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - ----Types: --- --- Passed to callbacks that handle opening files ----@alias BufInfo { fname: string, bufnr: buffer } --- --- Needed aliases ----@alias buffer integer: Buffer id ----@alias window integer: Window id --- --- The first argument is a list of BufInfo tables representing the newly opened files. --- The third argument is a single BufInfo table, only provided when a buffer is created from stdin. --- --- IMPORTANT: For `block_for` to work, you need to return a buffer number OR a buffer number and a window number. --- The `winnr` return value is not required, `vim.fn.bufwinid(bufnr)` is used if it is not provided. --- The `filetype` of this buffer will determine whether block should happen or not. --- ----@alias OpenHandler fun(files: BufInfo[], argv: string[], stdin_buf: BufInfo, guest_cwd: string):window, buffer --- -require("flatten").setup({ - callbacks = { - ---Called to determine if a nested session should wait for the host to close the file. - ---param argv: a list of all the arguments in the nested session - ---@type fun(argv: table): boolean - should_block = require("flatten").default_should_block, - - ---If this returns true, the nested session will be opened. - ---If false, default behavior is used, and - ---config.nest_if_no_args is respected. - ---@type fun(host: channel):boolean - should_nest = require("flatten").default_should_nest, - - ---Called before a nested session is opened. - pre_open = function() end, - - ---Called after a nested session is opened. - ---@param bufnr buffer - ---@param winnr window - ---@param filetype string - ---@param is_blocking boolean - ---@param is_diff boolean - post_open = function(bufnr, winnr, filetype, is_blocking, is_diff) - -- If the file is a git commit, create one-shot autocmd to delete its buffer on write - if filetype == "gitcommit" or filetype == "gitrebase" then - vim.api.nvim_create_autocmd("BufWritePost", { - buffer = bufnr, - once = true, - callback = vim.schedule_wrap(function() vim.api.nvim_buf_delete(bufnr, {}) end), - }) - end - end, - - ---Called when a nested session is done waiting for the host. - ---@param filetype string - block_end = function(filetype) end, - }, - -- <String, Bool> dictionary of filetypes that should be blocking - block_for = { - gitcommit = true, - }, - -- Command passthrough - allow_cmd_passthrough = true, - -- Allow a nested session to open if Neovim is opened without arguments - nest_if_no_args = false, - -- Window options - window = { - -- Options: - -- current -> open in current window (default) - -- alternate -> open in alternate window (recommended) - -- tab -> open in new tab - -- split -> open in split - -- vsplit -> open in vsplit - -- smart -> smart open (avoids special buffers) - -- OpenHandler -> allows you to handle file opening yourself (see Types) - -- - -- TODO: Open gitcommit filetypes in the current buffer, everything else in a new tab <2023-08-29> - open = "split", - - -- Options: - -- vsplit -> opens files in diff vsplits - -- split -> opens files in diff splits - -- tab_vsplit -> creates a new tabpage, and opens diff vsplits - -- tab_split -> creates a new tabpage, and opens diff splits - -- OpenHandler -> allows you to handle file opening yourself (see Types) - diff = "tab_vsplit", - - -- Affects which file gets focused when opening multiple at once - -- Options: - -- "first" -> open first file of new files (default) - -- "last" -> open last file of new files - focus = "first", - }, - -- Override this function to use a different socket to connect to the host - -- On the host side this can return nil or the socket address. - -- On the guest side this should return the socket address - -- or a non-zero channel id from `sockconnect` - -- flatten.nvim will detect if the address refers to this instance of nvim, to determine if this is a host or a guest - pipe_path = require("flatten").default_pipe_path, - -- The `default_pipe_path` will treat the first nvim instance within a single kitty/wezterm session as the host - -- You can configure this behaviour using the following: - one_per = { - kitty = true, -- Flatten all instance in the current Kitty session - wezterm = true, -- Flatten all instance in the current Wezterm session - }, -}) diff --git a/modules/by-name/nv/nvim/plgs/leap/default.nix b/modules/by-name/nv/nvim/plgs/leap/default.nix deleted file mode 100644 index e5c42d2f..00000000 --- a/modules/by-name/nv/nvim/plgs/leap/default.nix +++ /dev/null @@ -1,74 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - config, - lib, - ... -}: let - cfg = config.soispha.programs.nvim; -in { - home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable { - plugins.leap = { - enable = true; - addDefaultMappings = false; # They don't work with dvorak. - safeLabels = [ - "f" - "j" - "k" - "l" - "/" - "z" - "S" - "F" - "J" - "K" - "L" - "H" - "W" - "E" - "M" - "B" - "U" - "X" - "?" - "Z" - ]; - }; - keymaps = [ - { - key = "j"; - action = "<Plug>(leap-forward-to)"; - options.desc = "jump forward to"; - } - { - key = "J"; - action = "<Plug>(leap-backward-to)"; - options.desc = "jump backward to"; - } - { - key = "gj"; - action = "<Plug>(leap-from-window)"; - options.desc = "jump to enterable windows"; - } - /* - {key= "x"; - mode = "v"; - action = "<Plug>(leap-forward-till)"; - options.desc = "leap forward till"; - } - {key= "X"; - mode = "v"; - action = "<Plug>(leap-backward-till)"; - options.desc = "leap backward till"; - } - */ - ]; - }; -} diff --git a/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix b/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix index 3a1c6bf9..e652a60d 100644 --- a/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix +++ b/modules/by-name/nv/nvim/plgs/lf-nvim/default.nix @@ -8,21 +8,88 @@ # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. { - pkgs, lib, config, ... }: let cfg = config.soispha.programs.nvim; in { - # TODO: package lf-nvim though a module # TODO: change the nvim path, when I change the path with lf home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable { - extraConfigLuaPost = '' - ${lib.strings.fileContents ./lua/lf-nvim.lua} - ''; - extraPlugins = [ - pkgs.vimPlugins.lf-nvim - ]; + plugins.lf = { + enable = true; + + settings = { + default_actions = { + "<C-o>" = "tab drop"; + "<C-t>" = "tabedit"; + "<C-v>" = "vsplit"; + "<C-x>" = "split"; + }; + + default_action = "drop"; + + winblend = 10; + dir = ""; + direction = "float"; + border = "rounded"; + height.__raw = "vim.fn.float2nr(vim.fn.round(0.75 * vim.o.lines))"; + width.__raw = "vim.fn.float2nr(vim.fn.round(0.75 * vim.o.columns))"; + escape_quit = true; + focus_on_open = true; + mappings = true; + tmux = false; + default_file_manager = true; + disable_netrw_warning = true; + highlights = { + Normal = {link = "Normal";}; + NormalFloat = {link = "Normal";}; + FloatBorder = { + guifg = "#cdcbe0"; + guibg = "#191726"; + }; + }; + + layout_mapping = "<M-u>"; + views = [ + { + width = 0.800; + height = 0.800; + } + { + width = 0.600; + height = 0.600; + } + { + width = 0.950; + height = 0.950; + } + { + width = 0.500; + height = 0.500; + col = 0; + row = 0; + } + { + width = 0.500; + height = 0.500; + col = 0; + row = 0.5; + } + { + width = 0.500; + height = 0.500; + col = 0.5; + row = 0; + } + { + width = 0.500; + height = 0.500; + col = 0.5; + row = 0.5; + } + ]; + }; + }; }; } diff --git a/modules/by-name/nv/nvim/plgs/lf-nvim/lua/lf-nvim.lua b/modules/by-name/nv/nvim/plgs/lf-nvim/lua/lf-nvim.lua deleted file mode 100644 index 8c40ab50..00000000 --- a/modules/by-name/nv/nvim/plgs/lf-nvim/lua/lf-nvim.lua +++ /dev/null @@ -1,53 +0,0 @@ --- nixos-config - My current NixOS configuration --- --- Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> --- SPDX-License-Identifier: GPL-3.0-or-later --- --- This file is part of my nixos-config. --- --- You should have received a copy of the License along with this program. --- If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -local fn = vim.fn - --- Defaults -require("lf").setup({ - default_action = "drop", -- default action when `Lf` opens a file - -- TODO: what do these mappings do? - default_actions = { -- default action keybindings - ["<C-t>"] = "tabedit", - ["<C-x>"] = "split", - ["<C-v>"] = "vsplit", - ["<C-o>"] = "tab drop", - }, - - winblend = 10, -- psuedotransparency level - dir = "", -- directory where `lf` starts ('gwd' is git-working-directory, ""/nil is CWD) - direction = "float", -- window type: float horizontal vertical - border = "rounded", -- border kind: single double shadow curved - height = fn.float2nr(fn.round(0.75 * vim.o.lines)), -- height of the *floating* window - width = fn.float2nr(fn.round(0.75 * vim.o.columns)), -- width of the *floating* window - escape_quit = true, -- map escape to the quit command (so it doesn't go into a meta normal mode) - focus_on_open = true, -- focus the current file when opening Lf (experimental) - mappings = true, -- whether terminal buffer mapping is enabled - tmux = false, -- tmux statusline can be disabled on opening of Lf - default_file_manager = true, -- make lf default file manager - disable_netrw_warning = true, -- don't display a message when opening a directory with `default_file_manager` as true - highlights = { -- highlights passed to toggleterm - Normal = { link = "Normal" }, - NormalFloat = { link = "Normal" }, - FloatBorder = { guifg = "#cdcbe0", guibg = "#191726" }, - }, - - -- Layout configurations - layout_mapping = "<M-u>", -- resize window with this key - views = { -- window dimensions to rotate through - { width = 0.800, height = 0.800 }, - { width = 0.600, height = 0.600 }, - { width = 0.950, height = 0.950 }, - { width = 0.500, height = 0.500, col = 0, row = 0 }, - { width = 0.500, height = 0.500, col = 0, row = 0.5 }, - { width = 0.500, height = 0.500, col = 0.5, row = 0 }, - { width = 0.500, height = 0.500, col = 0.5, row = 0.5 }, - }, -}) diff --git a/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/default.nix b/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/default.nix deleted file mode 100644 index 85458310..00000000 --- a/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/default.nix +++ /dev/null @@ -1,62 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - lib, - config, - pkgs, - ... -}: let - cfg = config.soispha.programs.nvim; -in { - home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable { - # TODO: package lsp-progress-nvim though a module - extraConfigLuaPost = '' - ${lib.strings.fileContents ./lua/lsp-progress-nvim.lua} - ''; - extraPlugins = [ - pkgs.vimExtraPlugins.lsp-progress-nvim - ]; - - # Status line setup - autoGroups.lsp_refresh.clear = true; - autoCmd = [ - { - event = ["User LspProgressStatusUpdated"]; - pattern = ["*"]; - callback = - /* - lua - */ - { - __raw = '' - require("lualine").refresh - ''; - }; - group = "lsp_refresh"; - description = "Refresh the statusbar when the lsp status was updated."; - } - ]; - plugins.lualine = let - get_lsp_progress = { - __raw = - /* - lua - */ - '' - require('lsp-progress').progress - ''; - }; - in { - sections = { - lualine_c = [{name = get_lsp_progress;}]; - }; - }; - }; -} diff --git a/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/lua/lsp-progress-nvim.lua b/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/lua/lsp-progress-nvim.lua deleted file mode 100644 index 2886d821..00000000 --- a/modules/by-name/nv/nvim/plgs/lsp-progress-nvim/lua/lsp-progress-nvim.lua +++ /dev/null @@ -1,156 +0,0 @@ --- nixos-config - My current NixOS configuration --- --- Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> --- SPDX-License-Identifier: GPL-3.0-or-later --- --- This file is part of my nixos-config. --- --- You should have received a copy of the License along with this program. --- If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - ---- @type table<string, any> -require("lsp-progress").setup({ - -- Spinning icons. - -- - --- @type string[] - spinner = { "⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷" }, - - -- Spinning update time in milliseconds. - -- - --- @type integer - spin_update_time = 200, - - -- Last message cached decay time in milliseconds. - -- - -- Message could be really fast(appear and disappear in an - -- instant) that user cannot even see it, thus we cache the last message - -- for a while for user view. - -- - --- @type integer - decay = 700, - - -- User event name. - -- - --- @type string - event = "LspProgressStatusUpdated", - - -- Event update time limit in milliseconds. - -- - -- Sometimes progress handler could emit many events in an instant, while - -- refreshing statusline cause too heavy synchronized IO, so we limit the - -- event rate to reduce this cost. - -- - --- @type integer - event_update_time_limit = 100, - - -- Max progress string length, by default -1 is unlimited. - -- - --- @type integer - max_size = -1, - - -- Regular internal update time. - -- - -- Emit user event to update the lsp progress status, even there's no new - -- message. - -- - --- @type integer - regular_internal_update_time = 500, - - -- Disable emitting events on specific mode/filetype. - -- User events would interrupt insert mode, thus break which-key like plugins behaviour. - -- See: - -- * https://github.com/linrongbin16/lsp-progress.nvim/issues/50 - -- * https://neovim.io/doc/user/builtin.html#mode() - -- - --- @type table[] - disable_events_opts = { { mode = "i", filetype = "TelescopePrompt" } }, - - -- Format series message. - -- - -- By default it looks like: `formatting isort (100%) - done`. - -- - --- @param title string|nil - --- Message title. - --- @param message string|nil - --- Message body. - --- @param percentage number|nil - --- Progress in percentage numbers: 0-100. - --- @param done boolean - --- Indicate whether this series is the last one in progress. - --- @return string|nil messages - --- The returned value will be passed to function `client_format` as - --- one of the `series_messages` array, or ignored if return nil. - series_format = function(title, message, percentage, done) - local builder = {} - local has_title = false - local has_message = false - if title and title ~= "" then - table.insert(builder, title) - has_title = true - end - if message and message ~= "" then - table.insert(builder, message) - has_message = true - end - if percentage and (has_title or has_message) then table.insert(builder, string.format("(%.0f%%%%)", percentage)) end - if done and (has_title or has_message) then table.insert(builder, "- done") end - return table.concat(builder, " ") - end, - - -- Format client message. - -- - -- By default it looks like: - -- `[null-ls] ⣷ formatting isort (100%) - done, formatting black (50%)`. - -- - --- @param client_name string - --- Client name. - --- @param spinner string - --- Spinner icon. - --- @param series_messages string[]|table[] - --- Messages array. - --- @return string|nil messages - --- The returned value will be passed to function `format` as one of the - --- `client_messages` array, or ignored if return nil. - client_format = function(client_name, spinner, series_messages) - return #series_messages > 0 - and ("[" .. client_name .. "] " .. spinner .. " " .. table.concat(series_messages, ", ")) - or nil - end, - - -- Format (final) message. - -- - -- By default it looks like: - -- ` LSP [null-ls] ⣷ formatting isort (100%) - done, formatting black (50%)` - -- - --- @param client_messages string[]|table[] - --- Client messages array. - --- @return nil|string message - --- The returned value will be returned from `progress` API. - format = function(client_messages) - local sign = " LSP" -- nf-fa-gear \uf013 - return #client_messages > 0 and (sign .. " " .. table.concat(client_messages, " ")) or sign - end, - - -- Enable debug. - -- - --- @type boolean - debug = false, - - -- Print log to console(command line). - -- - --- @type boolean - console_log = false, - - -- Print log to file. - -- - --- @type boolean - file_log = true, - - -- Log file to write, work with `file_log=true`. - -- - -- For Windows: `$env:USERPROFILE\AppData\Local\nvim-data\lsp-progress.log`. - -- For *NIX: `~/.local/share/nvim/lsp-progress.log`. - -- - --- @type string - file_log_name = "lsp-progress.log", -}) diff --git a/modules/by-name/nv/nvim/plgs/lsp/servers/default.nix b/modules/by-name/nv/nvim/plgs/lsp/servers/default.nix index 8ff130fe..b6e47ca4 100644 --- a/modules/by-name/nv/nvim/plgs/lsp/servers/default.nix +++ b/modules/by-name/nv/nvim/plgs/lsp/servers/default.nix @@ -9,7 +9,6 @@ # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. {...}: { imports = [ - # ./servers/pylyzer.nix ./servers/bashls.nix ./servers/ccls.nix ./servers/quick-lint-js.nix diff --git a/modules/by-name/nv/nvim/plgs/raw_plugins/default.nix b/modules/by-name/nv/nvim/plgs/raw_plugins/default.nix deleted file mode 100644 index c981ee08..00000000 --- a/modules/by-name/nv/nvim/plgs/raw_plugins/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - config, - lib, - ... -}: let - cfg = config.soispha.programs.nvim; -in { - home-manager.users.soispha.programs.nixvim = lib.mkIf cfg.enable { - # Not all plugins have own modules - # You can add missing plugins here - # `pkgs.vimExtraPlugins` is added by the overlay you added at the beginning - # For a list of available plugins, look here: - # https://github.com/jooooscha/nixpkgs-vim-extra-plugins/blob/main/plugins.md - extraPlugins = [ - ]; - }; -} diff --git a/modules/by-name/nv/nvim/plgs/treesitter/default.nix b/modules/by-name/nv/nvim/plgs/treesitter/default.nix index c8b48cd1..ed1499f8 100644 --- a/modules/by-name/nv/nvim/plgs/treesitter/default.nix +++ b/modules/by-name/nv/nvim/plgs/treesitter/default.nix @@ -50,7 +50,7 @@ in { # Set this to `true` if you depend on 'syntax' being enabled (like for indentation). # Using this option may slow down your editor; and you may see some duplicate highlights. # Instead of true it can also be a list of languages - additionalVimRegexHighlighting = ["latex"]; + additionalVimRegexHighlighting = []; }; incrementalSelection = { diff --git a/modules/by-name/qu/qutebrowser/include/redirects.py b/modules/by-name/qu/qutebrowser/include/redirects.py new file mode 100644 index 00000000..23456a25 --- /dev/null +++ b/modules/by-name/qu/qutebrowser/include/redirects.py @@ -0,0 +1,64 @@ +# Based on the redirect scripts from here: +# - https://github.com/Phantop/dotfiles/blob/9f6256820dbb99cdf5afd373b74d93fe8b8972d7/qutebrowser/include/redirects.py +# - https://gitlab.com/jgkamat/dotfiles/-/blob/0e5f05d347079a9839cb2c7878fd81d9850928ce/qutebrowser/.config/qutebrowser/pyconfig/redirectors.py + +from qutebrowser.api import interceptor, message + +import operator +import typing + +from PyQt6.QtCore import QUrl + + +def get_host(url: QUrl, base: bool = False) -> str: + host = url.host() + if base: + # www.someSite.com -> someSite.com + return ".".join(host.split(".")[-2:]) + else: + return host + + +def partial(func, *part_args): + def wrapper(*extra_args): + return func(*part_args, *extra_args) + + return wrapper + + +def farside_redir(target: str, url: QUrl) -> bool: + url.setHost("farside.link") + url.setPath("/" + target + url.path()) + return True + + +# Any return value other than a literal 'False' means we redirect +REDIRECT_MAP: typing.Dict[str, typing.Callable[..., typing.Optional[bool]]] = { + "reddit.com": operator.methodcaller("setHost", "redlib.vhack.eu"), + # Source: https://libredirect.github.io/ + "medium.com": partial(farside_redir, "scribe"), + "stackoverflow.com": partial(farside_redir, "anonymousoverflow"), + "goodreads.com": partial(farside_redir, "biblioreads"), +} + + +def rewrite(info: interceptor.Request): + if ( + info.resource_type != interceptor.ResourceType.main_frame + or info.request_url.scheme() in {"data", "blob"} + ): + return + + url = info.request_url + + redir = REDIRECT_MAP.get(get_host(url, base=False)) + if redir is None: + # Try again, but now only with the base host. + redir = REDIRECT_MAP.get(get_host(url, base=True)) + + if redir is not None and redir(url) is not False: + message.info("Redirecting to " + url.toString()) + info.redirect(url) + + +interceptor.register(rewrite) diff --git a/modules/by-name/qu/qutebrowser/module.hm.nix b/modules/by-name/qu/qutebrowser/module.hm.nix new file mode 100644 index 00000000..3f0f0d52 --- /dev/null +++ b/modules/by-name/qu/qutebrowser/module.hm.nix @@ -0,0 +1,490 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.programs.qutebrowser; + + /* + Flattens an attribute set of key values to stringified keys and their values. + + This is necessary, as qutebrowser only understands key value settings. + + ## Determining the keys and values + + Currently, this function will recursively iterate through the `configAttrs`, whilst + adding up the attribute keys, until one of the following conditions apply: + - The value is not an attribute set. + - The value is “marked” as being a raw attribute set. This is done automatically via the + `apply` functions in the option that take attribute sets (i.e., dictionaries) as + values. + + ## Marking an attribute set as value + Currently, this function assumes that a attribute set is meant as value, if it's key is + `__raw`. For example: + ```nix + { + bindings.command.__raw = { + normal.L = "close"; + }; + } + ``` + + # Type + + flattenSettings :: AttrSet -> [{key :: String; value :: Any}] + + # Arguments + + configAttrs + : The configuration attribute set to flatten. + + # Examples + + flattenSettings {aliases.__raw = {c = "close";}; colors.background = "0xffffff00";} + => [ + {key = "aliases"; value = {c = "close";};} + {key = "colors.background"; value = "0xffffff00";} + ] + */ + flattenSettings = let + isValue = aS: (builtins.attrNames aS) == ["__raw"]; + in + configAttrs: + lib.collect (aS: (builtins.attrNames aS) == ["key" "value"]) ( + lib.attrsets.mapAttrsRecursiveCond (a: !(isValue a)) ( + path: value: + assert builtins.isList path; { + key = lib.concatStringsSep "." path; + inherit value; + } + ) + configAttrs + ); + + pythonize = identCount: v: let + nextIdentCount = identCount + 2; + prevIdentCount = identCount - 2; + ident = builtins.concatStringsSep "" (builtins.genList (_: " ") identCount); + prevIdent = builtins.concatStringsSep "" (builtins.genList (_: " ") prevIdentCount); + in + if v == null + then "None" + else if builtins.isBool v + then + ( + if v + then "True" + else "False" + ) + else if builtins.isString v + then ''"${lib.escape ["\"" "\\"] v}"'' + else if builtins.isInt v + then builtins.toString v + else if builtins.isList v + then + ( + let + items = builtins.map (pythonize nextIdentCount) v; + in + if (builtins.length items) < 2 + then "[${builtins.concatStringsSep "," items}]" + else "[\n${ident}${builtins.concatStringsSep ",\n${ident}" items}\n${prevIdent}]" + ) + else if builtins.isAttrs v + then + if (v ? __raw && v.__raw == null) + # Make it possible to skip values, as we would otherwise unconditional override the + # non-set default values with `{}`. + then null + else if (v ? __raw && builtins.isList v.__raw) + # The raw value is already pre-rendered (e.g., used by the bindings.commands to use + # the `config.bind` functions instead of setting the keys directly.) + then v.__raw + else + ( + # {key = "value"; other = "other";} -> "{'key': 'value', 'other': 'other'}" + let + items = + lib.attrsets.mapAttrsToList + (key: value: ''${pythonize nextIdentCount key}: ${pythonize nextIdentCount value}'') + (v.__raw or v); + in + if (builtins.length items) == 0 + then "{}" + else "{\n${ident}${builtins.concatStringsSep ",\n${ident}" items}\n${prevIdent}}" + ) + else builtins.throw "Cannot serialize a '${builtins.typeOf v}' as python value."; + + configSet = keyValue: maybe_url: let + value = pythonize 2 keyValue.value; + in + if value == null + then "" + else if builtins.isList value + then builtins.concatStringsSep "\n" value + else "config.set(${pythonize 2 keyValue.key}, ${value}${ + if (maybe_url != null) + then ", ${maybe_url}" + else "" + })"; + urlConfigSet = url: conf: builtins.map (c: configSet c url) (flattenSettings conf); + extraConfigSet = name: path_or_string: ''config.source("${ + if (builtins.isPath path_or_string) + then path_or_string + else pkgs.writeText name path_or_string + }")''; + + mkRaw = value: {__raw = value;}; + formatQuickmarks = n: s: "${n} ${s}"; + + settingsType = lib.types.submodule { + freeformType = lib.types.attrsOf lib.types.anything; + options = { + # A list of config keys, that take dicts and need special handling: + # (See their configdata.yml for the source of this list) + # aliases + # bindings.commands + # bindings.default + # bindings.key_mappings + # content.headers.custom + # content.javascript.log + # hints.selectors + # statusbar.padding + # url.searchengines + + aliases = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf lib.types.str); + default = null; + apply = mkRaw; + }; + + bindings = let + keyBindType = lib.types.nullOr (lib.types.attrsOf ( + lib.types.attrsOf ( + lib.types.nullOr ( + lib.types.separatedString " ;; " + ) + ) + )); + in { + key_mappings = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf lib.types.str); + default = null; + apply = mkRaw; + }; + + # This is special, as we need to use the `config.bind` command, instead of the + # normal one. + commands = lib.mkOption { + type = keyBindType; + default = null; + apply = v: + if v == null + then null + else { + __raw = + lib.lists.flatten + (lib.mapAttrsToList + (mode: mappings: + lib.mapAttrsToList + (key: value: "config.bind(${pythonize 0 key}, ${pythonize 0 value}, mode=${pythonize 0 mode})") + mappings) + v); + }; + example = lib.literalExpression '' + { + normal = { + "<Ctrl-v>" = "spawn mpv {url}"; + ",p" = "spawn --userscript qute-pass"; + ",l" = '''config-cycle spellcheck.languages ["en-GB"] ["en-US"]'''; + "<F1>" = mkMerge [ + "config-cycle tabs.show never always" + "config-cycle statusbar.show in-mode always" + "config-cycle scrolling.bar never always" + ]; + }; + prompt = { + "<Ctrl-y>" = "prompt-yes"; + }; + } + ''; + }; + + default = lib.mkOption { + type = keyBindType; + default = null; + apply = mkRaw; + }; + }; + + content = { + headers = { + custom = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf lib.types.str); + default = null; + apply = mkRaw; + }; + }; + javascript = { + log = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf lib.types.str); + default = null; + apply = mkRaw; + }; + }; + }; + + hints = { + selectors = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf lib.types.str); + default = null; + apply = mkRaw; + }; + }; + + qt = { + environ = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf lib.types.str); + default = null; + apply = mkRaw; + }; + }; + + url = { + searchengines = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf lib.types.str); + default = null; + apply = mkRaw; + example = lib.literalExpression '' + { + w = "https://en.wikipedia.org/wiki/Special:Search?search={}&go=Go&ns0=1"; + aw = "https://wiki.archlinux.org/?search={}"; + nw = "https://wiki.nixos.org/index.php?search={}"; + g = "https://www.google.com/search?hl=en&q={}"; + } + ''; + }; + }; + statusbar = { + padding = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf lib.types.int); + default = null; + apply = mkRaw; + }; + }; + }; + }; +in { + options.programs.qutebrowser = { + enable = lib.mkEnableOption "qutebrowser"; + + package = lib.mkPackageOption pkgs "qutebrowser" {}; + + loadAutoconfig = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Load settings configured via the GUI. + ''; + }; + + settings = lib.mkOption { + type = settingsType; + + default = {}; + description = '' + Options to add to qutebrowser {file}`config.py` file. + See <https://qutebrowser.org/doc/help/settings.html> + for options. + ''; + example = lib.literalExpression '' + { + colors = { + hints = { + bg = "#000000"; + fg = "#ffffff"; + }; + tabs.bar.bg = "#000000"; + }; + tabs.tabs_are_windows = true; + } + ''; + }; + + quickmarks = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = {}; + description = '' + Quickmarks to add to qutebrowser's {file}`quickmarks` file. + Note that when Home Manager manages your quickmarks, you cannot edit them at runtime. + ''; + example = lib.literalExpression '' + { + nixpkgs = "https://github.com/NixOS/nixpkgs"; + home-manager = "https://github.com/nix-community/home-manager"; + } + ''; + }; + + greasemonkey = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = []; + example = lib.literalExpression '' + [ + (pkgs.fetchurl { + url = "https://raw.githubusercontent.com/afreakk/greasemonkeyscripts/1d1be041a65c251692ee082eda64d2637edf6444/youtube_sponsorblock.js"; + sha256 = "sha256-e3QgDPa3AOpPyzwvVjPQyEsSUC9goisjBUDMxLwg8ZE="; + }) + (pkgs.writeText "some-script.js" ''' + // ==UserScript== + // @name Some Greasemonkey script + // ==/UserScript== + ''') + ] + ''; + description = '' + Greasemonkey userscripts to add to qutebrowser's {file}`greasemonkey` + directory. + ''; + }; + + perUrlSettings = lib.mkOption { + type = lib.types.attrsOf settingsType; + default = {}; + description = '' + Options to set, as in {option}`settings` but per url pattern. + + See <https://qutebrowser.org/doc/help/settings.html> for options, + but beware, that not every option supports being set per-url. + ''; + example = lib.literalExpression '' + { + "zoom.us" = { + content = { + autoplay = true; + media.audio_capture = true; + media.video_capture = true; + }; + }; + "github.com".colors.webpage.darkmode.enabled = false; + }; + ''; + }; + + extraConfig = lib.mkOption { + type = lib.types.attrsOf (lib.types.either lib.types.str lib.types.pathInStore); + default = {}; + description = '' + Extra config snippets. The attribute name is their name, and the value their + value. + ''; + example = lib.literalExpression '' + { + "redirects" = ' ' + from PyQt5.QtCore import QUrl + from qutebrowser.api import interceptor + + def intercept(info: interceptor.Request): + if info.request_url.host() == 'www.youtube.com': + new_url = QUrl(info.request_url) + new_url.setHost('www.invidio.us') + try: + info.redirect(new_url) + except interceptors.RedirectFailedException: + pass + + interceptor.register(intercept) + ' ' + } + ''; + }; + }; + + config = let + qutebrowserConfig = lib.concatStringsSep "\n" ( + [ + ( + if cfg.loadAutoconfig + then "config.load_autoconfig()" + else "config.load_autoconfig(False)" + ) + ] + ++ builtins.map (c: configSet c null) (flattenSettings cfg.settings) + ++ lib.lists.flatten (lib.mapAttrsToList urlConfigSet cfg.perUrlSettings) + ++ lib.mapAttrsToList extraConfigSet cfg.extraConfig + ); + + quickmarksFile = lib.optionals (cfg.quickmarks != {}) lib.concatStringsSep "\n" ( + lib.mapAttrsToList formatQuickmarks cfg.quickmarks + ); + + greasemonkeyDir = + lib.optionals ( + cfg.greasemonkey != [] + ) + pkgs.linkFarmFromDrvs "greasemonkey-userscripts" + cfg.greasemonkey; + in + lib.mkIf cfg.enable { + home = { + packages = [cfg.package]; + + file = { + ".qutebrowser/config.py" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { + text = qutebrowserConfig; + }; + + ".qutebrowser/quickmarks" = + lib.mkIf (cfg.quickmarks != {} && pkgs.stdenv.hostPlatform.isDarwin) + { + text = quickmarksFile; + }; + + ".qutebrowser/greasemonkey" = + lib.mkIf (cfg.greasemonkey != [] && pkgs.stdenv.hostPlatform.isDarwin) + { + source = greasemonkeyDir; + }; + }; + }; + + xdg = { + configFile = { + "qutebrowser/config.py" = lib.mkIf pkgs.stdenv.hostPlatform.isLinux { + text = qutebrowserConfig; + onChange = '' + hash="$(echo -n "$USER" | md5sum | cut -d' ' -f1)" + socket="''${XDG_RUNTIME_DIR:-/run/user/$UID}/qutebrowser/ipc-$hash" + if [[ -S $socket ]]; then + command=${ + lib.escapeShellArg ( + builtins.toJSON { + args = [":config-source"]; + target_arg = null; + protocol_version = 1; + } + ) + } + echo "$command" | ${pkgs.socat}/bin/socat -lf /dev/null - UNIX-CONNECT:"$socket" + fi + unset hash socket command + ''; + }; + + "qutebrowser/quickmarks" = + lib.mkIf (cfg.quickmarks != {} && pkgs.stdenv.hostPlatform.isLinux) + { + text = quickmarksFile; + }; + + "qutebrowser/greasemonkey" = + lib.mkIf (cfg.greasemonkey != [] && pkgs.stdenv.hostPlatform.isLinux) + { + source = greasemonkeyDir; + }; + }; + }; + }; +} diff --git a/modules/by-name/qu/qutebrowser/module.nix b/modules/by-name/qu/qutebrowser/module.nix new file mode 100644 index 00000000..dab06237 --- /dev/null +++ b/modules/by-name/qu/qutebrowser/module.nix @@ -0,0 +1,106 @@ +{ + config, + lib, + pkgs, + self, + ... +}: let + cfg = config.soispha.programs.qutebrowser; + + qutebrowsersWithProfiles = let + xdg_data_home = config.home-manager.users.soispha.xdg.dataHome; + xdg_config_home = config.home-manager.users.soispha.xdg.configHome; + + mkQutebrowser = name: let + statusbar_widgets = [ + "keypress" + "text:${name}" + "search_match" + "url" + "scroll" + "history" + "tabs" + "progress" + ]; + + statusbar_widgets_str = + # NOTE(@bpeetz): We need either two layers of escaping or the binary wrapper, as we first inline this + # into the runCommand below, and then into the actual qutebrowser wrapper script. <2025-06-16> + lib.strings.escapeShellArg (builtins.toJSON statusbar_widgets); + in + pkgs.runCommandLocal "qutebrowser-${name}" { + nativeBuildInputs = [ + pkgs.makeBinaryWrapper + ]; + } + '' + makeWrapper ${lib.getExe pkgs.qutebrowser-patched} "$out/bin/qutebrowser-${name}" \ + --add-flags --no-err-windows \ + --add-flags --basedir \ + --add-flags "${xdg_data_home}/qutebrowser/${name}" \ + --add-flags --config \ + --add-flags "${xdg_config_home}/qutebrowser/config.py" \ + --add-flags --set \ + --add-flags statusbar.widgets \ + --add-flags ${statusbar_widgets_str} + ''; + in + builtins.filter (val: val != null) (lib.mapAttrsToList (name: value: + if value.enable + then mkQutebrowser name + else null) + cfg.profiles); +in { + options.soispha.programs.qutebrowser = { + enable = lib.mkEnableOption "qutebrowser"; + + key = lib.mkOption { + type = lib.types.str; + description = '' + The gpg key, used when decrypting the keepassxc connection key. + ''; + }; + + profiles = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule { + options = { + enable = + (lib.mkEnableOption "this profile") + // { + default = true; + }; + }; + }); + + description = "A name enable map of profies to create besides the default `default` profile."; + default = {}; + }; + }; + + config = lib.mkIf cfg.enable { + home-manager.users.soispha = { + disabledModules = [ + "${self.inputs.home-manager}/modules/programs/qutebrowser.nix" + ]; + imports = [ + ./module.hm.nix + ]; + + home.packages = qutebrowsersWithProfiles; + + programs.qutebrowser = { + enable = true; + package = pkgs.hello; # TODO: Set to null, once supported <2025-06-06> + + settings = import ./settings { + inherit lib pkgs; + cfg = config.soispha.programs.qutebrowser; + }; + + extraConfig = { + "redirects" = ./include/redirects.py; + }; + }; + }; + }; +} diff --git a/modules/by-name/qu/qutebrowser/settings/default.nix b/modules/by-name/qu/qutebrowser/settings/default.nix new file mode 100644 index 00000000..fc097eac --- /dev/null +++ b/modules/by-name/qu/qutebrowser/settings/default.nix @@ -0,0 +1,537 @@ +{ + lib, + pkgs, + cfg, +}: let + millisecond = 1; + second = 1000 * millisecond; + + wordlist = + pkgs.runCommandNoCCLocal "wordlist" { + nativeBuildInputs = [pkgs.python3]; + } + '' + python ${ + pkgs.writeText "normalize-words" + # python + '' + import string + import os + + # Perform qutebrowser's normalizations, to reduce our dependency closure. + # See <//qutebrowser/qutebrowser/browser/hints.py> for them. + with open("${pkgs.scowl}/share/dict/words.txt", encoding = "latin1") as wordfile: + alphabet = set(string.ascii_lowercase) + hints = set() + lines = (line.rstrip().lower() for line in wordfile) + for word in lines: + if len(word) > 4: + # we don't need words longer than 4 + continue + if set(word) - alphabet: + # contains none-alphabetic chars + continue + for i in range(len(word)): + # remove all prefixes of this word + hints.discard(word[:i + 1]) + hints.add(word) + + with open(os.environ["out"], "w") as out: + for word in hints: + out.write(word) + out.write("\n") + '' + } + ''; +in { + aliases = { + q = "close"; + qa = "quit"; + w = "session-save"; + wq = "quit --save"; + wqa = "quit --save"; + read = "spawn --userscript readability"; + }; + + auto_save = { + interval = 10 * second; + session = true; # Safe/restore the session + }; + + backend = "webengine"; + + bindings = { + default = {}; # Disable the default key bindings + + commands = import ./keybindings.nix {inherit cfg lib;}; + + key_mappings = { + "<Ctrl-6>" = "<Ctrl-^>"; + "<Ctrl-Enter>" = "<Ctrl-Return>"; + "<Ctrl-I>" = "<Tab>"; + "<Ctrl-J>" = "<Return>"; + "<Ctrl-M>" = "<Return>"; + "<Ctrl-[>" = "<Escape>"; + "<Enter>" = "<Return>"; + "<Shift-Enter>" = "<Return>"; + "<Shift-Return>" = "<Return>"; + }; + }; + + changelog_after_upgrade = "minor"; + + fonts = {}; + colors = { + # TODO(@bpeetz): Use a nord color scheme (or stylix). <2025-05-31> + + # Make things readable. + messages.error.fg = "black"; + completion.match.fg = "black"; + + webpage = { + darkmode = { + enabled = true; + algorithm = "lightness-cielab"; + policy = { + images = "smart"; + page = "smart"; + }; + threshold = { + background = 0; # 0 -> always + foreground = 256; # 256 -> always + }; + }; + preferred_color_scheme = "auto"; + }; + }; + + completion = { + cmd_history_max_items = -1; # No limit. + delay = 0; # delay before updating completions in milliseconds. + favorite_paths = []; + height = "50%"; + min_chars = 1; + open_categories = ["searchengines" "quickmarks" "bookmarks" "history" "filesystem"]; + + quick = true; # Select, when only one left. + + scrollbar = { + padding = 0; + width = 0; + }; + + show = "auto"; # Only show, when selected + + shrink = true; + + use_best_match = false; + web_history = { + exclude = []; + max_items = -1; # unlimited. + }; + }; + + confirm_quit = [ + "downloads" + ]; + + content = { + autoplay = false; + + blocking = { + enabled = true; + + # Sources for brave's adblocker + adblock = { + lists = [ + "https://easylist.to/easylist/easylist.txt" + "https://easylist.to/easylist/easyprivacy.txt" + ]; + }; + + # Sources for the (simpler) /etc/hosts based one. + hosts = { + block_subdomains = true; + lists = []; + }; + + method = "adblock"; # Only brave's + whitelist = []; + }; + + # Allow websites to read canvas elements. + canvas_reading = true; + + cookies = { + store = true; + accept = "no-3rdparty"; + }; + + default_encoding = "utf-8"; + + dns_prefetch = true; + + fullscreen = { + # Fullscreen is limited to the browser window. + window = true; + overlay_timeout = 3 * second; + }; + + headers = { + accept_language = "en-CA,sv,en;q=0.9"; + custom = {}; + do_not_track = true; + referer = "same-domain"; + user_agent = "Mozilla/5.0 ({os_info}) AppleWebKit/{webkit_version} (KHTML, like Gecko) {upstream_browser_key}/{upstream_browser_version_short} Safari/{webkit_version}"; + }; + + hyperlink_auditing = false; + + # Auto-load images. + images = true; + + javascript = { + enabled = true; + + can_open_tabs_automatically = false; + alert = true; + clipboard = "ask"; + legacy_touch_events = "never"; + + log = { + error = "debug"; + warning = "debug"; + info = "debug"; + unknown = "debug"; + }; + + modal_dialog = false; + prompt = true; + }; + + local_content_can_access_file_urls = true; + local_content_can_access_remote_urls = false; + + local_storage = true; + + desktop_capture = "ask"; + geolocation = "ask"; + persistent_storage = "ask"; + mouse_lock = "ask"; + register_protocol_handler = "ask"; + media = { + audio_capture = "ask"; + audio_video_capture = "ask"; + video_capture = "ask"; + }; + + mute = false; + + notifications = { + # TODO(@bpeetz): I might change that. <2025-05-31> + enabled = true; + + presenter = "libnotify"; + show_origin = true; + }; + + pdfjs = false; + + # TODO(@bpeetz): What are “plugins in Web pages”? <2025-05-31> + plugins = false; + + prefers_reduced_motion = false; + print_element_backgrounds = true; + private_browsing = false; + proxy = "system"; + + site_specific_quirks = { + enabled = true; + skip = []; + }; + + tls = { + certificate_errors = "ask"; + }; + + unknown_url_scheme_policy = "allow-from-user-interaction"; + user_stylesheets = []; + + webgl = true; + + webrtc_ip_handling_policy = "all-interfaces"; + xss_auditing = false; + }; + + downloads = { + location = { + # Use OS default. + directory = null; + prompt = true; + remember = true; + suggestion = "path"; + }; + + # TODO(@bpeetz): I might want to set that. <2025-05-31> + open_dispatcher = null; + + position = "top"; + prevent_mixed_content = true; + + # Never remove downloads without my intervention. + remove_finished = -1; + }; + + editor = { + command = [ + "${lib.getExe pkgs.alacritty}" + "--title" + "floating please" + "--command" + "nvim" + "-c" + "normal {line}G{column0}|" + "{file}" + ]; + encoding = "utf-8"; + remove_file = true; + }; + + fileselect = { + handler = "default"; + }; + + hints = { + auto_follow = "unique-match"; + auto_follow_timeout = 0; + + chars = "asdfghjkl"; + dictionary = "${wordlist}"; + + hide_unmatched_rapid_hints = true; + leave_on_load = false; + + min_chars = 1; + next_regexes = ["\\bnext\\b" "\\bmore\\b" "\\bnewer\\b" "\\b[>→≫]\\b" "\\b(>>|»)\\b" "\\bcontinue\\b"]; + prev_regexes = ["\\bprev(ious)?\\b" "\\bback\\b" "\\bolder\\b" "\\b[<←≪]\\b" "\\b(<<|«)\\b"]; + + scatter = true; + uppercase = false; + mode = "word"; + }; + + input = { + escape_quits_reporter = false; + forward_unbound_keys = "auto"; + + insert_mode = { + auto_enter = true; + auto_leave = true; + auto_load = false; + leave_on_load = true; + plugins = false; + }; + + links_included_in_focus_chain = true; + match_counts = true; + + media_keys = true; + + mode_override = null; + + mouse = { + back_forward_buttons = true; + rocker_gestures = false; + }; + + partial_timeout = 0; + spatial_navigation = false; + }; + + keyhint = { + blacklist = []; + delay = 250 * millisecond; + }; + + logging = { + level = { + console = "info"; + ram = "debug"; + }; + }; + + messages = { + timeout = 3 * second; + }; + + new_instance_open_target = "tab"; + new_instance_open_target_window = "last-focused"; + + prompt = { + filebrowser = true; + }; + + qt = { + args = []; + + chromium = { + experimental_web_platform_features = "auto"; + low_end_device_mode = "auto"; + process_model = "process-per-site-instance"; + sandboxing = "enable-all"; + }; + + environ = {}; + force_platform = null; + force_platformtheme = null; + force_software_rendering = "none"; + + highdpi = true; + + workarounds = { + disable_accelerated_2d_canvas = "auto"; + disable_hangouts_extension = false; + locale = false; + remove_service_workers = false; + }; + }; + + scrolling = { + bar = "never"; + smooth = false; + }; + + search = { + ignore_case = "smart"; + incremental = true; + wrap = true; + wrap_messages = true; + }; + + session = { + default_name = null; + lazy_restore = true; + }; + + spellcheck = { + # TODO(@bpeetz): Installing them (reproducibly) is simply not worth the hassle, as + # qutebrowser already provides quick access to an editor. <2025-06-04> + # languages = ["en-GB" "sv-SE" "de-DE"]; + }; + + statusbar = { + padding = { + bottom = 5; + left = 5; + right = 5; + top = 5; + }; + + position = "top"; + show = "always"; + widgets = [ + /* + Already set in the wrappers + */ + ]; + }; + + tabs = { + background = true; + close_mouse_button = "middle"; + close_mouse_button_on_bar = "new-tab"; + + favicons = { + scale = 1; + show = "always"; + }; + + focus_stack_size = 10; + + last_close = "default-page"; + + max_width = -1; + min_width = -1; + + mode_on_change = "normal"; + + mousewheel_switching = true; + + new_position = { + related = "next"; + unrelated = "next"; + stacking = true; + }; + + pinned = { + frozen = true; + shrink = true; + }; + + position = "top"; + + select_on_remove = "last-used"; + + show = "multiple"; + show_switching_delay = 2 * second; + + tabs_are_windows = false; + title = { + alignment = "center"; + elide = "middle"; + format = "{audio}{index}: {current_title}"; + format_pinned = "{index}"; + }; + + tooltips = true; + undo_stack_size = 100; + width = "15%"; + wrap = true; + }; + + url = { + auto_search = "naive"; + default_page = "qute://start"; + incdec_segments = ["path" "query"]; + + open_base_url = false; # Of search engine. + searchengines = rec { + DEFAULT = leta; + + leta = "https://leta.mullvad.net/search?q={}"; + "@ls" = leta; + + # NIX + "@np" = "https://search.nixos.org/packages?type=packages&query={}"; # Nix packages + + "@ng" = "https://noogle.dev/q?term={}"; # Nix functions + + "@no" = "https://search.nixos.org/options?type=options&query={}"; # NixOS options + "@nh" = "https://home-manager-options.extranix.com/?query={}&release=master"; # Home-Manager options + + "@ni" = "https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+{}"; # Nixpkgs issues + "@nr" = "https://github.com/NixOS/nixpkgs/pulls?q=is%3Apr+is%3Aopen+{}"; # Nixpkgs pull requests + + "@nt" = "https://nixpk.gs/pr-tracker.html?pr={}"; # Nixpkgs pull requests tracker + "@nw" = "https://wiki.nixos.org/w/index.php?search={}"; # NixOS Wiki + + # RUST + "@rs" = "https://doc.rust-lang.org/std/?search={}"; # Rust std + "@rt" = "https://docs.rs/tokio/latest/tokio/index.html?search={}"; # Rust tokio + + # OTHER + "@gs" = "https://scholar.google.com/scholar?hl=en&q={}"; # Google Scholar + "@wp" = "https://en.wikipedia.org/wiki/{}"; # Wikipedia + "@aw" = "https://wiki.archlinux.org/index.php?search={}"; # Arch Wiki + }; + + start_pages = ["qute://start"]; + yank_ignored_parameters = ["ref" "utm_source" "utm_medium" "utm_campaign" "utm_term" "utm_content" "utm_name"]; + }; + + window = { + hide_decoration = true; + title_format = "{perc}{current_title}{title_sep}qutebrowser"; + transparent = false; + }; +} diff --git a/modules/by-name/qu/qutebrowser/settings/keybindings.nix b/modules/by-name/qu/qutebrowser/settings/keybindings.nix new file mode 100644 index 00000000..fde78457 --- /dev/null +++ b/modules/by-name/qu/qutebrowser/settings/keybindings.nix @@ -0,0 +1,289 @@ +{ + cfg, + lib, +}: { + caret = { + "<Escape>" = "mode-leave"; + + H = "scroll left"; + T = "scroll down"; + N = "scroll up"; + S = "scroll right"; + h = "move-to-prev-char"; + t = "move-to-next-line"; + n = "move-to-prev-line"; + s = "move-to-next-char"; + + "$" = "move-to-end-of-line"; + "0" = "move-to-start-of-line"; + G = "move-to-end-of-document"; + gg = "move-to-start-of-document"; + + b = "move-to-prev-word"; + c = "mode-enter normal"; + e = "move-to-end-of-word"; + w = "move-to-next-word"; + + "{" = "move-to-end-of-prev-block"; + "}" = "move-to-end-of-next-block"; + "[" = "move-to-start-of-prev-block"; + "]" = "move-to-start-of-next-block"; + + y = "yank selection"; + Y = "yank selection -s"; + V = "selection-toggle --line"; + v = "selection-toggle"; + "<Ctrl-Space>" = "selection-drop"; + "<Return>" = "yank selection"; + "<Space>" = "selection-toggle"; + o = "selection-reverse"; + }; + + command = { + "<Alt-B>" = "rl-backward-word"; + "<Alt-Backspace>" = "rl-backward-kill-word"; + "<Alt-D>" = "rl-kill-word"; + "<Alt-F>" = "rl-forward-word"; + "<Ctrl-?>" = "rl-delete-char"; + "<Ctrl-A>" = "rl-beginning-of-line"; + "<Ctrl-B>" = "rl-backward-char"; + "<Ctrl-C>" = "completion-item-yank"; + "<Ctrl-D>" = "completion-item-del"; + "<Ctrl-E>" = "rl-end-of-line"; + "<Ctrl-F>" = "rl-forward-char"; + "<Ctrl-H>" = "rl-backward-delete-char"; + "<Ctrl-K>" = "rl-kill-line"; + "<Ctrl-N>" = "command-history-next"; + "<Ctrl-P>" = "command-history-prev"; + "<Ctrl-Return>" = "command-accept --rapid"; + "<Ctrl-Shift-C>" = "completion-item-yank --sel"; + "<Ctrl-Shift-Tab>" = "completion-item-focus prev-category"; + "<Ctrl-Shift-W>" = "rl-filename-rubout"; + "<Ctrl-Tab>" = "completion-item-focus next-category"; + "<Ctrl-U>" = "rl-unix-line-discard"; + "<Ctrl-W>" = "rl-rubout \" \""; + "<Ctrl-Y>" = "rl-yank"; + "<Down>" = "completion-item-focus --history next"; + "<Escape>" = "mode-leave"; + "<PgDown>" = "completion-item-focus next-page"; + "<PgUp>" = "completion-item-focus prev-page"; + "<Return>" = "command-accept"; + "<Shift-Delete>" = "completion-item-del"; + "<Shift-Tab>" = "completion-item-focus prev"; + "<Tab>" = "completion-item-focus next"; + "<Up>" = "completion-item-focus --history prev"; + }; + + hint = { + "<Ctrl-B>" = "hint all tab-bg"; + "<Ctrl-F>" = "hint links"; + "<Ctrl-R>" = "hint --rapid links tab-bg"; + "<Escape>" = "mode-leave"; + "<Return>" = "hint-follow"; + }; + + insert = { + "<Ctrl-E>" = "edit-text"; + "<Escape>" = "mode-leave"; + "<Shift-Escape>" = "fake-key <Escape>"; + "<Shift-Ins>" = "insert-text -- {primary}"; + "<Ctrl-k>" = "spawn --userscript qute-keepassxc --key ${lib.escapeShellArg cfg.key}"; + }; + + normal = { + # a + # b + # c + # d -> download management + # e -> [e]merge tab + # f -> `hint all` + # g -> tabs [g]oing + # h -> `back` + # i -> `mode-enter insert` + # j -> inputs + # k + # l -> `search-next` + # m -> in page movement + # n -> `scroll up` + # o + # p + # q -> `macro-record` + # r + # s -> `forward` + # t -> `scroll down` + # u -> `undo` + # v -> `mode-enter caret` + # w -> theme switching + # x -> hinting + # y -> yanking + # z + + # Theme switching + wd = "set --temp colors.webpage.darkmode.enabled true"; + wl = "set --temp colors.webpage.darkmode.enabled false"; + + # Tab [g]oing + "g$" = "tab-focus -1"; + g0 = "tab-focus 1"; + gh = "home"; + gH = "history"; + gs = "cmd-set-text --space :open"; + gP = "open -- {primary}"; + gp = "open -- {clipboard}"; + go = "cmd-set-text :open {url:pretty}"; + gt = "cmd-set-text --space :tab-select"; + # TODO(@bpeetz): Make this to a lf tab listing. <2025-05-31> + "\\f" = "cmd-set-text --space --relative :tab-focus"; + + eP = "open --tab -- {primary}"; + ep = "open --tab -- {clipboard}"; + ea = "open --tab"; + es = "cmd-set-text --space :open --tab"; + eo = "cmd-set-text :open --tab --related {url:pretty}"; + eh = "back --tab"; + en = "forward --tab"; + ec = "tab-clone"; + em = "tab-move"; + ed = "tab-close"; + eR = "reload --force"; + er = "reload"; + + # Download management + dm = "download"; + dc = "download-cancel"; + dp = "download-clear"; + do = "download-open"; + dr = "download-retry"; + + # In page hierarchy [m]ovement + mi = "navigate increment"; + md = "navigate increment"; + mp = "navigate prev"; + mn = "navigate next"; + mu = "navigate up"; + mh = "navigate strip"; + + # Page movement + H = "scroll left"; + t = "scroll down"; + n = "scroll up"; + S = "scroll right"; + h = "back"; + T = "tab-prev"; + N = "tab-next"; + s = "forward"; + G = "scroll-to-perc"; + gg = "scroll-to-perc 0"; + + l = "search-next"; + L = "search-prev"; + + "+" = "zoom-in"; + "-" = "zoom-out"; + "=" = "zoom"; + + "." = "cmd-repeat-last"; + "/" = "cmd-set-text /"; + "?" = "cmd-set-text ?"; + ":" = "cmd-set-text :"; + + # Hinting + xI = "hint images tab"; + xi = "hint images"; + xO = "hint links fill :open --tab --related {hint-url}"; + xo = "hint links fill :open {hint-url}"; + xY = "hint links yank-primary"; + xy = "hint links yank"; + xb = "hint all tab-bg"; + xf = "hint all tab-fg"; + xd = "hint links download"; + xh = "hint all hover"; + xr = "hint --rapid links tab-bg"; + xt = "hint inputs"; + f = "hint all"; + + # Inputs + jf = "hint inputs --first"; + jk = "spawn --userscript qute-keepassxc --key ${lib.escapeShellArg cfg.key}"; + + # Yanking + yD = "yank domain --sel"; + yM = "yank inline [{title}]({url:yank}) --sel"; + yP = "yank pretty-url --sel"; + yT = "yank title --sel"; + yY = "yank --sel"; + yd = "yank domain"; + ym = "yank inline [{title}]({url:yank})"; + yp = "yank pretty-url"; + yt = "yank title"; + yy = "yank"; + + "<Escape>" = "clear-keychain ;; search ;; fullscreen --leave ;; clear-messages"; + "<Shift-Space>" = "scroll-page 0 -1"; + "<Space>" = "scroll-page 0 1"; + "<Ctrl-Return>" = "selection-follow --tab"; + "<Return>" = "selection-follow"; + "<back>" = "back"; + "<forward>" = "forward"; + + i = "mode-enter insert"; + "'" = "mode-enter jump_mark"; + "`" = "mode-enter set_mark"; + v = "mode-enter caret"; + V = "mode-enter caret ;; selection-toggle --line"; + "<Ctrl-V>" = "mode-enter passthrough"; + + q = "macro-record"; + "@" = "macro-run"; + u = "undo"; + U = "undo --window"; + }; + + passthrough = { + "<Shift-Escape>" = "mode-leave"; + }; + + prompt = { + "<Alt-B>" = "rl-backward-word"; + "<Alt-Backspace>" = "rl-backward-kill-word"; + "<Alt-D>" = "rl-kill-word"; + "<Alt-E>" = "prompt-fileselect-external"; + "<Alt-F>" = "rl-forward-word"; + "<Alt-Shift-Y>" = "prompt-yank --sel"; + "<Alt-Y>" = "prompt-yank"; + "<Ctrl-?>" = "rl-delete-char"; + "<Ctrl-A>" = "rl-beginning-of-line"; + "<Ctrl-B>" = "rl-backward-char"; + "<Ctrl-E>" = "rl-end-of-line"; + "<Ctrl-F>" = "rl-forward-char"; + "<Ctrl-H>" = "rl-backward-delete-char"; + "<Ctrl-K>" = "rl-kill-line"; + "<Ctrl-P>" = "prompt-open-download --pdfjs"; + "<Ctrl-Shift-W>" = "rl-filename-rubout"; + "<Ctrl-U>" = "rl-unix-line-discard"; + "<Ctrl-W>" = "rl-rubout \" \""; + "<Ctrl-X>" = "prompt-open-download"; + "<Ctrl-Y>" = "rl-yank"; + "<Down>" = "prompt-item-focus next"; + "<Escape>" = "mode-leave"; + "<Return>" = "prompt-accept"; + "<Shift-Tab>" = "prompt-item-focus prev"; + "<Tab>" = "prompt-item-focus next"; + "<Up>" = "prompt-item-focus prev"; + }; + + register = { + "<Escape>" = "mode-leave"; + }; + + yesno = { + "<Alt-Shift-Y>" = "prompt-yank --sel"; + "<Alt-Y>" = "prompt-yank"; + "<Escape>" = "mode-leave"; + "<Return>" = "prompt-accept"; + N = "prompt-accept --save no"; + Y = "prompt-accept --save yes"; + n = "prompt-accept no"; + y = "prompt-accept yes"; + }; +} diff --git a/modules/by-name/ri/river/init_base.sh b/modules/by-name/ri/river/init_base.sh index b92f59e0..edd7827f 100755 --- a/modules/by-name/ri/river/init_base.sh +++ b/modules/by-name/ri/river/init_base.sh @@ -10,8 +10,9 @@ # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -# NOTE: Keep this in sync with the file from `river-start` <2025-02-03> -RIVER_LOG_FILE="$HOME/.local/share/river/log" +RIVER_LOG_FILE="$HOME/.cache/river/init-log" + +echo >"$RIVER_LOG_FILE" err_fail() { if ! "$@"; then diff --git a/modules/by-name/ri/river/keymap.nix b/modules/by-name/ri/river/keymap.nix new file mode 100644 index 00000000..fd911f69 --- /dev/null +++ b/modules/by-name/ri/river/keymap.nix @@ -0,0 +1,150 @@ +{ + lib, + pkgs, + libraries, + config, + ... +}: let + index2tag = input: builtins.toString (libraries.base.pow 2 (input - 1)); + + mkTagCommand = name: index: [name (index2tag index)]; + mkSpawn' = pkg: binaryName: args: further: (further + // (let + maybeSpace = + if args == "" + then "" + else " "; + in { + command = [ + "spawn" + "${lib.getExe' pkg binaryName}${maybeSpace}${args}" + ]; + + description = "${binaryName}${maybeSpace}${args}"; + })); + + mkSpawn = pkg: args: further: (mkSpawn' pkg pkg.meta.mainProgram args further); + + cfg = config.soispha.programs.river; +in { + soispha.programs.river.init.mappings.keymap = lib.mkIf cfg.enable (lib.fixedPoints.fix + (self: { + "<LEFT_SUPER>" = { + # Change focus + "f" = { + "t" = ["focus-view" "next"]; + "n" = ["focus-view" "previous"]; + "T" = ["focus-output" "next"]; + "N" = ["focus-output" "previous"]; + }; + + # Spawn standard programs + "r" = { + "a" = mkSpawn pkgs.alacritty "" {}; + "b" = mkSpawn pkgs.tskm "open select" {once = true;}; + "k" = mkSpawn pkgs.keepassxc "" {once = true;}; + "s" = mkSpawn pkgs.signal-desktop "" {once = true;}; + "p" = mkSpawn pkgs.screenshot_persistent "" {once = true;}; + }; + + # Client changes + "c" = { + "f" = ["toggle-fullscreen"]; + "c" = ["close"]; + " " = ["toggle-float"]; + "<ENTER>" = ["zoom"]; + "o" = ["send-to-output" "next"]; + "t" = ["swap" "next"]; + "n" = ["swap" "previous"]; + }; + + # This is a fill in for <Super-L>, as that is otherwise nearly impossible to input. + "l" = self."<LEFT_SUPER>".x.l; + + # River compositor control. + "x" = { + "q" = ["exit"]; + "l" = mkSpawn pkgs.lock "" {once = true;}; + }; + + # Media control + "m" = { + "r" = mkSpawn' pkgs.wireplumber "wpctl" "set-volume @DEFAULT_SINK@ 5%+" {}; + "l" = mkSpawn' pkgs.wireplumber "wpctl" "set-volume @DEFAULT_SINK@ 5%-" {}; + "m" = mkSpawn pkgs.mpp "toggle" {}; + }; + + # Select tags to view. + "v" = { + "0" = ["set-view-tags" (builtins.toString ((libraries.base.pow 2 32) - 1))]; + "p" = ["send-to-previous-tags"]; + + "1" = mkTagCommand "set-view-tags" 1; + "2" = mkTagCommand "set-view-tags" 2; + "3" = mkTagCommand "set-view-tags" 3; + "4" = mkTagCommand "set-view-tags" 4; + "5" = mkTagCommand "set-view-tags" 5; + "6" = mkTagCommand "set-view-tags" 6; + "7" = mkTagCommand "set-view-tags" 7; + "8" = mkTagCommand "set-view-tags" 8; + "9" = mkTagCommand "set-view-tags" 9; + + # Add tags to view. + "a" = { + "1" = mkTagCommand "toggle-view-tags" 1; + "2" = mkTagCommand "toggle-view-tags" 2; + "3" = mkTagCommand "toggle-view-tags" 3; + "4" = mkTagCommand "toggle-view-tags" 4; + "5" = mkTagCommand "toggle-view-tags" 5; + "6" = mkTagCommand "toggle-view-tags" 6; + "7" = mkTagCommand "toggle-view-tags" 7; + "8" = mkTagCommand "toggle-view-tags" 8; + "9" = mkTagCommand "toggle-view-tags" 9; + }; + }; + + # Select tags to focus. + "f" = { + "0" = ["set-focused-tags" (builtins.toString ((libraries.base.pow 2 32) - 1))]; + "p" = ["focus-previous-tags"]; + + "1" = mkTagCommand "set-focused-tags" 1; + "2" = mkTagCommand "set-focused-tags" 2; + "3" = mkTagCommand "set-focused-tags" 3; + "4" = mkTagCommand "set-focused-tags" 4; + "5" = mkTagCommand "set-focused-tags" 5; + "6" = mkTagCommand "set-focused-tags" 6; + "7" = mkTagCommand "set-focused-tags" 7; + "8" = mkTagCommand "set-focused-tags" 8; + "9" = mkTagCommand "set-focused-tags" 9; + }; + }; + + # Screen locking + "<Super-l>" = self."<LEFT_SUPER>".x.l; + + # Audio + "<MEDIA_RAISEVOLUME>" = + self."<LEFT_SUPER>".m.r + // { + allow_locked = true; + }; + "<MEDIA_LOWERVOLUME>" = + self."<LEFT_SUPER>".m.l + // { + allow_locked = true; + }; + "<MEDIA_MUTEVOLUME>" = + self."<LEFT_SUPER>".m.m + // { + allow_locked = true; + }; + + # Mouse + "<Meta-<MOUSE_LEFT>>" = ["move-view"]; + "<Meta-<MOUSE_RIGHT>>" = ["resize-view"]; + + # Screenshot + "<PRINTSCREEN>" = self."<LEFT_SUPER>".r.p; + })); +} diff --git a/modules/by-name/ri/river/module.nix b/modules/by-name/ri/river/module.nix index 33c8a713..8be77777 100644 --- a/modules/by-name/ri/river/module.nix +++ b/modules/by-name/ri/river/module.nix @@ -36,10 +36,22 @@ longRunningPrograms = builtins.concatStringsSep "\n" (builtins.map mkLrProgram cfg.init.backgroundStart); keymapFormat = pkgs.formats.json {}; + keymapGenerate = name: value: + pkgs.runCommandLocal "mk-${name}-and-check" { + nativeBuildInputs = [pkgs.river-mk-keymap]; + preferLocalBuild = true; + + env = { + JSON_FILE = keymapFormat.generate name value; + }; + } '' + river-mk-keymap --keymap "$JSON_FILE" init --dry-run; + cp "$JSON_FILE" "$out" + ''; keymappings = '' err_fail ${riverctl} keyboard-layout ${esa cfg.init.mappings.layout} - err_fail ${lib.getExe pkgs.river-mk-keymap} ${keymapFormat.generate "keys.json" cfg.init.mappings.keymap} + err_fail ${lib.getExe pkgs.river-mk-keymap} --keymap ${keymapGenerate "keys.json" cfg.init.mappings.keymap} init ''; mkRule = { @@ -175,6 +187,10 @@ in { }; }; + imports = [ + ./keymap.nix + ]; + config = lib.mkIf cfg.enable { services.udev.packages = lib.mkIf cfg.unicodeInput.enable [externalBinaries.qmk_firmware.packages.${system}.qmk_unicode_type]; @@ -193,7 +209,7 @@ in { }; home.packages = [ - pkgs.river-start + (pkgs.callPackage ./river-start/package.nix {}) ]; xdg.configFile."river/init" = { diff --git a/pkgs/by-name/ri/river-start/package.nix b/modules/by-name/ri/river/river-start/package.nix index 10957cc0..10957cc0 100644 --- a/pkgs/by-name/ri/river-start/package.nix +++ b/modules/by-name/ri/river/river-start/package.nix diff --git a/pkgs/by-name/ri/river-start/river-start.sh b/modules/by-name/ri/river/river-start/river-start.sh index e3a4adcb..55eddfcf 100755 --- a/pkgs/by-name/ri/river-start/river-start.sh +++ b/modules/by-name/ri/river/river-start/river-start.sh @@ -10,8 +10,7 @@ # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -# NOTE: Keep this in sync with the file from `base_init.sh` <2025-02-03> -RIVER_LOG_FILE="$HOME/.local/share/river/log" +RIVER_LOG_FILE="$HOME/.cache/river/wm-log" [ -d "$(dirname "$RIVER_LOG_FILE")" ] || mkdir --parents "$(dirname "$RIVER_LOG_FILE")" diff --git a/modules/by-name/ts/tskm/module.nix b/modules/by-name/ts/tskm/module.nix index 9bf2b389..6f6517f8 100644 --- a/modules/by-name/ts/tskm/module.nix +++ b/modules/by-name/ts/tskm/module.nix @@ -23,13 +23,13 @@ in [name] ++ subprojects; - firefoxProfiles = builtins.listToAttrs (lib.imap0 (index: name: - lib.attrsets.nameValuePair name { + qutebrowserProfiles = builtins.listToAttrs ( + builtins.map (name: { inherit name; - # Add one here, so that we can have the default profile at id 0. - id = index + 1; + value = {}; }) - allProjectNames); + allProjectNames + ); contexts = builtins.concatStringsSep "\n" @@ -99,7 +99,8 @@ in { config = lib.mkIf cfg.enable { soispha.programs = { - firefox.profiles = firefoxProfiles; + qutebrowser.profiles = qutebrowserProfiles; + taskwarrior = { includeFiles = { tskm-contexts = contextsFile; diff --git a/modules/by-name/xd/xdg/module.nix b/modules/by-name/xd/xdg/module.nix index 94c5a975..496ed129 100644 --- a/modules/by-name/xd/xdg/module.nix +++ b/modules/by-name/xd/xdg/module.nix @@ -26,7 +26,9 @@ name = "url-handler"; runtimeInputs = [pkgs.rofi pkgs.libnotify pkgs.zathura pkgs.tskm]; - inheritPath = false; + + # We need to run the browser in tskm or nvim and alacritty. + inheritPath = true; text = builtins.readFile ./scripts/url-handler.sh; }; diff --git a/modules/by-name/zs/zsh/config/command_not_found/command_not_found_insult.sh b/modules/by-name/zs/zsh/config/command_not_found/command_not_found_insult.sh deleted file mode 100644 index a5d71939..00000000 --- a/modules/by-name/zs/zsh/config/command_not_found/command_not_found_insult.sh +++ /dev/null @@ -1,309 +0,0 @@ -#! /usr/bin/env bash - -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -print_message() { - - local messages - local message - - ### STANDARD INSULTS ### - declare -a _array1=( - "(╯°□°)╯︵ ┻━┻" - "¯\_(ツ)_/¯" - "ACHTUNG! ALLES TURISTEN UND NONTEKNISCHEN LOOKENPEEPERS! DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN. IST NICHT FÜR GEWERKEN BEI DUMMKOPFEN. DER RUBBERNECKEN SIGHTSEEREN KEEPEN DAS COTTONPICKEN HÄNDER IN DAS POCKETS MUSS. ZO RELAXEN UND WATSCHEN DER BLINKENLICHTEN." - "And the Darwin Award goes to.... ${USER}!" - "Allowing you to survive childbirth was medical malpractice." - "Are you always this stupid or are you making a special effort today?!" - "Are you even trying?!" - "Bad." - "Boooo!" - "Brains aren't everything. In your case they're nothing." - "Commands, random gibberish, who cares!" - "Come on! You can do it!" - "Don't you have anything better to do?!" - "Don't you know anything?" - "Dropped on your head as a baby, eh?" - "error code: 1D10T" - "Even your mom loves you only as a friend." - "ERROR_INCOMPETENT_USER" - "Fake it till you make it!" - "Go outside." - "Haha, n00b!" - "How many times do I have to flush before you go away?" - "I am _seriously_ considering 'rm -rf /'-ing myself..." - "I don't know what makes you so stupid, but it really works." - "I was going to give you a nasty look, but I see you already have one." - "If beauty fades then you have nothing to worry about." - "If brains were gasoline you wouldn’t have enough to propel a flea’s motorcycle around a doughnut." - "If ignorance is bliss, you must be the happiest person on earth." - "If shit was music, you'd be an orchestra." - "If what you don't know can't hurt you, you're invulnerable." - "Incompetence is also a form of competence" - "I’d slap you, but that’d be animal abuse." - "I’ve heard of being hit with the ugly stick, but you must have been beaten senseless with it." - "Keep trying, someday you'll do something intelligent!" - "Let’s play horse. I’ll be the front end. And you be yourself." - "Life is good, you should get one." - "lol" - "lol... plz" - "My keyboard is not a touch screen!" - "My uptime is longer than your relationships." - "Nice try." - "n00b alert!" - "Pathetic" - "Perhaps computers are not for you..." - "Perhaps you should leave the command line alone..." - "Please step away from the keyboard!" - "plz uninstall" - "Pro tip: type a valid command!" - "Rose are red. Violets are blue. I have five fingers. The middle one's for you." - "RTFM!" - "Sorry what? I don’t understand idiot language." - "The degree of your stupidity is enough to boil water." - "The worst one today!" - "This is not a search engine." - "This is not Windows" - "This is why nobody likes you." - "This is why you get to see your children only once a month." - "Try using your brain the next time!" - "Two wrongs don't make a right, take your parents as an example." - "Typing incorrect commands, eh?" - "u suk" - "What if... you type an actual command the next time!" - "What if I told you... it is possible to type valid commands." - "What is this...? Amateur hour!?" - "Why are you so stupid?!" - "Why are you doing this to me?!" - "Why did the chicken cross the road? To get the hell away from you." - "Wow! That was impressively wrong!" - "Y u no speak computer???" - "You are not as bad as people say, you are much, much worse." - "You are not useless since you can still be used as a bad example." - "You must have been born on a highway because that's where most accidents happen." - "Your application for reduced salary has been sent!" - "Your mom had a severe case of diarrhea when you were born." - "You're proof that god has a sense of humor." - "You’re so dumb your first words were DUH." - "You're so fat, people jog around you for exercise." - "You’re the reason Santa says ho, ho, ho, on Christmas!" - ) - ### SHAKESPEARE INSULTS ### - declare -a array2=( - "A most notable coward, an infinite and endless liar, an hourly promise breaker, the owner of no one good quality." - "Away, you starvelling, you elf-skin, you dried neat's-tongue, bull's-pizzle, you stock-fish!" - "Away, you three-inch fool! " - "Come, come, you froward and unable worms!" - "Go, prick thy face, and over-red thy fear, Thou lily-liver’d boy." - "His wit's as thick as a Tewkesbury mustard." - "I am pigeon-liver'd and lack gall." - "I am sick when I do look on thee " - "I must tell you friendly in your ear, sell when you can, you are not for all markets." - "If thou wilt needs marry, marry a fool; for wise men know well enough what monsters you make of them." - "I'll beat thee, but I would infect my hands." - "I scorn you, scurvy companion. " - "Methink'st thou art a general offence and every man should beat thee." - "More of your conversation would infect my brain." - "My wife's a hobby horse!" - "Peace, ye fat guts!" - "Poisonous bunch-backed toad! " - "The rankest compound of villainous smell that ever offended nostril" - "The tartness of his face sours ripe grapes." - "There's no more faith in thee than in a stewed prune." - "Thine forward voice, now, is to speak well of thine friend; thine backward voice is to utter foul speeches and to detract." - "That trunk of humours, that bolting-hutch of beastliness, that swollen parcel of dropsies, that huge bombard of sack, that stuffed cloak-bag of guts, that roasted Manningtree ox with pudding in his belly, that reverend vice, that grey Iniquity, that father ruffian, that vanity in years?" - "Thine face is not worth sunburning." - "This woman's an easy glove, my lord, she goes off and on at pleasure." - "Thou art a boil, a plague sore." - "Was the Duke a flesh-monger, a fool and a coward?" - "Thou art as fat as butter." - "Here is the babe, as loathsome as a toad." - "Like the toad; ugly and venomous." - "Thou art unfit for any place but hell." - "Thou cream faced loon" - "Thou clay-brained guts, thou knotty-pated fool, thou whoreson obscene greasy tallow-catch!" - "Thou damned and luxurious mountain goat." - "Thou elvish-mark'd, abortive, rooting hog!" - "Thou leathern-jerkin, crystal-button, knot-pated, agatering, puke-stocking, caddis-garter, smooth-tongue, Spanish pouch!" - "Thou lump of foul deformity" - "That poisonous bunch-back'd toad!" - "Thou sodden-witted lord! Thou hast no more brain than I have in mine elbows " - "Thou subtle, perjur'd, false, disloyal man!" - "Thou whoreson zed , thou unnecessary letter!" - "Thy sin’s not accidental, but a trade." - "Thy tongue outvenoms all the worms of Nile." - "Would thou wert clean enough to spit upon" - "Would thou wouldst burst!" - "You poor, base, rascally, cheating lack-linen mate! " - "You are as a candle, the better burnt out." - "You scullion! You rampallian! You fustilarian! I’ll tickle your catastrophe!" - "You starvelling, you eel-skin, you dried neat's-tongue, you bull's-pizzle, you stock-fish-O for breath to utter what is like thee!-you tailor's-yard, you sheath, you bow-case, you vile standing tuck!" - "Your brain is as dry as the remainder biscuit after voyage." - "Virginity breeds mites, much like a cheese." - "Villain, I have done thy mother" - ) - ### MARTIN LUTHER INSULTS ### - declare -a array3=( - "You live like simple cattle or irrational pigs and, despite the fact that the gospel has returned, have mastered the fine art of misusing all your freedom." - "You shameful gluttons and servants of your bellies are better suited to be swineherds and keepers of dogs." - "You deserve not only to be given no food to eat, but also to have the dogs set upon you and to be pelted with horse manure." - "Oh, what mad senseless fools you are!" - "For this you deserve to have God deprive you of his Word and blessing and once again allow preachers of lies to arise who lead you to the devil - and wring sweat and blood out of you besides." - "All your holiness is only stench and filth, and it merits nothing but wrath and damnation." - "May your grain spoil in the barn, your beer in the cellar, your cattle perish in the stall. Yes, your entire hoard ought to be consumed by rust so that you will never enjoy it." - "You relish and delight in the chance to stir up someone else's dirt like pigs that roll in manure and root around in it with their snouts." - "Your sin smells to high heaven." - "Your words are so foolishly and ignorantly composed that I cannot believe you understand them." - "You are the most insane heretics and ingrafters of heretical perversity." - "What you say is a blasphemy that has made you worthy of a thousand deaths." - "Behold, indeed, this little golden work of a golden teacher! It is a work most worthy of golden letters, and lest there be something about it which is not golden, it must be handed down by golden disciples, namely, by those about whom it is said, 'The idols of the nations are silver and gold. They have eyes, but they see not.'" - "You are worthy only to be mocked by the words of error." - "It is presumptuous for people who are as ignorant as you are not to take up the work of a herdsman." - "What bilgewater of heresies has ever been spoken so heretically as what you have said?" - "What do you mean when you say this? Are you dreaming in the throes of a fever or are you laboring under a madness?" - "Your astute minds have been completely turned into stinking mushrooms." - "You are the prostitute of heretics!" - "I am tired of the pestilent voice of your sirens." - "You are a bungling magpie, croaking loudly." - "You forgot to purge yourself with hellabore while you were preparing to fabricate this lie." - "You are more corrupt than any Babylon or Sodom ever was, and, as far as I can see, are characterized by a completely depraved, hopeless, and notorious godlessness." - "Your home, once the holiest of all, has become the most licentious den of thieves, the most shameless of all brothels, the kingdom of sin, death, and hell. It is so bad that even Antichrist himself, if he should come, could think of nothing to add to its wickedness." - "What devilish unchristian thing would you not undertake?" - "You are an extraordinary creature, being neither God nor man. Perhaps you are the devil himself." - "Even if the Antichrist appears, what greater evil can he do than what you have done and do daily?" - "It may be that you want to build yourself a heaven of your own, like those jugglers build themselves out of linen cloth at the Shrove Tuesday carnival. Is it not disgusting that we have to hear such foolish and childish things from you?" - "In our country, fruit grows on trees and from trees, and meditation upon sin grows from contrition. But in your land, trees may grow on fruits, contrition from sins, people walk on their ears, and everything is upside down." - "O you wolf in Christendom!" - "You know less than does a log on the ground." - "I think that all the devils have at once entered into you." - "You are worse than all the devils. What you have done, no devil has ever done. Your end is near, you son of perdition and Antichrist! Stop now, you are going to far!" - "You are the true, chief, and final Antichrist." - "How far will you go, O devilish pride?" - "All Christians should be on guard against your antichristian poison." - "I think you received these ideas in your pipe dreams." - "You are in all you do the very opposite of Christ as befits a true Antichrist." - "You are a person of sin and the child of perdition, leading all the world with you to the devil, using your lying and deceitful ways." - "You are not a pious fraud, but an infernal, diabolical, antichristian fraud." - "You are the Roman Nimrod and a teacher of sin." - "It is the old dragon from the abyss of hell who is standing before me!" - "You hold fast to human dreams and the doctrines of devils." - "If you who are assembled in a council are so frivolous and irresponsible as to waste time and money on unnecessary questions, when it is the business of a council to deal only with the important and necessary matters, we should not only refuse to obey you, but consider you insane or criminals." - "Even Lucifer was not guilty of so great a sacrilege in heaven, for he only presumed to be God's equal. God help us!" - "You condemned the holy gospel and replaced it with the teaching of the dragon from hell." - "Your words are un-Christian, antichristian, and spoken by the inspiration of the evil spirit." - "What happened to the house built on sand in Matthew 7 will also happen to you." - "Must we believe your nightmares?" - "Look how this great heretic speaks brazenly and sacrilegiously." - "You run against God with the horns of your pride up in the air and thus plunge into the abyss of hell. Woe unto you, Antichrist!" - "You are the devil's most dangerous tool!" - "It seems I must have liars and villains for opponents. I am not worthy in the sight of God that a godly and honorable person should discuss these matters with me in a Christian way. This is my greatest lament." - "May the Lord Jesus protect me and all devout souls from your contagion and your company!" - "This venom - the mere smell of which kills a man!" - "You are a Baal-zebub - that is, a man of flies." - "You are full of poisonous refuse and insane foolishness." - "You are ignorant, stupid, godless blasphemers." - "You moderate enforcer and eulogizer of moderation. You are one of those bloody and deceitful people who affect modesty in words and appearance, but who meanwhile breathe out threats and blood." - "We leave you to your own devices, for nothing properly suits you except hypocrisy, flattery, and lies." - "In lying fashion you ignore what even children know." - "The reward of such flattery is what your crass stupidity deserves. Therefore, we shall turn from you, a sevenfold stupid and blasphemous wise person." - "People of your sort are hirelings, dumb dogs unable to bark, who see the wolf coming and flee or, rather, join up with the wolf." - "You are a wolf and apostle of Satan." - "You are the ultimate scourges of the world, the Antichrist together with your sophists and bishops." - "You cowardly slave, you corrupt sycophant, with your sickening advice!" - "You are idiots and swine." - "Every letter of yours breathes Moabitish pride. So much can a single bull inflate a single bubble that you practically make distinguished asses into gods." - "You sophistic worms, grasshoppers, locusts, frogs and lice!" - 'You completely close your mind and do nothing but shout, "Anathema, anathema, anathema!" so that by your own voice you are judged mad.' - "Let this generation of vipers prepare itself for unquenchable fire!" - "You rush forward as an ass under the pelt of a lion." - "In appearance and words you simulate modesty, but you are so swollen with haughtiness, arrogance, pride, malice, villainy, rashness, superciliousness, ignorance, and stupidity that there is nothing to surpass you." - "Blind moles!" - "We despise your whorish impudence." - ) - ### EDIT THIS LINE IF YOU ONLY WANT TO USE CERTAIN INSULT LISTS ### - messages=( - # "${array1[@]}" ## normal ones - "${array2[@]}" ## Shakespeare - "${array3[@]}" ## Luther - ) - - # If CMD_NOT_FOUND_MSGS array is populated use those messages instead of the defaults - [[ -n ${CMD_NOT_FOUND_MSGS} ]] && messages=("${CMD_NOT_FOUND_MSGS[@]}") - - # If CMD_NOT_FOUND_MSGS_APPEND array is populated append those to the existing messages - [[ -n ${CMD_NOT_FOUND_MSGS_APPEND} ]] && messages+=("${CMD_NOT_FOUND_MSGS_APPEND[@]}") - - # Seed RANDOM with an integer of some length - RANDOM=$(od -vAn -N4 -tu </dev/urandom) - - # Print a randomly selected message, but only about half the time to annoy the user a - # little bit less. - if [[ $((RANDOM % 2)) -lt 1 ]]; then - message=${messages[RANDOM % ${#messages[@]}]} - printf "\n %s%s%s\n\n" "$(tput bold)$(tput setaf 1)" "$message" "$(tput sgr0)" >&2 - fi -} - -function_exists() { - # Zsh returns 0 even on non existing functions with -F so use -f - declare -f "$1" >/dev/null - return $? -} - -# -# The idea below is to copy any existing handlers to another function -# name and insert the message in front of the old handler in the -# new handler. By default, neither bash or zsh has has a handler function -# defined, so the default behaviour is replicated. -# -# Also, ensure the handler is only copied once. If we do not ensure this -# the handler would add itself recursively if this file happens to be -# sourced multiple times in the same shell, resulting in a neverending -# stream of messages. -# - -# -# Zsh -# -if function_exists command_not_found_handler; then - if ! function_exists orig_command_not_found_handler; then - eval "orig_$(declare -f command_not_found_handler)" - fi -else - orig_command_not_found_handler() { - printf "zsh: command not found: %s\n" "$1" >&2 - return 127 - } -fi - -command_not_found_handler() { - print_message - orig_command_not_found_handler "$@" -} - -# -# Bash -# -if function_exists command_not_found_handle; then - if ! function_exists orig_command_not_found_handle; then - eval "orig_$(declare -f command_not_found_handle)" - fi -else - orig_command_not_found_handle() { - printf "%s: %s: command not found\n" "$0" "$1" >&2 - return 127 - } -fi - -command_not_found_handle() { - print_message - orig_command_not_found_handle "$@" -} diff --git a/modules/by-name/zs/zsh/module.nix b/modules/by-name/zs/zsh/module.nix index 038048da..644854a2 100644 --- a/modules/by-name/zs/zsh/module.nix +++ b/modules/by-name/zs/zsh/module.nix @@ -10,8 +10,6 @@ { config, lib, - system, - pkgs, ... }: let cfg = config.soispha.programs.zsh; @@ -111,10 +109,7 @@ in { + sourceFile ./plugins/zsh-history-substring-search.zsh ); end = lib.modules.mkAfter ( - # NOTE(@bpeetz): Put this here, so that command handler in `extraFiles` - # are not overriding this. <2025-05-16> - sourceFile ./config/command_not_found/command_not_found_insult.sh - + sourceFile ./config/keymaps_start.zsh + sourceFile ./config/keymaps_start.zsh + sourceFile ./config/keymaps/command.zsh + sourceFile ./config/keymaps/emacs.zsh + sourceFile ./config/keymaps/isearch.zsh @@ -138,11 +133,6 @@ in { HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND = "bg=cyan,fg=white"; HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND = "fg=red,underline,standout,bold"; }; - - shellAliases = { - ll = ". ${lib.getExe pkgs.ll}"; - lm = ". ${lib.getExe pkgs.lm}"; - }; }; }; }; diff --git a/modules/common/default.nix b/modules/common/default.nix index 504782f3..a272bd52 100644 --- a/modules/common/default.nix +++ b/modules/common/default.nix @@ -24,6 +24,8 @@ externalBinaries, ... }: { + # TODO(@bpeetz): Move this file to default options in their respective modules. <2025-05-31> + soispha = { age.enable = true; boot.enable = true; @@ -168,8 +170,6 @@ "~/.local/share" "~/.local/.Trash-1000" - "~/.mozilla/firefox" - "~/media" "~/school" "~/repos" @@ -178,6 +178,13 @@ }; programs = { + i3bar-river.enable = true; + i3status-rust.enable = true; + + qutebrowser = { + enable = true; + }; + nvim = { enable = true; shell = pkgs.zsh; @@ -228,12 +235,12 @@ title = "*"; action = "ssd"; } - # This remove the focus border around Firefox (which is useful because the Firefox is nearly always in its own tag.) - { - app-id = "firefox"; - title = "*"; - action = "csd"; - } + # # This remove the focus border around Firefox (which is useful because the Firefox is nearly always in its own tag.) + # { + # app-id = "firefox"; + # title = "*"; + # action = "csd"; + # } ]; generalSettings = { # background @@ -256,8 +263,8 @@ pointer-12951-6505-ZSA_Technology_Labs_Moonlander_Mark_I = [["pointer-accel" "0"] ["accel-profile" "none"]]; }; backgroundStart = [ + # TODO(@bpeetz): Move these to systemd units/their own modules <2025-05-18> pkgs.gammastep - pkgs.yambar pkgs.mako ["${lib.getExe pkgs.swaybg}" "--image" "${./abstract-nord.png}"] @@ -266,7 +273,6 @@ ]; }; }; - firefox.enable = true; mpv.enable = true; steam.enable = true; ssh.enable = true; @@ -283,7 +289,7 @@ projects = builtins.fromJSON (builtins.readFile ./projects.json); }; nix-index.enable = true; - yambar.enable = true; + yambar.enable = false; yt.enable = true; zathura.enable = true; zsh.enable = true; diff --git a/modules/common/nixos_shell_configuration.nix b/modules/common/nixos_shell_configuration.nix index bbaa8477..1bec0145 100644 --- a/modules/common/nixos_shell_configuration.nix +++ b/modules/common/nixos_shell_configuration.nix @@ -56,8 +56,6 @@ soispha = { hardware = { enable = false; - enableGraphics = false; - cpuType = "vm"; }; disks.enable = false; diff --git a/modules/common/projects.json b/modules/common/projects.json index 48a10f03..df3b0c60 100644 --- a/modules/common/projects.json +++ b/modules/common/projects.json @@ -1,7 +1,4 @@ { - "3d-printer": { - "prefix": "hardware" - }, "aoc": { "prefix": "programming/advent_of_code" }, @@ -15,19 +12,6 @@ "pc": {} } }, - "camera": { - "prefix": "programming/zig" - }, - "hardware": { - "prefix": "research" - }, - "input": { - "prefix": "research", - "subprojects": { - "dotfiles": {}, - "read-things": {} - } - }, "latex": { "prefix": "programming/latex" }, @@ -36,45 +20,10 @@ "bank": {}, "google": {}, "health": {}, + "job": {}, "sweden": {} } }, - "possible-projects": { - "prefix": "research" - }, - "presentation": { - "prefix": "research" - }, - "school": { - "prefix": "research", - "subprojects": { - "biologie": {}, - "chemie": { - "subprojects": { - "facharbeit": {} - } - }, - "deutsch": {}, - "english": {}, - "extern": { - "subprojects": { - "bwinf": {}, - "dsa": {} - } - }, - "geographie": {}, - "geschichte": {}, - "infomatik": {}, - "klausuren": {}, - "latein": {}, - "mathematik": {}, - "musik": {}, - "philosophie": {}, - "physik": {}, - "sozialkunde": {}, - "sport": {} - } - }, "server": { "prefix": "config", "subprojects": { @@ -86,15 +35,8 @@ "sudo-less": {} } }, - "serverphone": { - "prefix": "programming/rust" - }, "smartphone": { - "prefix": "hardware", - "subprojects": { - "airdrop": {}, - "airplay": {} - } + "prefix": "hardware" }, "system": { "prefix": "config", @@ -121,12 +63,5 @@ "netflix": {}, "youtube": {} } - }, - "trinitrix": { - "prefix": "programming/rust", - "subprojects": { - "documentation": {}, - "testing": {} - } } } diff --git a/modules/default.nix b/modules/default.nix index ef885a21..f83cf683 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -15,7 +15,6 @@ (libraries.extra.mkByName { baseDirectory = ./by-name; fileName = "module.nix"; - finalizeFunction = name: value: value; }); in { imports = files; diff --git a/modules/home.legacy/conf/beets/default.nix b/modules/home.legacy/conf/beets/default.nix index de05ca24..612a5f03 100644 --- a/modules/home.legacy/conf/beets/default.nix +++ b/modules/home.legacy/conf/beets/default.nix @@ -41,9 +41,12 @@ in { color = true; }; - include = [ - "./replace_override.yaml" - ]; + replace = { + "[/]" = "\\"; + "[\\x00-\\x1f]" = ""; + "\\s+$" = ""; + "^\\s+" = ""; + }; import = { # move, instead of copying or linking the files @@ -62,15 +65,11 @@ in { }; paths = let - j = lib.strings.concatStringsSep "/"; + join = lib.strings.concatStringsSep "/"; in { - default = j ["[Default]" "$genre" "$first_artist" "$album ($albumtype)" "$track $title"]; - "albumtype:live" = j ["[Live]" "$genre" "$first_artist" "$album ($albumtype)" "$track $title"]; + "albumtype:live" = join ["[Live, please delete]" "$genre" "$first_artist" "$album ($albumtype)" "$track $title"]; - "albumtype:album" = j ["Music" "$genre" "$first_artist" "$album ($albumtype)" "$track $title"]; - "albumtype::(Single|EP)" = j ["Music" "$genre" "$first_artist_singleton" "$album ($albumtype)" "$track $title"]; - "albumtype:compilation" = j ["Complilations" "$genre" "Various Artists" "$album ($albumtype)" "$track $title"]; - "albumtype:soundtrack" = j ["Soundtracks" "$genre" "$first_artist" "$album" "$track $title"]; + default = "$albumartist/$album%aunique{}/$track $title"; }; inherit plugins; @@ -102,8 +101,6 @@ in { }; }; - xdg.configFile."beets/replace_override.yaml".source = ./replace_override.yaml; - # Use the json formatter instead of the YAML one, as the YAML formatter mangles the # longer python inline strings. # YAML is a superset of JSON. diff --git a/modules/home.legacy/conf/beets/plugins.nix b/modules/home.legacy/conf/beets/plugins.nix index 09eeac5b..a3abb580 100644 --- a/modules/home.legacy/conf/beets/plugins.nix +++ b/modules/home.legacy/conf/beets/plugins.nix @@ -17,9 +17,6 @@ # <2024-08-07> # "scrub" - # Help submitting stuff to music brainz - "mbsubmit" - # Extract things from the music file # "xtractor" @@ -29,12 +26,6 @@ # Check for bad files "badfiles" - # Alows to use inline python for parsing tags - "inline" - - # Support player integration - "play" - # Show tags on files/queries "info" @@ -47,9 +38,6 @@ # Warn, when importing a matching item "ihate" - # Allow fuzzy searching - "fuzzy" - # Filter out duplicates "duplicates" @@ -59,9 +47,6 @@ # Download album art "fetchart" - # Fetches tags from `last.fm` and adds them as genres to imported music - "lastgenre" - # Run commands on events "hook" diff --git a/modules/home.legacy/conf/beets/plugins/default.nix b/modules/home.legacy/conf/beets/plugins/default.nix index 65cd935c..ddba95e0 100644 --- a/modules/home.legacy/conf/beets/plugins/default.nix +++ b/modules/home.legacy/conf/beets/plugins/default.nix @@ -11,13 +11,8 @@ imports = [ ./badfiles ./duplicates - ./fuzzy ./ihate - ./inline - ./lastgenre ./lyrics - ./mbsubmit - ./play ./replaygain ./smartplaylist # ./xtractor diff --git a/modules/home.legacy/conf/beets/plugins/fuzzy/default.nix b/modules/home.legacy/conf/beets/plugins/fuzzy/default.nix deleted file mode 100644 index de37c4e8..00000000 --- a/modules/home.legacy/conf/beets/plugins/fuzzy/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{...}: { - programs.beets.settings.fuzzy = { - # The prefix denoting that a search should be run in fuzzy mode - prefix = "."; - }; -} diff --git a/modules/home.legacy/conf/beets/plugins/inline/default.nix b/modules/home.legacy/conf/beets/plugins/inline/default.nix deleted file mode 100644 index b5655028..00000000 --- a/modules/home.legacy/conf/beets/plugins/inline/default.nix +++ /dev/null @@ -1,51 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{...}: { - programs.beets.settings = { - item_fields = { - # Taken from https://github.com/trapd00r/configs/blob/4f3dada5700846cca6c2869e6fa6b3c795b87b67/beets/config.yaml - first_artist = - /* - python - */ - '' - # import an album to another artists directory, like: - # Tom Jones │1999│ Burning Down the House [Single, CD, FLAC] - # to The Cardigans/+singles/Tom Jones & the Cardigans │1999│ Burning Down the House [Single, CD, FLAC] - # https://github.com/beetbox/beets/discussions/4012#discussioncomment-1021414 - # beet import --set myartist='The Cardigans' - # we must first check to see if myartist is defined, that is, given on - # import time, or we raise an NameError exception. - try: - myartist - except NameError: - import re - return re.split(',|\\s+(feat(.?|uring)|&|(Vs|Ft).)', albumartist, 1, flags=re.IGNORECASE)[0] - else: - return myartist - ''; - - first_artist_singleton = - /* - python - */ - '' - try: - myartist - except NameError: - import re - return re.split(',|\\s+(feat(.?|uring)|&|(Vs|Ft).)', artist, 1, flags=re.IGNORECASE)[0] - else: - return myartist - ''; - }; - album_fields = {}; - }; -} diff --git a/modules/home.legacy/conf/beets/plugins/lastgenre/default.nix b/modules/home.legacy/conf/beets/plugins/lastgenre/default.nix deleted file mode 100644 index 4d3dcfb0..00000000 --- a/modules/home.legacy/conf/beets/plugins/lastgenre/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{...}: { - programs.beets.settings.lastgenre = { - prefer_specific = false; - # Lookup the track, not the album - source = "track"; - }; -} diff --git a/modules/home.legacy/conf/beets/plugins/mbsubmit/default.nix b/modules/home.legacy/conf/beets/plugins/mbsubmit/default.nix index bdcb3721..e69de29b 100644 --- a/modules/home.legacy/conf/beets/plugins/mbsubmit/default.nix +++ b/modules/home.legacy/conf/beets/plugins/mbsubmit/default.nix @@ -1,18 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - lib, - pkgs, - ... -}: { - programs.beets.settings.mbsubmit = { - picard_path = lib.getExe pkgs.picard; - }; -} diff --git a/modules/home.legacy/conf/beets/plugins/play/default.nix b/modules/home.legacy/conf/beets/plugins/play/default.nix deleted file mode 100644 index 9d26f16a..00000000 --- a/modules/home.legacy/conf/beets/plugins/play/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - lib, - pkgs, - config, - ... -}: { - programs.beets.settings.play = { - command = "${lib.getExe pkgs.mpc} $args add"; - relative_to = config.services.mpd.musicDirectory; - - # Run the command with the returned paths as arguments - raw = true; - }; -} diff --git a/modules/home.legacy/conf/beets/replace_override.yaml b/modules/home.legacy/conf/beets/replace_override.yaml deleted file mode 100644 index aea5e54a..00000000 --- a/modules/home.legacy/conf/beets/replace_override.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - ---- -replace: - '[\\/]': _ - '^\.': _ - '[\x00-\x1f]': _ - '[<>:"\?\*\|]': _ - '\.$': _ - '\s+$': '' - '^\s+': '' - '^-': _ diff --git a/pkgs/by-name/fu/fupdate/Cargo.lock b/pkgs/by-name/fu/fupdate/Cargo.lock index 018381f3..d2d07c28 100644 --- a/pkgs/by-name/fu/fupdate/Cargo.lock +++ b/pkgs/by-name/fu/fupdate/Cargo.lock @@ -13,9 +13,9 @@ version = 4 [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -28,36 +28,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "once_cell", + "once_cell_polyfill", "windows-sys", ] @@ -69,9 +69,9 @@ checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "clap" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -79,9 +79,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.50" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91d3baa3bcd889d60e6ef28874126a0b384fd225ab83aa6d8a801c519194ce1" +checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677" dependencies = [ "clap", "clap_lex", @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", @@ -115,15 +115,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "fupdate" @@ -156,10 +156,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] -name = "once_cell" -version = "1.21.3" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "proc-macro2" @@ -193,9 +193,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", diff --git a/pkgs/by-name/fu/fupdate/Cargo.toml b/pkgs/by-name/fu/fupdate/Cargo.toml index b0ad1897..3acd3bca 100644 --- a/pkgs/by-name/fu/fupdate/Cargo.toml +++ b/pkgs/by-name/fu/fupdate/Cargo.toml @@ -17,8 +17,8 @@ edition = "2021" [dependencies] anyhow = "1.0.98" -clap = { version = "4.5.38", features = ["derive"] } -clap_complete = { version = "4.5.50", features = ["unstable-dynamic"] } +clap = { version = "4.5.40", features = ["derive"] } +clap_complete = { version = "4.5.54", features = ["unstable-dynamic"] } [profile.release] lto = true diff --git a/pkgs/by-name/fu/fupdate/flake.lock b/pkgs/by-name/fu/fupdate/flake.lock index d9641458..1ebbe915 100644 --- a/pkgs/by-name/fu/fupdate/flake.lock +++ b/pkgs/by-name/fu/fupdate/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1747312588, - "narHash": "sha256-MmJvj6mlWzeRwKGLcwmZpKaOPZ5nJb/6al5CXqJsgjo=", + "lastModified": 1751596331, + "narHash": "sha256-7WSzIrw0nCl8iYroj7c//LLsf2zgNEIJNyUSvx4MPLI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b1bebd0fe266bbd1820019612ead889e96a8fa2d", + "rev": "472908faa934435cf781ae8fac77291af3d137d3", "type": "github" }, "original": { diff --git a/pkgs/by-name/fu/fupdate/src/main.rs b/pkgs/by-name/fu/fupdate/src/main.rs index e664628a..b4af6cd6 100644 --- a/pkgs/by-name/fu/fupdate/src/main.rs +++ b/pkgs/by-name/fu/fupdate/src/main.rs @@ -33,16 +33,12 @@ fn main() -> Result<(), anyhow::Error> { // println!("Running: `fupdate-{command} {}`", args.join(" ")); - let mut child = Command::new(format!("fupdate-{command}")) + let child = Command::new(format!("fupdate-{command}")) .args(args) - .spawn() + .status() .with_context(|| format!("Failed to spawn `fupdate-{command}`"))?; - if !child - .wait() - .with_context(|| format!("Failed to wait for `fupdate-{command}` to finish"))? - .success() - { + if !child.success() { bail!("Command `fupdate-{command} {}` failed!", args.join(" ")); } } @@ -50,7 +46,12 @@ fn main() -> Result<(), anyhow::Error> { Ok(()) } -#[test] -fn verify_cli() { - CliArgs::command().debug_assert(); +#[cfg(test)] +mod test { + use clap::CommandFactory; + + #[test] + fn verify_cli() { + super::CliArgs::command().debug_assert(); + } } diff --git a/pkgs/by-name/ge/generate_moz_extension/.envrc b/pkgs/by-name/ge/generate_moz_extension/.envrc deleted file mode 100644 index 294de504..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/.envrc +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env sh - -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -use flake diff --git a/pkgs/by-name/ge/generate_moz_extension/.gitignore b/pkgs/by-name/ge/generate_moz_extension/.gitignore deleted file mode 100644 index cc03ebd7..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -/target -/result -.direnv diff --git a/pkgs/by-name/ge/generate_moz_extension/Cargo.lock b/pkgs/by-name/ge/generate_moz_extension/Cargo.lock deleted file mode 100644 index 7236ca03..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/Cargo.lock +++ /dev/null @@ -1,1640 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "anyhow" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bitflags" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" - -[[package]] -name = "bumpalo" -version = "3.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "cc" -version = "1.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generate_extensions" -version = "0.1.0" -dependencies = [ - "anyhow", - "futures", - "reqwest", - "serde", - "serde_json", - "tokio", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "h2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" - -[[package]] -name = "http" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "hyper" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "libc", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2549ca8c7241c82f59c80ba2a6f415d931c5b58d24fb8412caa1a1f02c49139a" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8197e866e47b68f8f7d95249e172903bec06004b18b2937f1095d40a0c57de04" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "miniz_oxide" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" -dependencies = [ - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", -] - -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "openssl" -version = "0.10.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "potential_utf" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" -dependencies = [ - "zerovec", -] - -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" - -[[package]] -name = "reqwest" -version = "0.12.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-native-tls", - "tower", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-registry", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustix" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustls" -version = "0.23.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" -dependencies = [ - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "schannel" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" - -[[package]] -name = "socket2" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tempfile" -version = "3.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tokio" -version = "1.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-macros" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" -dependencies = [ - "wit-bindgen-rt", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "windows-link" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" - -[[package]] -name = "windows-registry" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.53.0", -] - -[[package]] -name = "windows-result" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b895b5356fc36103d0f64dd1e94dfa7ac5633f1c9dd6e80fe9ec4adef69e09d" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/pkgs/by-name/ge/generate_moz_extension/Cargo.toml b/pkgs/by-name/ge/generate_moz_extension/Cargo.toml deleted file mode 100644 index 11d08177..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -[package] -name = "generate_extensions" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.97" -futures = "0.3.31" -reqwest = "0.12.15" -serde = { version = "1.0.219", features = ["derive"] } -serde_json = "1.0.140" -tokio = { version = "1.44.2", features = ["macros", "rt-multi-thread"] } diff --git a/pkgs/by-name/ge/generate_moz_extension/examples/generate_extensions.sh b/pkgs/by-name/ge/generate_moz_extension/examples/generate_extensions.sh deleted file mode 100755 index 3e990b6d..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/examples/generate_extensions.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -tmp=$(mktemp) -cat <<EOF | awk '!/^\s*#/' >"$tmp" - darkreader:navbar - keepassxc-browser:navbar - vhack-libredirect:navbar - # torproject-snowflake:navbar - tridactyl-vim:menupanel - ublock-origin:menupanel -EOF - -# The cat execution should be unquoted; -# shellcheck disable=SC2046 -cargo run -- $(cat "$tmp") - -rm "$tmp" diff --git a/pkgs/by-name/ge/generate_moz_extension/flake.lock b/pkgs/by-name/ge/generate_moz_extension/flake.lock deleted file mode 100644 index 441a1232..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/flake.lock +++ /dev/null @@ -1,98 +0,0 @@ -{ - "nodes": { - "crane": { - "locked": { - "lastModified": 1747260204, - "narHash": "sha256-KUb6MFWc2DYeTCmcEkrBrrqhxAgO6NHZh5qQKwsjG6I=", - "owner": "ipetkov", - "repo": "crane", - "rev": "7f85510df37247c86a0c44032f49aa18292ee11f", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1747312588, - "narHash": "sha256-MmJvj6mlWzeRwKGLcwmZpKaOPZ5nJb/6al5CXqJsgjo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b1bebd0fe266bbd1820019612ead889e96a8fa2d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "crane": "crane", - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay" - } - }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1747363019, - "narHash": "sha256-N4dwkRBmpOosa4gfFkFf/LTD8oOcNkAyvZ07JvRDEf0=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "0e624f2b1972a34be1a9b35290ed18ea4b419b6f", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/pkgs/by-name/ge/generate_moz_extension/flake.lock.license b/pkgs/by-name/ge/generate_moz_extension/flake.lock.license deleted file mode 100644 index eae6a84c..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/flake.lock.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/pkgs/by-name/ge/generate_moz_extension/flake.nix b/pkgs/by-name/ge/generate_moz_extension/flake.nix deleted file mode 100644 index a7125642..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/flake.nix +++ /dev/null @@ -1,84 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - description = "A simple way to query the mozialla api for extension data"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - - crane = { - url = "github:ipetkov/crane"; - inputs = { - nixpkgs.follows = "nixpkgs"; - }; - }; - - flake-utils.url = "github:numtide/flake-utils"; - - rust-overlay = { - url = "github:oxalica/rust-overlay"; - inputs = { - nixpkgs.follows = "nixpkgs"; - flake-utils.follows = "flake-utils"; - }; - }; - }; - - outputs = { - self, - nixpkgs, - crane, - flake-utils, - rust-overlay, - ... - }: - flake-utils.lib.eachDefaultSystem (system: let - pkgs = import nixpkgs { - inherit system; - overlays = [(import rust-overlay)]; - }; - - rust-stable = pkgs.rust-bin.stable.latest.default; - rust-minimal = pkgs.rust-bin.stable.latest.minimal; - - craneLib = (crane.mkLib pkgs).overrideToolchain rust-minimal; - - buildInputs = [ - pkgs.openssl # needed for openssl - ]; - nativeBuildInputs = [ - pkgs.pkg-config # needed for openssl - ]; - - craneBuild = craneLib.buildPackage { - src = craneLib.cleanCargoSource ./.; - inherit buildInputs nativeBuildInputs; - - doCheck = true; - }; - in { - packages.default = craneBuild; - app.default = { - type = "app"; - program = "${self.packages.${system}.default}/bin/generate_extensions"; - }; - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - cocogitto - - rust-stable - cargo-edit - ]; - inherit buildInputs nativeBuildInputs; - }; - }); -} -# vim: ts=2 - diff --git a/pkgs/by-name/ge/generate_moz_extension/package.nix b/pkgs/by-name/ge/generate_moz_extension/package.nix deleted file mode 100644 index aae5ea6c..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/package.nix +++ /dev/null @@ -1,29 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - rustPlatform, - openssl, - pkg-config, -}: -rustPlatform.buildRustPackage { - pname = "generate_firefox_extensions"; - version = "0.1.0"; - - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - }; - buildInputs = [ - openssl # needed for openssl-sys crate - ]; - nativeBuildInputs = [ - pkg-config # needed for openssl dependency - ]; -} diff --git a/pkgs/by-name/ge/generate_moz_extension/res/generate_extensions.py b/pkgs/by-name/ge/generate_moz_extension/res/generate_extensions.py deleted file mode 100644 index a262ca77..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/res/generate_extensions.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python - -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -# source: https://github.com/etu/nixconfig/blob/ba47d577c8bfb4a1c06927c34ece34118f4a0460/modules/graphical/firefox/generate.py - -from concurrent.futures import ThreadPoolExecutor -import json -import requests - -EXTENSIONS = sorted( - [ - "darkreader", - "firenvim", - "keepassxc-browser", - "simple-tab-groups", - ] -) - - -def index_ext(ext: str): - # print(f"Indexing {ext}...") - - resp = requests.get(f"https://addons.mozilla.org/api/v5/addons/addon/{ext}/").json() - rel = resp["current_version"] - - if not rel["file"]["hash"].startswith("sha256:"): - raise ValueError("Unhandled hash type") - - return { - "pname": ext, - "version": rel["version"], - "addonId": resp["guid"], - "url": rel["file"]["url"], - "sha256": rel["file"]["hash"], - } - - -if __name__ == "__main__": - # outfile = os.path.dirname(os.path.realpath(__file__)) + "/extensions.json" - - with ThreadPoolExecutor() as e: - extensions = {ext: e.submit(index_ext, ext) for ext in EXTENSIONS} - extensions = {k: v.result() for k, v in extensions.items()} - - # with open(outfile, "w") as f: - print(json.dumps(extensions, indent=2)) diff --git a/pkgs/by-name/ge/generate_moz_extension/res/reference.json b/pkgs/by-name/ge/generate_moz_extension/res/reference.json deleted file mode 100644 index f46ea8ec..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/res/reference.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "darkreader": { - "pname": "darkreader", - "version": "4.9.62", - "addonId": "addon@darkreader.org", - "url": "https://addons.mozilla.org/firefox/downloads/file/4053589/darkreader-4.9.62.xpi", - "sha256": "sha256:e537a2cee45ed7c26f79ecd3ed362620e3f00d24c158532a58e163a63a3d60cc" - }, - "firenvim": { - "pname": "firenvim", - "version": "0.2.14", - "addonId": "firenvim@lacamb.re", - "url": "https://addons.mozilla.org/firefox/downloads/file/4026386/firenvim-0.2.14.xpi", - "sha256": "sha256:a8c495a59e30eaabbb3fcd188db9b5e28b40bffefe41a3f0fa22ecc58c80c2b6" - }, - "keepassxc-browser": { - "pname": "keepassxc-browser", - "version": "1.8.4", - "addonId": "keepassxc-browser@keepassxc.org", - "url": "https://addons.mozilla.org/firefox/downloads/file/4045866/keepassxc_browser-1.8.4.xpi", - "sha256": "sha256:cc39aa058cb8915cfc88424e2e1cebe3ccfc3f95d7bddb2abd0c4905d2b17719" - }, - "simple-tab-groups": { - "pname": "simple-tab-groups", - "version": "4.7.2.1", - "addonId": "simple-tab-groups@drive4ik", - "url": "https://addons.mozilla.org/firefox/downloads/file/3873608/simple_tab_groups-4.7.2.1.xpi", - "sha256": "sha256:75077589098ca62c00b86cf9554c6120bf8dc04c5f916fe26f84915f5147b2a4" - } -} diff --git a/pkgs/by-name/ge/generate_moz_extension/res/reference.json.license b/pkgs/by-name/ge/generate_moz_extension/res/reference.json.license deleted file mode 100644 index eae6a84c..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/res/reference.json.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/pkgs/by-name/ge/generate_moz_extension/res/test.json b/pkgs/by-name/ge/generate_moz_extension/res/test.json deleted file mode 100644 index daa1d19a..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/res/test.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "darkreader": { - "addon_id": "addon@darkreader.org", - "pname": "darkreader", - "sha256": "sha256:e537a2cee45ed7c26f79ecd3ed362620e3f00d24c158532a58e163a63a3d60cc", - "url": "https://addons.mozilla.org/firefox/downloads/file/4053589/darkreader-4.9.62.xpi", - "version": "4.9.62" - }, - "firenvim": { - "addon_id": "firenvim@lacamb.re", - "pname": "firenvim", - "sha256": "sha256:a8c495a59e30eaabbb3fcd188db9b5e28b40bffefe41a3f0fa22ecc58c80c2b6", - "url": "https://addons.mozilla.org/firefox/downloads/file/4026386/firenvim-0.2.14.xpi", - "version": "0.2.14" - }, - "keepassxc-browser": { - "addon_id": "keepassxc-browser@keepassxc.org", - "pname": "keepassxc-browser", - "sha256": "sha256:cc39aa058cb8915cfc88424e2e1cebe3ccfc3f95d7bddb2abd0c4905d2b17719", - "url": "https://addons.mozilla.org/firefox/downloads/file/4045866/keepassxc_browser-1.8.4.xpi", - "version": "1.8.4" - }, - "simple-tab-groups": { - "addon_id": "simple-tab-groups@drive4ik", - "pname": "simple-tab-groups", - "sha256": "sha256:75077589098ca62c00b86cf9554c6120bf8dc04c5f916fe26f84915f5147b2a4", - "url": "https://addons.mozilla.org/firefox/downloads/file/3873608/simple_tab_groups-4.7.2.1.xpi", - "version": "4.7.2.1" - } -} diff --git a/pkgs/by-name/ge/generate_moz_extension/res/test.json.license b/pkgs/by-name/ge/generate_moz_extension/res/test.json.license deleted file mode 100644 index eae6a84c..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/res/test.json.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/pkgs/by-name/ge/generate_moz_extension/src/main.rs b/pkgs/by-name/ge/generate_moz_extension/src/main.rs deleted file mode 100644 index 58a19160..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/src/main.rs +++ /dev/null @@ -1,148 +0,0 @@ -// nixos-config - My current NixOS configuration -// -// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of my nixos-config. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -use std::env::args; - -use anyhow::{bail, Context}; -use futures::StreamExt; -use reqwest::Client; -use serde_json::{json, Map, Value}; - -pub mod types; - -macro_rules! get_json_value { - ($key:expr, $json_value:ident, $type:ident, $get:ident) => { - match $json_value.get($key) { - Some(resp) => { - let resp = resp.to_owned(); - if resp.$type() { - resp.$get().expect( - "The should have been checked in the if guard, so unpacking here is fine", - ).to_owned() - } else { - bail!( - "Value {} => \n{}\n is not of type: {}", - $key, - resp, - stringify!($type) - ); - } - } - None => { - bail!( - "There seems to be no '{}' in your json data (json value: '{}')\n Has the api changend?", - $key, serde_json::to_string_pretty(&$json_value).expect("Will always work") - ); - } - } - }; -} - -use futures::stream::futures_unordered::FuturesUnordered; -use types::{Extension, InputExtension}; - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - let mut extensions: Vec<InputExtension> = vec![]; - for input_extension in args() - .skip(1) - .map(|str| InputExtension::try_from(str)) - .collect::<Vec<anyhow::Result<InputExtension>>>() - { - extensions.push(input_extension?); - } - - let resulting_extensions = process_extensions(extensions).await?; - - let mut output = Map::new(); - for extension in resulting_extensions { - output.insert(extension.pname.clone(), json!(extension)); - } - - println!( - "{}", - serde_json::to_string_pretty(&serde_json::Value::Object(output)).expect( - "This is constructed from json, it should also be possible to serialize it again" - ) - ); - Ok(()) -} - -async fn process_extensions(extensions: Vec<InputExtension>) -> anyhow::Result<Vec<Extension>> { - let mut output = Vec::with_capacity(extensions.len()); - - let client = Client::new(); - for extension in extensions - .iter() - .map(|ext| { - let local_client = &client; - index_extension(ext, local_client) - }) - .collect::<FuturesUnordered<_>>() - .collect::<Vec<_>>() - .await - { - output.push(extension?); - } - Ok(output) -} - -async fn index_extension(extension: &InputExtension, client: &Client) -> anyhow::Result<Extension> { - let response = client - .get(format!( - "https://addons.mozilla.org/api/v5/addons/addon/{}", - extension, - )) - .send() - .await - .context("Accessing the mozzila extenios api failed with error: {e}")?; - - eprintln!("Indexing {} ({})...", extension, response.status()); - let response: Value = serde_json::from_str( - &response - .text() - .await - .context("Turning the response to text fail with error: {e}")?, - ) - .context("Deserializing the response failed! Error: {e}")?; - - if let Some(detail) = response.get("detail") { - if detail == "Not found." { - bail!("Your extension ('{}') was not found!", extension); - } - }; - - let release = { get_json_value!("current_version", response, is_object, as_object) }; - - #[allow(non_snake_case)] - let addonId = { get_json_value!("guid", response, is_string, as_str) }; - - let version = { get_json_value!("version", release, is_string, as_str) }; - let file = { get_json_value!("file", release, is_object, as_object) }; - - let url = { get_json_value!("url", file, is_string, as_str) }; - let sha256 = { - let hash = get_json_value!("hash", file, is_string, as_str); - if hash.starts_with("sha256:") { - hash - } else { - bail!("This hash type is unhandled: {}", hash); - } - }; - - Ok(Extension { - pname: extension.moz_name.clone(), - default_area: extension.default_area, - version, - addonId, - url, - sha256, - }) -} diff --git a/pkgs/by-name/ge/generate_moz_extension/src/types.rs b/pkgs/by-name/ge/generate_moz_extension/src/types.rs deleted file mode 100644 index 231e747c..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/src/types.rs +++ /dev/null @@ -1,81 +0,0 @@ -// nixos-config - My current NixOS configuration -// -// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of my nixos-config. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -use std::fmt::Display; - -use anyhow::anyhow; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Serialize, Deserialize)] -#[allow(non_snake_case)] -pub struct Extension { - pub pname: String, - pub default_area: DefaultArea, - pub version: String, - pub addonId: String, - pub url: String, - pub sha256: String, -} - -#[derive(Debug, Clone)] -pub struct InputExtension { - pub moz_name: String, - pub default_area: DefaultArea, -} -#[derive(Debug, Clone, Copy, Deserialize, Serialize)] -#[allow(non_camel_case_types)] -pub enum DefaultArea { - navbar, - menupanel, -} - -impl Display for DefaultArea { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - DefaultArea::navbar => f.write_str("navbar"), - DefaultArea::menupanel => f.write_str("menupanel"), - } - } -} - -impl TryFrom<&str> for DefaultArea { - type Error = anyhow::Error; - - fn try_from(value: &str) -> Result<Self, Self::Error> { - match value { - "navbar" => Ok(Self::navbar), - "menupanel" => Ok(Self::menupanel), - _ => Err(anyhow!( - "Your <default_area> needs to be one of 'navbar' or 'menupanel', but is: '{}'", - value - )), - } - } -} - -impl Display for InputExtension { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&self.moz_name) - } -} -impl TryFrom<String> for InputExtension { - type Error = anyhow::Error; - - fn try_from(value: String) -> Result<Self, Self::Error> { - if let Some((moz_name, default_area)) = value.split_once(':') { - Ok(Self { - moz_name: moz_name.to_owned(), - default_area: default_area.try_into()?, - }) - } else { - Err(anyhow!("Can't parse the input string as a InputExtension!\n Needs to be: '<moz_name>:<default_area>'")) - } - } -} diff --git a/pkgs/by-name/ge/generate_moz_extension/update.sh b/pkgs/by-name/ge/generate_moz_extension/update.sh deleted file mode 100755 index c7c35d39..00000000 --- a/pkgs/by-name/ge/generate_moz_extension/update.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env sh - -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -[ "$1" = "upgrade" ] && cargo upgrade -cargo update - -# vim: ft=sh diff --git a/pkgs/by-name/i3/i3bar-river-patched/0001-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch b/pkgs/by-name/i3/i3bar-river-patched/0001-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch new file mode 100644 index 00000000..7bfdd7bc --- /dev/null +++ b/pkgs/by-name/i3/i3bar-river-patched/0001-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch @@ -0,0 +1,110 @@ +From 8ae692a461fad2f23231d50b78bb706408facfe6 Mon Sep 17 00:00:00 2001 +From: Benedikt Peetz <benedikt.peetz@b-peetz.de> +Date: Tue, 20 May 2025 19:58:57 +0200 +Subject: [PATCH] feat(crate::bar): Put the leftmost block in the middle of the + bar + +This is a workaround for the limitation in the i3 blocks protocol, as +this does not allow for centred blocks. +--- + src/bar.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 52 insertions(+), 11 deletions(-) + +diff --git a/src/bar.rs b/src/bar.rs +index 96533e3..76f8025 100644 +--- a/src/bar.rs ++++ b/src/bar.rs +@@ -338,16 +338,55 @@ impl Bar { + } + + // Display the blocks +- render_blocks( +- &cairo_ctx, +- &ss.config, +- palette, +- ss.blocks_cache.get_computed(), +- &mut self.blocks_btns, +- offset_left, +- width_f, +- height_f, +- ); ++ { ++ if !ss.blocks_cache.get_computed().is_empty() { ++ let first_block = &ss.blocks_cache.get_computed()[0]; ++ ++ let blocks = &ss.blocks_cache.get_computed()[1..]; ++ ++ let other_start = render_blocks( ++ &cairo_ctx, ++ &ss.config, ++ palette, ++ blocks, ++ &mut self.blocks_btns, ++ offset_left, ++ width_f, ++ height_f, ++ ); ++ ++ // Draw the first block _after_ the other ones, so that we can nudge it more to the ++ // left, if the others are spanning over the middle. ++ let mut start = (width_f / 2.0) - (first_block.full.width / 2.0); ++ if start + first_block.full.width > other_start { ++ start = other_start ++ - first_block.full.width ++ - first_block.block.separator_block_width as f64; ++ } ++ ++ first_block.full.render( ++ &cairo_ctx, ++ RenderOptions { ++ x_offset: start, ++ bar_height: height_f, ++ fg_color: first_block.block.color.unwrap_or(palette.color), ++ bg_color: first_block.block.background, ++ r_left: ss.config.blocks_r, ++ r_right: ss.config.blocks_r, ++ overlap: ss.config.blocks_overlap, ++ }, ++ ); ++ ++ self.blocks_btns.push( ++ start, ++ first_block.full.width, ++ ( ++ first_block.block.name.clone(), ++ first_block.block.instance.clone(), ++ ), ++ ); ++ } ++ } + + self.viewport + .set_destination(conn, self.width as i32, self.height as i32); +@@ -422,7 +461,7 @@ fn render_blocks( + offset_left: f64, + full_width: f64, + full_height: f64, +-) { ++) -> f64 { + context.rectangle(offset_left, 0.0, full_width - offset_left, full_height); + context.clip(); + +@@ -507,6 +546,7 @@ fn render_blocks( + } + + // Render blocks ++ let leftmost_start = full_width - blocks_width; + buttons.clear(); + for series in blocks_computed { + let s_len = series.blocks.len(); +@@ -550,6 +590,7 @@ fn render_blocks( + } + + context.reset_clip(); ++ leftmost_start + } + + fn layer_surface_cb(ctx: EventCtx<State, ZwlrLayerSurfaceV1>) { +-- +2.49.0 + diff --git a/pkgs/by-name/i3/i3bar-river-patched/package.nix b/pkgs/by-name/i3/i3bar-river-patched/package.nix new file mode 100644 index 00000000..26f11ab3 --- /dev/null +++ b/pkgs/by-name/i3/i3bar-river-patched/package.nix @@ -0,0 +1,54 @@ +# nixos-config - My current NixOS configuration +# +# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> +# SPDX-License-Identifier: GPL-3.0-or-later +# +# This file is part of my nixos-config. +# +# You should have received a copy of the License along with this program. +# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. +{ + lib, + fetchFromGitHub, + rustPlatform, + pkg-config, + pango, +}: +rustPlatform.buildRustPackage { + pname = "i3bar-river-patched"; + version = "1.1.0-unstable-2025-05-20"; + + src = fetchFromGitHub { + owner = "bpeetz"; + repo = "i3bar-river"; + rev = "d460a9a283426e9474a0034a146d09816e92f571"; + hash = "sha256-E04b2FzEhOX5NyE/VpEGdg27Sg+1+lSSRZbGyX6PXrk="; + }; + + cargoHash = "sha256-jIB4XH67FmtPxAatHkuW8v5mNgr/KsyriaBNZ5t2dLo="; + + cargoPatches = [ + # TODO(@bpeetz): Open an issues, whether something like that could be up-streamed. <2025-05-20> + ./0001-feat-crate-bar-Put-the-leftmost-block-in-the-middle-.patch + ]; + + # Remove the WMs that I don't use. + buildNoDefaultFeatures = true; + buildFeatures = [ + # "hyprland" + # "niri" + "river" + ]; + + nativeBuildInputs = [pkg-config]; + buildInputs = [pango]; + + meta = with lib; { + description = "Port of i3bar for river"; + homepage = "https://github.com/MaxVerevkin/i3bar-river"; + license = licenses.gpl3Only; + maintainers = with maintainers; [nicegamer7]; + mainProgram = "i3bar-river"; + platforms = platforms.linux; + }; +} diff --git a/pkgs/by-name/i3/i3status-rust-patched/package.nix b/pkgs/by-name/i3/i3status-rust-patched/package.nix new file mode 100644 index 00000000..9f172d49 --- /dev/null +++ b/pkgs/by-name/i3/i3status-rust-patched/package.nix @@ -0,0 +1,34 @@ +# nixos-config - My current NixOS configuration +# +# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> +# SPDX-License-Identifier: GPL-3.0-or-later +# +# This file is part of my nixos-config. +# +# You should have received a copy of the License along with this program. +# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. +{ + i3status-rust, + fetchpatch2, +}: +i3status-rust.overrideAttrs (final: prev: { + pname = "${prev.pname}-patched"; + + patches = + (prev.patches or []) + ++ [ + # Btrfs support for disk_space block. + (fetchpatch2 { + name = "disk_space: Support btrfs backend"; + url = "https://patch-diff.githubusercontent.com/raw/greshake/i3status-rust/pull/2159.patch"; + hash = "sha256-S2/biX6FTLJNfI9QVgwr+V8IGMRnSFIZnTrhc+1LvqQ="; + }) + + # Correctly calculate the used memory. + (fetchpatch2 { + name = "memory: Avoid estimating available memory, use kernel estimate instead"; + url = "https://patch-diff.githubusercontent.com/raw/greshake/i3status-rust/pull/2160.patch"; + hash = "sha256-1wB2KpXhC/UIxAgRioOYj/bnrzRSuaHAdbeoZ2O5E/Y="; + }) + ]; +}) diff --git a/pkgs/by-name/lf/lf-make-map/Cargo.lock b/pkgs/by-name/lf/lf-make-map/Cargo.lock index f6891648..e05520ee 100644 --- a/pkgs/by-name/lf/lf-make-map/Cargo.lock +++ b/pkgs/by-name/lf/lf-make-map/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -43,36 +43,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "once_cell", + "once_cell_polyfill", "windows-sys", ] @@ -84,30 +84,30 @@ checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "cc" -version = "1.2.23" +version = "1.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" +checksum = "4ad45f4f74e4e20eaa392913b7b33a7091c87e59628f4dd27888205ad888843c" dependencies = [ "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "chrono" @@ -125,9 +125,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -135,9 +135,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", @@ -159,15 +159,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "core-foundation-sys" @@ -183,9 +183,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "iana-time-zone" @@ -240,9 +240,9 @@ dependencies = [ [[package]] name = "keymaps" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a522bbaa39bddd54945580e369ed37113ea96f4cb8f0322be0d5e04aa4d7293" +checksum = "ea59e8e461942cf1d6a7ad938848d6fd2e40eb43799c21192c09226ecc86710f" dependencies = [ "thiserror", ] @@ -261,9 +261,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.172" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "log" @@ -287,6 +287,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] name = "proc-macro2" version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -306,9 +312,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "same-file" @@ -346,9 +352,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -386,12 +392,11 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -485,9 +490,9 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.61.1" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46ec44dc15085cea82cf9c78f85a9114c463a369786585ad2882d1ff0b0acf40" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", @@ -520,24 +525,24 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-result" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b895b5356fc36103d0f64dd1e94dfa7ac5633f1c9dd6e80fe9ec4adef69e09d" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a7ab927b2637c19b3dbe0965e75d8f2d30bdd697a1516191cad2ec4df8fb28a" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] diff --git a/pkgs/by-name/lf/lf-make-map/Cargo.toml b/pkgs/by-name/lf/lf-make-map/Cargo.toml index 22860e12..57dc61a5 100644 --- a/pkgs/by-name/lf/lf-make-map/Cargo.toml +++ b/pkgs/by-name/lf/lf-make-map/Cargo.toml @@ -18,8 +18,8 @@ edition = "2024" [dependencies] anyhow = "1.0.98" -clap = { version = "4.5.37", features = ["derive", "env"] } -keymaps = "1.1.1" +clap = { version = "4.5.40", features = ["derive", "env"] } +keymaps = "1.2.0" log = "0.4.27" stderrlog = "0.6.0" walkdir = "2.5.0" diff --git a/pkgs/by-name/lf/lf-make-map/flake.lock b/pkgs/by-name/lf/lf-make-map/flake.lock index d9641458..1ebbe915 100644 --- a/pkgs/by-name/lf/lf-make-map/flake.lock +++ b/pkgs/by-name/lf/lf-make-map/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1747312588, - "narHash": "sha256-MmJvj6mlWzeRwKGLcwmZpKaOPZ5nJb/6al5CXqJsgjo=", + "lastModified": 1751596331, + "narHash": "sha256-7WSzIrw0nCl8iYroj7c//LLsf2zgNEIJNyUSvx4MPLI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b1bebd0fe266bbd1820019612ead889e96a8fa2d", + "rev": "472908faa934435cf781ae8fac77291af3d137d3", "type": "github" }, "original": { diff --git a/pkgs/by-name/mp/mpp/package.nix b/pkgs/by-name/mp/mpp/package.nix index 0d2f6c8d..f0e454f7 100644 --- a/pkgs/by-name/mp/mpp/package.nix +++ b/pkgs/by-name/mp/mpp/package.nix @@ -70,6 +70,8 @@ fd "." --hidden --type file | while read -r file_path; do sed --in-place 's/mpc/mpp/g' "$file_path" done + + # TODO(@bpeetz): Also change this in man-pages. <2025-05-20> ''; installPhase = '' @@ -79,6 +81,8 @@ }; in symlinkJoin { - name = "mpp-merged"; + name = "mpp"; paths = [script mpcShare]; + + inherit (script) meta; } diff --git a/pkgs/by-name/qu/qutebrowser-patched/0001-fix-standardpaths-Continue-to-work-with-xdg-while-ba.patch b/pkgs/by-name/qu/qutebrowser-patched/0001-fix-standardpaths-Continue-to-work-with-xdg-while-ba.patch new file mode 100644 index 00000000..fa2e2482 --- /dev/null +++ b/pkgs/by-name/qu/qutebrowser-patched/0001-fix-standardpaths-Continue-to-work-with-xdg-while-ba.patch @@ -0,0 +1,54 @@ +From 8a0aa0e244fa565b8c55aab38cc5e84323c3b481 Mon Sep 17 00:00:00 2001 +From: Benedikt Peetz <benedikt.peetz@b-peetz.de> +Date: Tue, 3 Jun 2025 12:43:44 +0200 +Subject: [PATCH] fix(standardpaths): Continue to work with xdg, while + `--basedir` is set + +This can be used to simulate firefox's profiles feature (i.e., completely separated +data/runtime/cache dirs), while still keeping to the xdg basedir standard. +--- + qutebrowser/utils/standarddir.py | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/qutebrowser/utils/standarddir.py b/qutebrowser/utils/standarddir.py +index b82845a96..61319daed 100644 +--- a/qutebrowser/utils/standarddir.py ++++ b/qutebrowser/utils/standarddir.py +@@ -285,12 +285,11 @@ def _from_args( + The overridden path, or None if there is no override. + """ + basedir_suffix = { +- QStandardPaths.StandardLocation.ConfigLocation: 'config', +- QStandardPaths.StandardLocation.AppDataLocation: 'data', +- QStandardPaths.StandardLocation.AppLocalDataLocation: 'data', +- QStandardPaths.StandardLocation.CacheLocation: 'cache', +- QStandardPaths.StandardLocation.DownloadLocation: 'download', +- QStandardPaths.StandardLocation.RuntimeLocation: 'runtime', ++ QStandardPaths.StandardLocation.ConfigLocation: ('config', False), ++ QStandardPaths.StandardLocation.AppDataLocation: ('data', False), ++ QStandardPaths.StandardLocation.AppLocalDataLocation: ('data', False), ++ QStandardPaths.StandardLocation.CacheLocation: ('cache', True), ++ QStandardPaths.StandardLocation.RuntimeLocation: ('runtime', True), + } + + if getattr(args, 'basedir', None) is None: +@@ -298,10 +297,14 @@ def _from_args( + assert args is not None + + try: +- suffix = basedir_suffix[typ] ++ (suffix, extend) = basedir_suffix[typ] + except KeyError: # pragma: no cover + return None +- return os.path.abspath(os.path.join(args.basedir, suffix)) ++ ++ if extend: ++ return os.path.abspath(os.path.join(_writable_location(typ), os.path.basename(args.basedir))) ++ else: ++ return os.path.abspath(os.path.join(args.basedir, suffix)) + + + def _create(path: str) -> None: +-- +2.49.0 + diff --git a/pkgs/by-name/qu/qutebrowser-patched/package.nix b/pkgs/by-name/qu/qutebrowser-patched/package.nix new file mode 100644 index 00000000..1f2ea889 --- /dev/null +++ b/pkgs/by-name/qu/qutebrowser-patched/package.nix @@ -0,0 +1,6 @@ +{qutebrowser}: +qutebrowser.overrideAttrs (final: prev: { + pname = "${prev.pname}-patched"; + + patches = (prev.patches or []) ++ [./0001-fix-standardpaths-Continue-to-work-with-xdg-while-ba.patch]; +}) diff --git a/pkgs/by-name/ri/river-mk-keymap/Cargo.lock b/pkgs/by-name/ri/river-mk-keymap/Cargo.lock index e8d62767..7ac1734d 100644 --- a/pkgs/by-name/ri/river-mk-keymap/Cargo.lock +++ b/pkgs/by-name/ri/river-mk-keymap/Cargo.lock @@ -12,10 +12,26 @@ version = 4 [[package]] +name = "ab_glyph" +version = "0.2.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0f4f6fbdc5ee39f2ede9f5f3ec79477271a6d6a2baff22310d51736bda6cea" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2187590a23ab1e3df8681afdf0987c48504d80291f002fcdb651f0ef5e25169" + +[[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -28,37 +44,37 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "once_cell", - "windows-sys", + "once_cell_polyfill", + "windows-sys 0.59.0", ] [[package]] @@ -68,10 +84,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.2.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad45f4f74e4e20eaa392913b7b33a7091c87e59628f4dd27888205ad888843c" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] name = "clap" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -79,9 +134,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -91,9 +146,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", @@ -103,15 +158,205 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "core-text" +version = "20.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" +dependencies = [ + "core-foundation", + "core-graphics", + "foreign-types", + "libc", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.60.2", +] + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dwrote" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe1f192fcce01590bd8d839aca53ce0d11d803bf291b2a6c4ad925a8f0024be" +dependencies = [ + "lazy_static", + "libc", + "winapi", + "wio", +] + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "float-ord" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d" + +[[package]] +name = "font-kit" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c7e611d49285d4c4b2e1727b72cf05353558885cc5252f93707b845dfcaf3d3" +dependencies = [ + "bitflags 2.9.1", + "byteorder", + "core-foundation", + "core-graphics", + "core-text", + "dirs", + "dwrote", + "float-ord", + "freetype-sys", + "lazy_static", + "libc", + "log", + "pathfinder_geometry", + "pathfinder_simd", + "walkdir", + "winapi", + "yeslogic-fontconfig-sys", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "freetype-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7edc5b9669349acfda99533e9e0bcf26a51862ab43b08ee7745c55d28eb134" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] [[package]] name = "heck" @@ -133,19 +378,78 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "keymaps" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a522bbaa39bddd54945580e369ed37113ea96f4cb8f0322be0d5e04aa4d7293" +checksum = "ea59e8e461942cf1d6a7ad938848d6fd2e40eb43799c21192c09226ecc86710f" dependencies = [ "serde", "thiserror", ] [[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.2", +] + +[[package]] +name = "libredox" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" +dependencies = [ + "bitflags 2.9.1", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "memmap2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] [[package]] name = "once_cell" @@ -154,6 +458,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "owned_ttf_parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "pathfinder_geometry" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" +dependencies = [ + "log", + "pathfinder_simd", +] + +[[package]] +name = "pathfinder_simd" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf9027960355bf3afff9841918474a81a5f972ac6d226d518060bba758b5ad57" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] name = "proc-macro2" version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -163,6 +513,15 @@ dependencies = [ ] [[package]] +name = "quick-xml" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +dependencies = [ + "memchr", +] + +[[package]] name = "quote" version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -172,14 +531,70 @@ dependencies = [ ] [[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] name = "river-mk-keymap" version = "0.1.0" dependencies = [ + "ab_glyph", "anyhow", "clap", + "font-kit", "keymaps", + "memmap2", + "rustix 1.0.7", "serde", "serde_json", + "shlex", + "thiserror", + "vte", + "wayland-client", + "wayland-protocols-wlr", + "wayland-scanner", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.0", ] [[package]] @@ -189,6 +604,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] name = "serde" version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -221,6 +651,18 @@ dependencies = [ ] [[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -228,9 +670,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -258,6 +700,12 @@ dependencies = [ ] [[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + +[[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -270,12 +718,148 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] +name = "vte" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5924018406ce0063cd67f8e008104968b74b563ee1b85dde3ed1f7cb87d3dbd" +dependencies = [ + "arrayvec", + "memchr", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wayland-backend" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" +dependencies = [ + "cc", + "downcast-rs", + "rustix 0.38.44", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" +dependencies = [ + "bitflags 2.9.1", + "rustix 0.38.44", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" +dependencies = [ + "pkg-config", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", ] [[package]] @@ -284,14 +868,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -301,43 +901,111 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + +[[package]] +name = "yeslogic-fontconfig-sys" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503a066b4c037c440169d995b869046827dbc71263f6e8f3be6d77d4f3229dbd" +dependencies = [ + "dlib", + "once_cell", + "pkg-config", +] diff --git a/pkgs/by-name/ri/river-mk-keymap/Cargo.toml b/pkgs/by-name/ri/river-mk-keymap/Cargo.toml index d9c44e8a..9d8d2bba 100644 --- a/pkgs/by-name/ri/river-mk-keymap/Cargo.toml +++ b/pkgs/by-name/ri/river-mk-keymap/Cargo.toml @@ -16,11 +16,21 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +ab_glyph = "0.2.30" anyhow = "1.0.98" -clap = { version = "4.5.38", features = ["derive"] } -keymaps = { version = "1.1.1", features = ["serde", "mouse-keys"] } +clap = { version = "4.5.40", features = ["derive"] } +font-kit = "0.14.3" +keymaps = { version = "1.2.0", features = ["serde", "mouse-keys", "modifier-keys"] } +memmap2 = "0.9.5" +rustix = { version = "1.0.7", features = ["fs", "shm"] } serde = { version = "1.0.219", features = ["derive"] } serde_json = "1.0.140" +shlex = "1.3.0" +thiserror = "2.0.12" +vte = "0.15.0" +wayland-client = {version = "0.31.10", default-features = false} +wayland-protocols-wlr = { version = "0.3.8", features = ["client"] } +wayland-scanner = {version = "0.31.6", default-features = false} [profile.release] lto = true diff --git a/pkgs/by-name/ri/river-mk-keymap/TODO b/pkgs/by-name/ri/river-mk-keymap/TODO deleted file mode 100644 index be77953e..00000000 --- a/pkgs/by-name/ri/river-mk-keymap/TODO +++ /dev/null @@ -1 +0,0 @@ -Look at https://github.com/stefur/flow for river wayland inclusion diff --git a/pkgs/by-name/ri/river-mk-keymap/TODO.license b/pkgs/by-name/ri/river-mk-keymap/TODO.license deleted file mode 100644 index eae6a84c..00000000 --- a/pkgs/by-name/ri/river-mk-keymap/TODO.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/pkgs/by-name/ri/river-mk-keymap/contrib/example.json b/pkgs/by-name/ri/river-mk-keymap/contrib/example.json index c8673f9a..bddd61c0 100644 --- a/pkgs/by-name/ri/river-mk-keymap/contrib/example.json +++ b/pkgs/by-name/ri/river-mk-keymap/contrib/example.json @@ -1,5 +1,8 @@ { - "<M-a>": { - "command": ["focus-view", "next"] + "Kbad": { + "command": ["spawn", "/nix/store/1xfyw9c5ala73y8sayrsf98vcrr3jrww-libnotify-0.8.6/bin/notify-send hi"] + }, + "Kbae": { + "command": ["e"] } } diff --git a/pkgs/by-name/ri/river-mk-keymap/contrib/init.json b/pkgs/by-name/ri/river-mk-keymap/contrib/init.json new file mode 100644 index 00000000..a5f24307 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/contrib/init.json @@ -0,0 +1,261 @@ +{ + "<Alt+Ctrl+Super+Shift-Z>": [ + "spawn", + "/nix/store/h71ca2rxlnlcyv4604ih2b2gla5ly27d-qmk-unicode-type-1.0.0/bin/qmk-unicode-type 106 65377" + ], + "<MEDIA_LOWERVOLUME>": { + "allow_locked": true, + "command": [ + "spawn", + "/nix/store/7h9w2sycqj3i2lp61nibgv7qhvwy3pi9-wireplumber-0.5.10/bin/wpctl set-volume @DEFAULT_SINK@ 5%-" + ] + }, + "<MEDIA_MUTEVOLUME>": { + "allow_locked": true, + "command": [ + "spawn", + "/nix/store/08bgv5x7gfhkczf0lgrpim1rw51jlxvn-mpp/bin/mpp toggle" + ] + }, + "<MEDIA_RAISEVOLUME>": { + "allow_locked": true, + "command": [ + "spawn", + "/nix/store/7h9w2sycqj3i2lp61nibgv7qhvwy3pi9-wireplumber-0.5.10/bin/wpctl set-volume @DEFAULT_SINK@ 5%+" + ] + }, + "<LEFT_SUPER>": { + "c": { + "<ENTER>": [ + "zoom" + ], + " ": [ + "toggle-float" + ], + "c": [ + "close" + ], + "f": [ + "toggle-fullscreen" + ], + "n": [ + "swap", + "previous" + ], + "o": [ + "send-to-output", + "next" + ], + "t": [ + "swap", + "next" + ] + }, + "f": { + "0": [ + "set-focused-tags", + "4294967295" + ], + "1": [ + "set-focused-tags", + "1" + ], + "2": [ + "set-focused-tags", + "2" + ], + "3": [ + "set-focused-tags", + "4" + ], + "4": [ + "set-focused-tags", + "8" + ], + "5": [ + "set-focused-tags", + "16" + ], + "6": [ + "set-focused-tags", + "32" + ], + "7": [ + "set-focused-tags", + "64" + ], + "8": [ + "set-focused-tags", + "128" + ], + "9": [ + "set-focused-tags", + "256" + ], + "<Ctrl-n>": [ + "focus-output", + "previous" + ], + "<Ctrl-t>": [ + "focus-output", + "next" + ], + "n": [ + "focus-view", + "previous" + ], + "p": [ + "focus-previous-tags" + ], + "t": [ + "focus-view", + "next" + ] + }, + "m": { + "l": { + "command": [ + "spawn", + "/nix/store/7h9w2sycqj3i2lp61nibgv7qhvwy3pi9-wireplumber-0.5.10/bin/wpctl set-volume @DEFAULT_SINK@ 5%-" + ], + "description": "wpctl set-volume @DEFAULT_SINK@ 5%-" + }, + "m": [ + "spawn", + "/nix/store/08bgv5x7gfhkczf0lgrpim1rw51jlxvn-mpp/bin/mpp toggle" + ], + "r": [ + "spawn", + "/nix/store/7h9w2sycqj3i2lp61nibgv7qhvwy3pi9-wireplumber-0.5.10/bin/wpctl set-volume @DEFAULT_SINK@ 5%+" + ] + }, + "r": { + "a": [ + "spawn", + "/nix/store/h601phmb09d9dwwziwsim6m0r31qajr3-alacritty-0.15.1/bin/alacritty" + ], + "b": [ + "spawn", + "/nix/store/k8gfhk1lglwr8k6477ygkr9hh037a4kw-tskm-0.1.0/bin/tskm open select" + ], + "k": [ + "spawn", + "/nix/store/xpinf75gxhl8aglw2z7631k89iiml7rz-keepassxc-2.7.10/bin/keepassxc" + ], + "p": [ + "spawn", + "/nix/store/skgvjhmqp3jbmaw70xlz86a66lg13395-screenshot_persistent/bin/screenshot_persistent" + ], + "s": [ + "spawn", + "/nix/store/zvzr8cj57jhxyrzjym2rv3w95w7zw901-signal-desktop-7.56.1/bin/signal-desktop" + ] + }, + "v": { + "0": [ + "set-view-tags", + "4294967295" + ], + "1": [ + "set-view-tags", + "1" + ], + "2": [ + "set-view-tags", + "2" + ], + "3": [ + "set-view-tags", + "4" + ], + "4": [ + "set-view-tags", + "8" + ], + "5": [ + "set-view-tags", + "16" + ], + "6": [ + "set-view-tags", + "32" + ], + "7": [ + "set-view-tags", + "64" + ], + "8": [ + "set-view-tags", + "128" + ], + "9": [ + "set-view-tags", + "256" + ], + "a": { + "1": [ + "toggle-view-tags", + "1" + ], + "2": [ + "toggle-view-tags", + "2" + ], + "3": [ + "toggle-view-tags", + "4" + ], + "4": [ + "toggle-view-tags", + "8" + ], + "5": [ + "toggle-view-tags", + "16" + ], + "6": [ + "toggle-view-tags", + "32" + ], + "7": [ + "toggle-view-tags", + "64" + ], + "8": [ + "toggle-view-tags", + "128" + ], + "9": [ + "toggle-view-tags", + "256" + ] + }, + "p": [ + "send-to-previous-tags" + ] + }, + "x": { + "l": [ + "spawn", + "/nix/store/4gp8yj8cz3d78hn01firv7dlqf4ap1fj-lock/bin/lock" + ], + "q": [ + "exit" + ] + } + }, + "<Super-<MOUSE_LEFT>>": [ + "move-view" + ], + "<Super-<MOUSE_RIGHT>>": [ + "resize-view" + ], + "<Super-L>": [ + "spawn", + "/nix/store/4gp8yj8cz3d78hn01firv7dlqf4ap1fj-lock/bin/lock" + ], + "<PRINTSCREEN>": [ + "spawn", + "/nix/store/skgvjhmqp3jbmaw70xlz86a66lg13395-screenshot_persistent/bin/screenshot_persistent" + ] +} diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.lock b/pkgs/by-name/ri/river-mk-keymap/flake.lock index d9641458..1ebbe915 100644 --- a/pkgs/by-name/ri/river-mk-keymap/flake.lock +++ b/pkgs/by-name/ri/river-mk-keymap/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1747312588, - "narHash": "sha256-MmJvj6mlWzeRwKGLcwmZpKaOPZ5nJb/6al5CXqJsgjo=", + "lastModified": 1751596331, + "narHash": "sha256-7WSzIrw0nCl8iYroj7c//LLsf2zgNEIJNyUSvx4MPLI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b1bebd0fe266bbd1820019612ead889e96a8fa2d", + "rev": "472908faa934435cf781ae8fac77291af3d137d3", "type": "github" }, "original": { diff --git a/pkgs/by-name/ri/river-mk-keymap/flake.nix b/pkgs/by-name/ri/river-mk-keymap/flake.nix index e15e99fa..b7e2a0c4 100644 --- a/pkgs/by-name/ri/river-mk-keymap/flake.nix +++ b/pkgs/by-name/ri/river-mk-keymap/flake.nix @@ -17,8 +17,20 @@ outputs = {nixpkgs, ...}: let system = "x86_64-linux"; pkgs = nixpkgs.legacyPackages."${system}"; + + nativeBuildInputs = [ + pkgs.pkg-config + ]; + + buildInputs = [ + pkgs.wayland + pkgs.libxkbcommon + pkgs.fontconfig + ]; in { devShells."${system}".default = pkgs.mkShell { + inherit nativeBuildInputs buildInputs; + packages = with pkgs; [ cargo clippy diff --git a/pkgs/by-name/ri/river-mk-keymap/package.nix b/pkgs/by-name/ri/river-mk-keymap/package.nix index 7d6d4f3a..bb3dc285 100644 --- a/pkgs/by-name/ri/river-mk-keymap/package.nix +++ b/pkgs/by-name/ri/river-mk-keymap/package.nix @@ -7,7 +7,13 @@ # # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{rustPlatform}: +{ + rustPlatform, + pkg-config, + wayland, + libxkbcommon, + fontconfig, +}: rustPlatform.buildRustPackage { pname = "river-mk-keymap"; version = "0.1.0"; @@ -17,6 +23,16 @@ rustPlatform.buildRustPackage { lockFile = ./Cargo.lock; }; + nativeBuildInputs = [ + pkg-config + ]; + + buildInputs = [ + wayland + libxkbcommon + fontconfig + ]; + meta = { mainProgram = "river-mk-keymap"; }; diff --git a/pkgs/by-name/ri/river-mk-keymap/resources/river-control-unstable-v1.xml b/pkgs/by-name/ri/river-mk-keymap/resources/river-control-unstable-v1.xml new file mode 100644 index 00000000..aa5fc4dc --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/resources/river-control-unstable-v1.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="river_control_unstable_v1"> + <copyright> + Copyright 2020 The River Developers + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + </copyright> + + <interface name="zriver_control_v1" version="1"> + <description summary="run compositor commands"> + This interface allows clients to run compositor commands and receive a + success/failure response with output or a failure message respectively. + + Each command is built up in a series of add_argument requests and + executed with a run_command request. The first argument is the command + to be run. + + A complete list of commands should be made available in the man page of + the compositor. + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy the river_control object"> + This request indicates that the client will not use the + river_control object any more. Objects that have been created + through this instance are not affected. + </description> + </request> + + <request name="add_argument"> + <description summary="add an argument to the current command"> + Arguments are stored by the server in the order they were sent until + the run_command request is made. + </description> + <arg name="argument" type="string" summary="the argument to add"/> + </request> + + <request name="run_command"> + <description summary="run the current command"> + Execute the command built up using the add_argument request for the + given seat. + </description> + <arg name="seat" type="object" interface="wl_seat"/> + <arg name="callback" type="new_id" interface="zriver_command_callback_v1" + summary="callback object"/> + </request> + </interface> + + <interface name="zriver_command_callback_v1" version="1"> + <description summary="callback object"> + This object is created by the run_command request. Exactly one of the + success or failure events will be sent. This object will be destroyed + by the compositor after one of the events is sent. + </description> + + <event name="success" type="destructor"> + <description summary="command successful"> + Sent when the command has been successfully received and executed by + the compositor. Some commands may produce output, in which case the + output argument will be a non-empty string. + </description> + <arg name="output" type="string" summary="the output of the command"/> + </event> + + <event name="failure" type="destructor"> + <description summary="command failed"> + Sent when the command could not be carried out. This could be due to + sending a non-existent command, no command, not enough arguments, too + many arguments, invalid arguments, etc. + </description> + <arg name="failure_message" type="string" + summary="a message explaining why failure occurred"/> + </event> + </interface> +</protocol> diff --git a/pkgs/by-name/ri/river-mk-keymap/resources/river-status-unstable-v1.xml b/pkgs/by-name/ri/river-mk-keymap/resources/river-status-unstable-v1.xml new file mode 100644 index 00000000..e9629dde --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/resources/river-status-unstable-v1.xml @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="river_status_unstable_v1"> + <copyright> + Copyright 2020 The River Developers + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + </copyright> + + <interface name="zriver_status_manager_v1" version="4"> + <description summary="manage river status objects"> + A global factory for objects that receive status information specific + to river. It could be used to implement, for example, a status bar. + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy the river_status_manager object"> + This request indicates that the client will not use the + river_status_manager object any more. Objects that have been created + through this instance are not affected. + </description> + </request> + + <request name="get_river_output_status"> + <description summary="create an output status object"> + This creates a new river_output_status object for the given wl_output. + </description> + <arg name="id" type="new_id" interface="zriver_output_status_v1"/> + <arg name="output" type="object" interface="wl_output"/> + </request> + + <request name="get_river_seat_status"> + <description summary="create a seat status object"> + This creates a new river_seat_status object for the given wl_seat. + </description> + <arg name="id" type="new_id" interface="zriver_seat_status_v1"/> + <arg name="seat" type="object" interface="wl_seat"/> + </request> + </interface> + + <interface name="zriver_output_status_v1" version="4"> + <description summary="track output tags and focus"> + This interface allows clients to receive information about the current + windowing state of an output. + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy the river_output_status object"> + This request indicates that the client will not use the + river_output_status object any more. + </description> + </request> + + <event name="focused_tags"> + <description summary="focused tags of the output"> + Sent once binding the interface and again whenever the tag focus of + the output changes. + </description> + <arg name="tags" type="uint" summary="32-bit bitfield"/> + </event> + + <event name="view_tags"> + <description summary="tag state of an output's views"> + Sent once on binding the interface and again whenever the tag state + of the output changes. + </description> + <arg name="tags" type="array" summary="array of 32-bit bitfields"/> + </event> + + <event name="urgent_tags" since="2"> + <description summary="tags of the output with an urgent view"> + Sent once on binding the interface and again whenever the set of + tags with at least one urgent view changes. + </description> + <arg name="tags" type="uint" summary="32-bit bitfield"/> + </event> + + <event name="layout_name" since="4"> + <description summary="name of the layout"> + Sent once on binding the interface should a layout name exist and again + whenever the name changes. + </description> + <arg name="name" type="string" summary="layout name"/> + </event> + + <event name="layout_name_clear" since="4"> + <description summary="name of the layout"> + Sent when the current layout name has been removed without a new one + being set, for example when the active layout generator disconnects. + </description> + </event> + </interface> + + <interface name="zriver_seat_status_v1" version="3"> + <description summary="track seat focus"> + This interface allows clients to receive information about the current + focus of a seat. Note that (un)focused_output events will only be sent + if the client has bound the relevant wl_output globals. + </description> + + <request name="destroy" type="destructor"> + <description summary="destroy the river_seat_status object"> + This request indicates that the client will not use the + river_seat_status object any more. + </description> + </request> + + <event name="focused_output"> + <description summary="the seat focused an output"> + Sent on binding the interface and again whenever an output gains focus. + </description> + <arg name="output" type="object" interface="wl_output"/> + </event> + + <event name="unfocused_output"> + <description summary="the seat unfocused an output"> + Sent whenever an output loses focus. + </description> + <arg name="output" type="object" interface="wl_output"/> + </event> + + <event name="focused_view"> + <description summary="information on the focused view"> + Sent once on binding the interface and again whenever the focused + view or a property thereof changes. The title may be an empty string + if no view is focused or the focused view did not set a title. + </description> + <arg name="title" type="string" summary="title of the focused view"/> + </event> + + <event name="mode" since="3"> + <description summary="the active mode changed"> + Sent once on binding the interface and again whenever a new mode + is entered (e.g. with riverctl enter-mode foobar). + </description> + <arg name="name" type="string" summary="name of the mode"/> + </event> + </interface> +</protocol> diff --git a/pkgs/by-name/ri/river-mk-keymap/src/cli.rs b/pkgs/by-name/ri/river-mk-keymap/src/cli.rs index e3c49310..ad872cc9 100644 --- a/pkgs/by-name/ri/river-mk-keymap/src/cli.rs +++ b/pkgs/by-name/ri/river-mk-keymap/src/cli.rs @@ -16,6 +16,20 @@ use clap::Parser; #[command(author, version, about, long_about = None)] /// A tool to manage your key mappings for the river window manager pub(super) struct Args { - /// Path to mappings JSON file - pub path: PathBuf, + #[command(subcommand)] + pub command: SubCommand, + + #[arg(long, short)] + /// Path to mapping config JSON file + pub keymap: PathBuf, +} + +#[derive(clap::Subcommand, Clone, Debug)] +pub(super) enum SubCommand { + Init { + #[arg(short, long, default_value_t = false)] + /// Only show what would be done, don't actually perform the init. + dry_run: bool, + }, + ShowHelp {}, } diff --git a/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs b/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs index e948ccfe..52a6ba8a 100644 --- a/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs +++ b/pkgs/by-name/ri/river-mk-keymap/src/key_map/commands.rs @@ -8,112 +8,306 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::process::Command; +use std::{env::current_exe, path::Path, process::Command}; -use keymaps::key_repr::{KeyValue, MediaKeyCode, MouseKeyValue}; +use anyhow::{bail, Result}; +use keymaps::key_repr::{Key, KeyValue, Keys, MediaKeyCode, ModifierKeyCode, MouseKeyValue}; +use rustix::path::Arg; -use super::{KeyMap, MapMode}; +use super::KeyMap; impl KeyMap { - #[must_use] - pub fn to_commands(self) -> Vec<Command> { - self.0 - .iter() - .flat_map(|(key, value)| { - let key = key.last().expect("Will exist"); - let mods = { - let modifiers = key.modifiers(); - let mut output = vec![]; - - if modifiers.alt() { - output.push("Alt"); - } - if modifiers.ctrl() { - output.push("Control"); - } - if modifiers.meta() { - output.push("Super"); - } - if modifiers.shift() { - output.push("Shift"); - } - if output.is_empty() { - "None".to_owned() - } else { - output.join("+") - } - }; - let key_value = match key.value() { - KeyValue::Backspace => "BackSpace".to_owned(), - KeyValue::Enter => "Enter".to_owned(), - KeyValue::Left => "Left".to_owned(), - KeyValue::Right => "Right".to_owned(), - KeyValue::Up => "Up".to_owned(), - KeyValue::Down => "Down".to_owned(), - KeyValue::Home => "Home".to_owned(), - KeyValue::End => "End".to_owned(), - KeyValue::PageUp => "Page_Up".to_owned(), - KeyValue::PageDown => "Page_Down".to_owned(), - KeyValue::Tab => "Tab".to_owned(), - KeyValue::BackTab => "BackTab".to_owned(), - KeyValue::Delete => "Delete".to_owned(), - KeyValue::Insert => "Insert".to_owned(), - KeyValue::F(num) => format!("F{num}"), - KeyValue::Char(a) => a.to_string(), - KeyValue::Null => "Null".to_owned(), - KeyValue::Esc => "Esc".to_owned(), - KeyValue::CapsLock => "CapsLock".to_owned(), - KeyValue::ScrollLock => "ScrollLock".to_owned(), - KeyValue::NumLock => "NumLock".to_owned(), - KeyValue::PrintScreen => "Print".to_owned(), - KeyValue::Pause => "Pause".to_owned(), - KeyValue::Menu => "Menu".to_owned(), - KeyValue::KeypadBegin => "KeypadBegin".to_owned(), - KeyValue::Media(media_key_code) => match media_key_code { - MediaKeyCode::Play => "XF86AudioPlay".to_owned(), - MediaKeyCode::Pause => "XF86AudioPause".to_owned(), - MediaKeyCode::PlayPause => "XF86AudioPlayPause".to_owned(), - MediaKeyCode::Reverse => "XF86AudioReverse".to_owned(), - MediaKeyCode::Stop => "XF86AudioStop".to_owned(), - MediaKeyCode::FastForward => "XF86AudioFastForward".to_owned(), - MediaKeyCode::Rewind => "XF86AudioRewind".to_owned(), - MediaKeyCode::TrackNext => "XF86AudioTrackNext".to_owned(), - MediaKeyCode::TrackPrevious => "XF86AudioTrackPrevious".to_owned(), - MediaKeyCode::Record => "XF86AudioRecord".to_owned(), - MediaKeyCode::LowerVolume => "XF86AudioLowerVolume".to_owned(), - MediaKeyCode::RaiseVolume => "XF86AudioRaiseVolume".to_owned(), - MediaKeyCode::MuteVolume => "XF86AudioMuteVolume".to_owned(), - }, - KeyValue::MouseKey(mouse_key_value) => match mouse_key_value { - MouseKeyValue::Left => "BTN_LEFT".to_owned(), - MouseKeyValue::Right => "BTN_RIGHT".to_owned(), - MouseKeyValue::Middle => "BTN_MIDDLE".to_owned(), - }, - _ => todo!(), + /// # Errors + /// If impossible requests are made. + /// + /// # Panics + /// If internal assertions fail. + #[allow(clippy::too_many_lines)] + pub fn to_commands(self, keymap_path: &Path) -> Result<Vec<Command>> { + self.0.iter().try_for_each(|(keys, value)| { + let (prefix, last) = keys.split_at(keys.len() - 1); + let prefix = prefix.to_owned(); + + if value.allow_locked && !prefix.is_empty() { + bail!( + "Only single key mappings can be used \ + in locked mode, but '{}' contains multiple ('{}').", + Keys::from(keys), + Keys::from(prefix), + ) + } + + if !prefix.is_empty() + && [ + "<ESC>".parse().expect("hardcoded"), + "<BACKSPACE>".parse().expect("hardcoded"), + ] + .contains(&last[0]) + { + bail!( + "You cannot use <ESC> or <BACKSPACE> as the final part of a \ + prefixed mapping, as that is used to return \ + to 'normal' or the upper mode; found in '{}'", + Keys::from(keys), + ) + } + + Ok(()) + })?; + + let mut output: Vec<_> = self + .0 + .into_iter() + .flat_map(|(keys, value)| { + let (prefix, mapping) = keys.split_at(keys.len() - 1); + + let (final_mode, mut base): (Option<String>, _) = + prefix + .iter() + .fold((None, vec![]), |(acc_mode, mut acc_vec), key| { + // Declare intermediate modes for each key. + let mode_name: String = { + let base = key.to_string_repr(); + + if let Some(result) = &acc_mode { + result.to_owned() + base.as_str() + } else { + base + } + }; + + let mut riverctl = Command::new("riverctl"); + riverctl.args(["declare-mode", mode_name.as_str()]); + + let mut output = vec![riverctl]; + + // Provide keymaps for entering and leaving the mode + if let Some(acc_mode) = acc_mode.clone() { + output.extend(key_to_command( + key.to_owned(), + &["enter-mode".to_owned(), mode_name.clone()], + &acc_mode, + false, + )); + } else { + // Also spawn the help display if we start from the “normal” mode. + output.extend(key_to_command( + key.to_owned(), + &[ + "spawn".to_owned(), + format!( + "{} && sleep 1 && {}", + shlex::try_join([ + "riverctl", + "enter-mode", + mode_name.as_str() + ]) + .expect("Should work"), + shlex::try_join([ + current_exe() + .expect("Should have a current exe") + .as_os_str() + .as_str() + .expect("Should be valid utf8"), + "--keymap", + keymap_path.to_str().expect("Should be valid utf8"), + "show-help", + ]) + .expect("Should work"), + ), + ], + "normal", + false, + )); + } + + // Provide a mapping for going up a mode + output.extend(key_to_command( + "<BACKSPACE>".parse().expect("Hardcoded"), + &[ + "enter-mode".to_owned(), + acc_mode.unwrap_or("normal".to_owned()), + ], + &mode_name, + false, + )); + + // Another one for going back to normal. + output.extend(key_to_command( + "<ESC>".parse().expect("Hardcoded"), + &["enter-mode".to_owned(), "normal".to_owned()], + &mode_name, + false, + )); + + acc_vec.extend(output); + + (Some(mode_name), acc_vec) + }); + + let command = if value.once { + vec![ + "spawn".to_owned(), + format!( + "riverctl {} && {}", + shlex::try_join(value.command.iter().map(String::as_str)) + .expect("Should work"), + shlex::try_join(["riverctl", "enter-mode", "normal"]) + .expect("Should work"), + ), + ] + } else { + value.command }; + base.extend(key_to_command( + mapping[0], + &command, + final_mode.as_ref().map_or("normal", |v| v.as_str()), + value.allow_locked, + )); - value - .modes - .iter() - .map(|mode| { - let mut riverctl = Command::new("riverctl"); - riverctl.args([value.map_mode.as_command(), mode, &mods, &key_value]); - - riverctl.args(value.command.iter().map(String::as_str)); - riverctl - }) - .collect::<Vec<_>>() + base }) - .collect() + .collect(); + + output.sort_by_cached_key(|cmd| format!("{cmd:?}")); + output.dedup_by_key(|cmd| format!("{cmd:?}")); + + Ok(output) } } -impl MapMode { - pub(crate) fn as_command(self) -> &'static str { - match self { - MapMode::Map => "map", - MapMode::MapMouse => "map-pointer", - MapMode::Unmap => "unmap", +fn key_value_to_xkb_common_name(value: KeyValue) -> (String, Vec<&'static str>) { + let mut extra_modifiers = vec![]; + + let output = match value { + KeyValue::Backspace => "BackSpace".to_owned(), + KeyValue::Enter => "Return".to_owned(), + KeyValue::Left => "Left".to_owned(), + KeyValue::Right => "Right".to_owned(), + KeyValue::Up => "Up".to_owned(), + KeyValue::Down => "Down".to_owned(), + KeyValue::Home => "Home".to_owned(), + KeyValue::End => "End".to_owned(), + KeyValue::PageUp => "Page_Up".to_owned(), + KeyValue::PageDown => "Page_Down".to_owned(), + KeyValue::Tab => "Tab".to_owned(), + KeyValue::BackTab => "BackTab".to_owned(), + KeyValue::Delete => "Delete".to_owned(), + KeyValue::Insert => "Insert".to_owned(), + KeyValue::F(num) => format!("F{num}"), + KeyValue::Char(a) => { + // River does not differentiate between 'a' and 'A', + // so we need to do it beforehand. + if a.is_ascii_uppercase() { + extra_modifiers.push("Shift"); + } + + if a == ' ' { + "Space".to_string() + } else { + a.to_string() + } } + KeyValue::Null => "Null".to_owned(), + KeyValue::Esc => "Escape".to_owned(), + KeyValue::CapsLock => "CapsLock".to_owned(), + KeyValue::ScrollLock => "ScrollLock".to_owned(), + KeyValue::NumLock => "NumLock".to_owned(), + KeyValue::PrintScreen => "Print".to_owned(), + KeyValue::Pause => "Pause".to_owned(), + KeyValue::Menu => "Menu".to_owned(), + KeyValue::KeypadBegin => "KeypadBegin".to_owned(), + KeyValue::Media(media_key_code) => match media_key_code { + MediaKeyCode::Play => "XF86AudioPlay".to_owned(), + MediaKeyCode::Pause => "XF86AudioPause".to_owned(), + MediaKeyCode::PlayPause => "XF86AudioPlayPause".to_owned(), + MediaKeyCode::Reverse => "XF86AudioReverse".to_owned(), + MediaKeyCode::Stop => "XF86AudioStop".to_owned(), + MediaKeyCode::FastForward => "XF86AudioFastForward".to_owned(), + MediaKeyCode::Rewind => "XF86AudioRewind".to_owned(), + MediaKeyCode::TrackNext => "XF86AudioTrackNext".to_owned(), + MediaKeyCode::TrackPrevious => "XF86AudioTrackPrevious".to_owned(), + MediaKeyCode::Record => "XF86AudioRecord".to_owned(), + MediaKeyCode::LowerVolume => "XF86AudioLowerVolume".to_owned(), + MediaKeyCode::RaiseVolume => "XF86AudioRaiseVolume".to_owned(), + MediaKeyCode::MuteVolume => "XF86AudioMute".to_owned(), + }, + KeyValue::MouseKey(mouse_key_value) => match mouse_key_value { + MouseKeyValue::Left => "BTN_LEFT".to_owned(), + MouseKeyValue::Right => "BTN_RIGHT".to_owned(), + MouseKeyValue::Middle => "BTN_MIDDLE".to_owned(), + }, + KeyValue::ModifierKey(modifier_key_code) => match modifier_key_code { + ModifierKeyCode::LeftAlt => "ALT_L".to_owned(), + ModifierKeyCode::RightAlt => "ALT_R".to_owned(), + ModifierKeyCode::LeftCtrl => "CTRL_L".to_owned(), + ModifierKeyCode::RightCtrl => "CTRL_R".to_owned(), + ModifierKeyCode::LeftMeta => "SUPER_L".to_owned(), + ModifierKeyCode::RightMeta => "SUPER_R".to_owned(), + ModifierKeyCode::LeftShift => "SHIFT_L".to_owned(), + ModifierKeyCode::RightShift => "SHIFT_R".to_owned(), + }, + other => todo!("Key value: {other} not known."), + }; + + (output, extra_modifiers) +} + +fn key_to_command(key: Key, command: &[String], mode: &str, allow_locked: bool) -> Vec<Command> { + let mut modifiers = { + let modifiers = key.modifiers(); + let mut output = vec![]; + + if modifiers.alt() { + output.push("Alt"); + } + if modifiers.ctrl() { + output.push("Control"); + } + if modifiers.meta() { + output.push("Super"); + } + if modifiers.shift() { + output.push("Shift"); + } + output + }; + + let (key_value, extra_modifiers) = key_value_to_xkb_common_name(key.value()); + modifiers.extend(extra_modifiers); + + let map_mode = if let KeyValue::MouseKey(_) = key.value() { + "map-pointer" + } else { + "map" + }; + + let modifiers = if modifiers.is_empty() { + "None".to_owned() + } else { + modifiers.join("+") + }; + + let mut output = vec![{ + let mut riverctl = Command::new("riverctl"); + riverctl.args([map_mode, mode, &modifiers, &key_value]); + + riverctl.args(command.iter().map(String::as_str)); + + riverctl + }]; + + if allow_locked { + output.push({ + let mut riverctl = Command::new("riverctl"); + riverctl.args([map_mode, "locked", &modifiers, &key_value]); + + riverctl.args(command.iter().map(String::as_str)); + + riverctl + }); } + + output } diff --git a/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs b/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs index 2c82ee05..16dc02f4 100644 --- a/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs +++ b/pkgs/by-name/ri/river-mk-keymap/src/key_map/mod.rs @@ -8,40 +8,100 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::{collections::HashMap, fmt::Display, ops::Deref, str::FromStr}; +use std::{fmt::Display, ops::Deref, str::FromStr}; -use anyhow::Context; -use keymaps::{key_repr::Key, map_tree::MapTrie}; +use anyhow::{anyhow, bail, Context, Result}; +use keymaps::{ + key_repr::{Key, Keys}, + map_tree::MapTrie, +}; use serde::{Deserialize, Serialize}; +use serde_json::{Map, Value}; pub mod commands; -#[derive(Deserialize, Serialize, Debug)] -#[allow(clippy::module_name_repetitions)] -pub struct RawKeyMap(HashMap<Key, KeyConfig>); - #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, PartialOrd)] -/// What values to use for: `riverctl <map_mode> <mode> <mods> <key> <command..>` +/// What values to use for: `riverctl <command..>` +#[serde(deny_unknown_fields)] pub struct KeyConfig { command: Vec<String>, - #[serde(default = "default_mode")] - modes: Vec<String>, + /// Whether to allow this key mapping in the “locked” mode. + #[serde(default)] + allow_locked: bool, + + /// Whether to go back to the normal mode, after running this command. + #[serde(default)] + once: bool, - #[serde(default = "MapMode::default")] - map_mode: MapMode, + /// Use a different description to display this command, instead of the `command`. + description: Option<String>, } impl FromStr for KeyMap { type Err = anyhow::Error; fn from_str(s: &str) -> Result<Self, Self::Err> { - let raw: RawKeyMap = - serde_json::from_str(s).context("Failed to parse the keymap config file as json.")?; + fn decode_value( + output: &mut MapTrie<KeyConfig>, + current_key: Vec<Key>, + value: &Value, + ) -> Result<()> { + let key_config = if let Some(value) = value.as_array() { + KeyConfig { + command: value + .iter() + .map(|v| v.as_str().map(ToOwned::to_owned)) + .collect::<Option<_>>() + .ok_or(anyhow!("A array contained a non-string value: {value:#?}"))?, + allow_locked: false, + once: false, + description: None, + } + } else if let Some(object) = value.as_object() { + if object.contains_key("command") { + serde_json::from_value(value.to_owned()) + .with_context(|| format!("Failed to parse key config: {value:#?}"))? + } else { + for (key, value) in object { + let mut local_current_key = current_key.clone(); + local_current_key.push( + Key::from_str(key) + .with_context(|| format!("Failed to parse key '{key}'"))?, + ); + + decode_value(output, local_current_key, value)?; + } + return Ok(()); + } + } else { + bail!("Value ({}) is invalid (not array or object).", value) + }; + + output + .insert(¤t_key, key_config.clone()) + .with_context(|| { + format!( + "Failed to insert mapping {} -> {key_config}", + Keys::from(current_key) + ) + })?; + + Ok(()) + } + let mut out = MapTrie::<KeyConfig>::new(); - for (key, value) in raw.0 { - out.insert(&[key], value.clone()) - .with_context(|| format!("Failed to insert mapping {key} -> {value}"))?; + + let raw: Map<String, Value> = + serde_json::from_str(s).context("Failed to parse the keymap config file as json.")?; + + for (key, value) in raw { + decode_value( + &mut out, + vec![Key::from_str(&key) + .with_context(|| format!("Failed to parse key ('{key}')"))?], + &value, + )?; } Ok(Self(out)) @@ -49,25 +109,11 @@ impl FromStr for KeyMap { } impl Display for KeyConfig { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(self.command.join(" ").as_str()) - } -} - -fn default_mode() -> Vec<String> { - vec!["normal".to_owned()] -} - -#[derive(Copy, Deserialize, Serialize, Debug, Clone, Default, PartialEq, PartialOrd)] -enum MapMode { - #[default] - Map, - MapMouse, - Unmap, -} - -impl Display for MapMode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - <Self as std::fmt::Debug>::fmt(self, f) + if let Some(desc) = &self.description { + f.write_str(desc) + } else { + f.write_str(self.command.join(" ").as_str()) + } } } diff --git a/pkgs/by-name/ri/river-mk-keymap/src/main.rs b/pkgs/by-name/ri/river-mk-keymap/src/main.rs index 63955f7f..18c291cf 100644 --- a/pkgs/by-name/ri/river-mk-keymap/src/main.rs +++ b/pkgs/by-name/ri/river-mk-keymap/src/main.rs @@ -13,31 +13,57 @@ use std::fs; use anyhow::Context; use clap::Parser; -mod cli; +pub mod cli; pub mod key_map; +pub mod wayland; use crate::{cli::Args, key_map::KeyMap}; fn main() -> Result<(), anyhow::Error> { let args = Args::parse(); - let keymap_file = fs::read_to_string(&args.path) - .with_context(|| format!("Failed to open keymap file at: '{}'.", args.path.display()))?; - - let keymap: KeyMap = keymap_file - .parse() - .with_context(|| format!("Failed to parse keymap file at: {}", args.path.display()))?; - - // println!("{keymap}"); - // println!("Commands:"); - for mut command in keymap.to_commands() { - // println!("Executing {command:?}"); - let status = command - .status() - .with_context(|| format!("Failed to run command: '{command:?}'"))?; - - if !status.success() { - eprintln!("Command ('{command:?}') returned with non zero exit code: {status}"); + + let keymap_path = &args.keymap.canonicalize().with_context(|| { + format!( + "Failed to canonicalize kepmay path: '{}'", + args.keymap.display() + ) + })?; + + let config = { + let keymap_file = fs::read_to_string(keymap_path).with_context(|| { + format!( + "Failed to open keymap file at: '{}'.", + keymap_path.display() + ) + })?; + + let keymap: KeyMap = keymap_file.parse().with_context(|| { + format!("Failed to parse keymap file at: {}", keymap_path.display()) + })?; + + keymap + }; + + match args.command { + cli::SubCommand::Init { dry_run } => { + println!("{config}"); + for mut command in config.to_commands(keymap_path)? { + if dry_run { + println!("{command:?}"); + } else { + let status = command + .status() + .with_context(|| format!("Failed to run command: '{command:?}'"))?; + + if !status.success() { + eprintln!( + "Command ('{command:?}') returned with non zero exit code: {status}" + ); + } + } + } } + cli::SubCommand::ShowHelp {} => wayland::main(config)?, } Ok(()) diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/ansi/mod.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/ansi/mod.rs new file mode 100644 index 00000000..0517ecf2 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/ansi/mod.rs @@ -0,0 +1,173 @@ +use std::mem; + +use vte::{Params, Parser, Perform}; + +#[derive(Debug, Clone, Copy)] +pub(crate) enum Color { + Black, + Red, + Green, + Yellow, + Blue, + Purple, + Cyan, + White, +} + +#[derive(Debug)] +struct Cleaner { + current_color: Option<Color>, + styles: StyledString, + current: String, +} + +#[derive(Debug)] +struct StyledStringInner { + val: String, + color: Option<Color>, +} + +pub(crate) struct StyledChar { + ch: char, + color: Option<Color>, +} + +impl StyledChar { + pub(crate) fn as_char(&self) -> char { + self.ch + } + + pub(crate) fn is_bold(&self) -> bool { + self.color.is_some() + } + + pub(crate) fn color(&self) -> Option<Color> { + self.color + } +} + +#[derive(Debug)] +pub(crate) struct StyledString { + inner: Vec<StyledStringInner>, +} + +impl StyledString { + fn push(&mut self, val: StyledStringInner) { + self.inner.push(val); + } + + pub(crate) fn chars(&self) -> impl Iterator<Item = StyledChar> + use<'_> { + self.inner.iter().flat_map(|inner| { + inner.val.chars().map(|ch| StyledChar { + ch, + color: inner.color, + }) + }) + } +} + +impl Cleaner { + fn reset_color(&mut self) { + self.styles.push(StyledStringInner { + val: mem::take(&mut self.current), + color: mem::take(&mut self.current_color), + }); + } + + fn set_color(&mut self, color: Color) { + self.current_color = Some(color); + } + + fn add_char(&mut self, c: char) { + self.current.push(c); + } +} + +impl Perform for Cleaner { + fn print(&mut self, c: char) { + self.add_char(c); + } + + fn execute(&mut self, byte: u8) { + if byte == b'\n' { + self.reset_color(); + self.add_char('\n'); + self.reset_color(); + } else { + eprintln!("Unknown [execute]: {byte:02x}"); + } + } + + fn hook(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { + eprintln!( + "Unknown [hook] params={params:?}, intermediates={intermediates:?}, ignore={ignore:?}, char={c:?}" + ); + } + + fn put(&mut self, byte: u8) { + eprintln!("Unknonw [put] {byte:02x}"); + } + + fn unhook(&mut self) { + eprintln!("Unknown [unhook]"); + } + + fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) { + eprintln!("Unkown [osc_dispatch] params={params:?} bell_terminated={bell_terminated}"); + } + + fn csi_dispatch(&mut self, params: &Params, _: &[u8], _: bool, c: char) { + let params: Vec<u16> = params.iter().flatten().copied().collect(); + + if c != 'm' { + return; + } + + // See: https://gist.github.com/JBlond/2fea43a3049b38287e5e9cefc87b2124 + match params[..] { + [0] => self.reset_color(), + // [0, regular] if matches!(regular, 30..=37) => {} + [1, bold] if matches!(bold, 30..=37) => match bold { + 30 => self.set_color(Color::Black), + 31 => self.set_color(Color::Red), + 32 => self.set_color(Color::Green), + 36 => self.set_color(Color::Yellow), + 34 => self.set_color(Color::Blue), + 35 => self.set_color(Color::Purple), + 33 => self.set_color(Color::Cyan), + 37 => self.set_color(Color::White), + _ => unreachable!("Was filtered out"), + }, + // [4, underline] if matches!(underline, 30..=37) => {} + // [background] if matches!(background, 40..=47) => {} + _ => todo!(), + } + + // println!( + // "[csi_dispatch] params={:#?}, intermediates={:?}, ignore={:?}, char={:?}", + // params, intermediates, ignore, c + // ); + } + + fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) { + eprintln!( + "Unkown [esc_dispatch] intermediates={intermediates:?}, ignore={ignore:?}, byte={byte:02x}" + ); + } +} + +pub(crate) fn parse(input: &str) -> StyledString { + let mut statemachine = Parser::new(); + let mut performer = Cleaner { + current_color: None, + styles: StyledString { inner: vec![] }, + current: String::new(), + }; + + let buf: Vec<_> = input.bytes().collect(); + + statemachine.advance(&mut performer, &buf[..]); + + assert!(performer.current.is_empty() && performer.current_color.is_none()); + performer.styles +} diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/dispatches.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/dispatches.rs new file mode 100644 index 00000000..c6e04fdf --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/dispatches.rs @@ -0,0 +1,214 @@ +use std::num::NonZero; + +use keymaps::key_repr::Key; +use wayland_client::{ + globals::GlobalListContents, + protocol::{ + wl_buffer::WlBuffer, wl_compositor::WlCompositor, wl_registry, wl_seat::WlSeat, + wl_shm::WlShm, wl_shm_pool::WlShmPool, wl_surface::WlSurface, + }, + Connection, Dispatch, QueueHandle, +}; + +use wayland_protocols_wlr::layer_shell::v1::client::{ + zwlr_layer_shell_v1::ZwlrLayerShellV1, + zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1}, +}; + +use crate::wayland::{ + ansi, render, + river::protocols::river_protocols::{ + zriver_seat_status_v1::{self, ZriverSeatStatusV1}, + zriver_status_manager_v1::ZriverStatusManagerV1, + }, + AppData, +}; + +impl Dispatch<ZriverSeatStatusV1, ()> for AppData { + fn event( + state: &mut Self, + _: &ZriverSeatStatusV1, + event: <ZriverSeatStatusV1 as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + if let zriver_seat_status_v1::Event::Mode { name } = event { + let new_text = { + if name == "normal" { + // We are back at the normal mode. + // There is no need to display the mappings anymore, exit. + state.should_exit = true; + return; + } else if let Ok(keys) = Key::parse_multiple(&name) { + if let Some(val) = state.config.get(&keys) { + ansi::parse(val.to_string().as_str()) + } else { + // Mode name not know, do nothing. + return; + } + } else { + // Mode name not valid, do nothing. + return; + } + }; + + let px_height; + (state.pixel_data, (state.max_px_width, px_height)) = + render::text(&new_text).expect("Works?"); + + // We add the `5` here, so that our letters don't stop exactly at the border. + state + .window + .0 + .set_size(state.max_px_width + 5, px_height + 5); + state.window.1.commit(); + + if state.configured { + state.draw(); + } + } + } +} + +impl Dispatch<ZwlrLayerSurfaceV1, ()> for AppData { + fn event( + state: &mut Self, + proxy: &ZwlrLayerSurfaceV1, + event: <ZwlrLayerSurfaceV1 as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + match event { + zwlr_layer_surface_v1::Event::Configure { + serial, + width, + height, + } => { + state.buffer = None; + + proxy.ack_configure(serial); + + state.width = NonZero::new(width).map_or_else(|| state.width, NonZero::get); + state.height = NonZero::new(height).map_or_else(|| state.height, NonZero::get); + + state.draw(); + + state.configured = true; + } + zwlr_layer_surface_v1::Event::Closed => { + state.should_exit = true; + } + _ => (), + } + } +} + +impl Dispatch<wl_registry::WlRegistry, GlobalListContents> for AppData { + fn event( + _: &mut AppData, + _: &wl_registry::WlRegistry, + _: wl_registry::Event, + _: &GlobalListContents, + _: &Connection, + _: &QueueHandle<AppData>, + ) { + } +} + +impl Dispatch<WlShmPool, ()> for AppData { + fn event( + _: &mut Self, + _: &WlShmPool, + _: <WlShmPool as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + } +} + +impl Dispatch<WlShm, ()> for AppData { + fn event( + _: &mut Self, + _: &WlShm, + _: <WlShm as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + } +} + +impl Dispatch<WlSurface, ()> for AppData { + fn event( + _: &mut Self, + _: &WlSurface, + _: <WlSurface as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + } +} + +impl Dispatch<WlCompositor, ()> for AppData { + fn event( + _: &mut Self, + _: &WlCompositor, + _: <WlCompositor as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + } +} + +impl Dispatch<WlSeat, ()> for AppData { + fn event( + _: &mut Self, + _: &WlSeat, + _: <WlSeat as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + } +} + +impl Dispatch<WlBuffer, ()> for AppData { + fn event( + _: &mut Self, + _: &WlBuffer, + _: <WlBuffer as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + } +} + +impl Dispatch<ZriverStatusManagerV1, ()> for AppData { + fn event( + _: &mut Self, + _: &ZriverStatusManagerV1, + _: <ZriverStatusManagerV1 as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + } +} + +impl Dispatch<ZwlrLayerShellV1, ()> for AppData { + fn event( + _: &mut Self, + _: &ZwlrLayerShellV1, + _: <ZwlrLayerShellV1 as wayland_client::Proxy>::Event, + (): &(), + _: &Connection, + _: &QueueHandle<Self>, + ) { + } +} diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/mod.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/mod.rs new file mode 100644 index 00000000..44c010d5 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/mod.rs @@ -0,0 +1,272 @@ +#![allow( + clippy::cast_sign_loss, + clippy::cast_possible_wrap, + clippy::cast_precision_loss, + clippy::cast_possible_truncation +)] + +use anyhow::Result; +use wayland_client::{ + globals::registry_queue_init, + protocol::{ + wl_compositor::WlCompositor, + wl_seat::WlSeat, + wl_shm::{self, WlShm}, + wl_surface::WlSurface, + }, + Connection, +}; +use wayland_protocols_wlr::layer_shell::v1::client::{ + zwlr_layer_shell_v1::{self, ZwlrLayerShellV1}, + zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1}, +}; + +use crate::{ + key_map::KeyMap, + wayland::{ + ansi::Color, + river::protocols::river_protocols::zriver_status_manager_v1::ZriverStatusManagerV1, + shm::slot::{Buffer, SlotPool}, + }, +}; + +mod ansi; +mod render; +mod river; +mod shm; + +mod dispatches; + +struct AppData { + pool: SlotPool, + window: (ZwlrLayerSurfaceV1, WlSurface), + + configured: bool, + buffer: Option<Buffer>, + + width: u32, + height: u32, + + max_px_width: u32, + pixel_data: (Vec<f32>, Vec<Option<Color>>), + + config: KeyMap, + should_exit: bool, +} + +impl AppData { + #[allow(clippy::too_many_lines)] + fn draw(&mut self) { + let width = self.width; + let height = self.height; + let stride = self.width as i32 * 4; + + let buffer = self.buffer.get_or_insert_with(|| { + self.pool + .create_buffer( + width as i32, + height as i32, + stride, + wl_shm::Format::Argb8888, + ) + .expect("Works?") + .0 + }); + + let canvas = if let Some(canvas) = self.pool.canvas(buffer) { + canvas + } else { + // This should be rare, but if the compositor has not released the previous + // buffer, we need double-buffering. + let (second_buffer, canvas) = self + .pool + .create_buffer( + self.width as i32, + self.height as i32, + stride, + wl_shm::Format::Argb8888, + ) + .expect("create buffer"); + *buffer = second_buffer; + canvas + }; + + // Draw to the window. + { + canvas + .chunks_exact_mut(stride as usize) + .enumerate() + .for_each(|(row_index, row)| { + // let row_slice = row_slice(self.height, row_index as u32, 0.97); + // let allowed_columns = (f64::from(self.width) * row_slice).ceil() as usize; + + row.chunks_exact_mut(4) + .enumerate() + .for_each(|(column_index, chunk)| { + // const BACKGROUND_COLOR: u32 = 0xee58_5b70; + const BACKGROUND_COLOR: u32 = 0xee00_0000; + + assert!(column_index as u32 <= self.width); + + // if column_index > allowed_columns + // || column_index < (self.width as usize - allowed_columns) + // { + // let array: &mut [u8; 4] = chunk.try_into().unwrap(); + // *array = 0u32.to_le_bytes(); + // return; + // } + + if column_index >= (self.max_px_width as usize) { + let array: &mut [u8; 4] = chunk.try_into().unwrap(); + *array = BACKGROUND_COLOR.to_le_bytes(); + } else { + assert!(column_index < self.max_px_width as usize); + + let position = + column_index + row_index * self.max_px_width as usize; + + if let Some(coverage) = &self.pixel_data.0.get(position) { + let a = (BACKGROUND_COLOR & (0xff << (6 * 4))) >> 24; + + let (r, g, b) = if let Some(color) = self + .pixel_data + .1 + .get(position) + .expect("If the pixel is set, the color will too") + { + let (r, g, b) = match color { + Color::Black => (0, 0, 0), + Color::Red => (0xff, 0, 0), + Color::Green => (0, 0xff, 0), + Color::Yellow => (0xff, 0xff, 0), + Color::Blue => (0, 0, 0xff), + Color::Purple => (0x80, 0, 0x80), + Color::Cyan => (0, 0xff, 0xff), + Color::White => (0xff, 0xff, 0xff), + }; + + let r = (r as f32 * **coverage).ceil() as u32; + let g = (g as f32 * **coverage).ceil() as u32; + let b = (b as f32 * **coverage).ceil() as u32; + + (r, g, b) + } else { + let r = (255.0 * **coverage).ceil() as u32; + let g = (255.0 * **coverage).ceil() as u32; + let b = (255.0 * **coverage).ceil() as u32; + + (r, g, b) + }; + + let color: u32 = (a << 24) + (r << 16) + (g << 8) + b; + + let array: &mut [u8; 4] = chunk.try_into().unwrap(); + *array = color.to_le_bytes(); + } else { + let array: &mut [u8; 4] = chunk.try_into().unwrap(); + *array = BACKGROUND_COLOR.to_le_bytes(); + } + } + }); + }); + } + + self.window + .1 + .damage_buffer(0, 0, self.width as i32, self.height as i32); + + buffer.attach_to(&self.window.1).expect("works"); + self.window.1.commit(); + } +} + +/// # Errors +/// If a protocol error arises. +pub fn main(config: KeyMap) -> Result<()> { + let conn = Connection::connect_to_env()?; + let (globals, mut queue) = registry_queue_init::<AppData>(&conn)?; + let qh = queue.handle(); + + let seat: WlSeat = globals.bind(&qh, 9..=9, ())?; + let status_manager: ZriverStatusManagerV1 = globals.bind(&qh, 4..=4, ())?; + let _seat_status = status_manager.get_river_seat_status(&seat, &qh, ()); + + let compositor: WlCompositor = globals.bind(&qh, 6..=6, ())?; + let shm: WlShm = globals.bind(&qh, 1..=1, ())?; + // let xdg_wm: XdgWmBase = globals.bind(&qh, 5..=5, ())?; + + let surface = compositor.create_surface(&qh, ()); + let pool = SlotPool::new(1024 * 1024, &shm)?; + + let zwlr_layer_shell: ZwlrLayerShellV1 = globals.bind(&qh, 4..=4, ())?; + let layer_surface = zwlr_layer_shell.get_layer_surface( + &surface, + None, + zwlr_layer_shell_v1::Layer::Overlay, + "river-mk-keymap which-key".to_owned(), + &qh, + (), + ); + + layer_surface.set_size(256, 256); + layer_surface + .set_anchor(zwlr_layer_surface_v1::Anchor::Left | zwlr_layer_surface_v1::Anchor::Top); + + surface.commit(); + + let mut me = AppData { + config, + should_exit: false, + + configured: false, + buffer: None, + + width: 256, + height: 256, + + max_px_width: 0, + pixel_data: (vec![], vec![]), + + window: (layer_surface, surface), + + pool, + }; + + loop { + queue.blocking_dispatch(&mut me)?; + + if me.should_exit { + break; + } + } + + Ok(()) +} + +// /// Calculate which amount of the current row (`i`) should be painted, if we want a corner +// /// rounding of percent `p` and have an total of `n` rows. +// fn row_slice(n_u32: u32, i_u32: u32, p: f64) -> f64 { +// fn within_tolerance(a: f64, b: f64) -> bool { +// const ALLOWED_ERROR: f64 = 0.000_000_1; +// +// (a - b).abs() < ALLOWED_ERROR +// } +// +// let i = f64::from(i_u32); +// let n = f64::from(n_u32); +// +// let out = p + (1.0 - p) * (PI * i / n).sin(); +// +// assert!(out >= 0.0); +// assert!(out <= 1.0); +// +// if i_u32 == 0 || i_u32 == n_u32 { +// assert!(within_tolerance(out, p)); +// } +// +// if i_u32 < n_u32 / 2 { +// assert!(within_tolerance(out, row_slice(n_u32, n_u32 - i_u32, p))); +// } +// +// out +// } diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs new file mode 100644 index 00000000..7f0aaec9 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/layout.rs @@ -0,0 +1,57 @@ +use ab_glyph::{point, Font, Glyph, Point, ScaleFont}; + +use crate::wayland::ansi::{StyledChar, StyledString}; + +/// Simple paragraph layout for glyphs into `target`. +/// Starts at position `(0, ascent)`. +/// +/// This is for testing and examples. +pub(super) fn layout_paragraph<F, SF, BF, BSF>( + font: SF, + bold_font: BSF, + position: Point, + max_width: f32, + text: &StyledString, + target: &mut Vec<(Glyph, StyledChar)>, +) where + F: Font, + SF: ScaleFont<F>, + BF: Font, + BSF: ScaleFont<BF>, +{ + let v_advance = font.height() + font.line_gap(); + let mut caret = position + point(0.0, font.ascent()); + let mut last_glyph: Option<Glyph> = None; + + for c in text.chars() { + if c.as_char().is_control() { + if c.as_char() == '\n' { + caret = point(position.x, caret.y + v_advance); + last_glyph = None; + } + continue; + } + + let mut glyph = if c.is_bold() { + bold_font.scaled_glyph(c.as_char()) + } else { + font.scaled_glyph(c.as_char()) + }; + + if let Some(previous) = last_glyph.take() { + caret.x += font.kern(previous.id, glyph.id); + } + glyph.position = caret; + + last_glyph = Some(glyph.clone()); + caret.x += font.h_advance(glyph.id); + + if !c.as_char().is_whitespace() && caret.x > position.x + max_width { + caret = point(position.x, caret.y + v_advance); + glyph.position = caret; + last_glyph = None; + } + + target.push((glyph, c)); + } +} diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/mod.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/mod.rs new file mode 100644 index 00000000..e92def3c --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/render/mod.rs @@ -0,0 +1,129 @@ +use std::{fs::File, io::Read}; + +use ab_glyph::{point, Font, FontVec, PxScale, ScaleFont}; +use anyhow::{Context, Result}; +use font_kit::{ + family_name::FamilyName, handle::Handle, properties::Properties, source::SystemSource, +}; + +use crate::wayland::ansi::{Color, StyledString}; + +mod layout; + +fn get_font(weight: f32) -> Result<impl Font> { + let handle = SystemSource::new() + .select_best_match( + &[FamilyName::Monospace], + Properties::new().weight(font_kit::properties::Weight(weight)), + ) + .context("Failed to find a monospace font")?; + + match handle { + Handle::Path { path, font_index } => { + let data = { + let mut buffer = vec![]; + + let mut file = File::open(&path)?; + file.read_to_end(&mut buffer)?; + buffer + }; + + FontVec::try_from_vec_and_index(data, font_index).with_context(|| { + format!( + "Failed to load font at '{}' with index {}", + path.display(), + font_index + ) + }) + } + Handle::Memory { .. } => unimplemented!(), + } +} + +pub(super) type ColorVec = (Vec<f32>, Vec<Option<Color>>); +pub(super) fn text(input: &StyledString) -> Result<(ColorVec, (u32, u32))> { + let normal_font = get_font(400.0)?; + let bold_font = get_font(600.0)?; + + let height: f32 = 15.0; + let px_height = height.ceil() as usize; + + let scale = PxScale { + x: height, + y: height, + }; + + let scaled_font = normal_font.into_scaled(scale); + let bold_scaled_font = bold_font.into_scaled(scale); + + let mut glyphs = Vec::new(); + layout::layout_paragraph( + &scaled_font, + &bold_scaled_font, + point(0.0, 0.0), + 9999.0, + input, + &mut glyphs, + ); + + let px_width = glyphs + .iter() + .fold(0.0, |acc, (g, c)| { + let next = g.position.x + + if c.is_bold() { + bold_scaled_font.h_advance(g.id) + } else { + scaled_font.h_advance(g.id) + }; + + if next > acc { + next + } else { + acc + } + }) + .ceil() as usize; + + // Rasterise to a f32 alpha vec + let mut pixel_data = vec![0.0; px_width * px_height]; + let mut color_data = vec![None; px_width * px_height]; + for (g, c) in glyphs { + let maybe_glyph = if c.is_bold() { + bold_scaled_font.outline_glyph(g) + } else { + scaled_font.outline_glyph(g) + }; + + if let Some(og) = maybe_glyph { + let bounds = og.px_bounds(); + og.draw(|x, y, v| { + let x = x as f32 + bounds.min.x; + let y = y as f32 + bounds.min.y; + let next_idx = x as usize + y as usize * px_width; + + assure_idx(&mut pixel_data, next_idx, 0.0); + assure_idx(&mut color_data, next_idx, None); + + // save the coverage alpha + pixel_data[next_idx] += v; + color_data[next_idx] = c.color(); + }); + } + } + + let len = pixel_data.len(); + Ok(( + (pixel_data, color_data), + (px_width as u32, (len / px_width) as u32), + )) +} + +fn assure_idx<T: Copy + Clone>(pixel_data: &mut Vec<T>, next_idx: usize, fill: T) { + let last = pixel_data.len() - 1; + + if next_idx > last { + let needed = next_idx - last; + + pixel_data.extend(vec![fill; needed]); + } +} diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/river/mod.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/river/mod.rs new file mode 100644 index 00000000..f17c7ac8 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/river/mod.rs @@ -0,0 +1 @@ +pub(crate) mod protocols; diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/river/protocols.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/river/protocols.rs new file mode 100644 index 00000000..e54b65e1 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/river/protocols.rs @@ -0,0 +1,28 @@ +pub(crate) mod river_protocols { + use wayland_client; + // import objects from the core protocol if needed + use wayland_client::protocol::{wl_output, wl_seat}; + + // This module hosts a low-level representation of the protocol objects + // you will not need to interact with it yourself, but the code generated + // by the generate_client_code! macro will use it + // import the interfaces from the core protocol if needed + + #[allow(non_upper_case_globals)] + pub(crate) mod __status { + use wayland_client::backend as wayland_backend; + use wayland_client::protocol::__interfaces::{ + wl_output_interface, wl_seat_interface, WL_OUTPUT_INTERFACE, WL_SEAT_INTERFACE, + }; + wayland_scanner::generate_interfaces!("./resources/river-status-unstable-v1.xml"); + } + + use self::__status::{ + ZRIVER_OUTPUT_STATUS_V1_INTERFACE, ZRIVER_SEAT_STATUS_V1_INTERFACE, + ZRIVER_STATUS_MANAGER_V1_INTERFACE, + }; + + // This macro generates the actual types that represent the wayland objects of + // your custom protocol + wayland_scanner::generate_client_code!("./resources/river-status-unstable-v1.xml"); +} diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/mod.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/mod.rs new file mode 100644 index 00000000..65d3c590 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/mod.rs @@ -0,0 +1,21 @@ +#![allow(dead_code)] + +pub(crate) mod multi; +pub(crate) mod raw; +pub(crate) mod slot; + +use std::io; + +use wayland_client::globals::GlobalError; + +/// An error that may occur when creating a pool. +#[derive(Debug, thiserror::Error)] +pub enum CreatePoolError { + /// The [`wl_shm`] global is not bound. + #[error(transparent)] + Global(#[from] GlobalError), + + /// Error while allocating the shared memory. + #[error(transparent)] + Create(#[from] io::Error), +} diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/multi.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/multi.rs new file mode 100644 index 00000000..0b1fdc1b --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/multi.rs @@ -0,0 +1,437 @@ +//! A pool implementation which automatically manage buffers. +//! +//! This pool is built on the [`RawPool`]. +//! +//! The [`MultiPool`] takes a key which is used to identify buffers and tries to return the buffer associated to the key +//! if possible. If no buffer in the pool is associated to the key, it will create a new one. +//! +//! # Example +//! +//! ```rust +//! use smithay_client_toolkit::reexports::client::{ +//! QueueHandle, +//! protocol::wl_surface::WlSurface, +//! protocol::wl_shm::Format, +//! }; +//! use smithay_client_toolkit::shm::multi::MultiPool; +//! +//! struct WlFoo { +//! // The surface we'll draw on and the index of buffer associated to it +//! surface: (WlSurface, usize), +//! pool: MultiPool<(WlSurface, usize)> +//! } +//! +//! impl WlFoo { +//! fn draw(&mut self, qh: &QueueHandle<WlFoo>) { +//! let surface = &self.surface.0; +//! // We'll increment "i" until the pool can create a new buffer +//! // if there's no buffer associated with our surface and "i" or if +//! // a buffer with the obuffer associated with our surface and "i" is free for use. +//! // +//! // There's no limit to the amount of buffers we can allocate to our surface but since +//! // shm buffers are released fairly fast, it's unlikely we'll need more than double buffering. +//! for i in 0..2 { +//! self.surface.1 = i; +//! if let Ok((offset, buffer, slice)) = self.pool.create_buffer( +//! 100, +//! 100 * 4, +//! 100, +//! &self.surface, +//! Format::Argb8888, +//! ) { +//! /* +//! insert drawing code here +//! */ +//! surface.attach(Some(buffer), 0, 0); +//! surface.commit(); +//! // We exit the function after the draw. +//! return; +//! } +//! } +//! /* +//! If there's no buffer available we can for example request a frame callback +//! and trigger a redraw when it fires. +//! (not shown in this example) +//! */ +//! } +//! } +//! +//! fn draw(slice: &mut [u8]) { +//! todo!() +//! } +//! +//! ``` +//! + +use std::borrow::Borrow; +use std::io; +use std::os::unix::io::OwnedFd; + +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, +}; +use wayland_client::backend::protocol::Message; +use wayland_client::backend::{Backend, ObjectData, ObjectId}; +use wayland_client::{ + protocol::{wl_buffer, wl_shm}, + Proxy, +}; + +use crate::wayland::shm::CreatePoolError; + +use super::raw::RawPool; + +#[derive(Debug, thiserror::Error)] +pub(crate) enum PoolError { + #[error("buffer is currently used")] + InUse, + #[error("buffer is overlapping another")] + Overlap, + #[error("buffer could not be found")] + NotFound, +} + +/// This pool manages buffers associated with keys. +/// Only one buffer can be attributed to a given key. +#[derive(Debug)] +pub(crate) struct MultiPool<K> { + buffer_list: Vec<BufferSlot<K>>, + pub(crate) inner: RawPool, +} + +#[derive(Debug, thiserror::Error)] +pub(crate) struct BufferSlot<K> { + free: Arc<AtomicBool>, + size: usize, + used: usize, + offset: usize, + buffer: Option<wl_buffer::WlBuffer>, + key: K, +} + +impl<K> Drop for BufferSlot<K> { + fn drop(&mut self) { + self.destroy().ok(); + } +} + +impl<K> BufferSlot<K> { + pub(crate) fn destroy(&self) -> Result<(), PoolError> { + self.buffer + .as_ref() + .ok_or(PoolError::NotFound) + .and_then(|buffer| { + self.free + .load(Ordering::Relaxed) + .then(|| buffer.destroy()) + .ok_or(PoolError::InUse) + }) + } +} + +impl<K> MultiPool<K> { + pub(crate) fn new(shm: &wl_shm::WlShm) -> Result<Self, CreatePoolError> { + Ok(Self { + inner: RawPool::new(4096, shm)?, + buffer_list: Vec::new(), + }) + } + + /// Resizes the memory pool, notifying the server the pool has changed in size. + /// + /// The [`wl_shm`] protocol only allows the pool to be made bigger. If the new size is smaller than the + /// current size of the pool, this function will do nothing. + pub(crate) fn resize(&mut self, size: usize) -> io::Result<()> { + self.inner.resize(size) + } + + /// Removes the buffer with the given key from the pool and rearranges the others. + pub(crate) fn remove<Q>(&mut self, key: &Q) -> Option<BufferSlot<K>> + where + Q: PartialEq, + K: Borrow<Q>, + { + self.buffer_list + .iter() + .enumerate() + .find(|(_, slot)| slot.key.borrow().eq(key)) + .map(|(i, _)| i) + .map(|i| self.buffer_list.remove(i)) + } + + /// Insert a buffer into the pool. + /// + /// The parameters are: + /// + /// - `width`: the width of this buffer (in pixels) + /// - `height`: the height of this buffer (in pixels) + /// - `stride`: distance (in bytes) between the beginning of a row and the next one + /// - `key`: a borrowed form of the stored key type + /// - `format`: the encoding format of the pixels. + pub(crate) fn insert<Q>( + &mut self, + width: i32, + stride: i32, + height: i32, + key: &Q, + format: wl_shm::Format, + ) -> Result<usize, PoolError> + where + K: Borrow<Q>, + Q: PartialEq + ToOwned<Owned = K>, + { + let mut offset = 0; + let mut found_key = false; + let size = (stride * height) as usize; + let mut index = Err(PoolError::NotFound); + + for (i, buf_slot) in self.buffer_list.iter_mut().enumerate() { + if buf_slot.key.borrow().eq(key) { + found_key = true; + if buf_slot.free.load(Ordering::Relaxed) { + // Destroys the buffer if it's resized + if size != buf_slot.used { + if let Some(buffer) = buf_slot.buffer.take() { + buffer.destroy(); + } + } + // Increases the size of the Buffer if it's too small and add 5% padding. + // It is possible this buffer overlaps the following but the else if + // statement prevents this buffer from being returned if that's the case. + buf_slot.size = buf_slot.size.max(size + size / 20); + index = Ok(i); + } else { + index = Err(PoolError::InUse); + } + // If a buffer is resized, it is likely that the followings might overlap + } else if offset > buf_slot.offset { + // When the buffer is free, it's safe to shift it because we know the compositor won't try to read it. + if buf_slot.free.load(Ordering::Relaxed) { + if offset != buf_slot.offset { + if let Some(buffer) = buf_slot.buffer.take() { + buffer.destroy(); + } + } + buf_slot.offset = offset; + } else { + // If one of the overlapping buffers is busy, then no buffer can be returned because it could result in a data race. + index = Err(PoolError::InUse); + } + } else if found_key { + break; + } + let size = (buf_slot.size + 63) & !63; + offset += size; + } + + if !found_key { + if let Err(err) = index { + return self + .dyn_resize(offset, width, stride, height, key.to_owned(), format) + .map(|()| self.buffer_list.len() - 1) + .ok_or(err); + } + } + + index + } + + /// Retreives the buffer associated with the given key. + /// + /// The parameters are: + /// + /// - `width`: the width of this buffer (in pixels) + /// - `height`: the height of this buffer (in pixels) + /// - `stride`: distance (in bytes) between the beginning of a row and the next one + /// - `key`: a borrowed form of the stored key type + /// - `format`: the encoding format of the pixels. + pub(crate) fn get<Q>( + &mut self, + width: i32, + stride: i32, + height: i32, + key: &Q, + format: wl_shm::Format, + ) -> Option<(usize, &wl_buffer::WlBuffer, &mut [u8])> + where + Q: PartialEq, + K: Borrow<Q>, + { + let len = self.inner.len(); + let size = (stride * height) as usize; + let buf_slot = self + .buffer_list + .iter_mut() + .find(|buf_slot| buf_slot.key.borrow().eq(key))?; + + if buf_slot.size >= size { + return None; + } + + buf_slot.used = size; + let offset = buf_slot.offset; + if buf_slot.buffer.is_none() { + if offset + size > len { + self.inner.resize(offset + size + size / 20).ok()?; + } + let free = Arc::new(AtomicBool::new(true)); + let data = BufferObjectData { free: free.clone() }; + let buffer = self.inner.create_buffer_raw( + offset as i32, + width, + height, + stride, + format, + Arc::new(data), + ); + buf_slot.free = free; + buf_slot.buffer = Some(buffer); + } + let buf = buf_slot.buffer.as_ref()?; + buf_slot.free.store(false, Ordering::Relaxed); + Some((offset, buf, &mut self.inner.mmap()[offset..][..size])) + } + + /// Returns the buffer associated with the given key and its offset (usize) in the mempool. + /// + /// The parameters are: + /// + /// - `width`: the width of this buffer (in pixels) + /// - `height`: the height of this buffer (in pixels) + /// - `stride`: distance (in bytes) between the beginning of a row and the next one + /// - `key`: a borrowed form of the stored key type + /// - `format`: the encoding format of the pixels. + /// + /// The offset can be used to determine whether or not a buffer was moved in the mempool + /// and by consequence if it should be damaged partially or fully. + pub(crate) fn create_buffer<Q>( + &mut self, + width: i32, + stride: i32, + height: i32, + key: &Q, + format: wl_shm::Format, + ) -> Result<(usize, &wl_buffer::WlBuffer, &mut [u8]), PoolError> + where + K: Borrow<Q>, + Q: PartialEq + ToOwned<Owned = K>, + { + let index = self.insert(width, stride, height, key, format)?; + self.get_at(index, width, stride, height, format) + } + + /// Retreives the buffer at the given index. + fn get_at( + &mut self, + index: usize, + width: i32, + stride: i32, + height: i32, + format: wl_shm::Format, + ) -> Result<(usize, &wl_buffer::WlBuffer, &mut [u8]), PoolError> { + let len = self.inner.len(); + let size = (stride * height) as usize; + let buf_slot = self.buffer_list.get_mut(index).ok_or(PoolError::NotFound)?; + + if size > buf_slot.size { + return Err(PoolError::Overlap); + } + + buf_slot.used = size; + let offset = buf_slot.offset; + if buf_slot.buffer.is_none() { + if offset + size > len { + self.inner + .resize(offset + size + size / 20) + .map_err(|_| PoolError::Overlap)?; + } + let free = Arc::new(AtomicBool::new(true)); + let data = BufferObjectData { free: free.clone() }; + let buffer = self.inner.create_buffer_raw( + offset as i32, + width, + height, + stride, + format, + Arc::new(data), + ); + buf_slot.free = free; + buf_slot.buffer = Some(buffer); + } + buf_slot.free.store(false, Ordering::Relaxed); + let buf = buf_slot.buffer.as_ref().unwrap(); + Ok((offset, buf, &mut self.inner.mmap()[offset..][..size])) + } + + /// Calcule the offet and size of a buffer based on its stride. + fn offset(mut offset: i32, stride: i32, height: i32) -> (usize, usize) { + // bytes per pixel + let size = stride * height; + // 5% padding. + offset += offset / 20; + offset = (offset + 63) & !63; + (offset as usize, size as usize) + } + + #[allow(clippy::too_many_arguments)] + /// Resizes the pool and appends a new buffer. + fn dyn_resize( + &mut self, + offset: usize, + width: i32, + stride: i32, + height: i32, + key: K, + format: wl_shm::Format, + ) -> Option<()> { + let (offset, size) = Self::offset(offset as i32, stride, height); + if self.inner.len() < offset + size { + self.resize(offset + size + size / 20).ok()?; + } + let free = Arc::new(AtomicBool::new(true)); + let data = BufferObjectData { free: free.clone() }; + let buffer = self.inner.create_buffer_raw( + offset as i32, + width, + height, + stride, + format, + Arc::new(data), + ); + self.buffer_list.push(BufferSlot { + offset, + used: 0, + free, + buffer: Some(buffer), + size, + key, + }); + Some(()) + } +} + +struct BufferObjectData { + free: Arc<AtomicBool>, +} + +impl ObjectData for BufferObjectData { + fn event( + self: Arc<Self>, + _backend: &Backend, + msg: Message<ObjectId, OwnedFd>, + ) -> Option<Arc<dyn ObjectData>> { + debug_assert!(wayland_client::backend::protocol::same_interface( + msg.sender_id.interface(), + wl_buffer::WlBuffer::interface() + )); + debug_assert!(msg.opcode == 0); + + // wl_buffer only has a single event: wl_buffer.release + self.free.store(true, Ordering::Relaxed); + + None + } + + fn destroyed(&self, _: ObjectId) {} +} diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/raw.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/raw.rs new file mode 100644 index 00000000..a12afaa0 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/raw.rs @@ -0,0 +1,290 @@ +//! A raw shared memory pool handler. +//! +//! This is intended as a safe building block for higher level shared memory pool abstractions and is not +//! encouraged for most library users. + +use rustix::{ + io::Errno, + shm::{Mode, OFlags}, +}; +use std::{ + fs::File, + io, + ops::Deref, + os::unix::prelude::{AsFd, BorrowedFd, OwnedFd}, + sync::Arc, + time::{SystemTime, UNIX_EPOCH}, +}; + +use memmap2::MmapMut; +use wayland_client::{ + backend::ObjectData, + protocol::{wl_buffer, wl_shm, wl_shm_pool}, + Dispatch, Proxy, QueueHandle, WEnum, +}; + +use super::CreatePoolError; + +/// A raw handler for file backed shared memory pools. +/// +/// This type of pool will create the SHM memory pool and provide a way to resize the pool. +/// +/// This pool does not release buffers. If you need this, use one of the higher level pools. +#[derive(Debug)] +pub struct RawPool { + pool: DestroyOnDropPool, + len: usize, + mem_file: File, + mmap: MmapMut, +} + +impl RawPool { + pub fn new(len: usize, shm: &wl_shm::WlShm) -> Result<RawPool, CreatePoolError> { + let shm_fd = RawPool::create_shm_fd()?; + let mem_file = File::from(shm_fd); + mem_file.set_len(len as u64)?; + + let pool = shm + .send_constructor( + wl_shm::Request::CreatePool { + fd: mem_file.as_fd(), + size: len as i32, + }, + Arc::new(ShmPoolData), + ) + .unwrap_or_else(|_| Proxy::inert(shm.backend().clone())); + let mmap = unsafe { MmapMut::map_mut(&mem_file)? }; + + Ok(RawPool { + pool: DestroyOnDropPool(pool), + len, + mem_file, + mmap, + }) + } + + /// Resizes the memory pool, notifying the server the pool has changed in size. + /// + /// The [`wl_shm`] protocol only allows the pool to be made bigger. If the new size is smaller than the + /// current size of the pool, this function will do nothing. + pub fn resize(&mut self, size: usize) -> io::Result<()> { + if size > self.len { + self.len = size; + self.mem_file.set_len(size as u64)?; + self.pool.resize(size as i32); + self.mmap = unsafe { MmapMut::map_mut(&self.mem_file) }?; + } + + Ok(()) + } + + /// Returns a reference to the underlying shared memory file using the memmap2 crate. + pub fn mmap(&mut self) -> &mut MmapMut { + &mut self.mmap + } + + /// Returns the size of the mempool + #[allow(clippy::len_without_is_empty)] + pub fn len(&self) -> usize { + self.len + } + + /// Create a new buffer to this pool. + /// + /// ## Parameters + /// - `offset`: the offset (in bytes) from the beginning of the pool at which this buffer starts. + /// - `width` and `height`: the width and height of the buffer in pixels. + /// - `stride`: distance (in bytes) between the beginning of a row and the next one. + /// - `format`: the encoding format of the pixels. + /// + /// The encoding format of the pixels must be supported by the compositor or else a protocol error is + /// risen. You can ensure the format is supported by listening to [`Shm::formats`](crate::shm::Shm::formats). + /// + /// Note this function only creates the [`wl_buffer`] object, you will need to write to the pixels using the + /// [`io::Write`] implementation or [`RawPool::mmap`]. + #[allow(clippy::too_many_arguments)] + pub fn create_buffer<D, U>( + &mut self, + offset: i32, + width: i32, + height: i32, + stride: i32, + format: wl_shm::Format, + udata: U, + qh: &QueueHandle<D>, + ) -> wl_buffer::WlBuffer + where + D: Dispatch<wl_buffer::WlBuffer, U> + 'static, + U: Send + Sync + 'static, + { + self.pool + .create_buffer(offset, width, height, stride, format, qh, udata) + } + + /// Create a new buffer to this pool. + /// + /// This is identical to [`Self::create_buffer`], but allows using a custom [`ObjectData`] + /// implementation instead of relying on the [Dispatch] interface. + #[allow(clippy::too_many_arguments)] + pub fn create_buffer_raw( + &mut self, + offset: i32, + width: i32, + height: i32, + stride: i32, + format: wl_shm::Format, + data: Arc<dyn ObjectData + 'static>, + ) -> wl_buffer::WlBuffer { + self.pool + .send_constructor( + wl_shm_pool::Request::CreateBuffer { + offset, + width, + height, + stride, + format: WEnum::Value(format), + }, + data, + ) + .unwrap_or_else(|_| Proxy::inert(self.pool.backend().clone())) + } + + /// Returns the pool object used to communicate with the server. + pub fn pool(&self) -> &wl_shm_pool::WlShmPool { + &self.pool + } +} + +impl AsFd for RawPool { + fn as_fd(&self) -> BorrowedFd<'_> { + self.mem_file.as_fd() + } +} + +impl From<RawPool> for OwnedFd { + fn from(pool: RawPool) -> Self { + pool.mem_file.into() + } +} + +impl io::Write for RawPool { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + io::Write::write(&mut self.mem_file, buf) + } + + fn flush(&mut self) -> io::Result<()> { + io::Write::flush(&mut self.mem_file) + } +} + +impl io::Seek for RawPool { + fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> { + io::Seek::seek(&mut self.mem_file, pos) + } +} + +impl RawPool { + fn create_shm_fd() -> io::Result<OwnedFd> { + #[cfg(target_os = "linux")] + { + match RawPool::create_memfd() { + Ok(fd) => return Ok(fd), + + // Not supported, use fallback. + Err(Errno::NOSYS) => (), + + Err(err) => return Err(Into::<io::Error>::into(err)), + } + } + + let time = SystemTime::now(); + let mut mem_file_handle = format!( + "/smithay-client-toolkit-{}", + time.duration_since(UNIX_EPOCH).unwrap().subsec_nanos() + ); + + loop { + let flags = OFlags::CREATE | OFlags::EXCL | OFlags::RDWR; + + let mode = Mode::RUSR | Mode::WUSR; + + match rustix::shm::open(mem_file_handle.as_str(), flags, mode) { + Ok(fd) => match rustix::shm::unlink(mem_file_handle.as_str()) { + Ok(()) => return Ok(fd), + + Err(errno) => { + return Err(errno.into()); + } + }, + + Err(Errno::EXIST) => { + // Change the handle if we happen to be duplicate. + let time = SystemTime::now(); + + mem_file_handle = format!( + "/smithay-client-toolkit-{}", + time.duration_since(UNIX_EPOCH).unwrap().subsec_nanos() + ); + } + + Err(Errno::INTR) => (), + + Err(err) => return Err(err.into()), + } + } + } + + #[cfg(target_os = "linux")] + fn create_memfd() -> rustix::io::Result<OwnedFd> { + use rustix::fs::{MemfdFlags, SealFlags}; + + loop { + let name = c"smithay-client-toolkit"; + let flags = MemfdFlags::ALLOW_SEALING | MemfdFlags::CLOEXEC; + + match rustix::fs::memfd_create(name, flags) { + Ok(fd) => { + // We only need to seal for the purposes of optimization, ignore the errors. + let _ = rustix::fs::fcntl_add_seals(&fd, SealFlags::SHRINK | SealFlags::SEAL); + return Ok(fd); + } + + Err(Errno::INTR) => (), + + Err(err) => return Err(err), + } + } + } +} + +#[derive(Debug)] +struct DestroyOnDropPool(wl_shm_pool::WlShmPool); + +impl Deref for DestroyOnDropPool { + type Target = wl_shm_pool::WlShmPool; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Drop for DestroyOnDropPool { + fn drop(&mut self) { + self.0.destroy(); + } +} + +#[derive(Debug)] +struct ShmPoolData; + +impl ObjectData for ShmPoolData { + fn event( + self: Arc<Self>, + _: &wayland_client::backend::Backend, + _: wayland_client::backend::protocol::Message<wayland_client::backend::ObjectId, OwnedFd>, + ) -> Option<Arc<(dyn ObjectData + 'static)>> { + unreachable!("wl_shm_pool has no events") + } + + fn destroyed(&self, _: wayland_client::backend::ObjectId) {} +} diff --git a/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/slot.rs b/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/slot.rs new file mode 100644 index 00000000..ab52c5f6 --- /dev/null +++ b/pkgs/by-name/ri/river-mk-keymap/src/wayland/shm/slot.rs @@ -0,0 +1,596 @@ +//! A pool implementation based on buffer slots + +use std::io; +use std::{ + os::unix::io::{AsRawFd, OwnedFd}, + sync::{ + atomic::{AtomicU8, AtomicUsize, Ordering}, + Arc, Mutex, Weak, + }, +}; + +use wayland_client::backend::protocol::Message; +use wayland_client::backend::{ObjectData, ObjectId}; +use wayland_client::{ + protocol::{wl_buffer, wl_shm, wl_surface}, + Proxy, +}; + +use crate::wayland::shm::raw::RawPool; +use crate::wayland::shm::CreatePoolError; + +#[derive(Debug, thiserror::Error)] +pub(crate) enum CreateBufferError { + /// Slot creation error. + #[error(transparent)] + Io(#[from] io::Error), + + /// Pool mismatch. + #[error("Incorrect pool for slot")] + PoolMismatch, + + /// Slot size mismatch + #[error("Requested buffer size is too large for slot")] + SlotTooSmall, +} + +#[derive(Debug, thiserror::Error)] +pub(crate) enum ActivateSlotError { + /// Buffer was already active + #[error("Buffer was already active")] + AlreadyActive, +} + +#[derive(Debug)] +pub(crate) struct SlotPool { + pub(crate) inner: RawPool, + free_list: Arc<Mutex<Vec<FreelistEntry>>>, +} + +#[derive(Debug)] +struct FreelistEntry { + offset: usize, + len: usize, +} + +/// A chunk of memory allocated from a [`SlotPool`] +/// +/// Retaining this object is only required if you wish to resize or change the buffer's format +/// without changing the contents of the backing memory. +#[derive(Debug)] +pub(crate) struct Slot { + inner: Arc<SlotInner>, +} + +#[derive(Debug)] +struct SlotInner { + free_list: Weak<Mutex<Vec<FreelistEntry>>>, + offset: usize, + len: usize, + active_buffers: AtomicUsize, + /// Count of all "real" references to this slot. This includes all Slot objects and any + /// [`BufferData`] object that is not in the DEAD state. When this reaches zero, the memory for + /// this slot will return to the [`free_list`]. It is not possible for it to reach zero and have a + /// Slot or Buffer referring to it. + all_refs: AtomicUsize, +} + +/// A wrapper around a [`wl_buffer::WlBuffer`] which has been allocated via a [`SlotPool`]. +/// +/// When this object is dropped, the buffer will be destroyed immediately if it is not active, or +/// upon the server's release if it is. +#[derive(Debug)] +pub(crate) struct Buffer { + inner: wl_buffer::WlBuffer, + height: i32, + stride: i32, + slot: Slot, +} + +/// [`ObjectData`] for the [`WlBuffer`] +#[derive(Debug)] +struct BufferData { + inner: Arc<SlotInner>, + state: AtomicU8, +} + +// These constants define the value of BufferData::state, since AtomicEnum does not exist. +impl BufferData { + /// Buffer is counted in [`active_buffers`] list; will return to INACTIVE on Release. + const ACTIVE: u8 = 0; + + /// Buffer is not counted in [`active_buffers`] list, but also has not been destroyed. + const INACTIVE: u8 = 1; + + /// Buffer is counted in [`active_buffers`] list; will move to DEAD on Release + const DESTROY_ON_RELEASE: u8 = 2; + + /// Buffer has been destroyed + const DEAD: u8 = 3; + + /// Value that is [`ORed`] on buffer release to transition to the next state + const RELEASE_SET: u8 = 1; + + /// Value that is [`ORed`] on buffer destroy to transition to the next state + const DESTROY_SET: u8 = 2; + + /// Call after successfully transitioning the state to DEAD + fn record_death(&self) { + drop(Slot { + inner: self.inner.clone(), + }); + } +} + +impl SlotPool { + pub(crate) fn new(len: usize, shm: &wl_shm::WlShm) -> Result<Self, CreatePoolError> { + let inner = RawPool::new(len, shm)?; + let free_list = Arc::new(Mutex::new(vec![FreelistEntry { + offset: 0, + len: inner.len(), + }])); + Ok(SlotPool { inner, free_list }) + } + + /// Create a new buffer in a new slot. + /// + /// This returns the buffer and the canvas. The parameters are: + /// + /// - `width`: the width of this buffer (in pixels) + /// - `height`: the height of this buffer (in pixels) + /// - `stride`: distance (in bytes) between the beginning of a row and the next one + /// - `format`: the encoding format of the pixels. Using a format that was not + /// advertised to the `wl_shm` global by the server is a protocol error and will + /// terminate your connection. + /// + /// The [Slot] for this buffer will have exactly the size required for the data. It can be + /// accessed via [`Buffer::slot`] to create additional buffers that point to the same data. This + /// is required if you wish to change formats, buffer dimensions, or attach a canvas to + /// multiple surfaces. + /// + /// For more control over sizing, use [`Self::new_slot`] and [`Self::create_buffer_in`]. + pub(crate) fn create_buffer( + &mut self, + width: i32, + height: i32, + stride: i32, + format: wl_shm::Format, + ) -> Result<(Buffer, &mut [u8]), CreateBufferError> { + let len = (height as usize) * (stride as usize); + let slot = self.new_slot(len)?; + let buffer = self.create_buffer_in(&slot, width, height, stride, format)?; + let canvas = self.raw_data_mut(&slot); + Ok((buffer, canvas)) + } + + /// Get the bytes corresponding to a given slot or buffer if drawing to the slot is permitted. + /// + /// Returns `None` if there are active buffers in the slot or if the slot does not correspond + /// to this pool. + pub(crate) fn canvas(&mut self, key: &impl CanvasKey) -> Option<&mut [u8]> { + key.canvas(self) + } + + /// Returns the size, in bytes, of this pool. + #[allow(clippy::len_without_is_empty)] + pub(crate) fn len(&self) -> usize { + self.inner.len() + } + + /// Resizes the memory pool, notifying the server the pool has changed in size. + /// + /// This is an optimization; the pool automatically resizes when you allocate new slots. + pub(crate) fn resize(&mut self, size: usize) -> io::Result<()> { + let old_len = self.inner.len(); + self.inner.resize(size)?; + let new_len = self.inner.len(); + if old_len == new_len { + return Ok(()); + } + // add the new memory to the freelist + let mut free = self.free_list.lock().unwrap(); + if let Some(FreelistEntry { offset, len }) = free.last_mut() { + if *offset + *len == old_len { + *len += new_len - old_len; + return Ok(()); + } + } + free.push(FreelistEntry { + offset: old_len, + len: new_len - old_len, + }); + Ok(()) + } + + fn alloc(&mut self, size: usize) -> io::Result<usize> { + let mut free = self.free_list.lock().unwrap(); + for FreelistEntry { offset, len } in free.iter_mut() { + if *len >= size { + let rv = *offset; + *len -= size; + *offset += size; + return Ok(rv); + } + } + let mut rv = self.inner.len(); + let mut pop_tail = false; + if let Some(FreelistEntry { offset, len }) = free.last() { + if offset + len == self.inner.len() { + rv -= len; + pop_tail = true; + } + } + // resize like Vec::reserve, always at least doubling + let target = std::cmp::max(rv + size, self.inner.len() * 2); + self.inner.resize(target)?; + // adjust the end of the freelist here + if pop_tail { + free.pop(); + } + if target > rv + size { + free.push(FreelistEntry { + offset: rv + size, + len: target - rv - size, + }); + } + Ok(rv) + } + + fn free(free_list: &Mutex<Vec<FreelistEntry>>, mut offset: usize, mut len: usize) { + let mut free = free_list.lock().unwrap(); + let mut nf = Vec::with_capacity(free.len() + 1); + for &FreelistEntry { + offset: ioff, + len: ilen, + } in free.iter() + { + if ioff + ilen == offset { + offset = ioff; + len += ilen; + continue; + } + if ioff == offset + len { + len += ilen; + continue; + } + if ioff > offset + len && len != 0 { + nf.push(FreelistEntry { offset, len }); + len = 0; + } + if ilen != 0 { + nf.push(FreelistEntry { + offset: ioff, + len: ilen, + }); + } + } + if len != 0 { + nf.push(FreelistEntry { offset, len }); + } + *free = nf; + } + + /// Create a new slot with the given size in bytes. + pub(crate) fn new_slot(&mut self, mut len: usize) -> io::Result<Slot> { + len = (len + 63) & !63; + let offset = self.alloc(len)?; + + Ok(Slot { + inner: Arc::new(SlotInner { + free_list: Arc::downgrade(&self.free_list), + offset, + len, + active_buffers: AtomicUsize::new(0), + all_refs: AtomicUsize::new(1), + }), + }) + } + + /// Get the bytes corresponding to a given slot. + /// + /// Note: prefer using [`Self::canvas`], which will prevent drawing to a buffer that has not been + /// released by the server. + /// + /// Returns an empty buffer if the slot does not belong to this pool. + pub(crate) fn raw_data_mut(&mut self, slot: &Slot) -> &mut [u8] { + if slot.inner.free_list.as_ptr() == Arc::as_ptr(&self.free_list) { + &mut self.inner.mmap()[slot.inner.offset..][..slot.inner.len] + } else { + &mut [] + } + } + + /// Create a new buffer corresponding to a slot. + /// + /// The parameters are: + /// + /// - `width`: the width of this buffer (in pixels) + /// - `height`: the height of this buffer (in pixels) + /// - `stride`: distance (in bytes) between the beginning of a row and the next one + /// - `format`: the encoding format of the pixels. Using a format that was not + /// advertised to the `wl_shm` global by the server is a protocol error and will + /// terminate your connection + pub(crate) fn create_buffer_in( + &mut self, + slot: &Slot, + width: i32, + height: i32, + stride: i32, + format: wl_shm::Format, + ) -> Result<Buffer, CreateBufferError> { + let offset = slot.inner.offset as i32; + let len = (height as usize) * (stride as usize); + if len > slot.inner.len { + return Err(CreateBufferError::SlotTooSmall); + } + + if slot.inner.free_list.as_ptr() != Arc::as_ptr(&self.free_list) { + return Err(CreateBufferError::PoolMismatch); + } + + let slot = slot.clone(); + // take a ref for the BufferData, which will be destroyed by BufferData::record_death + slot.inner.all_refs.fetch_add(1, Ordering::Relaxed); + let data = Arc::new(BufferData { + inner: slot.inner.clone(), + state: AtomicU8::new(BufferData::INACTIVE), + }); + let buffer = self + .inner + .create_buffer_raw(offset, width, height, stride, format, data); + Ok(Buffer { + inner: buffer, + height, + stride, + slot, + }) + } +} + +impl Clone for Slot { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + inner.all_refs.fetch_add(1, Ordering::Relaxed); + Slot { inner } + } +} + +impl Drop for Slot { + fn drop(&mut self) { + if self.inner.all_refs.fetch_sub(1, Ordering::Relaxed) == 1 { + if let Some(free_list) = self.inner.free_list.upgrade() { + SlotPool::free(&free_list, self.inner.offset, self.inner.len); + } + } + } +} + +impl Drop for SlotInner { + fn drop(&mut self) { + debug_assert_eq!(*self.all_refs.get_mut(), 0); + } +} + +/// A helper trait for [`SlotPool::canvas`]. +pub(crate) trait CanvasKey { + fn canvas<'pool>(&self, pool: &'pool mut SlotPool) -> Option<&'pool mut [u8]>; +} + +impl Slot { + /// Return true if there are buffers referencing this slot whose contents are being accessed + /// by the server. + pub(crate) fn has_active_buffers(&self) -> bool { + self.inner.active_buffers.load(Ordering::Relaxed) != 0 + } + + /// Returns the size, in bytes, of this slot. + #[allow(clippy::len_without_is_empty)] + pub(crate) fn len(&self) -> usize { + self.inner.len + } + + /// Get the bytes corresponding to a given slot if drawing to the slot is permitted. + /// + /// Returns `None` if there are active buffers in the slot or if the slot does not correspond + /// to this pool. + pub(crate) fn canvas<'pool>(&self, pool: &'pool mut SlotPool) -> Option<&'pool mut [u8]> { + if self.has_active_buffers() { + return None; + } + if self.inner.free_list.as_ptr() == Arc::as_ptr(&pool.free_list) { + Some(&mut pool.inner.mmap()[self.inner.offset..][..self.inner.len]) + } else { + None + } + } +} + +impl CanvasKey for Slot { + fn canvas<'pool>(&self, pool: &'pool mut SlotPool) -> Option<&'pool mut [u8]> { + self.canvas(pool) + } +} + +impl Buffer { + /// Attach a buffer to a surface. + /// + /// This marks the slot as active until the server releases the buffer, which will happen + /// automatically assuming the surface is committed without attaching a different buffer. + /// + /// Note: if you need to ensure that [`canvas()`](Buffer::canvas) calls never return data that + /// could be attached to a surface in a multi-threaded client, make this call while you have + /// exclusive access to the corresponding [`SlotPool`]. + pub(crate) fn attach_to(&self, surface: &wl_surface::WlSurface) -> Result<(), ActivateSlotError> { + self.activate()?; + surface.attach(Some(&self.inner), 0, 0); + Ok(()) + } + + /// Get the inner buffer. + pub(crate) fn wl_buffer(&self) -> &wl_buffer::WlBuffer { + &self.inner + } + + pub(crate) fn height(&self) -> i32 { + self.height + } + + pub(crate) fn stride(&self) -> i32 { + self.stride + } + + fn data(&self) -> Option<&BufferData> { + self.inner.object_data()?.downcast_ref() + } + + /// Get the bytes corresponding to this buffer if drawing is permitted. + /// + /// This may be smaller than the canvas associated with the slot. + pub(crate) fn canvas<'pool>(&self, pool: &'pool mut SlotPool) -> Option<&'pool mut [u8]> { + let len = (self.height as usize) * (self.stride as usize); + if self.slot.inner.active_buffers.load(Ordering::Relaxed) != 0 { + return None; + } + if self.slot.inner.free_list.as_ptr() == Arc::as_ptr(&pool.free_list) { + Some(&mut pool.inner.mmap()[self.slot.inner.offset..][..len]) + } else { + None + } + } + + /// Get the slot corresponding to this buffer. + pub(crate) fn slot(&self) -> Slot { + self.slot.clone() + } + + /// Manually mark a buffer as active. + /// + /// An active buffer prevents drawing on its slot until a Release event is received or until + /// manually deactivated. + pub(crate) fn activate(&self) -> Result<(), ActivateSlotError> { + let data = self.data().expect("UserData type mismatch"); + + // This bitwise AND will transition INACTIVE -> ACTIVE, or do nothing if the buffer was + // already ACTIVE. No other ordering is required, as the server will not send a Release + // until we send our attach after returning Ok. + match data + .state + .fetch_and(!BufferData::RELEASE_SET, Ordering::Relaxed) + { + BufferData::INACTIVE => { + data.inner.active_buffers.fetch_add(1, Ordering::Relaxed); + Ok(()) + } + BufferData::ACTIVE => Err(ActivateSlotError::AlreadyActive), + _ => unreachable!("Invalid state in BufferData"), + } + } + + /// Manually mark a buffer as inactive. + /// + /// This should be used when the buffer was manually marked as active or when a buffer was + /// attached to a surface but not committed. Calling this function on a buffer that was + /// committed to a surface risks making the surface contents undefined. + pub(crate) fn deactivate(&self) -> Result<(), ActivateSlotError> { + let data = self.data().expect("UserData type mismatch"); + + // Same operation as the Release event, but we know the Buffer was not dropped. + match data + .state + .fetch_or(BufferData::RELEASE_SET, Ordering::Relaxed) + { + BufferData::ACTIVE => { + data.inner.active_buffers.fetch_sub(1, Ordering::Relaxed); + Ok(()) + } + BufferData::INACTIVE => Err(ActivateSlotError::AlreadyActive), + _ => unreachable!("Invalid state in BufferData"), + } + } +} + +impl CanvasKey for Buffer { + fn canvas<'pool>(&self, pool: &'pool mut SlotPool) -> Option<&'pool mut [u8]> { + self.canvas(pool) + } +} + +impl Drop for Buffer { + fn drop(&mut self) { + if let Some(data) = self.data() { + match data + .state + .fetch_or(BufferData::DESTROY_SET, Ordering::Relaxed) + { + BufferData::ACTIVE => { + // server is using the buffer, let ObjectData handle the destroy + } + BufferData::INACTIVE => { + data.record_death(); + self.inner.destroy(); + } + _ => unreachable!("Invalid state in BufferData"), + } + } + } +} + +impl ObjectData for BufferData { + fn event( + self: Arc<Self>, + handle: &wayland_client::backend::Backend, + msg: Message<ObjectId, OwnedFd>, + ) -> Option<Arc<dyn ObjectData>> { + debug_assert!(wayland_client::backend::protocol::same_interface( + msg.sender_id.interface(), + wl_buffer::WlBuffer::interface() + )); + debug_assert!(msg.opcode == 0); + + match self + .state + .fetch_or(BufferData::RELEASE_SET, Ordering::Relaxed) + { + BufferData::ACTIVE => { + self.inner.active_buffers.fetch_sub(1, Ordering::Relaxed); + } + BufferData::INACTIVE => { + // possible spurious release, or someone called deactivate incorrectly + eprintln!("Unexpected WlBuffer::Release on an inactive buffer"); + } + BufferData::DESTROY_ON_RELEASE => { + self.record_death(); + self.inner.active_buffers.fetch_sub(1, Ordering::Relaxed); + + // The Destroy message is identical to Release message (no args, same ID), so just reply + handle + .send_request(msg.map_fd(|x| x.as_raw_fd()), None, None) + .expect("Unexpected invalid ID"); + } + BufferData::DEAD => { + // no-op, this object is already unusable + } + _ => unreachable!("Invalid state in BufferData"), + } + + None + } + + fn destroyed(&self, _: ObjectId) {} +} + +impl Drop for BufferData { + fn drop(&mut self) { + let state = *self.state.get_mut(); + if state == BufferData::ACTIVE || state == BufferData::DESTROY_ON_RELEASE { + // Release the active-buffer count + self.inner.active_buffers.fetch_sub(1, Ordering::Relaxed); + } + + if state != BufferData::DEAD { + // nobody has ever transitioned state to DEAD, so we are responsible for freeing the + // extra reference + self.record_death(); + } + } +} diff --git a/pkgs/by-name/ts/tskm/.envrc b/pkgs/by-name/ts/tskm/.envrc index 2c7bb7c9..a84d550d 100644 --- a/pkgs/by-name/ts/tskm/.envrc +++ b/pkgs/by-name/ts/tskm/.envrc @@ -13,3 +13,6 @@ export TSKM_PROJECT_FILE=/home/soispha/repos/nix/config/modules/common/projects.json use flake + +PATH_add ./target/debug +PATH_add ./target/release diff --git a/pkgs/by-name/ts/tskm/Cargo.lock b/pkgs/by-name/ts/tskm/Cargo.lock index 5ec48790..db4a72a3 100644 --- a/pkgs/by-name/ts/tskm/Cargo.lock +++ b/pkgs/by-name/ts/tskm/Cargo.lock @@ -13,9 +13,9 @@ version = 4 [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" @@ -46,9 +46,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -61,37 +61,37 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "once_cell", - "windows-sys", + "once_cell_polyfill", + "windows-sys 0.59.0", ] [[package]] @@ -101,10 +101,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + +[[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" @@ -114,9 +120,9 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -126,18 +132,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.23" +version = "1.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" +checksum = "4ad45f4f74e4e20eaa392913b7b33a7091c87e59628f4dd27888205ad888843c" dependencies = [ "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "chrono" @@ -156,9 +162,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -166,9 +172,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -178,9 +184,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.50" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91d3baa3bcd889d60e6ef28874126a0b384fd225ab83aa6d8a801c519194ce1" +checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677" dependencies = [ "clap", "clap_lex", @@ -190,9 +196,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", @@ -202,15 +208,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "core-foundation-sys" @@ -245,7 +251,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.60.2", ] [[package]] @@ -260,6 +266,15 @@ dependencies = [ ] [[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] name = "fallible-iterator" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -273,15 +288,21 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "flate2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", ] [[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] name = "form_urlencoded" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -298,7 +319,7 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", ] [[package]] @@ -323,12 +344,30 @@ dependencies = [ ] [[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "foldhash", +] + +[[package]] name = "hashlink" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.4", ] [[package]] @@ -339,9 +378,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "iana-time-zone" @@ -416,9 +455,9 @@ checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2549ca8c7241c82f59c80ba2a6f415d931c5b58d24fb8412caa1a1f02c49139a" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", @@ -432,9 +471,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8197e866e47b68f8f7d95249e172903bec06004b18b2937f1095d40a0c57de04" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" @@ -482,7 +521,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -518,15 +557,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.172" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" dependencies = [ "bitflags", "libc", @@ -555,25 +594,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] -name = "lz4_flex" -version = "0.11.3" +name = "md5" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" -dependencies = [ - "twox-hash", -] +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] @@ -594,6 +630,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -640,9 +682,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "redox_users" @@ -664,16 +706,16 @@ dependencies = [ "bitflags", "fallible-iterator", "fallible-streaming-iterator", - "hashlink", + "hashlink 0.9.1", "libsqlite3-sys", "smallvec", ] [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "ryu" @@ -730,9 +772,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" @@ -741,18 +783,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] name = "stderrlog" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c910772f992ab17d32d6760e167d2353f4130ed50e796752689556af07dc6b" dependencies = [ - "chrono", "is-terminal", "log", "termcolor", @@ -786,9 +821,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -857,12 +892,11 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -884,23 +918,14 @@ dependencies = [ "clap_complete", "dirs", "log", - "lz4_flex", + "md5", "serde", "serde_json", "stderrlog", "taskchampion", "url", "walkdir", -] - -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if", - "static_assertions", + "yaml-rust2", ] [[package]] @@ -935,12 +960,14 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" dependencies = [ "getrandom 0.3.3", + "js-sys", "serde", + "wasm-bindgen", ] [[package]] @@ -967,9 +994,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -1060,7 +1087,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1071,9 +1098,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.61.1" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46ec44dc15085cea82cf9c78f85a9114c463a369786585ad2882d1ff0b0acf40" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", @@ -1106,24 +1133,24 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-result" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b895b5356fc36103d0f64dd1e94dfa7ac5633f1c9dd6e80fe9ec4adef69e09d" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a7ab927b2637c19b3dbe0965e75d8f2d30bdd697a1516191cad2ec4df8fb28a" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] @@ -1134,7 +1161,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", ] [[package]] @@ -1143,14 +1179,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -1160,48 +1212,96 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] name = "wit-bindgen-rt" version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1217,6 +1317,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] +name = "yaml-rust2" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ce2a4ff45552406d02501cea6c18d8a7e50228e7736a872951fe2fe75c91be7" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink 0.10.0", +] + +[[package]] name = "yoke" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1242,18 +1353,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", diff --git a/pkgs/by-name/ts/tskm/Cargo.toml b/pkgs/by-name/ts/tskm/Cargo.toml index c8b1832d..2655254b 100644 --- a/pkgs/by-name/ts/tskm/Cargo.toml +++ b/pkgs/by-name/ts/tskm/Cargo.toml @@ -16,18 +16,19 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.98" -clap = { version = "4.5.38", features = ["derive"] } -clap_complete = { version = "4.5.50", features = ["unstable-dynamic"] } -dirs = "6.0.0" -log = "0.4.27" -lz4_flex = "0.11.3" -serde = { version = "1.0.219", features = ["derive"] } -serde_json = "1.0.140" -stderrlog = "0.6.0" +anyhow = { version = "1.0.98", default-features = false } +clap = { version = "4.5.40", features = [ "derive", "std", "color", "help", "usage", "error-context", "suggestions", ], default-features = false } +clap_complete = { version = "4.5.54", features = ["unstable-dynamic"] } +dirs = { version = "6.0.0", default-features = false } +log = { version = "0.4.27", default-features = false } +serde = { version = "1.0.219", features = ["derive"], default-features = false } +serde_json = { version = "1.0.140", default-features = false } +stderrlog = { version = "0.6.0", default-features = false } taskchampion = { version = "2.0.3", default-features = false } -url = { version = "2.5.4", features = ["serde"] } -walkdir = "2.5.0" +url = { version = "2.5.4", features = ["serde"], default-features = false } +walkdir = { version = "2.5.0", default-features = false } +md5 = { version = "0.7.0", default-features = false } +yaml-rust2 = "0.10.3" [profile.release] lto = true diff --git a/pkgs/by-name/ts/tskm/flake.lock b/pkgs/by-name/ts/tskm/flake.lock index d9641458..1ebbe915 100644 --- a/pkgs/by-name/ts/tskm/flake.lock +++ b/pkgs/by-name/ts/tskm/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1747312588, - "narHash": "sha256-MmJvj6mlWzeRwKGLcwmZpKaOPZ5nJb/6al5CXqJsgjo=", + "lastModified": 1751596331, + "narHash": "sha256-7WSzIrw0nCl8iYroj7c//LLsf2zgNEIJNyUSvx4MPLI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b1bebd0fe266bbd1820019612ead889e96a8fa2d", + "rev": "472908faa934435cf781ae8fac77291af3d137d3", "type": "github" }, "original": { diff --git a/pkgs/by-name/ts/tskm/package.nix b/pkgs/by-name/ts/tskm/package.nix index d75afe6e..ad10865f 100644 --- a/pkgs/by-name/ts/tskm/package.nix +++ b/pkgs/by-name/ts/tskm/package.nix @@ -16,7 +16,6 @@ taskwarrior3, git, rofi, - firefox, sqlite, }: rustPlatform.buildRustPackage (finalAttrs: { @@ -32,7 +31,6 @@ rustPlatform.buildRustPackage (finalAttrs: { taskwarrior3 git rofi - firefox sqlite ]; diff --git a/pkgs/by-name/ts/tskm/src/browser/mod.rs b/pkgs/by-name/ts/tskm/src/browser/mod.rs new file mode 100644 index 00000000..d83bcbc4 --- /dev/null +++ b/pkgs/by-name/ts/tskm/src/browser/mod.rs @@ -0,0 +1,196 @@ +use std::{ + env, fs, + io::Write, + os::unix::net::UnixStream, + path::PathBuf, + process::{self, ExitStatus}, +}; + +use anyhow::{Context, Result}; +use log::{error, info}; +use serde_json::json; +use url::Url; + +use crate::{state::State, task}; + +#[allow(clippy::too_many_lines)] +pub fn open_in_browser( + selected_project: &task::Project, + state: &mut State, + urls: Option<Vec<Url>>, +) -> Result<()> { + let old_project: Option<task::Project> = + task::Project::get_current().context("Failed to get currently active project")?; + let old_task: Option<task::Task> = + task::Task::get_current(state).context("Failed to get currently active task")?; + + selected_project.activate().with_context(|| { + format!( + "Failed to active project: '{}'", + selected_project.to_project_display() + ) + })?; + + let tracking_task = { + let all_tasks = selected_project.get_tasks(state).with_context(|| { + format!( + "Failed to get assoctiated tasks for project: '{}'", + selected_project.to_project_display() + ) + })?; + + let tracking_task = all_tasks.into_iter().find(|t| { + let maybe_desc = t.description(state); + if let Ok(desc) = maybe_desc { + desc == "tracking" + } else { + error!( + "Getting task description returned error: {}", + maybe_desc.expect_err("We already check for Ok") + ); + false + } + }); + + if let Some(task) = tracking_task { + info!( + "Starting task {} -> tracking", + selected_project.to_project_display() + ); + task.start(state) + .with_context(|| format!("Failed to start task {task}"))?; + } + tracking_task + }; + + let status = { + // #!/bin/sh + // # initial idea: Florian Bruhin (The-Compiler) + // # author: Thore Bödecker (foxxx0) + // + // _url="$1" + // _qb_version='1.0.4' + // _proto_version=1 + // _ipc_socket="${XDG_RUNTIME_DIR}/qutebrowser/ipc-$(printf '%s' "$USER" | md5sum | cut -d' ' -f1)" + // _qute_bin="/usr/bin/qutebrowser" + // + // printf '{"args": ["%s"], "target_arg": null, "version": "%s", "protocol_version": %d, "cwd": "%s"}\n' \ + // "${_url}" \ + // "${_qb_version}" \ + // "${_proto_version}" \ + // "${PWD}" | socat -lf /dev/null - UNIX-CONNECT:"${_ipc_socket}" || "$_qute_bin" "$@" & + + let ipc_socket_path = PathBuf::from( + env::var("XDG_RUNTIME_DIR").context("Failed to access XDG_RUNTIME_DIR var")?, + ) + .join("qutebrowser") + .join(selected_project.to_project_display()) + .join(format!("ipc-{:x}", { + let user_name = env::var("USER").context("Failed to get USER var")?; + let base_dir = env::var("XDG_DATA_HOME").context("Failed to get XDG_DATA_HOME")?; + + md5::compute( + format!( + "{user_name}-{}", + PathBuf::from(base_dir) + .join("qutebrowser") + .join(selected_project.to_project_display()) + .display() + ) + .as_bytes(), + ) + })); + + let socket = if ipc_socket_path.exists() { + match UnixStream::connect(&ipc_socket_path) { + Ok(ok) => Some(ok), + Err(err) => match err.kind() { + std::io::ErrorKind::ConnectionRefused => { + // There is no qutebrowser listening to our connection. + fs::remove_file(&ipc_socket_path).with_context(|| { + format!( + "Failed to remove orphaned qutebrowser socket: {}", + ipc_socket_path.display() + ) + })?; + None + } + _ => Err(err).with_context(|| { + format!( + "Failed to connect to qutebrowser's ipc socket at: {}", + ipc_socket_path.display() + ) + })?, + }, + } + } else { + None + }; + + if let Some(mut stream) = socket { + let real_url = if let Some(urls) = urls { + urls.into_iter().map(|url| url.to_string()).collect() + } else { + // Always add a new tab, so that qutebrowser is marked as “urgent”. + vec!["qute://start".to_owned()] + }; + + stream.write_all( + json! { + { + "args": real_url, + "target_arg": null, + "version": "1.0.4", + "protocol_version": 1, + "cwd": "/" + } + } + .to_string() + .as_bytes(), + )?; + stream.write_all(b"\n")?; + + ExitStatus::default() + } else { + let args = if let Some(urls) = urls { + urls.iter().map(ToString::to_string).collect() + } else { + vec![] + }; + + process::Command::new(format!( + "qutebrowser-{}", + selected_project.to_project_display() + )) + .args(args) + .status() + .context("Failed to start qutebrowser")? + } + }; + + if !status.success() { + error!("Qutebrowser run exited with error."); + } + + if let Some(task) = tracking_task { + task.stop(state) + .with_context(|| format!("Failed to stop task {task}"))?; + } + if let Some(task) = old_task { + task.start(state) + .with_context(|| format!("Failed to start task {task}"))?; + } + + if let Some(project) = old_project { + project.activate().with_context(|| { + format!( + "Failed to activate project {}", + project.to_project_display() + ) + })?; + } else { + task::Project::clear().context("Failed to clear currently focused project")?; + } + + Ok(()) +} diff --git a/pkgs/by-name/ts/tskm/src/cli.rs b/pkgs/by-name/ts/tskm/src/cli.rs index f38d7879..23d9545f 100644 --- a/pkgs/by-name/ts/tskm/src/cli.rs +++ b/pkgs/by-name/ts/tskm/src/cli.rs @@ -11,12 +11,15 @@ use std::{ffi::OsStr, path::PathBuf}; use anyhow::{bail, Result}; -use clap::{builder::StyledStr, ArgAction, Parser, Subcommand}; +use clap::{builder::StyledStr, ArgAction, Parser, Subcommand, ValueEnum}; use clap_complete::{ArgValueCompleter, CompletionCandidate}; use url::Url; use crate::{ - interface::{input::Input, project::ProjectName}, + interface::{ + input::{Input, Tag}, + project::ProjectName, + }, state, task, }; @@ -25,7 +28,7 @@ use crate::{ /// This is the core interface to the system-integrated task management /// /// `tskm` effectively combines multiple applications together: -/// - `taskwarrior` projects are raised connected to `firefox` profiles, making it possible to “open” +/// - `taskwarrior` projects are connected to `qutebrowser` profiles, making it possible to “open” /// a project. /// /// - Every `taskwarrior` project has a determined `neorg` path, so that extra information for a @@ -66,7 +69,7 @@ pub enum Command { command: NeorgCommand, }, - /// Interface with the Firefox profile of each project. + /// Interface with the Qutebrowser profile of each project. Open { #[command(subcommand)] command: OpenCommand, @@ -91,8 +94,8 @@ pub enum NeorgCommand { /// Open the `neorg` project associated with id of the task. Task { /// The working set id of the task - #[arg(value_parser = task_from_working_set_id, add = ArgValueCompleter::new(complete_task_id))] - id: task::Task, + #[arg(value_name = "ID", value_parser = task_from_working_set_id, add = ArgValueCompleter::new(complete_task_id))] + task: task::Task, }, } @@ -108,38 +111,55 @@ fn task_from_working_set_id(id: &str) -> Result<task::Task> { #[derive(Subcommand, Debug)] pub enum OpenCommand { - /// Open each project's Firefox profile consecutively, that was opened since the last review. + /// Open each project's Qutebrowser profile consecutively, that was opened since the last review. /// /// This allows you to remove stale opened tabs and to commit open tabs to the `inputs`. - Review, + Review { + /// Review all projects, if they contain tabs + #[arg(short, long, default_value_t)] + non_empty: bool, + }, - /// Opens Firefox with either the supplied project or the currently active project profile. + /// Opens Qutebrowser with either the supplied project or the currently active project profile. Project { /// The project to open. #[arg(value_parser = task::Project::from_project_string, add = ArgValueCompleter::new(complete_project))] project: task::Project, - /// The URL to open. - url: Option<Url>, + /// The URLs to open. + urls: Option<Vec<Url>>, }, - /// Open a selected project in it's Firefox profile. + /// Open a selected project in it's Qutebrowser profile. /// /// This will use rofi's dmenu mode to select one project from the list of all registered /// projects. Select { - /// The URL to open. - url: Option<Url>, + /// The URLs to open. + urls: Option<Vec<Url>>, }, /// List all open tabs in the project. ListTabs { - /// The project to open. + /// The projects to open. #[arg(value_parser = task::Project::from_project_string, add = ArgValueCompleter::new(complete_project))] - project: Option<task::Project>, + projects: Option<Vec<task::Project>>, + + /// Only show the tabs, that are in this mode + #[arg(short, long, conflicts_with = "projects")] + mode: Option<ListMode>, }, } +#[derive(Clone, Copy, ValueEnum, Debug)] +pub enum ListMode { + // The tab contains no tabs. + Empty, + + // The tab contains tabs. + NonEmpty, +} + #[derive(Subcommand, Debug)] pub enum InputCommand { /// Add URLs as inputs to be categorized. @@ -153,7 +173,14 @@ pub enum InputCommand { /// Add all URLs in the file as inputs to be categorized. /// /// This expects each line to contain one URL. - File { file: PathBuf }, + File { + /// The file to read from. + file: PathBuf, + + /// Additional tags to apply to every read URL in the file. + #[arg(add = ArgValueCompleter::new(complete_tag))] + tags: Vec<Tag>, + }, /// Like 'review', but for the inputs that have previously been added. /// It takes a project in which to open the URLs. @@ -164,7 +191,14 @@ pub enum InputCommand { }, /// List all the previously added inputs. - List, + List { + /// Only list the inputs that have all the specified tags + #[arg(add = ArgValueCompleter::new(complete_tag))] + tags: Vec<Tag>, + }, + + /// Show all the available tags. + Tags {}, } fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> { @@ -219,8 +253,6 @@ fn complete_task_id(current: &OsStr) -> Vec<CompletionCandidate> { if project == current_project { if let Some(out) = format_task(task, current, &mut state) { output.push(out); - } else { - continue; } } } @@ -274,3 +306,27 @@ fn complete_input_url(current: &OsStr) -> Vec<CompletionCandidate> { output } +fn complete_tag(current: &OsStr) -> Vec<CompletionCandidate> { + let mut output = vec![]; + + let Some(current) = current.to_str() else { + return output; + }; + + if !current.starts_with('+') { + output.push(CompletionCandidate::new(format!("+{current}"))); + } + + output +} + +#[cfg(test)] +mod test { + use clap::CommandFactory; + + use super::CliArgs; + #[test] + fn verify_cli() { + CliArgs::command().debug_assert(); + } +} diff --git a/pkgs/by-name/ts/tskm/src/interface/input/handle.rs b/pkgs/by-name/ts/tskm/src/interface/input/handle.rs index 9c39cfef..76eea6dc 100644 --- a/pkgs/by-name/ts/tskm/src/interface/input/handle.rs +++ b/pkgs/by-name/ts/tskm/src/interface/input/handle.rs @@ -9,25 +9,25 @@ // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. use std::{ - fs, process, + collections::{HashMap, HashSet}, + fs, str::FromStr, - thread::{self, sleep}, - time::Duration, }; use anyhow::{Context, Result}; -use log::{error, info}; +use log::info; -use crate::cli::InputCommand; +use crate::{browser::open_in_browser, cli::InputCommand, state::State}; -use super::Input; +use super::{Input, Tag}; /// # Errors /// When command handling fails. /// /// # Panics /// When internal assertions fail. -pub fn handle(command: InputCommand) -> Result<()> { +#[allow(clippy::too_many_lines)] +pub fn handle(command: InputCommand, state: &mut State) -> Result<()> { match command { InputCommand::Add { inputs } => { for input in inputs { @@ -43,47 +43,37 @@ pub fn handle(command: InputCommand) -> Result<()> { })?; } } - InputCommand::File { file } => { - let file = fs::read_to_string(file)?; - for line in file.lines() { - let input = Input::from_str(line)?; + InputCommand::File { file, tags } => { + let file = fs::read_to_string(&file) + .with_context(|| format!("Failed to read input file '{}'", file.display()))?; + + let mut tag_set = HashSet::with_capacity(tags.len()); + for tag in tags { + tag_set.insert(tag); + } + + for line in file.lines().map(str::trim) { + if line.is_empty() { + continue; + } + + let mut input = Input::from_str(line)?; + input.tags = input.tags.union(&tag_set).cloned().collect(); + input.commit().with_context(|| { format!("Failed to add input ('{input}') to the input storage.") })?; } } InputCommand::Review { project } => { - let project = project.to_project_display(); - - let local_project = project.clone(); - let handle = thread::spawn(move || { - // We assume that the project is not yet open. - let mut firefox = process::Command::new("firefox") - .args(["-P", local_project.as_str(), "about:newtab"]) - .spawn()?; - - Ok::<_, anyhow::Error>(firefox.wait()?) - }); - // Give Firefox some time to start. - info!("Waiting on firefox to start"); - sleep(Duration::from_secs(4)); - - let project_str = project.as_str(); 'outer: for all in Input::all()?.chunks(100) { info!("Starting review for the first hundred URLs."); - for input in all { - info!("-> '{input}'"); - let status = process::Command::new("firefox") - .args(["-P", project_str, input.url().to_string().as_str()]) - .status()?; - - if status.success() { - input.remove()?; - } else { - error!("Adding `{input}` to Firefox failed!"); - } - } + open_in_browser( + &project, + state, + Some(all.iter().map(|f| f.url.clone()).collect()), + )?; { use std::io::{stdin, stdout, Write}; @@ -108,15 +98,51 @@ pub fn handle(command: InputCommand) -> Result<()> { } } } - - info!("Waiting for firefox to stop"); - handle.join().expect("Should be joinable")?; } - InputCommand::List => { - for url in Input::all()? { + InputCommand::List { tags } => { + let mut tag_set = HashSet::with_capacity(tags.len()); + for tag in tags { + tag_set.insert(tag); + } + + for url in Input::all()? + .iter() + .filter(|input| tag_set.is_subset(&input.tags)) + { println!("{url}"); } } + InputCommand::Tags {} => { + let mut without_tags = 0; + let mut tag_set: HashMap<Tag, u64> = HashMap::new(); + + for input in Input::all()? { + if input.tags.is_empty() { + without_tags += 1; + } + + for tag in input.tags { + if let Some(number) = tag_set.get_mut(&tag) { + *number += 1; + } else { + tag_set.insert(tag, 1); + } + } + } + + let mut tags: Vec<(Tag, u64)> = tag_set.into_iter().collect(); + tags.sort_by_key(|(_, number)| *number); + tags.reverse(); + + for (tag, number) in tags { + println!("{tag} {number}"); + } + + if without_tags != 0 { + println!(); + println!("Witohut tags: {without_tags}"); + } + } } Ok(()) } diff --git a/pkgs/by-name/ts/tskm/src/interface/input/mod.rs b/pkgs/by-name/ts/tskm/src/interface/input/mod.rs index 5485de3b..1d1d67f4 100644 --- a/pkgs/by-name/ts/tskm/src/interface/input/mod.rs +++ b/pkgs/by-name/ts/tskm/src/interface/input/mod.rs @@ -9,9 +9,9 @@ // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. use std::{ - collections::HashSet, + collections::{HashMap, HashSet}, fmt::Display, - fs::{self, read_to_string, File}, + fs, io::Write, path::PathBuf, process::Command, @@ -26,38 +26,47 @@ pub mod handle; pub use handle::handle; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct NoWhitespaceString(String); +pub struct Tag(String); -impl NoWhitespaceString { - /// # Panics - /// If the input contains whitespace. - #[must_use] - pub fn new(input: String) -> Self { - if input.contains(' ') { - panic!("Your input '{input}' contains whitespace. I did not expect that.") +impl Tag { + pub fn new(input: &str) -> Result<Self> { + Self::from_str(input) + } +} + +impl FromStr for Tag { + type Err = anyhow::Error; + + fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { + if let Some(tag) = s.strip_prefix('+') { + if tag.contains(' ') { + bail!("Your tag '{s}' should not whitespace.") + } + + Ok(Self(tag.to_owned())) } else { - Self(input) + bail!("Your tag '{s}' does not start with the required '+'"); } } } -impl Display for NoWhitespaceString { +impl Display for Tag { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) + write!(f, "+{}", self.0) } } -impl NoWhitespaceString { +impl Tag { #[must_use] pub fn as_str(&self) -> &str { &self.0 } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Input { url: Url, - tags: HashSet<NoWhitespaceString>, + tags: HashSet<Tag>, } impl FromStr for Input { @@ -71,13 +80,7 @@ impl FromStr for Input { tags: { tags.trim() .split(' ') - .map(|tag| { - if let Some(tag) = tag.strip_prefix('+') { - Ok(NoWhitespaceString::new(tag.to_owned())) - } else { - bail!("Your tag '{tag}' does not start with the required '+'"); - } - }) + .map(Tag::new) .collect::<Result<_, _>>()? }, }) @@ -101,13 +104,9 @@ impl Display for Input { self.url, self.tags .iter() - .fold(String::new(), |mut acc, tag| { - acc.push('+'); - acc.push_str(tag.as_str()); - acc.push(' '); - acc - }) - .trim() + .map(ToString::to_string) + .collect::<Vec<_>>() + .join(" ") ) } } @@ -123,7 +122,10 @@ impl Input { fn url_path(url: &Url) -> Result<PathBuf> { let base_path = Self::base_path(); - let url_path = base_path.join(url.to_string()); + let url_path = base_path + .join(url.scheme()) + .join(url.host_str().unwrap_or("<No Host>")) + .join(url.path().trim_matches('/')); fs::create_dir_all(&url_path) .with_context(|| format!("Failed to open file: '{}'", url_path.display()))?; @@ -142,17 +144,12 @@ impl Input { pub fn commit(&self) -> Result<()> { let url_path = Self::url_path(&self.url)?; - let url_content = { - if url_path.exists() { - read_to_string(&url_path)? - } else { - String::new() - } - }; - - let mut file = File::create(&url_path) + let mut file = fs::OpenOptions::new() + .create(true) + .append(true) + .open(&url_path) .with_context(|| format!("Failed to open file: '{}'", url_path.display()))?; - writeln!(file, "{url_content}{self}")?; + writeln!(file, "{self}")?; Self::git_commit(&format!("Add new url: '{self}'"))?; @@ -183,28 +180,7 @@ impl Input { Ok(()) } - /// Commit your changes - fn git_commit(message: &str) -> Result<()> { - let status = Command::new("git") - .args(["add", "."]) - .current_dir(Self::base_path()) - .status()?; - if !status.success() { - bail!("Git add . failed!"); - } - - let status = Command::new("git") - .args(["commit", "--message", message, "--no-gpg-sign"]) - .current_dir(Self::base_path()) - .status()?; - if !status.success() { - bail!("Git commit failed!"); - } - - Ok(()) - } - - /// Get all previously [`Self::commit`]ed inputs. + /// Get all previously [committed][`Self::commit`] inputs. /// /// # Errors /// When IO handling fails. @@ -227,41 +203,58 @@ impl Input { continue; } - let url_value_file = entry - .path() - .to_str() - .expect("All of these should be URLs and thus valid strings"); - assert!(url_value_file.ends_with("/url_value")); - - let url = { - let base = url_value_file - .strip_prefix(&format!("{}/", Self::base_path().display())) - .expect("This will exist"); - - let (proto, path) = base.split_once(':').expect("This will countain a :"); - - let path = path.strip_suffix("/url_value").expect("Will exist"); - - Url::from_str(&format!("{proto}:/{path}")) - .expect("This was a URL, it should still be one") - }; - let tags = { - let url_values = read_to_string(PathBuf::from(url_value_file))?; - url_values - .lines() - .map(|line| { - let input = Self::from_str(line)?; - Ok::<_, anyhow::Error>(input.tags) - }) - .collect::<Result<Vec<HashSet<NoWhitespaceString>>, _>>()? - .into_iter() - .flatten() - .collect() - }; - - output.push(Self { url, tags }); + let url_value_file = entry.path(); + assert!(url_value_file.ends_with("url_value")); + + let url_values = fs::read_to_string(PathBuf::from(url_value_file))?; + + let mut inputs: HashMap<Url, Self> = HashMap::new(); + for input in url_values + .lines() + .map(Self::from_str) + .collect::<Result<Vec<Self>, _>>()? + { + if let Some(found) = inputs.get_mut(&input.url) { + found.tags = found.tags.union(&input.tags).cloned().collect(); + } else { + assert_eq!(inputs.insert(input.url.clone(), input), None); + } + } + + output.extend(inputs.drain().map(|(_, value)| value)); } Ok(output) } + + /// Commit your changes + fn git_commit(message: &str) -> Result<()> { + if !Self::base_path().join(".git").exists() { + let status = Command::new("git") + .args(["init"]) + .current_dir(Self::base_path()) + .status()?; + if !status.success() { + bail!("Git init failed!"); + } + } + + let status = Command::new("git") + .args(["add", "."]) + .current_dir(Self::base_path()) + .status()?; + if !status.success() { + bail!("Git add . failed!"); + } + + let status = Command::new("git") + .args(["commit", "--message", message, "--no-gpg-sign"]) + .current_dir(Self::base_path()) + .status()?; + if !status.success() { + bail!("Git commit failed!"); + } + + Ok(()) + } } diff --git a/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs b/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs index 84abb273..ea3a89ae 100644 --- a/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs +++ b/pkgs/by-name/ts/tskm/src/interface/neorg/handle.rs @@ -21,8 +21,8 @@ use crate::{cli::NeorgCommand, state::State}; pub fn handle(command: NeorgCommand, state: &mut State) -> Result<()> { match command { - NeorgCommand::Task { id } => { - let project = id.project(state)?; + NeorgCommand::Task { task } => { + let project = task.project(state)?; let base = dirs::data_local_dir() .expect("This should exists") .join("tskm/notes"); @@ -40,15 +40,17 @@ pub fn handle(command: NeorgCommand, state: &mut State) -> Result<()> { String::new() }; - if !contents.contains(format!("% {}", id.uuid()).as_str()) { + if !contents.contains(format!("% {}", task.uuid()).as_str()) { let mut options = OpenOptions::new(); options.append(true).create(false); let mut file = options.open(&path)?; - file.write_all(format!("* TITLE (% {})", id.uuid()).as_bytes()) - .with_context(|| { - format!("Failed to write task uuid to file: '{}'", path.display()) - })?; + file.write_all( + format!("* {} (% {})", task.description(state)?, task.uuid()).as_bytes(), + ) + .with_context(|| { + format!("Failed to write task uuid to file: '{}'", path.display()) + })?; file.flush() .with_context(|| format!("Failed to flush file: '{}'", path.display()))?; } @@ -59,7 +61,7 @@ pub fn handle(command: NeorgCommand, state: &mut State) -> Result<()> { .args([ path.to_str().expect("Should be a utf-8 str"), "-c", - format!("/% {}", id.uuid()).as_str(), + format!("/% {}", task.uuid()).as_str(), ]) .status()?; if !status.success() { @@ -90,7 +92,7 @@ pub fn handle(command: NeorgCommand, state: &mut State) -> Result<()> { } { - id.mark_neorg_data(state)?; + task.mark_neorg_data(state)?; } } } diff --git a/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs b/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs index ed24c2cb..6bed1e39 100644 --- a/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs +++ b/pkgs/by-name/ts/tskm/src/interface/neorg/mod.rs @@ -12,7 +12,7 @@ use std::path::PathBuf; use anyhow::Result; -use crate::task::{run_task, Project}; +use crate::task::{Project, run_task}; pub mod handle; pub use handle::handle; diff --git a/pkgs/by-name/ts/tskm/src/interface/open/handle.rs b/pkgs/by-name/ts/tskm/src/interface/open/handle.rs index f5925523..0cf60b41 100644 --- a/pkgs/by-name/ts/tskm/src/interface/open/handle.rs +++ b/pkgs/by-name/ts/tskm/src/interface/open/handle.rs @@ -8,47 +8,66 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::{ - fs, - net::{IpAddr, Ipv4Addr}, - path::PathBuf, - process, -}; +use std::str::FromStr; use anyhow::{bail, Context, Result}; -use log::{error, info, warn}; +use log::{error, info}; use url::Url; -use crate::{cli::OpenCommand, rofi, state::State, task}; +use crate::{browser::open_in_browser, cli::OpenCommand, rofi, state::State, task}; +fn is_empty(project: &task::Project) -> Result<bool> { + let tabs = get_tabs(project)?; + + if tabs.is_empty() { + Ok(true) + } else if tabs.len() > 1 { + Ok(false) + } else { + let url = &tabs[0].1; + + Ok(url == &Url::from_str("qute://start/").expect("Hardcoded")) + } +} + +#[allow(clippy::too_many_lines)] pub fn handle(command: OpenCommand, state: &mut State) -> Result<()> { match command { - OpenCommand::Review => { + OpenCommand::Review { non_empty } => { for project in task::Project::all().context("Failed to get all project files")? { - if project.is_touched() { - info!("Reviewing project: '{}'", project.to_project_display()); + let is_empty = is_empty(project)?; + + if project.is_touched() || (non_empty && !is_empty) { + info!( + "Reviewing project: '{}' ({})", + project.to_project_display(), + if is_empty { "is empty" } else { "is not empty" } + ); open_in_browser(project, state, None).with_context(|| { format!( - "Failed to open project ('{}') in Firefox", - project.to_project_display() - ) - })?; - project.untouch().with_context(|| { - format!( - "Failed to untouch project ('{}')", + "Failed to open project ('{}') in qutebrowser", project.to_project_display() ) })?; + + if project.is_touched() { + project.untouch().with_context(|| { + format!( + "Failed to untouch project ('{}')", + project.to_project_display() + ) + })?; + } } } } - OpenCommand::Project { project, url } => { + OpenCommand::Project { project, urls } => { project.touch().context("Failed to touch project")?; - open_in_browser(&project, state, url).with_context(|| { + open_in_browser(&project, state, urls).with_context(|| { format!("Failed to open project: {}", project.to_project_display()) })?; } - OpenCommand::Select { url } => { + OpenCommand::Select { urls } => { let selected_project: task::Project = task::Project::from_project_string( &rofi::select( task::Project::all() @@ -66,177 +85,106 @@ pub fn handle(command: OpenCommand, state: &mut State) -> Result<()> { .touch() .context("Failed to touch project")?; - open_in_browser(&selected_project, state, url).context("Failed to open project")?; + open_in_browser(&selected_project, state, urls).context("Failed to open project")?; } - OpenCommand::ListTabs { project } => { - let project = if let Some(p) = project { - p - } else if let Some(p) = - task::Project::get_current().context("Failed to get currently focused project")? - { - p - } else { - bail!("You need to either supply a project or have a project active!"); + OpenCommand::ListTabs { projects, mode } => { + let projects = { + if let Some(p) = projects { + p + } else if mode.is_some() { + task::Project::all() + .context("Failed to get all projects")? + .to_owned() + } else if let Some(p) = task::Project::get_current() + .context("Failed to get currently focused project")? + { + vec![p] + } else { + bail!("You need to either select projects or pass --mode"); + } }; - let session_store = project.get_sessionstore().with_context(|| { - format!( - "Failed to get session store for project: '{}'", - project.to_project_display() - ) - })?; - - let selected = session_store - .windows - .iter() - .map(|w| w.selected) - .collect::<Vec<_>>(); - - let tabs = session_store - .windows - .iter() - .flat_map(|window| window.tabs.iter()) - .map(|tab| tab.entries.get(tab.index - 1).expect("This should be Some")) - .collect::<Vec<_>>(); - - for (index, entry) in tabs.iter().enumerate() { - let index = index + 1; - let is_selected = { - if selected.contains(&index) { - "🔻 " - } else { - " " + for project in &projects { + if let Some(mode) = mode { + match mode { + crate::cli::ListMode::Empty => { + if !is_empty(project)? { + continue; + } + + // We do not need to print, tabs they are always empty. + if projects.len() > 1 { + println!("/* {} */", project.to_project_display()); + } + continue; + } + crate::cli::ListMode::NonEmpty => { + if is_empty(project)? { + continue; + } + } } - }; - println!("{}{}", is_selected, entry.url); - } - } - } - Ok(()) -} - -fn open_in_browser( - selected_project: &task::Project, - state: &mut State, - url: Option<Url>, -) -> Result<()> { - let old_project: Option<task::Project> = - task::Project::get_current().context("Failed to get currently active project")?; - let old_task: Option<task::Task> = - task::Task::get_current(state).context("Failed to get currently active task")?; - - selected_project.activate().with_context(|| { - format!( - "Failed to active project: '{}'", - selected_project.to_project_display() - ) - })?; - - let tracking_task = { - let all_tasks = selected_project.get_tasks(state).with_context(|| { - format!( - "Failed to get assoctiated tasks for project: '{}'", - selected_project.to_project_display() - ) - })?; - - let tracking_task = all_tasks.into_iter().find(|t| { - let maybe_desc = t.description(state); - if let Ok(desc) = maybe_desc { - desc == "tracking" - } else { - error!( - "Getting task description returned error: {}", - maybe_desc.expect_err("We already check for Ok") - ); - false - } - }); - - if let Some(task) = tracking_task { - info!( - "Starting task {} -> tracking", - selected_project.to_project_display() - ); - task.start(state) - .with_context(|| format!("Failed to start task {task}"))?; - } - tracking_task - }; - - let status = { - let mut args = vec!["-P".to_owned(), selected_project.to_project_display()]; - if let Some(url) = url { - args.push(url.to_string()); - } else { - let lock_file = dirs::home_dir() - .expect("Exists") - .join(".mozilla/firefox") - .join(selected_project.to_project_display()) - .join("lock"); - - if lock_file.exists() { - let (ip, pid): (IpAddr, u32) = { - let link = fs::read_link(&lock_file).with_context(|| { - format!("Failed to readlink lock at '{}'", lock_file.display()) - })?; + } - let (ip, pid) = link - .to_str() - .expect("Should work") - .split_once(':') - .expect("The split works"); + if projects.len() > 1 { + println!("/* {} */", project.to_project_display()); + } - ( - ip.parse().expect("Should be a valid ip address"), - pid.parse().expect("Should be a valid pid"), - ) + let tabs = match get_tabs(project) { + Ok(ok) => ok, + Err(err) => { + if projects.len() > 1 { + error!( + "While trying to get the sessionstore for {}: {:?}", + project.to_project_display(), + err + ); + continue; + } + + return Err(err).with_context(|| { + format!( + "While trying to get the sessionstore for {}", + project.to_project_display() + ) + }); + } }; - if ip != Ipv4Addr::new(127, 0, 0, 2) { - warn!("Your ip is weird.."); - } - - if PathBuf::from("/proc").join(pid.to_string()).exists() { - // Another Firefox instance has already been started for this project - // Add a buffer URL to force Firefox to open it in the already open instance - args.push("about:newtab".to_owned()); - } else { - // This project does not yet have another Firefox instance - // We do not need to add anything to the arguments, Firefox will open a new - // instance. + for (active, url) in tabs { + let is_selected = { + if active { + "🔻 " + } else { + " " + } + }; + println!("{is_selected}{url}"); } - } else { - // There is no lock file and thus no instance already open. } - }; - - process::Command::new("firefox") - .args(args) - .status() - .context("Failed to start firefox")? - }; - - if !status.success() { - error!("Firefox run exited with error."); + } } - if let Some(task) = tracking_task { - task.stop(state) - .with_context(|| format!("Failed to stop task {task}"))?; - } - if let Some(task) = old_task { - task.start(state) - .with_context(|| format!("Failed to start task {task}"))?; - } + Ok(()) +} - if let Some(project) = old_project { - project.activate().with_context(|| { - format!("Failed to active project {}", project.to_project_display()) - })?; - } else { - task::Project::clear().context("Failed to clear currently focused project")?; - } +fn get_tabs(project: &task::Project) -> Result<Vec<(bool, Url)>> { + let session_store = project.get_sessionstore()?; - Ok(()) + let tabs = session_store + .windows + .iter() + .flat_map(|window| window.tabs.iter()) + .filter_map(|tab| { + tab.history + .iter() + .find(|hist| hist.active) + .map(|hist| (tab.active, hist)) + }) + .collect::<Vec<_>>(); + + Ok(tabs + .into_iter() + .map(|(active, hist)| (active, hist.url.clone())) + .collect()) } diff --git a/pkgs/by-name/ts/tskm/src/interface/open/mod.rs b/pkgs/by-name/ts/tskm/src/interface/open/mod.rs index a4060fa3..e302c7d1 100644 --- a/pkgs/by-name/ts/tskm/src/interface/open/mod.rs +++ b/pkgs/by-name/ts/tskm/src/interface/open/mod.rs @@ -8,13 +8,12 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::{collections::HashMap, fs::File, io}; +use std::{fs::File, io::Read, str::FromStr}; -use anyhow::{Context, Result}; -use lz4_flex::decompress_size_prepended; -use serde::Deserialize; -use serde_json::Value; +use anyhow::{anyhow, Context, Result}; +use taskchampion::chrono::NaiveDateTime; use url::Url; +use yaml_rust2::Yaml; use crate::task::Project; @@ -23,94 +22,149 @@ pub use handle::handle; impl Project { pub(super) fn get_sessionstore(&self) -> Result<SessionStore> { - let path = dirs::home_dir() - .expect("Will exist") - .join(".mozilla/firefox") + let path = dirs::data_local_dir() + .context("Failed to get data dir")? + .join("qutebrowser") .join(self.to_project_display()) - .join("sessionstore-backups/recovery.jsonlz4"); - let file = decompress_mozlz4( - File::open(&path) - .with_context(|| format!("Failed to open path '{}'", path.display()))?, - ) - .with_context(|| format!("Failed to decompress file as mozlzh '{}'", path.display()))?; - - let contents: SessionStore = serde_json::from_str(&file).with_context(|| { - format!( - "Failed to deserialize file ('{}') as session store.", - path.display() - ) - })?; - Ok(contents) - } -} - -fn decompress_mozlz4<P: io::Read>(mut file: P) -> Result<String> { - const MOZLZ4_MAGIC_NUMBER: &[u8] = b"mozLz40\0"; + .join("data/sessions/default.yml"); - let mut buf = [0u8; 8]; - file.read_exact(&mut buf) - .context("Failed to read the mozlz40 header.")?; + let mut file = File::open(&path) + .with_context(|| format!("Failed to open path '{}'", path.display()))?; - assert_eq!(buf, MOZLZ4_MAGIC_NUMBER); + let mut yaml_str = String::new(); + file.read_to_string(&mut yaml_str) + .context("Failed to read _autosave.yml path")?; + let yaml = yaml_rust2::YamlLoader::load_from_str(&yaml_str)?; - let mut buf = vec![]; - file.read_to_end(&mut buf).context("Failed to read file")?; + let store = qute_store_from_yaml(&yaml).context("Failed to read yaml store")?; - let uncompressed = decompress_size_prepended(&buf).context("Failed to decompress file")?; + Ok(store) + } +} - Ok(String::from_utf8(uncompressed).expect("This should be valid json and thus utf8")) +fn qute_store_from_yaml(yaml: &[Yaml]) -> Result<SessionStore> { + assert_eq!(yaml.len(), 1); + let doc = &yaml[0]; + + let hash = doc.as_hash().context("Invalid yaml")?; + let windows = hash + .get(&Yaml::String("windows".to_owned())) + .ok_or(anyhow!("Missing windows"))? + .as_vec() + .ok_or(anyhow!("Windows not vector"))?; + + Ok(SessionStore { + windows: windows + .iter() + .map(|window| { + let hash = window.as_hash().ok_or(anyhow!("Windows not hashmap"))?; + + Ok::<_, anyhow::Error>(Window { + geometry: hash + .get(&Yaml::String("geometry".to_owned())) + .ok_or(anyhow!("Missing window geometry"))? + .as_str() + .ok_or(anyhow!("geometry not string"))? + .to_owned(), + tabs: hash + .get(&Yaml::String("tabs".to_owned())) + .ok_or(anyhow!("Missing window tabs"))? + .as_vec() + .ok_or(anyhow!("Tabs not vec"))? + .iter() + .map(|tab| { + let hash = tab.as_hash().ok_or(anyhow!("Tab not hashmap"))?; + + Ok::<_, anyhow::Error>(Tab { + history: hash + .get(&Yaml::String("history".to_owned())) + .ok_or(anyhow!("Missing tab history"))? + .as_vec() + .ok_or(anyhow!("tab history not vec"))? + .iter() + .map(|history| { + let hash = history + .as_hash() + .ok_or(anyhow!("Tab history not hashmap"))?; + + Ok::<_, anyhow::Error>(TabHistory { + active: hash + .get(&Yaml::String("active".to_owned())) + .unwrap_or(&Yaml::Boolean(false)) + .as_bool() + .ok_or(anyhow!("tab history active not bool"))?, + last_visited: NaiveDateTime::from_str( + hash.get(&Yaml::String("last_visited".to_owned())) + .ok_or(anyhow!( + "Missing tab history last_visited" + ))? + .as_str() + .ok_or(anyhow!( + "tab history last_visited not string" + ))?, + ) + .context("Failed to parse last_visited")?, + pinned: hash + .get(&Yaml::String("pinned".to_owned())) + .ok_or(anyhow!("Missing tab history pinned"))? + .as_bool() + .ok_or(anyhow!("tab history pinned not bool"))?, + title: hash + .get(&Yaml::String("title".to_owned())) + .ok_or(anyhow!("Missing tab history title"))? + .as_str() + .ok_or(anyhow!("tab history title not string"))? + .to_owned(), + url: Url::parse( + hash.get(&Yaml::String("url".to_owned())) + .ok_or(anyhow!("Missing tab history url"))? + .as_str() + .ok_or(anyhow!("tab history url not string"))?, + ) + .context("Failed to parse url")?, + zoom: hash + .get(&Yaml::String("zoom".to_owned())) + .unwrap_or(&Yaml::Real("1.0".to_owned())) + .as_f64() + .ok_or(anyhow!("tab history zoom not 64"))?, + }) + }) + .collect::<Result<Vec<_>, _>>()?, + active: hash + .get(&Yaml::String("active".to_owned())) + .unwrap_or(&Yaml::Boolean(false)) + .as_bool() + .ok_or(anyhow!("active not bool"))?, + }) + }) + .collect::<Result<Vec<_>, _>>()?, + }) + }) + .collect::<Result<Vec<_>, _>>()?, + }) } -#[derive(Deserialize, Debug)] +#[derive(Debug)] pub struct SessionStore { pub windows: Vec<Window>, } - -#[derive(Deserialize, Debug)] +#[derive(Debug)] pub struct Window { + pub geometry: String, pub tabs: Vec<Tab>, - pub selected: usize, } - -#[derive(Deserialize, Debug)] +#[derive(Debug)] pub struct Tab { - pub entries: Vec<TabEntry>, - #[serde(rename = "lastAccessed")] - pub last_accessed: u64, - pub hidden: bool, - #[serde(rename = "searchMode")] - pub search_mode: Option<Value>, - #[serde(rename = "userContextId")] - pub user_context_id: u32, - pub attributes: TabAttributes, - #[serde(rename = "extData")] - pub ext_data: Option<HashMap<String, Value>>, - pub index: usize, - #[serde(rename = "requestedIndex")] - pub requested_index: Option<u32>, - pub image: Option<Url>, + pub history: Vec<TabHistory>, + pub active: bool, } - -#[derive(Deserialize, Debug)] -pub struct TabEntry { - pub url: Url, +#[derive(Debug)] +pub struct TabHistory { + pub active: bool, + pub last_visited: NaiveDateTime, + pub pinned: bool, + // pub scroll-pos: pub title: String, - #[serde(rename = "cacheKey")] - pub cache_key: u32, - #[serde(rename = "ID")] - pub id: u32, - #[serde(rename = "docshellUUID")] - pub docshell_uuid: Value, - #[serde(rename = "resultPrincipalURI")] - pub result_principal_uri: Option<Url>, - #[serde(rename = "hasUserInteraction")] - pub has_user_interaction: bool, - #[serde(rename = "triggeringPrincipal_base64")] - pub triggering_principal_base64: Value, - #[serde(rename = "docIdentifier")] - pub doc_identifier: u32, - pub persist: bool, + pub url: Url, + pub zoom: f64, } - -#[derive(Deserialize, Debug, Clone, Copy)] -pub struct TabAttributes {} diff --git a/pkgs/by-name/ts/tskm/src/interface/project/handle.rs b/pkgs/by-name/ts/tskm/src/interface/project/handle.rs index c698500f..6d44b340 100644 --- a/pkgs/by-name/ts/tskm/src/interface/project/handle.rs +++ b/pkgs/by-name/ts/tskm/src/interface/project/handle.rs @@ -10,7 +10,7 @@ use std::{env, fs::File, io::Write}; -use anyhow::{anyhow, Context, Result}; +use anyhow::{Context, Result, anyhow}; use log::trace; use crate::{cli::ProjectCommand, task}; @@ -70,10 +70,12 @@ pub fn handle(command: ProjectCommand) -> Result<()> { let new_definition = ProjectDefinition::default(); - assert!(definition - .subprojects - .insert(segment.clone(), new_definition) - .is_none()); + assert!( + definition + .subprojects + .insert(segment.clone(), new_definition) + .is_none() + ); definition = definition .subprojects diff --git a/pkgs/by-name/ts/tskm/src/main.rs b/pkgs/by-name/ts/tskm/src/main.rs index fe011e27..e6113111 100644 --- a/pkgs/by-name/ts/tskm/src/main.rs +++ b/pkgs/by-name/ts/tskm/src/main.rs @@ -17,6 +17,7 @@ use crate::{ state::State, }; +pub mod browser; pub mod cli; pub mod interface; pub mod rofi; @@ -34,14 +35,13 @@ fn main() -> Result<(), anyhow::Error> { .show_module_names(true) .color(stderrlog::ColorChoice::Auto) .verbosity(usize::from(args.verbosity)) - .timestamp(stderrlog::Timestamp::Off) .init() .expect("Let's just hope that this does not panic"); let mut state = State::new_rw()?; match args.command { - Command::Inputs { command } => input::handle(command)?, + Command::Inputs { command } => input::handle(command, &mut state)?, Command::Neorg { command } => neorg::handle(command, &mut state)?, Command::Open { command } => open::handle(command, &mut state)?, Command::Projects { command } => project::handle(command)?, diff --git a/pkgs/by-name/ts/tskm/src/state.rs b/pkgs/by-name/ts/tskm/src/state.rs index 3c611d8f..ae71764e 100644 --- a/pkgs/by-name/ts/tskm/src/state.rs +++ b/pkgs/by-name/ts/tskm/src/state.rs @@ -11,7 +11,7 @@ use std::path::PathBuf; use anyhow::Result; -use taskchampion::{storage::AccessMode, Replica, StorageConfig}; +use taskchampion::{Replica, StorageConfig, storage::AccessMode}; pub struct State { replica: Replica, diff --git a/pkgs/by-name/ts/tskm/src/task/mod.rs b/pkgs/by-name/ts/tskm/src/task/mod.rs index 7d00896f..9c671273 100644 --- a/pkgs/by-name/ts/tskm/src/task/mod.rs +++ b/pkgs/by-name/ts/tskm/src/task/mod.rs @@ -76,7 +76,6 @@ impl Task { pub fn uuid(&self) -> &taskchampion::Uuid { &self.uuid } - #[must_use] pub fn working_set_id(&self, state: &mut State) -> Result<usize> { Ok(state .replica() @@ -356,5 +355,13 @@ pub(crate) fn run_task(args: &[&str]) -> Result<String> { trace!("Output (stdout): '{}'", stdout.trim()); trace!("Output (stderr): '{}'", stderr.trim()); + if !output.status.success() { + bail!( + "Command `task {}` failed with status: {}", + args.join(" "), + output.status + ); + } + Ok(stdout.trim().to_owned()) } diff --git a/pkgs/by-name/ya/yambar-modules/.envrc b/pkgs/by-name/ya/yambar-modules/.envrc deleted file mode 100644 index 294de504..00000000 --- a/pkgs/by-name/ya/yambar-modules/.envrc +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env sh - -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -use flake diff --git a/pkgs/by-name/ya/yambar-modules/.gitignore b/pkgs/by-name/ya/yambar-modules/.gitignore deleted file mode 100644 index d888531a..00000000 --- a/pkgs/by-name/ya/yambar-modules/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -/target diff --git a/pkgs/by-name/ya/yambar-modules/Cargo.lock b/pkgs/by-name/ya/yambar-modules/Cargo.lock deleted file mode 100644 index d77812b5..00000000 --- a/pkgs/by-name/ya/yambar-modules/Cargo.lock +++ /dev/null @@ -1,140 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -version = 4 - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "ntapi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" -dependencies = [ - "winapi", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "sysinfo" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2f3ca6693feb29a89724516f016488e9aafc7f37264f898593ee4b942f31b" -dependencies = [ - "cfg-if", - "core-foundation-sys", - "libc", - "ntapi", - "once_cell", - "rayon", - "winapi", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "yambar-modules" -version = "0.1.0" -dependencies = [ - "sysinfo", -] diff --git a/pkgs/by-name/ya/yambar-modules/Cargo.toml b/pkgs/by-name/ya/yambar-modules/Cargo.toml deleted file mode 100644 index 45078170..00000000 --- a/pkgs/by-name/ya/yambar-modules/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -[package] -name = "yambar-modules" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -sysinfo = "0.28.4" diff --git a/pkgs/by-name/ya/yambar-modules/flake.lock b/pkgs/by-name/ya/yambar-modules/flake.lock deleted file mode 100644 index 5b6484da..00000000 --- a/pkgs/by-name/ya/yambar-modules/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1747312588, - "narHash": "sha256-MmJvj6mlWzeRwKGLcwmZpKaOPZ5nJb/6al5CXqJsgjo=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b1bebd0fe266bbd1820019612ead889e96a8fa2d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/pkgs/by-name/ya/yambar-modules/flake.lock.license b/pkgs/by-name/ya/yambar-modules/flake.lock.license deleted file mode 100644 index eae6a84c..00000000 --- a/pkgs/by-name/ya/yambar-modules/flake.lock.license +++ /dev/null @@ -1,9 +0,0 @@ -nixos-config - My current NixOS configuration - -Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -SPDX-License-Identifier: GPL-3.0-or-later - -This file is part of my nixos-config. - -You should have received a copy of the License along with this program. -If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. diff --git a/pkgs/by-name/ya/yambar-modules/flake.nix b/pkgs/by-name/ya/yambar-modules/flake.nix deleted file mode 100644 index 99ec66a8..00000000 --- a/pkgs/by-name/ya/yambar-modules/flake.nix +++ /dev/null @@ -1,41 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{ - description = "Extension modules for yambar(1)"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { - nixpkgs, - flake-utils, - ... - }: - flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages."${system}"; - in { - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - # rust stuff - cargo - clippy - rustc - rustfmt - - cargo-edit - cargo-expand - ]; - }; - }); -} -# vim: ts=2 - diff --git a/pkgs/by-name/ya/yambar-modules/package.nix b/pkgs/by-name/ya/yambar-modules/package.nix deleted file mode 100644 index ea25633e..00000000 --- a/pkgs/by-name/ya/yambar-modules/package.nix +++ /dev/null @@ -1,23 +0,0 @@ -# nixos-config - My current NixOS configuration -# -# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This file is part of my nixos-config. -# -# You should have received a copy of the License along with this program. -# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -{rustPlatform}: -rustPlatform.buildRustPackage { - pname = "yambar-modules"; - version = "0.1.0"; - - src = ./.; - cargoLock = { - lockFile = ./Cargo.lock; - }; - - meta = { - mainProgram = "yambar-modules"; - }; -} diff --git a/pkgs/by-name/ya/yambar-modules/src/cpu.rs b/pkgs/by-name/ya/yambar-modules/src/cpu.rs deleted file mode 100644 index f53107a8..00000000 --- a/pkgs/by-name/ya/yambar-modules/src/cpu.rs +++ /dev/null @@ -1,31 +0,0 @@ -// nixos-config - My current NixOS configuration -// -// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of my nixos-config. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -use std::{thread, time::Duration}; - -use sysinfo::{CpuExt, System, SystemExt}; - -pub fn cpu() { - let mut sys = System::new(); - - loop { - sys.refresh_cpu(); - let cpu_usage: f32 = sys.cpus().iter().map(|cpu| cpu.cpu_usage()).sum(); - println!( - "cpu|range:0-100|{:.0}", - cpu_usage / sys.cpus().iter().count() as f32 - ); - println!(); - - // Sleeping to give the system time to run for long - // enough to have useful information. - thread::sleep(Duration::from_secs(3)); - } -} diff --git a/pkgs/by-name/ya/yambar-modules/src/main.rs b/pkgs/by-name/ya/yambar-modules/src/main.rs deleted file mode 100644 index 03bafadf..00000000 --- a/pkgs/by-name/ya/yambar-modules/src/main.rs +++ /dev/null @@ -1,36 +0,0 @@ -// nixos-config - My current NixOS configuration -// -// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of my nixos-config. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -use std::{env::args, process}; - -mod cpu; -mod memory; - -fn main() { - let args: Vec<String> = args().collect(); - - if args.len() != 2 { - eprintln!("Usage: yambar-modules cpu|memory"); - process::exit(1); - } - - match args[1].as_str() { - "cpu" => { - cpu::cpu(); - } - "memory" => { - memory::memory(); - } - other => { - eprintln!("'{other}' is not a valid command. Only 'cpu' or 'memory'."); - process::exit(1); - } - } -} diff --git a/pkgs/by-name/ya/yambar-modules/src/memory.rs b/pkgs/by-name/ya/yambar-modules/src/memory.rs deleted file mode 100644 index 7c2c4669..00000000 --- a/pkgs/by-name/ya/yambar-modules/src/memory.rs +++ /dev/null @@ -1,39 +0,0 @@ -// nixos-config - My current NixOS configuration -// -// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de> -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of my nixos-config. -// -// You should have received a copy of the License along with this program. -// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. - -use std::{thread, time::Duration}; - -use sysinfo::{System, SystemExt}; - -pub fn memory() { - let mut sys = System::new(); - - loop { - sys.refresh_memory(); - - let memory_percentage: f64 = - 100 as f64 * (sys.used_memory() as f64 / sys.total_memory() as f64); - - println!("memperc|string|{:.0}", memory_percentage); - if sys.total_swap() > 0 { - let swap_percentage: f64 = - 100 as f64 * (sys.used_swap() as f64 / sys.total_swap() as f64); - println!("swapperc|string|{:.0}", swap_percentage); - println!("swapstate|bool|true"); - } else { - println!("swapstate|bool|false"); - } - println!(""); - - // Sleeping to give the system time to run for long - // enough to have useful information. - thread::sleep(Duration::from_secs(3)); - } -} diff --git a/pkgs/by-name/ya/yambar-modules/update.sh b/pkgs/by-name/ya/yambar-modules/update.sh deleted file mode 100755 index b9404867..00000000 --- a/pkgs/by-name/ya/yambar-modules/update.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env sh - -[ "$1" = "upgrade" ] && cargo upgrade -cargo update - -# vim: ft=sh diff --git a/pkgs/by-name/yt/yt/package.nix b/pkgs/by-name/yt/yt/package.nix index d73776c5..63a37a47 100644 --- a/pkgs/by-name/yt/yt/package.nix +++ b/pkgs/by-name/yt/yt/package.nix @@ -8,41 +8,64 @@ # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. { + lib, + rustPlatform, + installShellFiles, fetchgit, - ffmpeg, gitUpdater, - glibc, - lib, - llvmPackages_latest, - makeWrapper, + # buildInputs mpv-unwrapped, + python3Packages, python3, - rustPlatform, + ffmpeg, + openssl, + libffi, + zlib, + curl, + # NativeBuildInputs + makeWrapper, + llvmPackages_latest, + glibc, + mold-wrapped, sqlite, fd, + pkg-config, + SDL2, }: let - version = "1.5.0"; - - src = fetchgit { - url = "https://git.foss-syndicate.org/bpeetz/clients/yt"; - rev = "v${version}"; - hash = "sha256-P/mpF2KPjoC7XZ6juJubeGEHhL2ajdOeiuIEb5sYrS0="; - }; - - buildInputs = [ - (python3.withPackages (ps: [ps.yt-dlp])) - mpv-unwrapped.dev - ffmpeg - ]; + version = "1.7.1"; in - rustPlatform.buildRustPackage { - inherit version src buildInputs; + rustPlatform.buildRustPackage (finalAttrs: { + inherit version; pname = "yt"; + src = fetchgit { + url = "https://git.foss-syndicate.org/bpeetz/clients/yt"; + tag = "v${version}"; + hash = "sha256-FKEMbxJI7OOXakY/JMyoz1rVU57xPuJ49m/JsB2b5Cc="; + }; + + buildInputs = [ + python3Packages.yt-dlp + mpv-unwrapped.dev + ffmpeg + openssl + libffi + zlib + curl.dev + ]; + nativeBuildInputs = [ + installShellFiles makeWrapper sqlite fd + pkg-config + mold-wrapped + ]; + + checkInputs = [ + # Needed for the tests in `libmpv2` + SDL2 ]; passthru.updateScript = gitUpdater {rev-prefix = "v";}; @@ -52,27 +75,56 @@ in lib.versions.major llvmPackages_latest.clang-unwrapped.version; in { + # Needed for the compile time sqlite checks. + DATABASE_URL = "sqlite://database.sqlx"; + + # Required by yt_dlp FFMPEG_LOCATION = "${lib.getExe ffmpeg}"; - PYO3_PYTHON = lib.getExe (python3.withPackages (ps: [ps.yt-dlp])); + # Needed for the libmpv2. C_INCLUDE_PATH = "${glibc.dev}/include"; - DATABASE_URL = "sqlite://target/database.sqlx"; LIBCLANG_INCLUDE_PATH = "${llvmPackages_latest.clang-unwrapped.lib}/lib/clang/${clang_version}/include"; LIBCLANG_PATH = "${llvmPackages_latest.clang-unwrapped.lib}/lib/libclang.so"; }; - # Some tests depend on network access, others require a special library. - doCheck = false; + doCheck = true; prePatch = '' + # Generate the sqlite db, so that we can run the comp-time sqlite checks. bash ./scripts/mkdb.sh ''; - useFetchCargoVendor = true; - cargoHash = "sha256-0XTbC+mFsczUFXqAtiQ+BIsCfKilerhlzE41pzVjLVs="; + cargoHash = "sha256-E5kMlXIoagidovGonTqbz9SMmvgKitJ9+zZW9U8WK7s="; + + postInstall = let + collectDeps = pkg: let + next = pkg.propagatedBuildInputs or []; + in + [pkg] + ++ next + ++ (lib.flatten (builtins.map collectDeps next)); + + loadPythonDep = der: "${der}/lib/python${lib.versions.majorMinor python3.version}/site-packages"; + + pythonPath = builtins.concatStringsSep ":" (lib.lists.unique ( + builtins.map loadPythonDep ( + (collectDeps python3Packages.yt-dlp) + ++ [ + # HACK(@bpeetz): These packages are not picked up in the traversal up top. <2025-06-16> + python3Packages.chardet + ] + ) + )); + in '' + installShellCompletion --cmd yt \ + --bash <(COMPLETE=bash $out/bin/yt) \ + --fish <(COMPLETE=fish $out/bin/yt) \ + --zsh <(COMPLETE=zsh $out/bin/yt) - postInstall = '' + # NOTE: We cannot clear the path, because we need access to the $EDITOR. <2025-04-04> wrapProgram $out/bin/yt \ - --prefix PATH : ${lib.makeBinPath buildInputs} + --prefix PATH : ${lib.makeBinPath finalAttrs.buildInputs} \ + --set YTDLP_NO_PLUGINS 1 \ + --set PYTHONPATH ${pythonPath} ''; - } + }) diff --git a/update.sh b/update.sh index ff10f870..8f7d338e 100755 --- a/update.sh +++ b/update.sh @@ -22,7 +22,6 @@ __update_sh_run() { } __update_sh_run nix flake update -__update_sh_run ./modules/by-name/fi/firefox/update_extensions.sh "$@" __update_sh_run ./pkgs/update_pkgs.sh "$@" # __update_sh_run nix flake check |