From 677055fb9226a11a6c6326a58bd3311ffcc58c46 Mon Sep 17 00:00:00 2001
From: Matus Novak <matusnov@gmail.com>
Date: Fri, 10 May 2019 19:28:09 +0100
Subject: [PATCH] Added encoder GUI

---
 README.md                     |  80 --------
 report/images/encoder-gui.png | Bin 0 -> 32395 bytes
 src/rew/decoder-gui/main.cpp  |  53 +----
 src/rew/encoder-cli/main.cpp  |   2 +-
 src/rew/encoder-gui/main.cpp  | 370 +++++++++++++++++++++++++++++++++-
 5 files changed, 371 insertions(+), 134 deletions(-)
 create mode 100644 report/images/encoder-gui.png

diff --git a/README.md b/README.md
index 57bda1c..36fa546 100644
--- a/README.md
+++ b/README.md
@@ -23,82 +23,6 @@ website, encode it into an 48Khz audio, transmit over large distanced using
 FM transmitter, and then decode it on the other side and serve the files
 to the user.
 
-## Project structure
-
-This project contains the following sub-projects (libraries) that together
-create the final application. The four libraries together form a client and
-a server applications. Where the server forms of the emitter library and the
-encoder library, and the client only needs the decoder and the server library.
-
-* **encoder** - This is a shared library which takes a raw stream of bytes,
-  for example a tar file, and encodes it into an audio file. 
-* **decoder** - This is a shared library which takes a raw stream of 48Khz
-  audio samples and constructs the raw bytes back, that were created using
-  the encoder.
-* **emitter** - This is a shared library that consumes the raw data created
-  by the encoder and either saves it as an mp3 file, or emitts the data to 
-  the computer sound output.
-* **server** - This is a shared library that simply serves the decoded data
-  to the user.
-
-## Third party libraries
-
-This project also uses the following third party libraries:
-
-* **[asio](https://think-async.com/)** - C++11 library for creating a http server.
-* **[zlib](https://zlib.net/)** - C library for compression and decompression.
-* **[Catch2](https://github.com/catchorg/Catch2)** - C++14 library for unit tests only.
-* **[argagg](https://github.com/vietjtnguyen/argagg)** - For parsing command line arguments.
-* **[dirent](https://github.com/tronkko/dirent)** - Only needed on Windows as a replacement for Unix dirent.h header.
-
-## Milestones
-
-### 1. Basic project structure (Done)
-
-Create a basic project either using [Conan](https://conan.io/), [vcpkg](https://docs.microsoft.com/en-us/cpp/vcpkg?view=vs-2017), or simple git submodules for the third party libraries. Use CMake for the project configuration and C++ as the target language. 
-
-*Completed! The vcpkg has been chosen as the package manager for the third party libraries, later to be replaced by simple git submodules due to lack of proper Linux support (no static libraries support). The libraries as listed in the third party libraries section above has been chosen for their simplicity and large documentation. The C++ version 2017 has been chosen as the target language for this project. The project structure and configuration works both in Linux and Windows, the OSX has not been tested at this point.*
-
-### 2. Encoder and Decoder phase 1 (Todo)
-
-Create a basic encoder which takes a path to the source folder (a folder which contains the html files) and encodes them into a raw stream of audio samples. The audio samples will be targeted to 48Khz as this is the highest common sample rate used in personal computers in domestic use [1]. The next part of this milestone is to create a decoder, which takes raw data from the encoder and assembles back the raw input data. A proper unit tests must be crated during this step to create as the baseline for the next phase.
-
-*Completed! The Goertzel algorithm was used instead of the Fast Fourier Transform. The Goertzel alows to target a specific frequency, in this case two frequencies (for low and high bits). The algorithm is faster than the FFT which allows us to use this software on slower hardware. The decoding part has been programmed into blocks, similar to the GNU Radio framework.*
-
-### 3. Encoder and Decoder phase 2 (Todo)
-
-Create a data link layer, in which the source input (in the encoder) is split into chunks, a data packet(s). These data packets must be small in order for them to be easily transmitted and received. The higher the packet size is, the higher the chance of the packet loss [cittation needed]. The packets will additionally contain a fixed count, the total number of packets, alongside with an index number. The decoder must be able to reject the incorrect packets and verify the integrity of the data (using a checksum).
-
-*Partially completed, there are still some things to do when splitting data into data packets.*
-
-### 4. Testing with FM hardware (Todo)
-
-Testing the encoder and decoder with a real hardware. If an issue is raised, the phase 1 and 2 of the encoder and decoder must be further adjusted.
-
-### 5. Noise filtering (Todo)
-
-Implement unit testing with artificial and real noise in the audio data stream.
-
-### 6. Encoder CLI (Todo)
-
-Create a simple emitter that takes the encoded raw input as audio samples (in 48Khz) and emits them to the audio output of the machine. The encoded data must be transmited in a loop until the user decides to stop the transmission. The [PortAudio](http://www.portaudio.com/) library will be used for this process to access the hardware audio streams.
-
-### 7. Decoder CLI + HTTP Server (Todo)
-
-Create a simple server which takes the packets from the decoder and servers the files to the user. As an alternative, create a Windows driver (a service) which will act as an additional network device. This device will act as the internet gateway and will serve the files. Additionally, the server can cache the old files and the user will be able to view the previously transmitted version of the website. This server will also listed to the hardware audio input stream using The [PortAudio](http://www.portaudio.com/). The data will be fed to the decoder library.
-
-### 8. Documentation and user installation (Todo)
-
-Write down simple documentation and create an installation (exe or msi).
-
-### 9. Experiment with multiple baudrates (Todo)
-
-Experiment with multiple data streams encoded on top of each other. For example, a higher baud rate with a lower amplitude on top of lower baudrate with higher amplitude. If the user has the perfect signal, the application will choose the higher baudrate as the source, which results in faster loading times for the website.
-
-### 10. Experiment with transmitting data back (Todo)
-
-This application only works in one way, transmitting the data to the user. An experiment can be conducted to transmit data back to the server. Essentially creating a WiFi out of FM radio transmitters and receivers.
-
 ## Compiling
 
 You will need CMake 3.1 or newer with a relevant compiler (GCC, Clang, or Visual Studio 2017). The compiler must support C++17
@@ -116,7 +40,3 @@ cmake --build . --target ALL_BUILD --config MinSizeRel
 ```
 ctest --verbose -C "MinSizeRel"
 ```
-
-## References
-
-[1] [AES5-2008 (r2013): AES recommended practice for professional digital audio - Preferred sampling frequencies for applications employing pulse-code modulation](http://www.aes.org/publications/standards/search.cfm?docID=14) (revision of AES5-2003), Audio Engineering Society, 2014-06-16
\ No newline at end of file
diff --git a/report/images/encoder-gui.png b/report/images/encoder-gui.png
new file mode 100644
index 0000000000000000000000000000000000000000..06c5e2396aa140283b054a13ba2c87e23409cee5
GIT binary patch
literal 32395
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
LC|)M|`u+a`p{v~8

literal 0
HcmV?d00001

diff --git a/src/rew/decoder-gui/main.cpp b/src/rew/decoder-gui/main.cpp
index 5f92fd2..f1d6865 100644
--- a/src/rew/decoder-gui/main.cpp
+++ b/src/rew/decoder-gui/main.cpp
@@ -80,53 +80,6 @@ bool pathIsValid(const std::string& path) {
     return stat(path.c_str(), &info) == 0;
 }
 
-///=====================================================================================================================
-class CustomSink: public rew::Input<rew::NamedRawFile> {
-public:
-    CustomSink(const std::string& destination):destination(destination) {
-        
-    }
-    virtual ~CustomSink() = default;
-
-    void process(const rew::NamedRawFile* data, const size_t length) override {
-        for (size_t i = 0; i < length; i++) {
-            const auto& namedFile = data[i];
-
-            auto terminator = namedFile.length;
-            for (size_t i = 0; i < namedFile.length; i++) {
-                if (namedFile.data[i] == '\0') {
-                    terminator = i;
-                    break;
-                }
-            }
-
-            if (terminator != namedFile.length) {
-                const auto sptr = reinterpret_cast<const char*>(namedFile.data.get());
-                const auto name = std::string(sptr, terminator);
-
-                const auto contents = reinterpret_cast<const char*>(namedFile.data.get() + terminator + 1);
-                const auto total = namedFile.length - terminator - 1;
-                std::string path = destination + DELIMITER + name;
-
-                std::cout << "Writing file: " << path << " of size: " << total << " bytes!" << std::endl;
-                std::fstream file(path, std::ios::out | std::ios::binary);
-                if (!file) {
-                    std::cerr << "Failed to open file: " << path << " for writing!" << std::endl;
-                }
-                else {
-                    file.write(contents, total);
-                }
-            }
-            else {
-                std::cerr << "File index: " << namedFile.index << " successfully inflated but contains bad filename!" << std::endl;
-            }
-        }
-    }
-
-private:
-    std::string destination;
-};
-
 ///=====================================================================================================================
 static int onClosing(uiWindow *w, void *data) {
 	uiQuit();
@@ -393,7 +346,7 @@ static void widgetsSelectDestination(uiWindow* mainwin, uiBox* box) {
 	uiGridSetPadded(grid, 1);
 	uiBoxAppend(box, uiControl(grid), 0);
 
-    const auto fileButton = uiNewButton("Select Folder");
+    const auto fileButton = uiNewButton("Select File");
 	const auto fileEntry = uiNewEntry();
 
     static struct SelectFileData {
@@ -509,10 +462,6 @@ static void widgets(uiWindow* mainwin) {
 
 ///=====================================================================================================================
 int main (const int argc, char* argv[]) {
-#ifdef _WIN32
-    SetConsoleCtrlHandler(ctrlHandler, TRUE);
-#endif
-
     try {
         uiInitOptions o = {0};
         const char* err;
diff --git a/src/rew/encoder-cli/main.cpp b/src/rew/encoder-cli/main.cpp
index 98b6433..7df740a 100644
--- a/src/rew/encoder-cli/main.cpp
+++ b/src/rew/encoder-cli/main.cpp
@@ -170,7 +170,7 @@ int main(const int argc, char* argv[]) {
             // Create our source which will go through the directory
             auto source = std::make_shared<DirectoryTraverser>();
 
-            // Create the output wav file
+            // Create the output audio sink
             auto audioSink = std::make_shared<rew::PhysicalAudioSink>();
 
             // Finally combine everything together into a single encoder
diff --git a/src/rew/encoder-gui/main.cpp b/src/rew/encoder-gui/main.cpp
index 5cb1ac1..e658d40 100644
--- a/src/rew/encoder-gui/main.cpp
+++ b/src/rew/encoder-gui/main.cpp
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #endif
 #include <iostream>
+#include <thread>
 #include "folder.h"
 #include <rew/encoder/encoder.h>
 #include <rew/encoder/physical_audio_sink.h>
@@ -54,6 +55,20 @@ bool pathIsValid(const std::string& path) {
     return stat(path.c_str(), &info) == 0;
 }
 
+///=====================================================================================================================
+static int onClosing(uiWindow *w, void *data) {
+	uiQuit();
+	return 1;
+}
+
+///=====================================================================================================================
+static int onShouldQuit(void *data) {
+	uiWindow *mainwin = uiWindow(data);
+
+	uiControlDestroy(uiControl(mainwin));
+	return 1;
+}
+
 ///=====================================================================================================================
 std::vector<std::string> recursivelyParseFolder(const std::string& path) {
     std::vector<std::string> files;
@@ -118,10 +133,363 @@ private:
     }
 };
 
+///=====================================================================================================================
+class Context;
+static struct Globals {
+    std::shared_ptr<Context> context;
+    bool destinationFile = false;
+    bool destinationStream = false;
+    std::string sourceFileStr;
+    std::string destinationFileStr;
+    std::string extensions = "html";
+} globals;
+
+///=====================================================================================================================
+class Context: public std::enable_shared_from_this<Context> {
+public:
+    Context(Globals& globals, const std::function<void()>& callback)
+        : globals(globals), 
+          callback(callback) {
+
+        const auto inputPath = getFullPath(globals.sourceFileStr);
+
+        if (!pathIsValid(inputPath))
+            throw std::runtime_error("Input path: \"" + inputPath + "\" does not exist!");
+
+        if (!folderIsValid(inputPath))
+            throw std::runtime_error("Input path: \"" + inputPath + "\" is not a folder!");
+
+        // Create our source which will go through the directory
+        source = std::make_shared<DirectoryTraverser>();
+
+        loader = std::make_shared<rew::FileLoader>();
+        source->connect(loader);
+
+        if (globals.destinationFile) {
+            const auto outputPath = globals.destinationFileStr;
+
+            // Create the output wav file
+            wav = std::make_shared<rew::AudioSink>(std::make_shared<rew::WavWriter>());
+
+            // Finally combine everything together into a single encoder
+            encoder = std::make_shared<rew::Encoder>(loader, wav, DEFAULT_LOW_TONE_FREQ, DEFAULT_HIGH_TONE_FREQ,
+                DEFAULT_SAMPLE_LENGTH_MS);
+
+            thread = std::thread([=]() -> void {
+                wav->open(outputPath);
+                source->process(inputPath);
+                wav->close();
+
+                if (this->callback) {
+                    this->stopped = true;
+                    this->callback();
+                }
+            });
+        }
+
+        else if (globals.destinationStream) {
+            audio = std::make_shared<rew::PhysicalAudioSink>();
+
+            // Finally combine everything together into a single encoder
+            encoder = std::make_shared<rew::Encoder>(loader, audio, DEFAULT_LOW_TONE_FREQ, DEFAULT_HIGH_TONE_FREQ,
+                DEFAULT_SAMPLE_LENGTH_MS);
+
+            thread = std::thread([=]() -> void {
+                audio->start();
+                source->process(inputPath);
+                audio->join();
+                audio->close();
+
+                if (this->callback) {
+                    this->stopped = true;
+                    this->callback();
+                }
+            });
+        }
+
+        else {
+            throw std::runtime_error("Please select a destination");
+        }
+    }
+
+    ~Context() {
+        stop();
+    }
+
+    void stop() {
+        if (thread.joinable()) {
+            if (audio) audio->close();
+            thread.join();
+        }
+    }
+
+    inline bool isStopped() const {
+        return stopped;
+    }
+
+private:
+    Globals& globals;
+    std::shared_ptr<rew::FileLoader> loader;
+    std::shared_ptr<DirectoryTraverser> source;
+    std::shared_ptr<rew::PhysicalAudioSink> audio;
+    std::shared_ptr<rew::AudioSink> wav;
+    std::shared_ptr<rew::Encoder> encoder;
+    std::thread thread;
+    std::function<void()> callback;
+    bool stopped = false;
+};
+
+///=====================================================================================================================
+static void widgetsSelectSource(uiWindow* mainwin, uiBox* box) {
+    const auto group = uiNewGroup("Select source");
+	uiGroupSetMargined(group, 1);
+    uiBoxAppend(box, uiControl(group), 0);
+
+    uiBoxAppend(box, uiControl(uiNewHorizontalSeparator()), 0);
+
+    const auto grid = uiNewGrid();
+	uiGridSetPadded(grid, 1);
+	uiBoxAppend(box, uiControl(grid), 0);
+
+    const auto fileButton = uiNewButton("Select Folder");
+	const auto fileEntry = uiNewEntry();
+
+    static struct SelectFileData {
+        uiWindow* mainwin;
+        Globals& globals;
+        uiEntry* entry;
+    } selectFileData{mainwin, globals, fileEntry};
+
+    const auto onOpenFileClicked = [](uiButton *b, void *data) -> void {
+        auto& d = *reinterpret_cast<SelectFileData*>(data);
+
+        const auto filename = uiOpenFile(d.mainwin);
+        if (filename == NULL) {
+            uiEntrySetText(d.entry, "");
+            return;
+        }
+
+        if (!folderIsValid(filename)) {
+            uiMsgBoxError(d.mainwin, 
+                "Select folder error", 
+                "You must select a valid folder!");
+
+            uiEntrySetText(d.entry, "");
+            return;
+        }
+
+        uiEntrySetText(d.entry, filename);
+        d.globals.sourceFileStr = std::string(filename);
+        uiFreeText(filename);
+    };
+
+    uiEntryOnChanged(fileEntry, [](uiEntry* e, void* data) -> void {
+        auto& globals = *reinterpret_cast<Globals*>(data);
+        globals.sourceFileStr = std::string(uiEntryText(e));
+    }, &globals);
+
+	uiEntrySetReadOnly(fileEntry, 0);
+	uiButtonOnClicked(fileButton, onOpenFileClicked, &selectFileData);
+	uiGridAppend(grid, uiControl(fileButton),
+		0, 0, 1, 1,
+		0, uiAlignFill, 0, uiAlignFill);
+	uiGridAppend(grid, uiControl(fileEntry),
+		1, 0, 1, 1,
+        1, uiAlignFill, 0, uiAlignFill);
+
+    auto rb = uiNewRadioButtons();
+	uiRadioButtonsAppend(rb, "Html only");
+	uiRadioButtonsAppend(rb, "Html with images");
+	uiRadioButtonsAppend(rb, "Everything");
+    uiBoxAppend(box, uiControl(rb), 0);
+
+    uiRadioButtonsOnSelected(rb, [](uiRadioButtons* rb, void* data) -> void {
+        auto& globals = *reinterpret_cast<Globals*>(data);
+        switch (uiRadioButtonsSelected(rb)) {
+            case 0: globals.extensions = "html"; break;
+            case 1: globals.extensions = "html jpg jpeg png bmp svg tif tiff"; break;
+            case 2: globals.extensions = ""; break;
+            default: break;
+        }
+    }, &globals);
+}
+
+///=====================================================================================================================
+static void widgetsSelectDestination(uiWindow* mainwin, uiBox* box) {
+    const auto group = uiNewGroup("Select destination");
+	uiGroupSetMargined(group, 1);
+    uiBoxAppend(box, uiControl(group), 0);
+
+    uiBoxAppend(box, uiControl(uiNewHorizontalSeparator()), 0);
+
+    const auto cboxDevice = uiNewCheckbox("To audio output device");
+    const auto cboxFile = uiNewCheckbox("To audio file");
+
+    static struct CBoxData {
+        Globals& globals;
+        uiCheckbox* device;
+        uiCheckbox* file;
+    } cboxData{globals, cboxDevice, cboxFile};
+
+    uiBoxAppend(box, uiControl(cboxDevice), 0);
+    uiCheckboxOnToggled(cboxDevice, [](uiCheckbox* cbox, void* data) -> void {
+        auto& d = *reinterpret_cast<CBoxData*>(data);
+        d.globals.destinationStream = uiCheckboxChecked(cbox);
+        uiCheckboxSetChecked(d.file, !d.globals.destinationStream);
+    }, &cboxData);
+
+    const auto combo = uiNewCombobox();
+    const auto devices = rew::PhysicalAudioSink::getDevices();
+    for (const auto& device : devices) {
+        if (device.outputChannels == 0) continue;
+        uiComboboxAppend(combo, device.name.c_str());
+    }
+    uiBoxAppend(box, uiControl(combo), 0);
+    uiComboboxOnSelected(combo, [](uiCombobox* combo, void* data) -> void {
+        auto& d = *reinterpret_cast<CBoxData*>(data);
+        d.globals.destinationStream = true;
+        uiCheckboxSetChecked(d.device, d.globals.destinationStream);
+        uiCheckboxSetChecked(d.file, !d.globals.destinationStream);
+    }, &cboxData);
+
+    uiBoxAppend(box, uiControl(cboxFile), 0);
+    uiCheckboxOnToggled(cboxFile, [](uiCheckbox* cbox, void* data) -> void {
+        auto& d = *reinterpret_cast<CBoxData*>(data);
+        d.globals.destinationFile = uiCheckboxChecked(cbox);
+        uiCheckboxSetChecked(d.device, !d.globals.destinationFile);
+    }, &cboxData);
+
+    const auto grid = uiNewGrid();
+	uiGridSetPadded(grid, 1);
+	uiBoxAppend(box, uiControl(grid), 0);
+
+    const auto fileButton = uiNewButton("Select File");
+	const auto fileEntry = uiNewEntry();
+
+    static struct SelectFileData {
+        uiWindow* mainwin;
+        Globals& globals;
+        uiCheckbox* device;
+        uiCheckbox* file;
+        uiEntry* entry;
+    } selectFileData{mainwin, globals, cboxDevice, cboxFile, fileEntry};
+
+    const auto onOpenFileClicked = [](uiButton *b, void *data) -> void {
+        auto& d = *reinterpret_cast<SelectFileData*>(data);
+
+        const auto filename = uiSaveFile(d.mainwin);
+        if (filename == NULL) {
+            uiEntrySetText(d.entry, "");
+            return;
+        }
+
+        uiEntrySetText(d.entry, filename);
+        d.globals.destinationFileStr = std::string(filename);
+        uiFreeText(filename);
+
+        d.globals.destinationFile = true;
+        uiCheckboxSetChecked(d.device, !d.globals.destinationFile);
+        uiCheckboxSetChecked(d.file, d.globals.destinationFile);
+    };
+
+    uiEntryOnChanged(fileEntry, [](uiEntry* e, void* data) -> void {
+        auto& globals = *reinterpret_cast<Globals*>(data);
+        globals.sourceFileStr = std::string(uiEntryText(e));
+    }, &globals);
+
+	uiEntrySetReadOnly(fileEntry, 0);
+	uiButtonOnClicked(fileButton, onOpenFileClicked, &selectFileData);
+	uiGridAppend(grid, uiControl(fileButton),
+		0, 0, 1, 1,
+		0, uiAlignFill, 0, uiAlignFill);
+	uiGridAppend(grid, uiControl(fileEntry),
+		1, 0, 1, 1,
+        1, uiAlignFill, 0, uiAlignFill);
+}
+
+///=====================================================================================================================
+static void widgets(uiWindow* mainwin) {
+    const auto box = uiNewVerticalBox();
+	uiBoxSetPadded(box, 1);
+    uiWindowSetChild(mainwin, uiControl(box));
+
+    widgetsSelectSource(mainwin, box);
+    widgetsSelectDestination(mainwin, box);
+
+    uiBoxAppend(box, uiControl(uiNewHorizontalSeparator()), 0);
+
+    auto status = uiNewLabel("Press start to begin");
+    uiBoxAppend(box, uiControl(status), 0);
+
+    auto progressbar = uiNewProgressBar();
+	uiProgressBarSetValue(progressbar, 0);
+    uiBoxAppend(box, uiControl(progressbar), 0);
+
+    auto buttonGrid = uiNewGrid();
+    uiGridSetPadded(buttonGrid, 1);
+
+    static struct StatusData {
+        uiWindow* mainwin;
+        Globals& globals;
+        uiProgressBar* progress;
+        uiLabel* label;
+    } statusData{mainwin, globals, progressbar, status};
+
+    auto button = uiNewButton("Start");
+    uiButtonOnClicked(button, [](uiButton *b, void *data) -> void {
+        const auto callback = [=]() {
+            auto& d = *reinterpret_cast<StatusData*>(data);
+
+            uiProgressBarSetValue(d.progress, 0);
+            uiButtonSetText(b, "Start");
+        };
+
+        auto& d = *reinterpret_cast<StatusData*>(data);
+
+        if (!d.globals.context || d.globals.context->isStopped()) {
+            try {
+                d.globals.context = std::make_unique<Context>(d.globals, callback);
+                uiProgressBarSetValue(d.progress, -1);
+                uiButtonSetText(b, "Stop");
+            } catch (std::exception& e) {
+                uiMsgBoxError(d.mainwin, "Error", e.what());
+            }
+        } else {
+            d.globals.context.reset();
+            uiProgressBarSetValue(d.progress, 0);
+            uiButtonSetText(b, "Start");
+        }
+
+    }, &statusData);
+    uiGridAppend(buttonGrid, uiControl(button),
+		1, 0, 1, 1,
+        1, uiAlignCenter, 0, uiAlignFill);
+
+    uiBoxAppend(box, uiControl(buttonGrid), 0);
+}
+
 ///=====================================================================================================================
 int main(const int argc, char* argv[]) {
     try {
-        
+        uiInitOptions o = {0};
+        const char* err;
+        if ((err = uiInit(&o)) != nullptr) {
+            const auto e = std::string(err);
+            uiFreeInitError(err);
+            throw std::runtime_error(e);
+        }
+
+        const auto mainwin = uiNewWindow("Encoder", 640, 400, false);
+        uiWindowSetMargined(mainwin, 1);
+	    uiWindowOnClosing(mainwin, onClosing, NULL);
+        uiOnShouldQuit(onShouldQuit, mainwin);
+
+        widgets(mainwin);
+
+        uiControlShow(uiControl(mainwin));
+        uiMain();
+        uiUninit();
+        return 0;
 
         return EXIT_SUCCESS;
     }
-- 
GitLab