diff --git a/.SRCINFO b/.SRCINFO index b02b2a7..0a90765 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,7 +1,7 @@ pkgbase = superslicer-prerelease pkgdesc = G-code generator for 3D printers (RepRap, Makerbot, Ultimaker etc.) - pkgver = 2.4.58.2 - pkgrel = 2 + pkgver = 2.5.60.0 + pkgrel = 1 epoch = 1 url = https://github.com/supermerill/SuperSlicer arch = x86_64 @@ -13,7 +13,6 @@ pkgbase = superslicer-prerelease makedepends = libigl makedepends = openvdb makedepends = samurai - makedepends = wxgtk2 depends = boost-libs>=1.73.0 depends = cgal depends = glew @@ -22,19 +21,32 @@ pkgbase = superslicer-prerelease depends = nlopt depends = openvdb depends = qhull>=2020.2-4 - depends = wxgtk3 + depends = slicer-udev + depends = wxwidgets-gtk3 optdepends = superslicer-profiles: Predefined printer profiles - provides = superslicer=1:2.4.58.2 + provides = superslicer=1:2.5.60.0 conflicts = superslicer conflicts = superslicer-git options = !emptydirs - source = https://github.com/supermerill/SuperSlicer/archive/2.4.58.2.tar.gz - source = 0001-wxgtk3-is-broken-on-wayland.patch + source = https://github.com/supermerill/SuperSlicer/archive/2.5.60.0.tar.gz + source = 0001-boost1.79.patch source = 0002-fix-cereal.patch source = 0003-openexr3.patch - sha512sums = c5038bd13482a2a164ce7f3b126b9f0183b4220b2d46d84e86a0ad29624eb9e000c5b8ad876506e4042a80c7c57b7f34bbf2bf5affc385334e00da416c22fd27 - sha512sums = acf35ebe467e9fb30f1b77d15348f1a7b82dcf45a5b829e375e972b5d6b49968603b3fa090c4d1f56e8b5148e2b820e79afa269da60ace70de1ceadcf6e820c5 - sha512sums = c3ba2d16140d445168681ff442bda12e87de22f8b94d59c32576bd7079ffe5864cce8e62cddd1ed47458f9eddcbd3e1a02645b0645aad6f2e0cb08a876bf783f + source = 0004-fix-opencascade-version-check.patch + source = 0005-fix-opencascade-libs.patch + source = 0006-fix-non-const-lvalue.patch + source = 0007-boost1.84.patch + source = 0008-boost1.85.patch + source = 0009-fix-multiple-choice.patch + sha512sums = a53f4cc9b5a20f3f60d38553d47bfd19ce8bd739a8a16493bbcf64f75825fa760b8c107d7f927d49d967f7d067fac8c428c8f6e67219e74b0970d9ab7aa5b9e6 + sha512sums = fc18e8edf516f9479c3b0e201d1c74b42289f15ef8a64ff3a88c2bb14613978a9dcf7be50ff8b79faf054c7721a095a70715b0fb0747be48757f9502ba0eb859 + sha512sums = 58467732161eb0abe58cfb1e64e080f64f9f2221032b0d6176739fc81a61fe7838fa6479e9aac7fa0ee9805898f9293081c5e35a146df103830199b46354b97e sha512sums = 840e51b8feb3568ff46d309ece063f7188018fcaa43d19ec50ede408fdf2c237a3b7eaa11ba24409d8c3f7d6f5fb270181508cc56e0b2b0fef68b766130ef1eb + sha512sums = 4efb6dd48c8184f47b838228cf624a74429f35d133fb85316ddcde9d78bd462d64009ec9fe0b3f34232ddf4971f81ea03385ed661c771de9f0fd5bffcbe2a74c + sha512sums = a01abf748f82bc423f2c012ac430f78cfd5e56dede1d5999376e780267d0302d9a2a80c3eb15226c2f82102dda4c567c721ff99ab1fdeef504cbf9d9cb63ca53 + sha512sums = aca3a028eaab63baf83dd80d82615394435c97b9b45c99764ca84995d246096e3e5c2b564ed29e194652c8e221a80cf6abdc165cb3009fd20af586b0432b2bc9 + sha512sums = a92af974cb62901aab5a5c8c34672e9a7c90ea7246bbd7423421a9b7ee12a7b17073d90a6f36f994328c7dc9c2d0a6e4fd18c980a71863bc530d873ebaa80433 + sha512sums = ca9f407d87d8dd0181077bc2da5a8e2f8995eed88a4787b73ee6c62ef6d2380fd1394fe5412cdc34276d4182bce6f272173e9ccb653d1e28978e16f379114002 + sha512sums = 6d7ab93042a75f04e1c3c8f294d19dd39abaf22aa75caf996c6a0cf753f6472134a3d4fa443b73924800b2d3a710416a931745c168911c0df3709fb71ec00570 pkgname = superslicer-prerelease diff --git a/0001-boost1.79.patch b/0001-boost1.79.patch new file mode 100644 index 0000000..f3ad855 --- /dev/null +++ b/0001-boost1.79.patch @@ -0,0 +1,81 @@ +From 408e56f0390f20aaf793e0aa0c70c4d9544401d4 Mon Sep 17 00:00:00 2001 +From: Vojtech Bubnik +Date: Mon, 25 Apr 2022 08:33:48 +0200 +Subject: [PATCH] Fix of Boost 1.79 deprecated boost::filesystem::ofstream + #8238 Replacing boost::filesystem::fstream with boost::nowide::fstream + variants with the unfortunate cost of string path conversion on Windows from + 16 bits to UTF8 and back to 16 bits. + +Unfortunately we cannot use std::filesystem yet as it is missing +on older MACs and because the interface is crooked minefield on Windows +see https://github.com/microsoft/STL/issues/909 +--- + src/hints/HintsToPot.cpp | 2 +- + src/libslic3r/Preset.cpp | 2 +- + src/slic3r/GUI/HintNotification.cpp | 8 +++++--- + 3 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/hints/HintsToPot.cpp b/src/hints/HintsToPot.cpp +index 7c8029cdeb..4791f0612f 100644 +--- a/src/hints/HintsToPot.cpp ++++ b/src/hints/HintsToPot.cpp +@@ -9,7 +9,7 @@ + + bool write_to_pot(boost::filesystem::path path, const std::vector>& data) + { +- boost::filesystem::ofstream file(std::move(path), std::ios_base::app); ++ boost::nowide::ofstream file(path.string(), std::ios_base::app); + for (const auto& element : data) + { + //Example of .pot element +diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp +index f3a1c15b3e..f171cb14dd 100644 +--- a/src/libslic3r/Preset.cpp ++++ b/src/libslic3r/Preset.cpp +@@ -84,7 +84,7 @@ ConfigFileType guess_config_file_type(const ptree &tree) + VendorProfile VendorProfile::from_ini(const boost::filesystem::path &path, bool load_all) + { + ptree tree; +- boost::filesystem::ifstream ifs(path); ++ boost::nowide::ifstream ifs(path.string()); + boost::property_tree::read_ini(ifs, tree); + return VendorProfile::from_ini(tree, path, load_all); + } +diff --git a/src/slic3r/GUI/HintNotification.cpp b/src/slic3r/GUI/HintNotification.cpp +index 93e0fb3259..820b74eedb 100644 +--- a/src/slic3r/GUI/HintNotification.cpp ++++ b/src/slic3r/GUI/HintNotification.cpp +@@ -14,12 +14,14 @@ + #include "libslic3r/Config.hpp" + #include "libslic3r/PrintConfig.hpp" + ++#include ++ + #include + #include + #include + #include + #include +-#include ++ + #include + #include + #include +@@ -65,7 +67,7 @@ inline void push_style_color(ImGuiCol idx, const ImVec4& col, bool fading_out, f + + void write_used_binary(const std::vector& ids) + { +- boost::filesystem::ofstream file((boost::filesystem::path(data_dir()) / "cache" / "hints.cereal"), std::ios::binary); ++ boost::nowide::ofstream file((boost::filesystem::path(data_dir()) / "cache" / "hints.cereal").string(), std::ios::binary); + cereal::BinaryOutputArchive archive(file); + HintsCerealData cd { ids }; + try +@@ -84,7 +86,7 @@ void read_used_binary(std::vector& ids) + BOOST_LOG_TRIVIAL(warning) << "Failed to load to hints.cereal. File does not exists. " << path.string(); + return; + } +- boost::filesystem::ifstream file(path); ++ boost::nowide::ifstream file(path.string()); + cereal::BinaryInputArchive archive(file); + HintsCerealData cd; + try diff --git a/0001-wxgtk3-is-broken-on-wayland.patch b/0001-wxgtk3-is-broken-on-wayland.patch deleted file mode 100644 index b0371b4..0000000 --- a/0001-wxgtk3-is-broken-on-wayland.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp -index 4e85967a5..f141aabb5 100644 ---- a/src/slic3r/GUI/GUI.cpp -+++ b/src/slic3r/GUI/GUI.cpp -@@ -35,6 +35,16 @@ - - namespace Slic3r { namespace GUI { - -+// wxgtk3 is broken on wayland: https://trac.wxwidgets.org/ticket/17702 -+#ifdef __WXGTK3__ -+struct ForceX11 { -+ ForceX11() { -+ setenv("GDK_BACKEND", "x11", 1); -+ } -+}; -+static struct ForceX11 forcex11; -+#endif -+ - #if __APPLE__ - IOPMAssertionID assertionID; - #endif diff --git a/0002-fix-cereal.patch b/0002-fix-cereal.patch index 839b0ec..f3d52a0 100644 --- a/0002-fix-cereal.patch +++ b/0002-fix-cereal.patch @@ -34,12 +34,13 @@ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 01ef37905..98dbafa01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt -@@ -139,7 +139,7 @@ if (NOT WIN32) +@@ -139,8 +139,8 @@ if (NOT WIN32) set_target_properties(Slic3r PROPERTIES OUTPUT_NAME "${SLIC3R_APP_CMD}") endif () -target_link_libraries(Slic3r libslic3r cereal) +target_link_libraries(Slic3r libslic3r) + if (APPLE) # add_compile_options(-stdlib=libc++) # add_definitions(-DBOOST_THREAD_DONT_USE_CHRONO -DBOOST_NO_CXX11_RVALUE_REFERENCES -DBOOST_THREAD_USES_MOVE) diff --git a/0004-fix-opencascade-version-check.patch b/0004-fix-opencascade-version-check.patch new file mode 100644 index 0000000..2fa784a --- /dev/null +++ b/0004-fix-opencascade-version-check.patch @@ -0,0 +1,18 @@ +https://github.com/supermerill/SuperSlicer/issues/3912#issuecomment-1675135988 + +--- src/occt_wrapper/CMakeLists.txt.bak 2024-11-20 13:23:45.624527309 +0100 ++++ src/occt_wrapper/CMakeLists.txt 2024-11-20 13:23:56.347478724 +0100 +@@ -19,7 +19,12 @@ + + generate_export_header(OCCTWrapper) + +-find_package(OpenCASCADE 7.6.2 REQUIRED) ++find_package(OpenCASCADE REQUIRED) ++if (OpenCASCADE_VERSION VERSION_LESS 7.6.2) ++ message(FATAL_ERROR "OpenCASCADE v7 >= v7.6.2 must be used") ++elseif (OpenCASCADE_VERSION VERSION_GREATER_EQUAL 8.0.0) ++ message(FATAL_ERROR "OpenCASCADE v7 >= v7.6.2 must be used") ++endif () + + set(OCCT_LIBS + TKXDESTEP diff --git a/0005-fix-opencascade-libs.patch b/0005-fix-opencascade-libs.patch new file mode 100644 index 0000000..ebb023a --- /dev/null +++ b/0005-fix-opencascade-libs.patch @@ -0,0 +1,17 @@ +diff --git a/src/occt_wrapper/CMakeLists.txt b/src/occt_wrapper/CMakeLists.txt +index bde365264f..feea9ae66d 100644 +--- a/src/occt_wrapper/CMakeLists.txt ++++ b/src/occt_wrapper/CMakeLists.txt +@@ -27,11 +27,7 @@ elseif (OpenCASCADE_VERSION VERSION_GREATER_EQUAL 8.0.0) + endif () + + set(OCCT_LIBS +- TKXDESTEP +- TKSTEP +- TKSTEP209 +- TKSTEPAttr +- TKSTEPBase ++ TKDESTEP + TKXCAF + TKXSBase + TKVCAF diff --git a/0006-fix-non-const-lvalue.patch b/0006-fix-non-const-lvalue.patch new file mode 100644 index 0000000..0ccd25c --- /dev/null +++ b/0006-fix-non-const-lvalue.patch @@ -0,0 +1,19 @@ +diff --git a/src/libslic3r/MeshBoolean.cpp b/src/libslic3r/MeshBoolean.cpp +index 31fdc35de5..6e5e48e0f7 100644 +--- a/src/libslic3r/MeshBoolean.cpp ++++ b/src/libslic3r/MeshBoolean.cpp +@@ -147,12 +147,12 @@ template TriangleMesh cgal_to_triangle_mesh(const _Mesh &cgalmesh) + const auto &vertices = cgalmesh.vertices(); + int vsize = int(vertices.size()); + +- for (auto &vi : vertices) { ++ for (const auto &vi : vertices) { + auto &v = cgalmesh.point(vi); // Don't ask... + its.vertices.emplace_back(to_vec3f(v)); + } + +- for (auto &face : faces) { ++ for (const auto &face : faces) { + auto vtc = cgalmesh.vertices_around_face(cgalmesh.halfedge(face)); + + int i = 0; diff --git a/0007-boost1.84.patch b/0007-boost1.84.patch new file mode 100644 index 0000000..4ac2dfc --- /dev/null +++ b/0007-boost1.84.patch @@ -0,0 +1,34 @@ +diff --git a/src/slic3r/GUI/ScriptExecutor.cpp b/src/slic3r/GUI/ScriptExecutor.cpp +index 3e10680e46..3dcbf9643f 100644 +--- a/src/slic3r/GUI/ScriptExecutor.cpp ++++ b/src/slic3r/GUI/ScriptExecutor.cpp +@@ -827,6 +827,20 @@ void as_back_custom_initial_value(int preset_type, std::string& key) { + + /////// main script fucntions ////// + ++// stolen from https://www.boost.org/doc/libs/1_79_0/boost/filesystem/string_file.hpp ++static inline void load_string_file(boost::filesystem::path const& p, std::string& str) ++{ ++ boost::filesystem::ifstream file; ++ file.exceptions(std::ios_base::failbit | std::ios_base::badbit); ++ file.open(p, std::ios_base::binary); ++ const boost::uintmax_t sz = boost::filesystem::file_size(p); ++ if (BOOST_UNLIKELY(sz > static_cast< boost::uintmax_t >((std::numeric_limits< std::streamsize >::max)()))) ++ BOOST_FILESYSTEM_THROW(std::length_error("File size exceeds max read size")); ++ str.resize(static_cast< std::size_t >(sz), '\0'); ++ if (sz > 0u) ++ file.read(&str[0], static_cast< std::streamsize >(sz)); ++} ++ + //TODO: add "unset" function, that revert to last value (befoer a scripted set) if a set has been made since last not-scripted change. + void ScriptContainer::init(const std::string& tab_key, Tab* tab) + { +@@ -960,7 +974,7 @@ void ScriptContainer::init(const std::string& tab_key, Tab* tab) + //res = builder.AddSectionFromFile(ui_script_file.string().c_str()); //seems to be problematic on cyrillic locale + { + std::string all_file; +- boost::filesystem::load_string_file(ui_script_file, all_file); ++ load_string_file(ui_script_file, all_file); + res = builder.AddSectionFromMemory(ui_script_file.string().c_str(), all_file.c_str(), (unsigned int)(all_file.length()), 0); + } + if (res < 0) throw CompileErrorException("Error, can't build the script for tab " + tab_key); diff --git a/0008-boost1.85.patch b/0008-boost1.85.patch new file mode 100644 index 0000000..c57a224 --- /dev/null +++ b/0008-boost1.85.patch @@ -0,0 +1,12 @@ +diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp +index 2f8ac96a1a..ed615c8d3e 100644 +--- a/src/slic3r/GUI/RemovableDriveManager.cpp ++++ b/src/slic3r/GUI/RemovableDriveManager.cpp +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + #endif + diff --git a/0009-fix-multiple-choice.patch b/0009-fix-multiple-choice.patch new file mode 100644 index 0000000..91f9ad7 --- /dev/null +++ b/0009-fix-multiple-choice.patch @@ -0,0 +1,14 @@ +diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp +index 7ca307ff9d..11fdea36b1 100644 +--- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp ++++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp +@@ -564,7 +564,8 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr + // Always fill in the "printhost_port" combo box from the config and select it. + { + Choice* choice = dynamic_cast(m_optgroup->get_field("printhost_port")); +- choice->set_values({ m_config->opt_string("printhost_port") }); ++ const std::vector choice_values = { m_config->opt_string("printhost_port") }; ++ choice->set_values(choice_values); + choice->set_selection(); + } + diff --git a/PKGBUILD b/PKGBUILD index b76151b..eddfbaa 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,28 +1,42 @@ +# SPDX-License-Identifier: APGL-3.0 +# Maintainer: Dominic git at msrd0 dot de # Maintainer: Lukas1818 aur at lukas1818 dot de pkgname=superslicer-prerelease -pkgver=2.4.58.2 +pkgver=2.5.60.0 _pkgtag=$pkgver -pkgrel=2 +pkgrel=1 epoch=1 pkgdesc="G-code generator for 3D printers (RepRap, Makerbot, Ultimaker etc.)" arch=("$CARCH") url="https://github.com/supermerill/SuperSlicer" license=('AGPL3') options=(!emptydirs) -depends=('boost-libs>=1.73.0' 'cgal' 'glew' 'imath' 'libspnav' 'nlopt' 'openvdb' 'qhull>=2020.2-4' 'wxgtk3') -makedepends=('boost>=1.73.0' 'cereal>=1.3.0' 'cmake' 'eigen' 'libigl' 'openvdb' 'samurai' 'wxgtk2') # cmake doesn't detect wx if not both gtk2 and gtk3 are installed +depends=('boost-libs>=1.73.0' 'cgal' 'glew' 'imath' 'libspnav' 'nlopt' 'openvdb' 'qhull>=2020.2-4' 'slicer-udev' 'wxwidgets-gtk3') +makedepends=('boost>=1.73.0' 'cereal>=1.3.0' 'cmake' 'eigen' 'libigl' 'openvdb' 'samurai') optdepends=('superslicer-profiles: Predefined printer profiles') provides=("superslicer=$epoch:$pkgver") conflicts=('superslicer' 'superslicer-git') source=("https://github.com/supermerill/SuperSlicer/archive/$_pkgtag.tar.gz" - "0001-wxgtk3-is-broken-on-wayland.patch" + "0001-boost1.79.patch" "0002-fix-cereal.patch" - "0003-openexr3.patch") -sha512sums=('c5038bd13482a2a164ce7f3b126b9f0183b4220b2d46d84e86a0ad29624eb9e000c5b8ad876506e4042a80c7c57b7f34bbf2bf5affc385334e00da416c22fd27' - 'acf35ebe467e9fb30f1b77d15348f1a7b82dcf45a5b829e375e972b5d6b49968603b3fa090c4d1f56e8b5148e2b820e79afa269da60ace70de1ceadcf6e820c5' - 'c3ba2d16140d445168681ff442bda12e87de22f8b94d59c32576bd7079ffe5864cce8e62cddd1ed47458f9eddcbd3e1a02645b0645aad6f2e0cb08a876bf783f' - '840e51b8feb3568ff46d309ece063f7188018fcaa43d19ec50ede408fdf2c237a3b7eaa11ba24409d8c3f7d6f5fb270181508cc56e0b2b0fef68b766130ef1eb') + "0003-openexr3.patch" + "0004-fix-opencascade-version-check.patch" + "0005-fix-opencascade-libs.patch" + "0006-fix-non-const-lvalue.patch" + "0007-boost1.84.patch" + "0008-boost1.85.patch" + "0009-fix-multiple-choice.patch") +sha512sums=('a53f4cc9b5a20f3f60d38553d47bfd19ce8bd739a8a16493bbcf64f75825fa760b8c107d7f927d49d967f7d067fac8c428c8f6e67219e74b0970d9ab7aa5b9e6' + 'fc18e8edf516f9479c3b0e201d1c74b42289f15ef8a64ff3a88c2bb14613978a9dcf7be50ff8b79faf054c7721a095a70715b0fb0747be48757f9502ba0eb859' + '58467732161eb0abe58cfb1e64e080f64f9f2221032b0d6176739fc81a61fe7838fa6479e9aac7fa0ee9805898f9293081c5e35a146df103830199b46354b97e' + '840e51b8feb3568ff46d309ece063f7188018fcaa43d19ec50ede408fdf2c237a3b7eaa11ba24409d8c3f7d6f5fb270181508cc56e0b2b0fef68b766130ef1eb' + '4efb6dd48c8184f47b838228cf624a74429f35d133fb85316ddcde9d78bd462d64009ec9fe0b3f34232ddf4971f81ea03385ed661c771de9f0fd5bffcbe2a74c' + 'a01abf748f82bc423f2c012ac430f78cfd5e56dede1d5999376e780267d0302d9a2a80c3eb15226c2f82102dda4c567c721ff99ab1fdeef504cbf9d9cb63ca53' + 'aca3a028eaab63baf83dd80d82615394435c97b9b45c99764ca84995d246096e3e5c2b564ed29e194652c8e221a80cf6abdc165cb3009fd20af586b0432b2bc9' + 'a92af974cb62901aab5a5c8c34672e9a7c90ea7246bbd7423421a9b7ee12a7b17073d90a6f36f994328c7dc9c2d0a6e4fd18c980a71863bc530d873ebaa80433' + 'ca9f407d87d8dd0181077bc2da5a8e2f8995eed88a4787b73ee6c62ef6d2380fd1394fe5412cdc34276d4182bce6f272173e9ccb653d1e28978e16f379114002' + '6d7ab93042a75f04e1c3c8f294d19dd39abaf22aa75caf996c6a0cf753f6472134a3d4fa443b73924800b2d3a710416a931745c168911c0df3709fb71ec00570') prepare() { @@ -35,9 +49,15 @@ prepare() sed -i 's,add_subdirectory(test),,g' src/CMakeLists.txt # apply patches - patch -Np1 -i "$srcdir/0001-wxgtk3-is-broken-on-wayland.patch" + patch -Np1 -i "$srcdir/0001-boost1.79.patch" patch -Np1 -i "$srcdir/0002-fix-cereal.patch" patch -Np1 -i "$srcdir/0003-openexr3.patch" + patch -Np0 -i "$srcdir/0004-fix-opencascade-version-check.patch" + patch -Np1 -i "$srcdir/0005-fix-opencascade-libs.patch" + patch -Np1 -i "$srcdir/0006-fix-non-const-lvalue.patch" + patch -Np1 -i "$srcdir/0007-boost1.84.patch" + patch -Np1 -i "$srcdir/0008-boost1.85.patch" + patch -Np1 -i "$srcdir/0009-fix-multiple-choice.patch" } build() @@ -55,7 +75,8 @@ build() -DSLIC3R_WX_STABLE=ON \ -DSLIC3R_GTK=3 \ -DSLIC3R_BUILD_TESTS=OFF \ - -DSLIC3R_ALPHA=ON + -DSLIC3R_ALPHA=ON \ + -Wno-dev samu } @@ -66,4 +87,5 @@ package() DESTDIR="$pkgdir" samu install test ! -h "$pkgdir/usr/share/SuperSlicer/resources" || rm "$pkgdir/usr/share/SuperSlicer/resources" + rm -r "$pkgdir/usr/lib/udev" # provided by slicer-udev }