This is a step by step guide on developing a JavaFX GUI application, using the Hedera Hashgraph Java SDK and the IntelliJ IDEA IDE. I am writing this guide, because when I started writing my own JavaFX application for the Hedera Hashgraph Network, a lot of odd things and hard to fix issues occurred.

I am using a machine with a clean installation of macOS Catalina (10.15.04) – I have not downloaded anything before writing this post, to make it likelier that we have the same starting point. You should technically be able to follow this guide on any Windows or Mac machine, if you adapt some steps accordingly.


Install OpenJDK

Download an appropriate Java Development Kit (JDK) for your operating system.  I recommend downloading latest JDK version from the official OpenJDK website.

A screenshot which is showing an excerpt from the website http://jdk.java.net/14/ – specifically the Builds section, showing download links for the Linux, macOS and Windows Builds
Builds shown on http://jdk.java.net/14/

Unpack it by double clicking. You should see a folder named something like jdk-14.0.1.jdk (varies depending on your version). Newer versions should be fine.

Open up a Finder Window and hit CMD + Shift + G:

Enter /Library/Java/JavaVirtualMachines/

This should open the JavaVirtualMachines folder on your System. If you have a JDK installed already, it will likely show up here. This is is the standard folder where macOS puts Java installations.

To check the current installation you can open up the Terminal and enter java --version. If you have no JDK installed, this should return something like this.

This may open up a pop-up telling you where to download Java. Ignore that and move on with our own manual installation.

If you have a JDK installation, it would likely show up here too.

Drag and drop the newly downloaded and unpacked JDK into the JavaVirtualMachines folder. This will likely ask you for permission to do so.

Screenshot showing the folder jdk-14.0.1.jdk placed in the JavaVirtualMachines directory

After moving the jdk-14.0.1.jdk directory to your JavaVirtualMachines folder, open up your terminal again and check if the version is being recognised.

To do so, write the command java --version into the console and hit enter again.

The first time you do this, you should be prompted with this:

Hit Open. You console command should return the newly installed JDK version:

isik@MacBook-Pro ~ % java --version
openjdk 14.0.1 2020-04-14
OpenJDK Runtime Environment (build 14.0.1+7)
OpenJDK 64-Bit Server VM (build 14.0.1+7, mixed mode, sharing)

If this message (or a similar one, depending the OpenJDK version you installed) returned, you should be all set with the JDK installation and we can continue with installing JavaFX.

Install JavaFX

Download the latest release version of JavaFX. In the time of writing this tutorial, the latest release version was JavaFX 14.

Head over to https://gluonhq.com/products/javafx/ to see a full list of releases. The downloads list is categorised into three different sections, starting with Long Term Support, followed by Latest Released and last but not least the Early-Access Builds. We are only interested in the Latest Release section and the "JavaFX Mac OS X SDK" distribution.

Download the Latest Release version of the JavaFX Mac OS X SDK

After downloading JavaFX, it should unzip automatically. If not, double click it to unzip. Then, you will need to choose a destination for the installation. You can technically put it anywhere on your computer, as long as you remember the path to it. For simplicity I chose the Applications folder located in /Applications. To keep everything clean, I created a directory called JavaFX and put the unzipped distribution of JavaFX (javafx-sdk-14.0.1) inside it.


Install IntelliJ IDEA

Download the IntelliJ IDEA IDE. The free "community version" is sufficient.

Download IntelliJ IDEA: The Java IDE for Professional Developers by JetBrains
Download the latest version of IntelliJ IDEA for Windows, macOS or Linux.

Open the newly downloaded ideaIC-2020.1.dmg and follow the instructions. I went with all default settings.

Create a JavaFX project

Once installed, you will be prompted with the Welcome View of IntelliJ IDEA. Hit "Create New Project". The "New Project" View will open. Do NOT select the Java FX option on the left hand side and instead click Maven. Check the "Create from archetype" checkbox. Then click the "Add Archetype" button on the right hand side.

This will open the "Add archetype" View. The GroupId must be org.openjfx and the ArtifactId javafx-maven-archetypes. The Version must be set to 0.0.1 – Leave the Repository field empty.

Click OK. Your newly added Archetype should be preselected now. If not, type in javafx in the New Project View (after you clicked on any archetype, otherwise the search doesn't work) to quickly find the newly added Archetype in the list. Once selected, click Next.

You will be prompted to select a Name for your Project. You can name it whatever you want. If you click on Artifact Coordinates, it will show you several additional options. For beginners I would recommend to leave these as they are. The ArtifactId will be named automatically corresponding to your Project Name.

Hit Next. On the next Screen you will need to change the archetypeArtifactId property and set it to javafx-archetype-fxml, if you plan to use FXML to design your views (recommended) or to javafx-archetype-simple if you don't. To do so, double-click the archetypeArtifactId Property.

The last thing we need to do here is, to specify which JavaFX version we're using. To do so, click on the small plus sign on the bottom left corner, to add a new Maven Property. Name it javafx-version and set the value to whatever version you are using. Type in the version of the previously downloaded JavaFX SDK (in my case it is 14.0.1) and hit OK. Create your project now by clicking Finish. Give it some time to set up the project. This shouldn't take longer than a minute.

After it is loaded you will see the Project Window. To learn more about IntelliJ IDEA itself, head over to https://www.jetbrains.com/idea/documentation/.

The first thing you might notice, is the Experimental Feature Alert on the bottom right corner. Hit the down facing chevron to show the full text, scroll down and accept. The alert basically just tells you, that the newly introduced switch expression in OpenJDK 14 is experimental.

You may have noticed, that the first file that opened after creating the project, is the pom.xml file. POM stands for Project Object Model. It is an XML representation of a Maven project. We mainly use Maven and the corresponding pom.xml file to specify the dependencies we are using and to configure our project. To learn more about Maven, head over to http://maven.apache.org – For the purpose of this tutorial and developing your first app, you will likely not need to read through the Maven documentation. We will configure our pom.xml later in this tutorial.

The first thing we want to do now is, is to ensure that our JavaFX 14 "Hello World" application (which was created as a starting point from the previously added Archetype) is actually working.

If you would now try to run the project, you would get several errors. To resolve those, we need to do a few things.

First of all, we need to add a Run Configuration. Since we are using Maven as our Project Management tool, we can also use it, to manage our builds. So instead of having to manually creating Run Configurations by clicking the button in the top right corner of the IDE, our previously configured Project comes with a bunch of useful build commands, which we can use. To use them and to add them as Run Configurations for our IDE, we have to look at the Maven Build Tool, located in the right corner of your IDE. If you do not see the Maven Build Tool, take a look at the app menu (top) of IntelliJ IDEA and go to View/Tool Windows/Maven. This should open the Maven Menu. You should see a bunch of different build actions on the right hand side.

You will mainly need the Plugins section of the Maven build tool. Specifically Plugins/clean/clean:clean and Plugins/javafx/javafx:run – I recommend adding at least the javafx:run build action as a Run Configuration in your IDE. This basically means, that you will be able to use the green play button in the top right corner, to run your project. Which is more convenient because it allows you several things, like using shortcuts to run your project and more.

To add Plugins/javafx/javafx:run as a run configuration, simply right-click it in the Maven Build Tool and then click on Create 'Unnamed'.

Give it a Name. I named mine "Run via javafx:run". You can name yours whatever you want. I just named it like this to make it clear, which Maven action is being called.

Click OK to create your new Run Configuration. Now we're all set when it comes to our Configuration for running our OpenJDK/JavaFX 14 application.

Hit the green Play icon to run your application. You should now see an application, which is showing the Views (alternating by clicking the Button), specified in <YourProjectName>/src/main/resources/org.example.


Add the Hedera Hashgraph and netty transport dependency

Now all we need to do is to set up the correct dependencies to get going with Hedera Hashgraph. To do so, open your pom.xml file, located in the root folder of your Project. The generated XML file should look somewhat like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>HederaJavaFXTutorial</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>14.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>14.0.1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.1</version>
                <configuration>
                    <mainClass>org.example.App</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The whole XML is enclosed in the the <project> tags. Within that, we have sections for various things. We just need to focus on the <dependencies> section. Because we specified a lot of things while setting up the project, our IDE already added the JavaFX (OpenJFX) dependencies. Now we need to add two dependencies. One for allowing us to use the Hedera Java SDK in our application and the second one to handle is required to handle everything related to networking.

For the latest recommended configuration, head over to https://github.com/hashgraph/hedera-sdk-java and check the README .

As of writing this guide, the README says, that the current recommended version of the Hedera Hashgraph SDK is 1.1.4 and they name three differently flavoured network (transport) dependencies, optimised for different use cases. I went for the first one and added the "netty transport (for server or desktop applications)" dependency to my pom.xml file. Your POM file should look somewhat like this now.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>HederaJavaFXTutorial</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>14.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>14.0.1</version>
        </dependency>

        <!-- START OF Dependencies for Hedera Hashgraph -->

        <!-- Hedera Hashgraph SDK -->
        <dependency>
            <groupId>com.hedera.hashgraph</groupId>
            <artifactId>sdk</artifactId>
            <version>1.1.4</version>
        </dependency>

        <!-- netty transport (for server or desktop applications) -->
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.24.0</version>
        </dependency>

        <!-- END OF Dependencies for Hedera Hashgraph -->

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>11</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.1</version>
                <configuration>
                    <mainClass>org.example.App</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

After adding those, IntelliJ/Maven will tell you, that you need to load the newly added dependencies. To do so, click on the tiny Button which appears on the top right corner of the screen after every change you make to the pom.xml file.

Once loaded, open the module-info.java file in your project (located under src/main/java/module-info.java) and add the sdk as a requirement to your org.example module. The file should look like this now.

module org.example {
    requires javafx.controls;
    requires javafx.fxml;
    requires sdk;

    opens org.example to javafx.fxml;
    exports org.example;
}

If everything went accordingly, you should still be able to run your application.

Create Hedera Hashgraph Client

To get started with Hedera, we now need a Client Class. On the left hand side of the IDE, navigate to the src/main/java/org.example package. Right-click it, then select New and click on Java Class. Name it HederaClient (or whatever works best for you) and confirm creating the new class by pressing Enter.

Once you've created the Java Class, we will need to write a method, which takes the operators credentials, and returns a Client Object to the caller.

package org.example;

import com.hedera.hashgraph.sdk.Client;
import com.hedera.hashgraph.sdk.account.AccountId;
import com.hedera.hashgraph.sdk.crypto.ed25519.Ed25519PrivateKey;

import java.util.Map;

public class HederaClient {

    public static Client HederaClient(String operatorId, String operatorKey, String nodeId, String nodeAddress) {
        
        // Store method parameter variables in correct format
        var myOperatorId = AccountId.fromString(operatorId);
        var myOperatorKey = Ed25519PrivateKey.fromString(operatorKey);
        var myNodeId = AccountId.fromString(nodeId);
        var myNodeAddress = nodeAddress;

        // Build client
        var hederaClient = new Client(Map.of(myNodeId, myNodeAddress));

        // Set the the account ID and private key of the operator
        hederaClient.setOperator(myOperatorId, myOperatorKey);

        return hederaClient;

    }
}

Now that we've the code for setting up the Client, we can continue with changing our example application to connect to the Hedera Network and do some basic operations, such as performing a crypto currency transaction.

For the purpose of this tutorial, we do not need a SecondaryController. Go ahead and navigate to the SecondaryController.java in src/main/java/org.example/ and delete it. IntelliJ IDEA will tell you, that it detected usages. Ignore that and Click "Delete Anyway". Then get rid of the corresponding FXML file, which is called secondary.fxml and is located under src/main/resources/org.example/.

Open the primary.fxml file by double-clicking it. This is a fxml (JavaFX xml) representation of your View. To change your View, you can either just edit the fxml file in IntelliJ IDEA or use a tool like Scene Builder.

For our Demo application it is feasible to edit the fxml file manually. Let's take a look:

The primary.fxml file should look somewhat like this:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>

<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.PrimaryController">
   <children>
      <Label text="Primary View" />
      <Button fx:id="primaryButton" text="Switch to Secondary View" onAction="#switchToSecondary"/>
   </children>
   <padding>
      <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
   </padding>
</VBox>

My goal for the purpose of this guide, is to create a View, which allows the user to make a crypto currency transaction. The view should contain some InputFields to get the users credentials and his or her preferred node ID & address to connect to. To establish the connection, there should be a button, which calls the static method in our newly created HederaClient class and passes it the values entered into the Input Fields.

To allow for crypto currency transactions, there must also be two more Input Fields for asking the user, how much he or she wants to transfer (in tinybars) and to which address they want to send it. To confirm their action, there should be a button to do so. The results of the transaction then should be printed on the IDEs console.

While adding new elements to your fxml file, make sure, that you assign each element you want to communicate with, a unique fx:id. This is required to access these elements from your Controller class. For buttons you add, make sure that you assign them a fitting onAction attributes. Clicking the button should call a method which then performs the transaction. I named mine sendHbar.

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>

<?import javafx.scene.control.TextField?>
<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.PrimaryController">
   <children>
      <Label text="Primary View" />

      <Label text="Operator ID" />
      <TextField fx:id="operatorIdTf" promptText="OPERATOR_ID" text="0.0.28616" />

      <Label text="Operator key" />
      <TextField fx:id="operatorKeyTf" promptText="OPERATOR_KEY" text="302e020100300506032b657004220420338fb71889ca286319f16dfd741742d2e4080e22a4d1303def2d2bf3dfcb3494" />

      <Label text="Node ID" />
      <TextField fx:id="nodeIdTf" promptText="NODE_ID" text="0.0.3" />

      <Label text="Node address" />
      <TextField fx:id="nodeAddressTf" promptText="NODE_ADDRESS" text="0.testnet.hedera.com:50211" />

      <Button fx:id="primaryButton" text="Establish connection" onAction="#establishConnection"/>

      <Label text="Amount to send" />
      <TextField fx:id="amountToSendTf" promptText="amount to send" text="100" />

      <Label text="Recipient" />
      <TextField fx:id="recipientIdTf" promptText="amount to send" text="0.0.12343" />

      <Button fx:id="sendHbarButton" text="Send hbar" onAction="#sendHbar"/>

   </children>
   <padding>
      <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
   </padding>
</VBox>

IntelliJ IDEA may warn you, that some of the elements you used, are not imported in the  header of your fxml file. Allow IntelliJ IDEA to import those for you.

We now need to make the newly added elements visible in our Controller to access them. To do so, go to the PrimaryController class, and add the newly added elements as variables.

You PrimaryController should look like this:

package org.example;

import java.io.IOException;
import com.hedera.hashgraph.sdk.*;
import com.hedera.hashgraph.sdk.account.AccountId;
import com.hedera.hashgraph.sdk.account.CryptoTransferTransaction;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;

public class PrimaryController {

    @FXML
    private TextField operatorIdTf;
    @FXML
    private TextField operatorKeyTf;
    @FXML
    private TextField nodeIdTf;
    @FXML
    private TextField nodeAddressTf;
    @FXML
    private TextField amountToSendTf;
    @FXML
    private TextField recipientIdTf;


    @FXML
    private void establishConnection() throws IOException {
    }

    @FXML
    private void sendHbar() throws IOException {
    }
}

The names of variables must match their corresponding fx:id's. The onAction attributes must each have a method in the referring Controller class.

Now, we need to write two methods. One for each Button. The first Button's purpose is to read the first four InputFields and establish a connection. The second Button reads the last two InputFields (amountToSendTf and recipientIdTf) and tries to perform a crypto currency transaction from the operators account to the specified recipients account Id. The "Tf" in my example stands for Textfield. I name them like this, because it helps with identifying what's behind a variable, at a glance.

To establish a connection, we will use the previously created HederaClient class. To be able to use the client throughout the application, we will add it righter after the opening brackets of our class.

In our establishConnection method we will initialise a Client by taking the credentials for the InputFields defined in our FXML and assign the newly created client object, to our previously added client variable.

    @FXML
    private void establishConnection() throws IOException {
        try {
            client = HederaClient.createClient(
                    operatorIdTf.getText(), operatorKeyTf.getText(), nodeIdTf.getText(), nodeAddressTf.getText()
            );
            System.out.println("Succesfully connected");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

To be able to write applications for the Hedera Hashgraph network, you will have to get familiar with the Core Concepts described in their documentation.

Accounts
Hedera accounts

For our example, I will explain what we need to do, in order to submit a Transaction (specifically the CryptoTransferTransaction) to the network. Other transactions are build quite similarly and once you got the hang of it, you should be able to build and submit any kind of transaction and build a complex application.

To send crypto currency, I build a new CryptoTransferTransaction object and set some essential values, like the maximum transaction fee, the sender (which for security reasons not only requires the sendersId (in our case it happens to be the operator) but also the amount to send) and the unit. I have chosen Tinybar as a Unit in my example. Renaming the method and the Button to sendTinybars (instead of sendHbar) would have arguably made more sense. We also have to add the recipient and again the value and unit for security reasons. Then, the transaction is being executed by the client and the receipt is saved in a newly created variable. After that, I just write out what happened to the console. The catch expression essentially just catches any errors and writes a specific error message on the console.

The method should look somewhat like this:

    @FXML
    private void sendHbar() throws IOException {
        try {
            var transaction = new CryptoTransferTransaction()
                    .setMaxTransactionFee(250_000_000)
                    .addSender(AccountId.fromString(operatorIdTf.getText()),Hbar.from(Long.parseLong(amountToSendTf.getText()),HbarUnit.Tinybar))
                    .addRecipient(AccountId.fromString(recipientIdTf.getText()),Hbar.from(Long.parseLong(amountToSendTf.getText()),HbarUnit.Tinybar));
            var receipt = transaction.execute(client);

            System.out.println("successfully sent " + amountToSendTf.getText() + " from " + receipt.accountId + "to" + recipientIdTf.getText());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

The whole PrimaryController class looks like the following:

package org.example;

import java.io.IOException;
import com.hedera.hashgraph.sdk.*;
import com.hedera.hashgraph.sdk.account.AccountId;
import com.hedera.hashgraph.sdk.account.CryptoTransferTransaction;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;

public class PrimaryController {

    Client client;

    @FXML
    private TextField operatorIdTf;
    @FXML
    private TextField operatorKeyTf;
    @FXML
    private TextField nodeIdTf;
    @FXML
    private TextField nodeAddressTf;
    @FXML
    private TextField amountToSendTf;
    @FXML
    private TextField recipientIdTf;


    @FXML
    private void establishConnection() throws IOException {
        try {
            client = HederaClient.createClient(
                    operatorIdTf.getText(), operatorKeyTf.getText(), nodeIdTf.getText(), nodeAddressTf.getText()
            );
            System.out.println("Succesfully connected");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @FXML
    private void sendHbar() throws IOException {
        try {
            var transaction = new CryptoTransferTransaction()
                    .setMaxTransactionFee(250_000_000)
                    .addSender(AccountId.fromString(operatorIdTf.getText()),Hbar.from(Long.parseLong(amountToSendTf.getText()),HbarUnit.Tinybar))
                    .addRecipient(AccountId.fromString(recipientIdTf.getText()),Hbar.from(Long.parseLong(amountToSendTf.getText()),HbarUnit.Tinybar));
            var receipt = transaction.execute(client);

            System.out.println("successfully sent " + amountToSendTf.getText() + " from " + receipt.accountId + "to" + recipientIdTf.getText());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

After running the application, you should be able to establish a connection and verify if it worked by looking out for the "Successfully connected" message in your IDEs console. After establishing a connection by clicking a button, you should be able to enter a the amount of Tinybars you want to send and specify a recipient. After doing that, you can try to submit your transaction to the (Test-)network by clicking the Send hbar button. If everything goes to plan, 100 Tinybars will be deducted from your specified Operator/Sender ID and credited to the recipients account.

This should be a good starting point for developing Java based GUI application for the Hedera Hashgraph network. To strengthen your knowledge and start developing complex applications, you will have to read through the Hedera Hashgraph Documentation and if you want to work in Java and use JavaFX as your GUI Framework, I recommend looking into the Official OpenJFX Documentation as well. With JavaFX, it probably makes more sense, to watch some Tutorials on YouTube or other sites and just look up specifics in the official Documentation.

As a side note: At the time of writing this guide, the Java section of the Hedera Documentation was taken offline. They recently overhauled their Documentation and seem to focus on using examples written in JavaScript. Despite that, the Hedera Java SDK is still being updated on their GitHub account and there's no sign, that they plan to abandon it. I can imagine, that due to all the changes happening to the Java SDK right now, it did not make sense to keep it online. But that's just speculation.

Thank you for reading through, happy coding and if you happen to have any feedback or just want to say hi, feel free to contact me via Email or Twitter.