diff options
author | Mx Kookie <kookie@spacekookie.de> | 2020-10-31 19:35:09 +0100 |
---|---|---|
committer | Mx Kookie <kookie@spacekookie.de> | 2020-10-31 19:35:09 +0100 |
commit | c4625b175f8200f643fd6e11010932ea44c78433 (patch) | |
tree | bce3f89888c8ac3991fa5569a878a9eab6801ccc /infra/libkookie/nixpkgs/pkgs/applications/misc/cura | |
parent | 49f735974dd103039ddc4cb576bb76555164a9e7 (diff) | |
parent | d661aa56a8843e991261510c1bb28fdc2f6975ae (diff) |
Add 'infra/libkookie/' from commit 'd661aa56a8843e991261510c1bb28fdc2f6975ae'
git-subtree-dir: infra/libkookie
git-subtree-mainline: 49f735974dd103039ddc4cb576bb76555164a9e7
git-subtree-split: d661aa56a8843e991261510c1bb28fdc2f6975ae
Diffstat (limited to 'infra/libkookie/nixpkgs/pkgs/applications/misc/cura')
10 files changed, 446 insertions, 0 deletions
diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/default.nix b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/default.nix new file mode 100644 index 000000000000..c0aa0a481bdc --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/default.nix @@ -0,0 +1,64 @@ +{ mkDerivation, lib, fetchFromGitHub, cmake, python3, qtbase, qtquickcontrols2, qtgraphicaleffects, curaengine, plugins ? [] }: + +mkDerivation rec { + pname = "cura"; + version = "4.7.1"; + + src = fetchFromGitHub { + owner = "Ultimaker"; + repo = "Cura"; + rev = version; + sha256 = "19an168iad3cb5w8i71c0wbr79qnz5qnpxqx1j6dgh64qz6ffn2r"; + }; + + materials = fetchFromGitHub { + owner = "Ultimaker"; + repo = "fdm_materials"; + rev = version; + sha256 = "1w6i0dlff8b30q987x3y0zv8847fc8ppfcr9vi982msmv284c89z"; + }; + + buildInputs = [ qtbase qtquickcontrols2 qtgraphicaleffects ]; + propagatedBuildInputs = with python3.pkgs; [ + libsavitar numpy-stl pyserial requests uranium zeroconf + sentry-sdk trimesh + ] ++ plugins; + nativeBuildInputs = [ cmake python3.pkgs.wrapPython ]; + + cmakeFlags = [ + "-DURANIUM_DIR=${python3.pkgs.uranium.src}" + "-DCURA_VERSION=${version}" + ]; + + makeWrapperArgs = [ + # hacky workaround for https://github.com/NixOS/nixpkgs/issues/59901 + "--set OMP_NUM_THREADS 1" + ]; + + postPatch = '' + sed -i 's,/python''${PYTHON_VERSION_MAJOR}/dist-packages,/python''${PYTHON_VERSION_MAJOR}.''${PYTHON_VERSION_MINOR}/site-packages,g' CMakeLists.txt + sed -i 's, executable_name = .*, executable_name = "${curaengine}/bin/CuraEngine",' plugins/CuraEngineBackend/CuraEngineBackend.py + ''; + + postInstall = '' + mkdir -p $out/share/cura/resources/materials + cp ${materials}/*.fdm_material $out/share/cura/resources/materials/ + mkdir -p $out/lib/cura/plugins + for plugin in ${toString plugins}; do + ln -s $plugin/lib/cura/plugins/* $out/lib/cura/plugins + done + ''; + + postFixup = '' + wrapPythonPrograms + wrapQtApp $out/bin/cura + ''; + + meta = with lib; { + description = "3D printer / slicing GUI built on top of the Uranium framework"; + homepage = "https://github.com/Ultimaker/Cura"; + license = licenses.lgpl3Plus; + platforms = platforms.linux; + maintainers = with maintainers; [ abbradar gebner ]; + }; +} diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/curaengine-openmp-compat.patch b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/curaengine-openmp-compat.patch new file mode 100644 index 000000000000..3826e92440f0 --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/curaengine-openmp-compat.patch @@ -0,0 +1,47 @@ +# Notes by Charles Duffy <charles@dyfis.net> -- +# +# - The new version of OpenMP does not allow outside variables to be referenced +# *at all* without an explicit declaration of how they're supposed to be +# handled. Thus, this was an outright build failure beforehand. The new +# pragmas copy the initial value from the outer scope into each parallel +# thread. Since these variables are all constant within the loops, this is +# clearly correct. (Not sure it's *optimal*, but quite sure it isn't +# *wrong*). +# - Upstream has been contacted -- I'm a Lulzbot customer with an active +# support contract and sent them the patch. That said, they're in the middle +# of some major corporate churn (sold themselves out of near-bankruptcy to an +# out-of-state business entity formed as a holding company; moved to that +# state; have been slowly restaffing after), so a response may take a while. +# - The patch is purely my own work. + +--- curaengine/src/support.cpp.orig 2020-03-28 10:38:01.953912363 -0500 ++++ curaengine/src/support.cpp 2020-03-28 10:45:28.999791908 -0500 +@@ -854,7 +854,7 @@ + const double tan_angle = tan(angle) - 0.01; // the XY-component of the supportAngle + xy_disallowed_per_layer[0] = storage.getLayerOutlines(0, false).offset(xy_distance); + // for all other layers (of non support meshes) compute the overhang area and possibly use that when calculating the support disallowed area +- #pragma omp parallel for default(none) shared(xy_disallowed_per_layer, storage, mesh) schedule(dynamic) ++ #pragma omp parallel for default(none) firstprivate(layer_count, is_support_mesh_place_holder, use_xy_distance_overhang, z_distance_top, tan_angle, xy_distance, xy_distance_overhang) shared(xy_disallowed_per_layer, storage, mesh) schedule(dynamic) + for (unsigned int layer_idx = 1; layer_idx < layer_count; layer_idx++) + { + Polygons outlines = storage.getLayerOutlines(layer_idx, false); +@@ -1054,7 +1054,7 @@ + const int max_checking_layer_idx = std::min(static_cast<int>(storage.support.supportLayers.size()) + , static_cast<int>(layer_count - (layer_z_distance_top - 1))); + const size_t max_checking_idx_size_t = std::max(0, max_checking_layer_idx); +-#pragma omp parallel for default(none) shared(support_areas, storage) schedule(dynamic) ++#pragma omp parallel for default(none) firstprivate(max_checking_idx_size_t, layer_z_distance_top) shared(support_areas, storage) schedule(dynamic) + for (size_t layer_idx = 0; layer_idx < max_checking_idx_size_t; layer_idx++) + { + support_areas[layer_idx] = support_areas[layer_idx].difference(storage.getLayerOutlines(layer_idx + layer_z_distance_top - 1, false)); +--- curaengine/src/layerPart.cpp.orig 2020-03-28 10:36:40.381023651 -0500 ++++ curaengine/src/layerPart.cpp 2020-03-28 10:39:54.584140465 -0500 +@@ -49,7 +49,7 @@ + { + const auto total_layers = slicer->layers.size(); + assert(mesh.layers.size() == total_layers); +-#pragma omp parallel for default(none) shared(mesh, slicer) schedule(dynamic) ++#pragma omp parallel for default(none) firstprivate(total_layers) shared(mesh, slicer) schedule(dynamic) + for (unsigned int layer_nr = 0; layer_nr < total_layers; layer_nr++) + { + SliceLayer& layer_storage = mesh.layers[layer_nr]; diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/curaengine.nix b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/curaengine.nix new file mode 100644 index 000000000000..a5cfa937fd8d --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/curaengine.nix @@ -0,0 +1,27 @@ +{ gcc8Stdenv, callPackage, fetchgit, fetchpatch, cmake, libarcusLulzbot, stb, protobuf }: + +gcc8Stdenv.mkDerivation rec { + pname = "curaengine-lulzBot"; + version = "3.6.21"; + + src = fetchgit { + url = "https://code.alephobjects.com/source/curaengine-lulzbot.git"; + rev = "ec6a1a0f0aa387ef97e5c106633cf8d7fb9cd00d"; + sha256 = "0wdkvg1hmqp1gaym804lw09x4ngf5ffasd861jhflpy7djbmkfn8"; + }; + + patches = [ ./curaengine-openmp-compat.patch ]; + + nativeBuildInputs = [ cmake ]; + buildInputs = [ libarcusLulzbot stb protobuf ]; + + cmakeFlags = [ "-DCURA_ENGINE_VERSION=${version}" ]; + + meta = with gcc8Stdenv.lib; { + description = "A powerful, fast and robust engine for processing 3D models into 3D printing instruction"; + homepage = "https://code.alephobjects.com/source/curaengine-lulzbot/"; + license = licenses.agpl3; + platforms = platforms.linux; + maintainers = with maintainers; [ chaduffy ]; + }; +} diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/default.nix b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/default.nix new file mode 100644 index 000000000000..229966561c6d --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/default.nix @@ -0,0 +1,82 @@ +{ lib, mkDerivation, wrapQtAppsHook, callPackage, fetchgit, cmake, jq, python3, qtbase, qtquickcontrols2 }: + +let + # admittedly, we're using (printer firmware) blobs when we could compile them ourselves. + curaBinaryDataVersion = "3.6.21"; # Marlin v2.0.0.174 for Bio, v2.0.0.144 for others. + curaBinaryData = fetchgit { + url = "https://code.alephobjects.com/diffusion/CBD/cura-binary-data.git"; + rev = "5c75d0f6c10d8b7a903e2072a48cd1f08059509e"; + sha256 = "1qdsj6rczwzdwzyr7nz7fnypbphckjrnwl8c9dr6izsxyzs465c4"; + }; + + libarcusLulzbot = callPackage ./libarcus.nix { + inherit (python3.pkgs) buildPythonPackage sip pythonOlder; + }; + libsavitarLulzbot = callPackage ./libsavitar.nix { + inherit (python3.pkgs) buildPythonPackage sip pythonOlder; + }; + + inherit (python3.pkgs) buildPythonPackage pyqt5 numpy scipy shapely pythonOlder; + curaengine = callPackage ./curaengine.nix { + inherit libarcusLulzbot; + }; + uraniumLulzbot = callPackage ./uranium.nix { + inherit callPackage libarcusLulzbot; + inherit (python3.pkgs) buildPythonPackage pyqt5 numpy scipy shapely pythonOlder; + }; +in +mkDerivation rec { + pname = "cura-lulzbot"; + version = "3.6.21"; + + src = fetchgit { + url = "https://code.alephobjects.com/source/cura-lulzbot.git"; + rev = "7faeb18604c83004846a02c60cb240708db0034f"; + sha256 = "10q38s8c8x6xkh1vns4p3iqa5y267vrjh5vq8h55mg1q5001scyq"; + }; + + buildInputs = [ qtbase qtquickcontrols2 ]; + # numpy-stl temporarily disabled due to https://code.alephobjects.com/T8415 + propagatedBuildInputs = with python3.pkgs; [ pyserial requests zeroconf ] ++ [ libsavitarLulzbot uraniumLulzbot libarcusLulzbot ]; # numpy-stl + nativeBuildInputs = [ cmake python3.pkgs.wrapPython ]; + + cmakeFlags = [ + "-DURANIUM_DIR=${uraniumLulzbot.src}" + "-DCURA_VERSION=${version}" + ]; + + postPatch = '' + sed -i 's,/python''${PYTHON_VERSION_MAJOR}/dist-packages,/python''${PYTHON_VERSION_MAJOR}.''${PYTHON_VERSION_MINOR}/site-packages,g' CMakeLists.txt + sed -i 's, executable_name = .*, executable_name = "${curaengine}/bin/CuraEngine",' plugins/CuraEngineBackend/CuraEngineBackend.py + ''; + + preFixup = '' + substituteInPlace "$out/bin/cura-lulzbot" --replace 'import cura.CuraApplication' 'import Savitar; import cura.CuraApplication' + ln -sT "${curaBinaryData}/cura/resources/firmware" "$out/share/cura/resources/firmware" + ln -sT "${uraniumLulzbot}/share/uranium" "$out/share/uranium" + ${jq}/bin/jq --arg out "$out" '.build=$out' >"$out/version.json" <<'EOF' + ${builtins.toJSON { + cura = version; + cura_version = version; + binarydata = curaBinaryDataVersion; + engine = curaengine.version; + libarcus = libarcusLulzbot.version; + libsavitar = libsavitarLulzbot.version; + uranium = uraniumLulzbot.version; + }} + EOF + ''; + + postFixup = '' + wrapPythonPrograms + wrapQtApp "$out/bin/cura-lulzbot" + ''; + + meta = with lib; { + description = "3D printer / slicing GUI built on top of the Uranium framework"; + homepage = "https://code.alephobjects.com/diffusion/CURA/"; + license = licenses.agpl3; # a partial relicense to LGPL has happened, but not certain that all AGPL bits are expunged + platforms = platforms.linux; + maintainers = with maintainers; [ chaduffy ]; + }; +} diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/libarcus.nix b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/libarcus.nix new file mode 100644 index 000000000000..5edaabbacb0f --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/libarcus.nix @@ -0,0 +1,33 @@ +{ stdenv, buildPythonPackage, fetchgit, fetchurl, cmake, sip, protobuf, pythonOlder }: + +buildPythonPackage { + pname = "libarcus"; + version = "3.6.21"; + format = "other"; + + src = fetchgit { + url = "https://code.alephobjects.com/source/arcus.git"; + rev = "aeda02d7727f45b657afb72cef203283fbf09325"; + sha256 = "1ak0d4k745sx7paic27was3s4987z9h3czscjs21hxbi6qy83g99"; + }; + + disabled = pythonOlder "3.4.0"; + + propagatedBuildInputs = [ sip ]; + nativeBuildInputs = [ cmake ]; + buildInputs = [ protobuf ]; + + postPatch = '' + # To workaround buggy SIP detection which overrides PYTHONPATH + sed -i '/SET(ENV{PYTHONPATH}/d' cmake/FindSIP.cmake + ''; + + meta = with stdenv.lib; { + description = "Communication library between internal components for Ultimaker software"; + homepage = "https://code.alephobjects.com/source/arcus/"; + license = licenses.lgpl3Plus; + platforms = platforms.linux; + maintainers = with maintainers; [ chaduffy ]; + }; +} + diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/libsavitar.nix b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/libsavitar.nix new file mode 100644 index 000000000000..e32117a103ee --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/libsavitar.nix @@ -0,0 +1,33 @@ +{ stdenv, buildPythonPackage, pythonOlder, fetchgit, cmake, sip }: + +buildPythonPackage { + pname = "libsavitar-lulzbot"; + name = "libsavitar-lulzbot"; + version = "3.6.21"; + format = "other"; + + src = fetchgit { + url = "https://code.alephobjects.com/source/savitar.git"; + rev = "ee8ada42c55f54727ce4d275c294ba426d3d8234"; + sha256 = "1wm5ii3cmni8dk3c65kw4wglpypkdsfpgd480d3hc1r5bqpq0d6j"; + }; + + postPatch = '' + # To workaround buggy SIP detection which overrides PYTHONPATH + sed -i '/SET(ENV{PYTHONPATH}/d' cmake/FindSIP.cmake + ''; + + nativeBuildInputs = [ cmake ]; + + propagatedBuildInputs = [ sip ]; + + disabled = pythonOlder "3.4.0"; + + meta = with stdenv.lib; { + description = "C++ implementation of 3mf loading with SIP python bindings"; + homepage = "https://github.com/Ultimaker/libSavitar"; + license = licenses.lgpl3Plus; + platforms = platforms.unix; + maintainers = with maintainers; [ chaduffy ]; + }; +} diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/uranium.nix b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/uranium.nix new file mode 100644 index 000000000000..2ce0fab170ea --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/lulzbot/uranium.nix @@ -0,0 +1,38 @@ +{ stdenv, callPackage, fetchurl, fetchgit, buildPythonPackage, fetchFromGitHub, python, cmake +, pyqt5, numpy, scipy, shapely, libarcusLulzbot, doxygen, gettext, pythonOlder }: + +buildPythonPackage { + version = "3.6.21"; + pname = "uranium"; + name = "uraniumLulzbot"; + format = "other"; + + src = fetchgit { + url = "https://code.alephobjects.com/diffusion/U/uranium.git"; + rev = "54d911edd2551c5875c554928896122835a0dd6c"; + sha256 = "04bym3vwikaxw8ab0mymv9sc9n8i7yw5kfsv99ic811g9lzz3j1i"; + }; + + disabled = pythonOlder "3.5.0"; + + buildInputs = [ python gettext ]; + propagatedBuildInputs = [ pyqt5 numpy scipy shapely libarcusLulzbot ]; + nativeBuildInputs = [ cmake doxygen ]; + + postPatch = '' + sed -i 's,/python''${PYTHON_VERSION_MAJOR}/dist-packages,/python''${PYTHON_VERSION_MAJOR}.''${PYTHON_VERSION_MINOR}/site-packages,g' CMakeLists.txt + sed -i \ + -e "s,Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)).*,Resources.addSearchPath(\"$out/share/uranium/resources\")," \ + -e "s,self._plugin_registry.addPluginLocation(os.path.join(os.path.abspath(os.path.dirname(__file__)).*,self._plugin_registry.addPluginLocation(\"$out/lib/uranium/plugins\")," \ + UM/Application.py + ''; + + meta = with stdenv.lib; { + description = "A Python framework for building Desktop applications"; + homepage = "https://code.alephobjects.com/diffusion/U/"; + license = licenses.lgpl3Plus; + platforms = platforms.linux; + maintainers = with maintainers; [ chaduffy ]; + }; +} + diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/numpy-cast.patch b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/numpy-cast.patch new file mode 100644 index 000000000000..efb14182b3e6 --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/numpy-cast.patch @@ -0,0 +1,12 @@ +diff -urN Cura-15.04.old/Cura/util/sliceEngine.py Cura-15.04/Cura/util/sliceEngine.py +--- Cura-15.04.old/Cura/util/sliceEngine.py 2016-05-07 20:34:17.305020334 +0200 ++++ Cura-15.04/Cura/util/sliceEngine.py 2016-05-07 20:40:02.993286467 +0200 +@@ -343,7 +343,7 @@ + objMax[1] = max(oMax[1], objMax[1]) + if objMin is None: + return +- pos += (objMin + objMax) / 2.0 * 1000 ++ pos = numpy.add( pos, (objMin + objMax) / 2.0 * 1000, out=pos, casting='unsafe') + commandList += ['-s', 'posx=%d' % int(pos[0]), '-s', 'posy=%d' % int(pos[1])] + + vertexTotal = [0] * 4 diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/plugins.nix b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/plugins.nix new file mode 100644 index 000000000000..9082feb38a7a --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/plugins.nix @@ -0,0 +1,37 @@ +{ stdenv, fetchFromGitHub, fetchpatch, python3Packages }: + +let + + self = { + + octoprint = stdenv.mkDerivation rec { + pname = "Cura-OctoPrintPlugin"; + version = "3.5.16"; + + src = fetchFromGitHub { + owner = "fieldOfView"; + repo = pname; + rev = "8affa8aa9796cb37129d3b7222fff03f86c936cd"; + sha256 = "0l4qfcashkdmpdm8nm3klz6hmi1f0bmbpb9b1yn4mvg0fam6c5xi"; + }; + + propagatedBuildInputs = with python3Packages; [ + netifaces + ]; + + installPhase = '' + mkdir -p $out/lib/cura/plugins/OctoPrintPlugin + cp -rv . $out/lib/cura/plugins/OctoPrintPlugin/ + ''; + + meta = with stdenv.lib; { + description = "Enables printing directly to OctoPrint and monitoring the process"; + homepage = "https://github.com/fieldOfView/Cura-OctoPrintPlugin"; + license = licenses.agpl3; + maintainers = with maintainers; [ gebner ]; + }; + }; + + }; + +in self diff --git a/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/stable.nix b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/stable.nix new file mode 100644 index 000000000000..87d2aba891b6 --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/applications/misc/cura/stable.nix @@ -0,0 +1,73 @@ +{ stdenv, python27Packages, curaengine, makeDesktopItem, fetchurl }: +let + py = python27Packages; + version = "15.04"; +in +stdenv.mkDerivation rec { + pname = "cura"; + inherit version; + + src = fetchurl { + url = "https://github.com/daid/Cura/archive/${version}.tar.gz"; + sha256 = "0xbjvzhp8wzq9lnpmcg1fjf7j5h39bj5463sd5c8jzdjl96izizl"; + }; + + desktopItem = makeDesktopItem { + name = "Cura"; + exec = "cura"; + icon = "cura"; + comment = "Cura"; + desktopName = "Cura"; + genericName = "3D printing host software"; + categories = "GNOME;GTK;Utility;"; + }; + + python_deps = with py; [ pyopengl pyserial numpy wxPython30 power setuptools ]; + + pythonPath = python_deps; + + propagatedBuildInputs = python_deps; + + buildInputs = [ curaengine py.wrapPython ]; + + configurePhase = ""; + buildPhase = ""; + + patches = [ ./numpy-cast.patch ]; + + installPhase = '' + # Install Python code. + site_packages=$out/lib/python2.7/site-packages + mkdir -p $site_packages + cp -r Cura $site_packages/ + + # Install resources. + resources=$out/share/cura + mkdir -p $resources + cp -r resources/* $resources/ + sed -i 's|os.path.join(os.path.dirname(__file__), "../../resources")|"'$resources'"|g' $site_packages/Cura/util/resources.py + + # Install executable. + mkdir -p $out/bin + cp Cura/cura.py $out/bin/cura + chmod +x $out/bin/cura + sed -i 's|#!/usr/bin/python|#!/usr/bin/env python|' $out/bin/cura + wrapPythonPrograms + + # Make it find CuraEngine. + echo "def getEngineFilename(): return '${curaengine}/bin/CuraEngine'" >> $site_packages/Cura/util/sliceEngine.py + + # Install desktop item. + mkdir -p "$out"/share/applications + cp "$desktopItem"/share/applications/* "$out"/share/applications/ + mkdir -p "$out"/share/icons + ln -s "$resources/images/c.png" "$out"/share/icons/cura.png + ''; + + meta = with stdenv.lib; { + description = "3D printing host software"; + homepage = "https://github.com/daid/Cura"; + license = licenses.agpl3; + platforms = platforms.linux; + }; +} |