-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Any thoughts of integration with VCPKG? #11
Comments
No. I have no plans to do so. If I have time/motivation to put any effort into the distribution, the next thing I'd do would be providing packages for Debian based distros via OBS. But I'll leave this issue open since it is a valid feature request and contributions in that regard are welcome of course. Note that to avoid boilerplate code in the build system I outsourced a lot of logic into https://github.com/Martchus/cpp-utilities. So this integration is likely implemented best in that underlying library. |
@Martchus No problem. I wanted to learn how to add libraries to vcpkg so I'll use this as a learning experience. I'll let you know if I have any questions! |
Your library looks promising. But I don't know how to build this in Visual Studio. Finding hard to work with cmakelists.txt due to errors about missing package. It would be great if you provide projects of different format . Like for Visual Studio. I understand that you prefer Debian based distros via OBS. But Visual Studio is also quite popular. |
I'd like to note that building the library within Visual Studio (which likely also means using Microsoft's C++ compiler and standard library) is not supported by this project, at least not by my side. Of course I'm not doing anything on purpose to prevent it from working but I'm not going to take any effort into testing that configuration. The reason is that this is an open source project so the focus also lies on using open source tooling and open source platforms. Hence the Windows builds are conducted under GNU/Linux with GCC/mingw-w64.
Not among the developers of this project (mainly myself).
I would accept contributions to improve the CMake script for use within Visual Studio. However, I would not accept contributions which introduce different/independent project files as I have no motivation to maintain them.
Likely you did something wrong. Note that this library also depends on c++utilities. Please read the build instructions and lookup how to use CMake in general with Visual Studio. Note that you don't have to build the library itself within Visual Studio and your own project does not need to use CMake but can rely on the pkg-config file (which is intended to close the gap between different build systems). |
Hi there, @willkara , did you ever get a vcpkg integration working? I'm trying to use this tool in my project at the moment, and I'm running into a lot of issues just compiling the thing. I want a "x64-windows-static-md" version of the project (in vcpkg triplet terms). I'll agree with what @conceptworld has said, it's incredibly difficult working out how to build this library from a Windows PC - regardless of the compiler used (Visual Studio or otherwise). Even when I try to use your other repo with PKGBUILD files, I hit error after error: Would it be possible to provide a one-off precompiled Windows release, or provide more specific build instructions on the exact steps to build from a Windows environment (even if via WSL etc). Thanks, |
That should be generally feasible. At least the vcpkg triplet "win-x64-msvc-static" worked for me when I built tagparser against vcpkg-provided dependencies built using that triplet and when I built tagparser itself using the following configuration: https://github.com/Martchus/cpp-utilities/blob/2137568ad8a9c2035d75ee6d51e2205c6f7f337f/CMakePresets.json#L207 I have never tried building tagparser itself as vcpkg package. Note that to do so you would definitely need to package c++utilities first (which should not be a big deal, though).
To be frank, it doesn't look like you're very familiar with Arch Linux. This error message clearly states that certain dependencies are not available. This means you need to build those dependencies first. Note that you always need to build dependencies first and depended packages second. You need to apply this recursively. Normally you'd use some kind of helper script to build a bunch of packages in one go. If you're not familiar with Arch Linux then that's probably not the way to go. You could use my binary repository for Arch Linux, though.
Just build this project like any other CMake-based project. That also means building dependencies first and dependent packages second. I have already added a few remarks in the README of c++utilities which you'll going to build before tagparser. And before building c++utilities you obviously need to install its dependencies, too. The easiest approach is using MSYS2's mingw-w64 packages as explained in that README section. However, all dependencies are in vcpkg as well and I also have the mentioned CMake preset for that. You can also build the projects in one-go. That's what I have documented in the README of Tag Editor. Supposedly you'll can strip down the commands mentioned in my README files a little bit if you only want tagparser (and not the Tag Editor and anything using Qt). |
You are correct. I am just trying to muddle through the build instructions, which aren't very clear. I have no issue building projects normally, it's just this one refuses to build for me on Windows and the build instructions aren't clear at all. For instance, to mention to build https://github.com/Martchus/cpp-utilities first. When reading the build instructions you reference:
This "Building this straight" wording doesn't actually appear anywhere on the page:
When I try to build this via the cmake GUI I get a missing library, IconV: When I try to use vcpkg to install this, even this errors out: I'm not trying to be difficult, I legitimately can't work out how to build this thing at all on a Windows machine. When I try to follow the "remarks for building on Windows" section it tells me to use Arch Linux, which you quite rightly assume I am not familiar with. Can you please either provide actual step-by-step instructions on how to build this, or provide a pre-built Windows release? |
That's true. I guess there's room for improvement. I was referring to https://github.com/Martchus/tageditor#building-this-straight or https://github.com/Martchus/syncthingtray#building-this-straight depending or https://github.com/Martchus/passwordmanager#building-this-straight on where you're coming from.
Did you install that library? Like with any other CMake project you need to build and install dependencies first.
Maybe this vcpkg package is currently not building. I'm not a frequent user of vcpkg myself but I can say that it definitely worked for me at some point just by following their documentation. The command I've been using was
I personally would suggest you use MSYS2's mingw-w64 packages then (instead of vcpkg). Those packages are per-compiled so you cannot run into build errors. The mingw-w64 environment of MSYS2 is also very streamlined so you don't have to mess much with paths. It is definitely the way of least resistance under Windows.
It also tells you "Do not use them unless you know what you are doing." :-) |
I'll note down that I'm going to do the following improvements:
Note that documenting this is more challenging than you might think. The documentation needs to be generic enough so people with slightly different use cases and environments won't frown upon stuff that's too tailored to one specific usecase/environment. On the other hand, it still needs to contain platform specific details. Additionally, I have several projects and I don't like to duplicate stuff. That's where the wild referencing comes from. |
I have extended the build instructions of c++utilities: https://github.com/Martchus/cpp-utilities#remarks-for-building-on-windows |
With the help of the updated instructions I've done the following: REM Pre-requsites:
REM Cmake: https://cmake.org/download/
REM Visual Studio 17 2022: https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=community&rel=17
REM qt: https://www.qt.io/download-qt-installer (install to C:\src\qt and pick the optional 6.5.2 packages)
REM vcpkg:
REM Navigate to C:\src
REM git clone https://github.com/Microsoft/vcpkg.git
REM .\vcpkg\bootstrap-vcpkg.bat
REM vcpkg install boost-system:x64-windows-static boost-iostreams:x64-windows-static boost-filesystem:x64-windows-static boost-hana:x64-windows-static boost-process:x64-windows-static boost-asio:x64-windows-static libiconv:x64-windows-static zlib:x64-windows-static openssl:x64-windows-static cppunit:x64-windows-static
REM Environment variables:
REM MSVC_ROOT
REM C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532
REM QT_ROOT
REM C:\src\qt\6.5.2\msvc2019_64
REM QT_TOOLS
REM C:\src\qt\Tools
REM QT_TOOLS
REM C:\src\qt\Tools
REM VCPKG_ROOT
REM C:\src\vcpkg
REM WIN_KITS_ROOT
REM C:/Program Files (x86)/Windows Kits/10 From there I open a CMD window and go to a directory where I want to build, i.e. the desktop REM Directory to use for build:
SET "directory=%cd%\tagparser"
REM Empty/create the build directory
rd /s /q "%directory%" 2>NUL
mkdir "%directory%"
cd "%directory%"
REM Clone c++utilities repo
git clone --recursive https://github.com/Martchus/cpp-utilities c++utilities
REM Make Martchus/cpp-utilities
cmake --preset win-x64-msvc-static -S "%directory%/c++utilities" -B "%directory%/build-c++utilities" -DCMAKE_INSTALL_PREFIX="%directory%/release-c++utilities" Now I open an x64 Native Tools Command Prompt for VS 2022 prompt, as the default one errors here for some reason when trying to include standard C++ libraries: REM Build
cmake --build "%directory%/build-c++utilities"
REM Bundle the cpp-utilities
cmake --install "%directory%/build-c++utilities" I then repeat for the tagparser repo: REM Clone repo:
git clone --recursive https://github.com/Martchus/tagparser
REM Copy presets:
copy "c++utilities\CMakePresets.json" "tagparser\CMakePresets.json"
cmake --preset win-x64-msvc-static -S "%directory%/tagparser" -B "%directory%/build-tagparser" -DCMAKE_INSTALL_PREFIX="%directory%/release-tagparser" -Dc++utilities_DIR="%directory%/release-c++utilities\share\c++utilities\cmake" Again, I open an x64 Native Tools Command Prompt for VS 2022 prompt, as the default one errors here for some reason when trying to include standard C++ libraries: REM Build
cmake --build "%directory%/build-tagparser"
REM Bundle the tag parser
cmake --install "%directory%/build-tagparser"
REM Output is now in "%directory%/release-tagparser" If I do all this, I get the following output files: tagparser-compiled.zip So this seems to work correctly, please do say if anything looks wrong in this. From here, in my cmake project I am including them like so: include_directories("${CMAKE_CURRENT_LIST_DIR}/dependencies/tagparser/release-tagparser/include")
target_link_libraries(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_LIST_DIR}/dependencies/tagparser/release-tagparser/lib/tagparser.lib")
include_directories("${CMAKE_CURRENT_LIST_DIR}/dependencies/tagparser/release-c++utilities/include")
target_link_libraries(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_LIST_DIR}/dependencies/tagparser/release-c++utilities/include/c++utilities.lib") Again, no issues with this. When I then compile the project, I get the following warnings around "X needs to have dll-interface to be used by clients of class Y", which is a little confusing if everything has been statically compiled. PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(37,37): warning C4251: 'TagParser::StreamDataBlock::m_buffer': class 'std::unique_ptr<char [],std::default_delete<char []>>' needs to have dll-interface to be used by clients of class 'TagParser::StreamDataBlock' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(26,16): note: see declaration of 'std::unique_ptr<char [],std::default_delete<char []>>'
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(97,36): warning C4251: 'TagParser::FileDataBlock::m_fileInfo': class 'std::unique_ptr<TagParser::MediaFileInfo,std::default_delete<TagParser::MediaFileInfo>>' needs to have dll-interface to be used by clients of class 'TagParser::FileDataBlock' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(97,10): note: see declaration of 'std::unique_ptr<TagParser::MediaFileInfo,std::default_delete<TagParser::MediaFileInfo>>'
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(132,17): warning C4251: 'TagParser::AbstractAttachment::m_description': class 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' needs to have dll-interface to be used by clients of class 'TagParser::AbstractAttachment' [PROJECT.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xstring(5155,29): note: see declaration of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>'
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(133,17): warning C4251: 'TagParser::AbstractAttachment::m_name': class 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' needs to have dll-interface to be used by clients of class 'TagParser::AbstractAttachment' [PROJECT.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xstring(5155,29): note: see declaration of 'std::basic_string<char,std::char_traits<char>,std::al
locator<char>>'
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(134,17): warning C4251: 'TagParser::AbstractAttachment::m_mimeType': class 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' needs to have dll-interface to be used by clients of class 'TagParser::AbstractAttachment' [PROJECT.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xstring(5155,29): note: see declaration of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>'
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(136,38): warning C4251: 'TagParser::AbstractAttachment::m_data': class 'std::unique_ptr<TagParser::StreamDataBlock,std::default_delete<TagParser::StreamDataBlock>>' needs to have dll-interface to be used by clients of class 'TagParser::AbstractAttachment' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(118,23): note: see declaration of 'std::unique_ptr<TagParser::StreamDataBlock,std::default_delete<TagParser::StreamDataBlock>>'
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(137,48): warning C4251: 'TagParser::AbstractAttachment::m_p': class 'std::unique_ptr<TagParser::AbstractAttachmentPrivate,std::default_delete<TagParser::AbstractAttachmentPrivate>>' needs to have dll-interface to be used by clients of class 'TagParser::AbstractAttachment' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser/abstractattachment.h(137,10): note: see declaration of 'std::unique_ptr<TagParser::AbstractAttachmentPrivate,std::default_delete<TagParser::AbstractAttachmentPrivate>>'
PROJECT\tagparser\release-tagparser\include\tagparser\./exceptions.h(11,57): warning C4275: non dll-interface class 'std::exception' used as base for dll-interface class 'TagParser::Failure' [PROJECT.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\exception(38,19): note: see declaration of 'std::exception'
PROJECT\tagparser\release-tagparser\include\tagparser\./exceptions.h(11,25): note: see declaration of 'TagParser::Failure'
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(49,17): warning C4251: 'TagParser::TagTarget::m_levelName': class 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' needs to have dll-interface to be used by clients of class 'TagParser::TagTarget' [PROJECT.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xstring(5155,29): note: see declaration of 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>'
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(50,21): warning C4251: 'TagParser::TagTarget::m_tracks': class 'std::vector<TagParser::TagTarget::IdType,std::allocator<TagParser::TagTarget::IdType>>' needs to have dll-interface to be used by clients of class 'TagParser::TagTarget' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(23,34): note: see declaration of 'std::vector<TagParser::TagTarget::IdType,std::allocator<TagParser::TagTarget::IdType>>'
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(51,21): warning C4251: 'TagParser::TagTarget::m_chapters': class 'std::vector<TagParser::TagTarget::IdType,std::allocator<TagParser::TagTarget::IdType>>' needs to have dll-interface to be used by clients of class 'TagParser::TagTarget' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(23,34): note: see declaration of 'std::vector<TagParser::TagTarget::IdType,std::allocator<TagParser::TagTarget::IdType>>'
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(52,21): warning C4251: 'TagParser::TagTarget::m_editions': class 'std::vector<TagParser::TagTarget::IdType,std::allocator<TagParser::TagTarget::IdType>>' needs to have dll-interface to be used by clients of class 'TagParser::TagTarget' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(23,34): note: see declaration of 'std::vector<TagParser::TagTarget::IdType,std::allocator<TagParser::TagTarget::IdType>>'
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(53,21): warning C4251: 'TagParser::TagTarget::m_attachments':class 'std::vector<TagParser::TagTarget::IdType,std::allocator<TagParser::TagTarget::IdType>>' needs to have dll-interface to be used by clients of class 'TagParser::TagTarget' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser\./tagtarget.h(23,34): note: see declaration of 'std::vector<TagParser::Ta
gTarget::IdType,std::allocator<TagParser::TagTarget::IdType>>'
PROJECT\tagparser\release-tagparser\include\tagparser\./abstractcontainer.h(107,17): warning C4251: 'TagParser::AbstractContainer::m_doctype': class 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' needs to have dll-interface to be used by clients of class 'TagParser::AbstractContainer' [PROJECT.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xstring(5155,29): note: see declaration of 'std::basic_string<char,std::char_traits<char>,std::al
locator<char>>'
PROJECT\tagparser\release-tagparser\include\tagparser\./abstractcontainer.h(110,30): warning C4251: 'TagParser::AbstractContainer::m_titles': class 'std::vector<std::string,std::allocator<std::string>>' needs to have dll-interface to be used by clients of class 'TagParser::AbstractContainer' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser\./diagnostics.h(55,46): note: see declaration of 'std::vector<std::string
,std::allocator<std::string>>'
PROJECT\tagparser\release-tagparser\include\tagparser\./abstractcontainer.h(130,47): warning C4251: 'TagParser::AbstractContainer::m_p': class 'std::unique_ptr<TagParser::AbstractContainerPrivate,std::default_delete<TagParser::AbstractContainerPrivate>>' needs to have dll-interface to be used by clients of class 'TagParser::AbstractContainer' [PROJECT.vcxproj]
PROJECT\tagparser\release-tagparser\include\tagparser\./abstractcontainer.h(124,10): note: see declaration of 'std::unique_ptr<
TagParser::AbstractContainerPrivate,std::default_delete<TagParser::AbstractContainerPrivate>>'
PROJECT\tagparser\release-c++utilities\include\c++utilities\conversion\./conversionexception.h(11,76): warning C4275: non dll-interface class 'std::runtime_error' used as base for dll-interface class 'CppUtilities::ConversionException' [PROJECT.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\stdexcept(101,19): note: see declaration of 'std::runtime_error'
PROJECT\tagparser\release-c++utilities\include\c++utilities\conversion\./conversionexception.h(11,28): note: see declaration of
'CppUtilities::ConversionException' Furthermore, I am using the example code as follows: #include <tagparser/abstractattachment.h>
#include <tagparser/diagnostics.h>
#include <tagparser/mediafileinfo.h>
#include <tagparser/progressfeedback.h>
#include <tagparser/tag.h>
#include <tagparser/tagvalue.h>
#include <log.h>
#include <string>
void metadata() {
using namespace std::literals;
using namespace TagParser;
// create a MediaFileInfo for high-level access to overall functionality of the library
auto fileInfo = MediaFileInfo();
// create container for errors, warnings, etc.
auto diag = Diagnostics();
// create handle to abort gracefully and get feedback during during long operations
auto progress = AbortableProgressFeedback(
[](AbortableProgressFeedback &feedback) {
// callback for status update
log(LOG_INFO,"At step: %i", feedback.step());
},
[](AbortableProgressFeedback &feedback) {
// callback for percentage-only updates
log(LOG_INFO,"Step percentage: %i", feedback.stepPercentage());
});
// open file (might throw ios_base::failure)
std::string filePath = "D:/test.mp4";
fileInfo.setPath(filePath);
fileInfo.open();
// parse container format, tags, attachments and/or chapters as needed
// notes:
// - These functions might throw exceptions derived from ios_base::failure for IO errors and
// populate diag with possibly critical parsing messages you definitely want to check in production
// code.
// - Parsing a file can be expensive if the file is big or the disk IO is slow. You might want to
// run it in a separate thread.
// - At this point the parser does not make much use of the progress object.
fileInfo.parseContainerFormat(diag, progress);
fileInfo.parseTags(diag, progress);
fileInfo.parseAttachments(diag, progress);
fileInfo.parseChapters(diag, progress);
fileInfo.parseEverything(diag, progress); // just use that one if you want all over the above
// get tag as an object derived from the Tag class
// notes:
// - In real code you might want to check how many tags are assigned or use
// fileInfo.createAppropriateTags() to create tags as needed.
auto tag = fileInfo.tags().at(0);
// extract a field value and convert it to UTF-8 std::string (toString() might throw ConversionException)
auto title = tag->value(TagParser::KnownField::Title).toString(TagParser::TagTextEncoding::Utf8);
// change a field value using an encoding suitable for the tag format
tag->setValue(KnownField::Album, TagValue("some UTF-8 string", TagTextEncoding::Utf8, tag->proposedTextEncoding()));
// // get/remove/create attachments
// if (auto *const container = fileInfo.container()) {
// for (std::size_t i = 0, count = container->attachmentCount(); i != count; ++i) {
// auto attachment = container->attachment(i);
// if (attachment->mimeType() == "image/jpeg") {
// attachment->setIgnored(true); // remove existing attachment
// }
// }
// // create new attachment
// auto attachment = container->createAttachment();
// attachment->setName("The cover");
// attachment->setFile("cover.jpg", diag, progress);
// }
// apply changes to the file on disk
// notes:
// - Might throw exception derived from TagParser::Failure for fatal processing error or ios_base::failure
// for IO errors.
// - Applying changes can be expensive if the file is big or the disk IO is slow. You might want to
// run it in a separate thread.
// - Use progress.tryToAbort() from another thread or an interrupt handler to abort gracefully without leaving
// the file in an inconsistent state.
// - Be sure everything has been parsed before as the library needs to be aware of the whole file structure.
fileInfo.parseEverything(diag, progress);
fileInfo.applyChanges(diag, progress);
}
When I do this, I get the following error: C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory(677,47): error C2512: 'TagParser::DiagMessage::DiagMessage': no appropriate default constructor available [PROJECT.vcxproj]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory(677,47): note: while trying to match the argument list '()' |
Looks good, although I'm really not that familiar with MSVC myself so take my word with a grain of salt. Supposedly you could get away with not setting the Qt-related variables for just building c++utilities and tagparser but I have never tried that.
Ok, not sure about that. I've just been using the "normal" Windows terminal on my Windows 10 machine.
That looks very wrong. You must not specify the library and include path manually like this. When using CMake have to use the CMake module and link against the imported target provided by it. This imported target will pull in all required compiler and linker flags and will also take care of c++utilities and other transitive dependencies which you should not need to deal explicitly in your project at all (unless you want to use those directly). Just for the sake of completeness: When not using CMake then you have to use the compiler and linker flags specified in the pkg-config file that should have been installed as well.
Looks like the compiler flags that are necassary when consuming the static version of the library are missing. Probably because of the previous mistake.
Maybe the example doesn't compile with MSVC. With just that information it isn't really possible to investigate. |
https://github.com/Microsoft/vcpkg
I was wondering if you had any thoughts of making this library available through vcpkg? I'm currently using it for a project of mine but thought it could help spread the use of it if made available more easily.
The text was updated successfully, but these errors were encountered: