diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c08c40103184e14d708f01fa435b142e685236f4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+*.iml
+.gradle
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..956c004dc0ac315b0acae3a06888ea54bd6890f5
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1,2 @@
+/build
+/release
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..2ea288ce9b55c6f3e7ea080d19230e76e1747e72
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,65 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+android {
+    compileSdkVersion 29
+    buildToolsVersion "30.0.2"
+
+    defaultConfig {
+        applicationId "fr.nitorac.aurionweb"
+        minSdkVersion 19
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0.0"
+        multiDexEnabled true
+
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+    }
+
+    compileOptions {
+        coreLibraryDesugaringEnabled true
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    implementation fileTree(dir: "libs", include: ["*.jar"])
+    implementation 'androidx.appcompat:appcompat:1.2.0'
+    implementation 'com.google.android.material:material:1.2.1'
+    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
+    implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
+    implementation 'androidx.navigation:navigation-fragment:2.3.0'
+    implementation 'androidx.navigation:navigation-ui:2.3.0'
+    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
+    implementation 'org.jsoup:jsoup:1.13.1'
+    implementation 'com.google.code.gson:gson:2.8.6'
+    implementation 'org.projectlombok:lombok:1.18.12'
+    annotationProcessor 'org.projectlombok:lombok:1.18.12'
+
+    implementation 'com.github.lzyzsd:circleprogress:1.2.1'
+    implementation 'com.mindorks.android:prdownloader:0.6.0'
+
+    implementation 'com.afollestad.material-dialogs:core:3.3.0'
+    implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0'
+
+    testAnnotationProcessor 'org.projectlombok:lombok:1.18.12'
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+
+    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
+    implementation "androidx.core:core-ktx:1.3.2"
+    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
+    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+repositories {
+    mavenCentral()
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000000000000000000000000000000000000..481bb434814107eb79d7a30b676d344b0df2f8ce
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/fr/nitorac/aurionweb/ExampleInstrumentedTest.java b/app/src/androidTest/java/fr/nitorac/aurionweb/ExampleInstrumentedTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..78a697fe8f47cd70a621c84625862550f96e02ac
--- /dev/null
+++ b/app/src/androidTest/java/fr/nitorac/aurionweb/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package fr.nitorac.aurionweb;
+
+import android.content.Context;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        assertEquals("fr.nitorac.aurionweb", appContext.getPackageName());
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f77c85588bcbeb5cbb7989c8cae0cb523e9749b0
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="fr.nitorac.aurionweb">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission-sdk-23 android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission-sdk-23 android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
+    <uses-permission-sdk-23 android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
+
+    <application
+        android:name=".AurionApp"
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <provider
+            android:name="androidx.core.content.FileProvider"
+            android:authorities="${applicationId}.provider"
+            android:exported="false"
+            android:grantUriPermissions="true">
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/provider_paths"/>
+        </provider>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
new file mode 100644
index 0000000000000000000000000000000000000000..32a3deb7f2521963368bbbe9ac18e4e6e31f4ea2
Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/fr/nitorac/aurionweb/AurionApp.java b/app/src/main/java/fr/nitorac/aurionweb/AurionApp.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7ab6790123a5f4daf623a9f1e55158ee8ee18dd
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/AurionApp.java
@@ -0,0 +1,18 @@
+package fr.nitorac.aurionweb;
+
+import android.app.Application;
+
+import com.downloader.PRDownloader;
+import com.downloader.PRDownloaderConfig;
+
+public class AurionApp extends Application {
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        PRDownloader.initialize(getApplicationContext(), PRDownloaderConfig.newBuilder()
+                .setReadTimeout(30_000)
+                .setConnectTimeout(30_000)
+                .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0")
+                .build());
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java b/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..37e137f1e07bfc30a35c7ecb9b9b131b32749b98
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java
@@ -0,0 +1,70 @@
+package fr.nitorac.aurionweb;
+
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.navigation.ui.NavigationUI;
+
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+
+import fr.nitorac.aurionweb.aurionweb.AurionManager;
+import fr.nitorac.aurionweb.update.UpdateManager;
+
+public class MainActivity extends AppCompatActivity {
+
+    private static MainActivity mainActivity;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        mainActivity = this;
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        UpdateManager.getInstance().checkUpdates(this);
+        AurionManager.getInstance().spawnLoginDialog(this);
+
+        BottomNavigationView navView = findViewById(R.id.nav_view);
+        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
+        NavigationUI.setupWithNavController(navView, navController);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.appbar_menu, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.connect_menuitem:
+                AurionManager.getInstance().spawnLoginDialog(this);
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        UpdateManager.handleOnPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        UpdateManager.handleOnResume();
+    }
+
+    public static MainActivity getInstance(){
+        return mainActivity;
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/Utils.java b/app/src/main/java/fr/nitorac/aurionweb/Utils.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2fb787a8cf36bad30ee21ef003da83214733ec4
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/Utils.java
@@ -0,0 +1,96 @@
+package fr.nitorac.aurionweb;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.view.Display;
+import android.view.WindowManager;
+
+import com.google.gson.JsonObject;
+
+import org.jsoup.Connection;
+import org.jsoup.Jsoup;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.text.CharacterIterator;
+import java.text.Normalizer;
+import java.text.StringCharacterIterator;
+import java.util.Locale;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+
+public class Utils {
+
+    private static SSLContext sslContext;
+
+    public static Connection wrapSSL(String url) throws GeneralSecurityException, IOException {
+        return Jsoup.connect(url)
+                .sslSocketFactory(getContextForTrustedCertificates(MainActivity.getInstance().getApplicationContext()).getSocketFactory());
+    }
+
+    public static SSLContext getContextForTrustedCertificates(Context c) throws GeneralSecurityException, IOException {
+        if(sslContext == null){
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+
+            Certificate cas = cf.generateCertificate(c.getResources().openRawResource(R.raw.cas_ensiie_fr));
+            Certificate aurionweb = cf.generateCertificate(c.getResources().openRawResource(R.raw.aurionweb_ensiie_fr));
+
+            // Create a KeyStore containing our trusted CAs
+            String keyStoreType = KeyStore.getDefaultType();
+            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
+            keyStore.load(null, null);
+            keyStore.setCertificateEntry("cas", cas);
+            keyStore.setCertificateEntry("aurionweb", aurionweb);
+
+            // Create a TrustManager that trusts the CAs in our KeyStore
+            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
+            tmf.init(keyStore);
+
+            // Create an SSLContext that uses our TrustManager
+            sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(null, tmf.getTrustManagers(), null);
+        }
+
+        return sslContext;
+    }
+
+    public static Point getScreenSize(Context c){
+        WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
+        Display display = wm.getDefaultDisplay();
+        Point size = new Point();
+        display.getSize(size);
+        return size;
+    }
+    public static JsonObject strToJson(String text) {
+        JsonObject root = new JsonObject();
+        root.addProperty("text", text);
+        return root;
+    }
+
+    public static String stripAccents(String s) {
+        s = Normalizer.normalize(s, Normalizer.Form.NFD);
+        s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
+        return s;
+    }
+
+    public static String bytesToString(long bytes) {
+        long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
+        if (absB < 1024) {
+            return bytes + " o";
+        }
+        long value = absB;
+        CharacterIterator ci = new StringCharacterIterator("KMGTPE");
+        for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
+            value >>= 10;
+            ci.next();
+        }
+        value *= Long.signum(bytes);
+        return String.format(Locale.FRENCH, "%.1f %co", value / 1024.0, ci.current());
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..71bed7109a2a0964450a14c6d32a31f9cf31d41b
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java
@@ -0,0 +1,179 @@
+package fr.nitorac.aurionweb.aurionweb;
+
+import android.content.Context;
+import android.util.TypedValue;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.core.content.ContextCompat;
+
+import com.afollestad.materialdialogs.LayoutMode;
+import com.afollestad.materialdialogs.MaterialDialog;
+import com.afollestad.materialdialogs.bottomsheets.BottomSheet;
+import com.afollestad.materialdialogs.bottomsheets.BottomSheetsKt;
+import com.afollestad.materialdialogs.customview.DialogCustomViewExtKt;
+
+import org.jsoup.Connection;
+import org.jsoup.nodes.Document;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+import fr.nitorac.aurionweb.R;
+import fr.nitorac.aurionweb.Utils;
+
+public class AurionManager {
+
+    private static AurionManager instance;
+
+    public AurionManager(){
+
+    }
+
+    public boolean checkPassword(String username, String password) {
+        AurionSession session = new AurionSession();
+        try {
+            initConnection(session, username, password);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    // Instancie une connection vers AurionWeb
+    public Document initConnection(AurionSession AurionSession, String username, String pwd) throws IOException, GeneralSecurityException {
+        // Première connection pour récupérer un String "execution" nécessaire à la connection
+        Connection.Response initRes = Utils.wrapSSL("https://cas.ensiie.fr/login?service=https%3A%2F%2Faurionweb.ensiie.fr%2F%2Flogin%2Fcas")
+                .method(Connection.Method.GET)
+                .header("Cache-Control", "max-age=0")
+                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
+                .execute();
+        String execution = initRes.parse().getElementsByAttributeValue("name", "execution").get(0).attr("value");
+        //Requête effective permettant la validation de l'authentification sur CAS
+        Connection secConn = Utils.wrapSSL("https://cas.ensiie.fr/login?service=https%3A%2F%2Faurionweb.ensiie.fr%2F%2Flogin%2Fcas")
+                .method(Connection.Method.POST)
+                .followRedirects(true)
+                .header("Cache-Control", "max-age=0")
+                .header("Content-Type", "application/x-www-form-urlencoded")
+                .header("Host", "cas.ensiie.fr")
+                .header("Origin", "https://cas.ensiie.fr")
+                .header("Referer", "https://cas.ensiie.fr/login?service=https%3A%2F%2Faurionweb.ensiie.fr%2F%2Flogin%2Fcas")
+                .header("Sec-Fetch-Mode", "navigate")
+                .header("Sec-Fetch-Site", "same-origin")
+                .header("Upgrade-Insecure-Requests", "1")
+                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
+                .data("username", username)
+                .data("_eventId", "submit")
+                //.data("geolocation", "")
+                .data("execution", execution);
+        secConn.data("password", pwd);
+        Connection.Response sec = secConn.execute();
+        Document doc1 = sec.parse();
+        AurionSession.parseViewState(doc1);
+        AurionSession.setJSESSIONID(sec.cookie("JSESSIONID"));
+        //On trouve le form ID
+        AurionSession.parseConnectMenuFormId(doc1);
+        //On trouve l'ID du bouton Emploi du temps (pour les requêtes)
+        AurionSession.parseConnectMenuId(doc1);
+        //Requête effective permettant la validation de l'authentification sur CAS
+        Connection.Response tmp = Utils.wrapSSL("https://aurionweb.ensiie.fr/faces/MainMenuPage.xhtml")
+                .method(Connection.Method.POST)
+                .followRedirects(true)
+                .header("Cache-Control", "max-age=0")
+                .header("Content-Type", "application/x-www-form-urlencoded")
+                .header("Host", "aurionweb.ensiie.fr")
+                .header("Origin", "https://aurionweb.ensiie.fr")
+                .header("Referer", "https://aurionweb.ensiie.fr/")
+                .header("Faces-Request", "partial/ajax")
+                .header("Upgrade-Insecure-Requests", "1")
+                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
+                .cookie("JSESSIONID", AurionSession.getJSESSIONID())
+                .data("javax.faces.partial.ajax", "true")
+                .data("javax.faces.source", AurionSession.getMenuFormId())
+                .data("javax.faces.partial.execute", AurionSession.getMenuFormId())
+                .data("javax.faces.partial.render", "form:sidebar")
+                .data(AurionSession.getMenuFormId(), AurionSession.getMenuFormId())
+                .data("webscolaapp.Sidebar.ID_SUBMENU", AurionSession.getMenuId())
+                .data("form", "form")
+                //.data("form:largeurDivCenter", "1219")
+                //.data("form:sauvegarde", "")
+                .data("javax.faces.ViewState", AurionSession.getViewState())
+                .execute();
+        Document doc2 = tmp.parse();
+        AurionSession.parseViewState(doc2);
+        AurionSession.parseConnectSubmenuId(doc2);
+        // On charge une fois la page pour valider un affichage fictif (cote server aurion)
+        // Requête effective permettant la validation de l'authentification sur CAS
+        Connection.Response resp = Utils.wrapSSL("https://aurionweb.ensiie.fr/faces/MainMenuPage.xhtml")
+                .method(Connection.Method.POST)
+                .followRedirects(true)
+                .header("Cache-Control", "max-age=0")
+                .header("Content-Type", "application/x-www-form-urlencoded")
+                .header("Host", "aurionweb.ensiie.fr")
+                .header("Origin", "https://aurionweb.ensiie.fr")
+                .header("Referer", "https://aurionweb.ensiie.fr/")
+                .header("Upgrade-Insecure-Requests", "1")
+                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
+                .cookie("JSESSIONID", AurionSession.getJSESSIONID())
+                .data("form", "form")
+                //.data("form:largeurDivCenter", "1219")
+                //.data("form:sauvegarde", "")
+                .data("form:sidebar", "form:sidebar")
+                .data("form:sidebar_menuid", AurionSession.getSubmenuId())
+                .data("javax.faces.ViewState", AurionSession.getViewState())
+                .execute();
+        Document respDoc = resp.parse();
+        //On trouve le formId du ChoixPlanning
+        AurionSession.parseChoixPlanningFormId(respDoc);
+        //On trouve l'id du bouton 'Voir planning' necéssaire aux requêtes
+        AurionSession.parseChoixPlanningSubmitBtnId(respDoc);
+        AurionSession.parseViewState(respDoc);
+        return respDoc;
+    }
+
+    public void spawnLoginDialog(Context c){
+        final MaterialDialog dialog = new MaterialDialog(c, new BottomSheet(LayoutMode.MATCH_PARENT))
+                .title(null, "Connexion AurionWeb")
+                .icon(null, ContextCompat.getDrawable(c, R.drawable.ic_login))
+                .cancelable(true)
+                .noAutoDismiss()
+                .positiveButton(null, "CONNEXION", materialDialog -> {
+                    EditText login = materialDialog.getView().findViewById(R.id.loginInput);
+                    EditText pwd = materialDialog.getView().findViewById(R.id.passwordInput);
+                    CheckConnectionTask checkTask = new CheckConnectionTask(c, (res) -> {
+                        if(res){
+                            Toast.makeText(c, "Connexion réussie !", Toast.LENGTH_LONG).show();
+                            materialDialog.dismiss();
+                        }else{
+                            Toast.makeText(c, "Mauvais mot de passe ou erreur de connexion !", Toast.LENGTH_LONG).show();
+                        }
+                    });
+                    checkTask.execute(login.getText().toString().toLowerCase().trim(), pwd.getText().toString().trim());
+                    return null;
+                })
+                .negativeButton(null, "ANNULER", materialDialog -> {
+                    materialDialog.dismiss();
+                    return null;
+                });
+        BottomSheetsKt.setPeekHeight(dialog, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 400 /*dp*/, c.getResources().getDisplayMetrics()), null);
+
+        // Errk, dirtyyyy, but I can't find any other way to do it
+        DialogCustomViewExtKt.customView(dialog, R.layout.dialog_login, null, false, false, true, true);
+
+        // Errk, dirtyyyy, workaround to avoid a flickering issue when dialog is sliding
+        dialog.dismiss();
+
+        dialog.show();
+    }
+
+
+
+    public static AurionManager getInstance(){
+        if(instance == null){
+            instance = new AurionManager();
+        }
+
+        return instance;
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionSession.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionSession.java
new file mode 100644
index 0000000000000000000000000000000000000000..996e47dfe6737b6db1c9d051270e07bbce2e1937
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionSession.java
@@ -0,0 +1,178 @@
+package fr.nitorac.aurionweb.aurionweb;
+
+import android.util.Log;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import fr.nitorac.aurionweb.Utils;
+import lombok.AccessLevel;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@Data
+public class AurionSession {
+    private static final String TAG = "AurionSession";
+
+    @Getter(AccessLevel.NONE)
+    @Setter(AccessLevel.NONE)
+    private static final Pattern menuIdPattern = Pattern.compile("\\{PrimeFaces\\.ab\\(\\{s:\"(.*?)\"", Pattern.MULTILINE);
+
+    @Getter(AccessLevel.NONE)
+    @Setter(AccessLevel.NONE)
+    private static final Pattern liSubmenuPattern = Pattern.compile("'form:sidebar_menuid':'(.*?)'", Pattern.MULTILINE);
+    private static final List<String> elemsPopupLabel = Arrays.asList("cour", "interve", "ressourc");
+
+    private String JSESSIONID = "";
+
+    //Variables ID pour la connection et le menu (@see initConnection du AurionManager)
+    @Setter(AccessLevel.PRIVATE)
+    private String viewState = "";
+    @Setter(AccessLevel.NONE)
+    private String menuFormId = "";
+    @Setter(AccessLevel.NONE)
+    private String menuId = "";
+
+    //Variables ID pour le ChoixPlanning
+    @Setter(AccessLevel.NONE)
+    private String submenuId = "";
+    @Setter(AccessLevel.NONE)
+    private String choixpFormId = "";
+
+    //Variables ID pour le Planning
+    @Setter(AccessLevel.NONE)
+    private String choixpSubmitId = "";
+    @Setter(AccessLevel.NONE)
+    private String planningFormId = "";
+    //Variables ID pour le popup d'un événement du Planning : Cours, Intervenants, Ressources, et Infos
+    @Setter(AccessLevel.NONE)
+    private ArrayList<String> elemsPopupId = new ArrayList<>(3);
+    private Document lastDoc;
+
+    private static String getViewState(Document doc) {
+        Element view = doc.getElementById("j_id1:javax.faces.ViewState:0");
+        if (view == null) {
+            return null;
+        }
+        String test = view.attr("value");
+        return test.isEmpty() ? /* CDATA Node */view.text() : test;
+    }
+
+    public void parseViewState(Document doc) {
+        doc = setLastDoc(doc);
+        String viewState = getViewState(doc);
+        if (viewState == null) {
+            Log.e(TAG, "Impossible d'analyser le ViewState pour : \n" + doc.outerHtml());
+        }
+        setViewState(viewState);
+    }
+
+    public boolean parseConnectMenuFormId(Document doc) {
+        doc = setLastDoc(doc);
+        //On va récupérer l'ID Aurionweb qui correspond à la form du menu
+        String menuScript = doc.getElementsByAttributeValue("type", "text/javascript").stream().map(Node::outerHtml).filter(e -> e.contains("chargerSousMenu = function()")).findFirst().orElse("");
+        Matcher menuMatcher = menuIdPattern.matcher(menuScript);
+        menuFormId = menuMatcher.find() ? menuMatcher.group(1) : null;
+        if (menuFormId == null) {
+            Log.e(TAG, "Impossible de trouver l'ID menu dans : " + menuScript);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean parseConnectMenuId(Document doc) {
+        doc = setLastDoc(doc);
+        //Maintenant on va récupérer l'ID du menu qu'on souhaite, c'est à dire Emploi du temps
+        // (Oui c'est bien un menu même si on cherche une balise avec submenu_... comme classe x) (c'est aurionweb)
+        Element menuClass = doc.getElementsByAttributeValueContaining("class", "submenu_").stream().filter(e -> e.text().contains("Emploi du temps")).findFirst().orElse(null);
+        menuId = menuClass != null ? menuClass.classNames().stream().filter(c -> c.startsWith("submenu_")).findFirst().orElse("") : null;
+        if (menuId == null) {
+            Log.e(TAG, "Impossible de trouver un menu avec 'Emploi du temps' comme texte !");
+            return false;
+        }
+        return true;
+    }
+
+    public boolean parseConnectSubmenuId(Document doc) {
+        doc = setLastDoc(doc);
+        //On va maintenant trouver un ID de la forme '2_1' qui correspond à l'ID du lien "Planning d'un étudiant au choix"
+        Element liSubmenuID = Jsoup.parse(doc.getElementById("form:sidebar").text()).getElementsByTag("li").stream().filter(e -> Utils.stripAccents(e.text()).equalsIgnoreCase("Planning d'un etudiant au choix")).findFirst().orElse(null);
+        if (liSubmenuID != null) {
+            Matcher submenuMatcher = liSubmenuPattern.matcher(liSubmenuID.child(0).attr("onclick"));
+            if (submenuMatcher.find()) {
+                submenuId = submenuMatcher.group(1);
+                return true;
+            }
+        } else {
+            Log.e(TAG, "Impossible de trouver un sous menu de tag 'li' avec 'Planning d'un étudiant au choix' comme texte !");
+        }
+        return false;
+    }
+
+
+    public boolean parseChoixPlanningFormId(Document doc) {
+        doc = setLastDoc(doc);
+        //On va trouver l'ID principal correspondant à la form de la page ChoixPlanning d'Aurionweb
+        Element formDiv = doc.getElementsByAttributeValueContaining("class", "ui-datatable ui-widget").first();
+        if (formDiv != null) {
+            choixpFormId = formDiv.id();
+            return true;
+        }
+        return false;
+    }
+
+    public boolean parseChoixPlanningSubmitBtnId(Document doc) {
+        doc = setLastDoc(doc);
+        //On va trouver l'ID du bouton 'Voir planning' qui est nécessaire dans les données d'une requête accédant à l'edt d'un user
+        Element submitBtn = doc.getElementsByAttributeValue("type", "submit").stream().filter(e -> e.text().toLowerCase().contains("voir planning")).findFirst().orElse(null);
+        if (submitBtn != null) {
+            choixpSubmitId = submitBtn.id();
+            return true;
+        }
+        return false;
+    }
+
+    public boolean parsePlanningFormId(Document doc) {
+        doc = setLastDoc(doc);
+        //On va trouver la form id principale de la page
+        Element scheduleDiv = doc.getElementsByClass("schedule").first();
+        if (scheduleDiv != null) {
+            planningFormId = scheduleDiv.id();
+            return true;
+        }
+        return false;
+    }
+
+    public void parseEventProps(Document doc) {
+        elemsPopupId.clear();
+        for (int i = 0; i < elemsPopupLabel.size(); i++) {
+            elemsPopupId.add(null);
+        }
+        for (Element e : doc.getElementsByTag("a")) {
+            if (e.children().size() == 0) {
+                for (int i = 0; i < elemsPopupLabel.size(); i++) {
+                    if (e.text().toLowerCase().contains(elemsPopupLabel.get(i))) {
+                        //substring(1) pour retirer le # devant
+                        elemsPopupId.set(i, doc.getElementById(e.attr("href").substring(1)).getElementsByAttributeValueContaining("id", "_data").first().id());
+                    }
+                }
+            }
+        }
+    }
+
+
+    public Document setLastDoc(Document doc) {
+        return doc == null ? getLastDoc() : (lastDoc = doc);
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionView.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionView.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b13e02b19336e43d85c4469768e8d2a64837414
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionView.java
@@ -0,0 +1,7 @@
+package fr.nitorac.aurionweb.aurionweb;
+
+public class AurionView {
+    public AurionView(){
+
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/CheckConnectionTask.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/CheckConnectionTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..974ddb5088325ce130d3c84c8d718c2be58324bc
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/CheckConnectionTask.java
@@ -0,0 +1,50 @@
+package fr.nitorac.aurionweb.aurionweb;
+
+import android.content.Context;
+import android.os.AsyncTask;
+
+import com.afollestad.materialdialogs.LayoutMode;
+import com.afollestad.materialdialogs.MaterialDialog;
+import com.afollestad.materialdialogs.bottomsheets.BottomSheet;
+import com.afollestad.materialdialogs.customview.DialogCustomViewExtKt;
+
+import fr.nitorac.aurionweb.R;
+
+public class CheckConnectionTask extends AsyncTask<String, Void, Boolean> {
+
+    private MaterialDialog loading;
+    private ConnectionCheck callback;
+
+    public CheckConnectionTask(Context c, ConnectionCheck callback){
+        this.callback = callback;
+        loading = new MaterialDialog(c, new BottomSheet(LayoutMode.WRAP_CONTENT))
+            .cancelable(false)
+            .cancelOnTouchOutside(false)
+            .title(R.string.loading, null)
+            .noAutoDismiss();
+        DialogCustomViewExtKt.customView(loading, R.layout.dialog_loading, null, false, false, true, true);
+        loading.dismiss();
+    }
+
+    @Override
+    protected void onPreExecute() {
+        super.onPreExecute();
+        loading.show();
+    }
+
+    @Override
+    protected void onPostExecute(Boolean res) {
+        super.onPostExecute(res);
+        loading.dismiss();
+        callback.onResult(res);
+    }
+
+    @Override
+    protected Boolean doInBackground(String... creds) {
+        return AurionManager.getInstance().checkPassword(creds[0], creds[1]);
+    }
+
+    public interface ConnectionCheck {
+        void onResult(Boolean res);
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelper.java b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..f73a917b0c464749c482a86f8122561d004795ff
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelper.java
@@ -0,0 +1,11 @@
+package fr.nitorac.aurionweb.security;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+public interface SecurityHelper {
+
+    void init() throws GeneralSecurityException, IOException;
+    String decrypt(String encrypted) throws GeneralSecurityException, IOException;
+    String encrypt(String raw) throws GeneralSecurityException, IOException;
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPostM.java b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPostM.java
new file mode 100644
index 0000000000000000000000000000000000000000..b15d398dd3ff759e35332a8a9658378c05f8f85d
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPostM.java
@@ -0,0 +1,66 @@
+package fr.nitorac.aurionweb.security;
+
+import android.os.Build;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+import android.util.Base64;
+
+import androidx.annotation.RequiresApi;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.Key;
+import java.security.KeyStore;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.GCMParameterSpec;
+
+@RequiresApi(api = Build.VERSION_CODES.M)
+public class SecurityHelperPostM implements SecurityHelper {
+
+    private static final String AndroidKeyStore = "AndroidKeyStore";
+    private static final String AES_MODE = "AES/GCM/NoPadding";
+
+    private KeyStore keyStore;
+
+    public SecurityHelperPostM() throws GeneralSecurityException, IOException {
+        init();
+    }
+
+    public void init() throws GeneralSecurityException, IOException {
+        keyStore = KeyStore.getInstance(AndroidKeyStore);
+        keyStore.load(null);
+
+        if (!keyStore.containsAlias(SecurityManager.KEYSTORE_NAME)) {
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, AndroidKeyStore);
+            keyGenerator.init(
+                    new KeyGenParameterSpec.Builder(SecurityManager.KEYSTORE_NAME,
+                            KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                            .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                            .setRandomizedEncryptionRequired(true)
+                            .build());
+            keyGenerator.generateKey();
+        }
+    }
+
+    private Key getSecretKey() throws GeneralSecurityException {
+        return keyStore.getKey(SecurityManager.KEYSTORE_NAME, null);
+    }
+
+    public String encrypt(String raw) throws GeneralSecurityException {
+        Cipher c = Cipher.getInstance(AES_MODE);
+        c.init(Cipher.ENCRYPT_MODE, getSecretKey(), c.getParameters());
+        byte[] encodedBytes = c.doFinal(raw.getBytes(StandardCharsets.UTF_8));
+        return Base64.encodeToString(encodedBytes, Base64.DEFAULT).replace("\n", "") + ":" + Base64.encodeToString(c.getIV(), Base64.DEFAULT);
+    }
+
+    public String decrypt(String encrypted) throws GeneralSecurityException  {
+        String[] data = encrypted.split(":");
+        Cipher c = Cipher.getInstance(AES_MODE);
+        c.init(Cipher.DECRYPT_MODE, getSecretKey(), new GCMParameterSpec(128, Base64.decode(data[1], Base64.DEFAULT)));
+        return new String(c.doFinal(Base64.decode(data[0], Base64.DEFAULT)), StandardCharsets.UTF_8);
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPreM.java b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPreM.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a73b260ec3c49cf9f7ab0bd3be82d1dbecab10d
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityHelperPreM.java
@@ -0,0 +1,135 @@
+package fr.nitorac.aurionweb.security;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.security.KeyPairGeneratorSpec;
+import android.util.Base64;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Calendar;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.spec.SecretKeySpec;
+import javax.security.auth.x500.X500Principal;
+
+public class SecurityHelperPreM implements SecurityHelper {
+
+    private static final String AndroidKeyStore = "AndroidKeyStore";
+    private static final String RSA_MODE =  "RSA/ECB/PKCS1Padding";
+    private static final String AES_MODE = "AES/ECB/PKCS7Padding";
+
+    private Context context;
+    private KeyStore keyStore;
+
+    public SecurityHelperPreM(Context context) throws GeneralSecurityException, IOException {
+        this.context = context;
+        init();
+    }
+
+    public void init() throws GeneralSecurityException, IOException {
+        keyStore = KeyStore.getInstance(AndroidKeyStore);
+        keyStore.load(null);// Generate the RSA key pairs
+        if (!keyStore.containsAlias(SecurityManager.KEYSTORE_NAME)) {
+            // Generate a key pair for encryption
+            Calendar start = Calendar.getInstance();
+            Calendar end = Calendar.getInstance();
+            end.add(Calendar.YEAR, 60);
+            KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
+                    .setAlias(SecurityManager.KEYSTORE_NAME)
+                    .setSubject(new X500Principal("CN=" + SecurityManager.KEYSTORE_NAME))
+                    .setSerialNumber(BigInteger.TEN)
+                    .setStartDate(start.getTime())
+                    .setEndDate(end.getTime())
+                    .build();
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", AndroidKeyStore);
+            kpg.initialize(spec);
+            kpg.generateKeyPair();
+        }
+
+        SharedPreferences pref = context.getSharedPreferences(SecurityManager.SEC_SHARED_PREF, Context.MODE_PRIVATE);
+        String enryptedKeyB64 = pref.getString(SecurityManager.ENCRYPT_KEY, null);
+        if (enryptedKeyB64 == null) {
+            byte[] key = new byte[16];
+            SecureRandom secureRandom = new SecureRandom();
+            secureRandom.nextBytes(key);
+            byte[] encryptedKey = rsaEncrypt(key);
+            enryptedKeyB64 = Base64.encodeToString(encryptedKey, Base64.DEFAULT);
+            SharedPreferences.Editor edit = pref.edit();
+            edit.putString(SecurityManager.ENCRYPT_KEY, enryptedKeyB64);
+            edit.apply();
+        }
+    }
+
+    private byte[] rsaEncrypt(byte[] secret) throws GeneralSecurityException, IOException {
+        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(SecurityManager.KEYSTORE_NAME, null);
+        // Encrypt the text
+        Cipher inputCipher = Cipher.getInstance(RSA_MODE, "AndroidOpenSSL");
+        inputCipher.init(Cipher.ENCRYPT_MODE, privateKeyEntry.getCertificate().getPublicKey());
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, inputCipher);
+        cipherOutputStream.write(secret);
+        cipherOutputStream.close();
+
+        return outputStream.toByteArray();
+    }
+
+    private  byte[]  rsaDecrypt(byte[] encrypted) throws GeneralSecurityException, IOException {
+        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(SecurityManager.KEYSTORE_NAME, null);
+        Cipher output = Cipher.getInstance(RSA_MODE, "AndroidOpenSSL");
+        output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
+        CipherInputStream cipherInputStream = new CipherInputStream(
+                new ByteArrayInputStream(encrypted), output);
+        ArrayList<Byte> values = new ArrayList<>();
+        int nextByte;
+        while ((nextByte = cipherInputStream.read()) != -1) {
+            values.add((byte)nextByte);
+        }
+
+        byte[] bytes = new byte[values.size()];
+        for(int i = 0; i < bytes.length; i++) {
+            bytes[i] = values.get(i);
+        }
+        return bytes;
+    }
+
+    private Key getSecretKey(Context context) throws GeneralSecurityException, IOException {
+        SharedPreferences pref = context.getSharedPreferences(SecurityManager.SEC_SHARED_PREF, Context.MODE_PRIVATE);
+        String enryptedKeyB64 = pref.getString(SecurityManager.ENCRYPT_KEY, null);
+        if(enryptedKeyB64 == null){
+            throw new InvalidKeyException("Impossible de trouver la clé AES sauvegardée !");
+        }
+        byte[] encryptedKey = Base64.decode(enryptedKeyB64, Base64.DEFAULT);
+        byte[] key = rsaDecrypt(encryptedKey);
+        return new SecretKeySpec(key, "AES");
+    }
+
+    @SuppressLint("GetInstance") // Vu qu'on fait du legacy ici, ça sert à rien d'avoir ces warnings
+    public String encrypt(String input) throws GeneralSecurityException, IOException {
+        Cipher c = Cipher.getInstance(AES_MODE, "BC");
+        c.init(Cipher.ENCRYPT_MODE, getSecretKey(context));
+        byte[] encodedBytes = c.doFinal(input.getBytes(StandardCharsets.UTF_8));
+        return Base64.encodeToString(encodedBytes, Base64.DEFAULT);
+    }
+
+    @SuppressLint("GetInstance") // Vu qu'on fait du legacy ici, ça sert à rien d'avoir ces warnings
+    public String decrypt(String encrypted) throws GeneralSecurityException, IOException {
+        Cipher c = Cipher.getInstance(AES_MODE, "BC");
+        c.init(Cipher.DECRYPT_MODE, getSecretKey(context));
+        return new String(c.doFinal(Base64.decode(encrypted, Base64.DEFAULT)), StandardCharsets.UTF_8);
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/security/SecurityManager.java b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..0efccaeff166b17440f29211b1e96302e8202957
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/security/SecurityManager.java
@@ -0,0 +1,35 @@
+package fr.nitorac.aurionweb.security;
+
+import android.content.Context;
+import android.os.Build;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+/**
+ * On utilise une méthode assez compliquée pour stocker le mot de passe Aurionweb
+ *
+ * Etant donné qu'on ne peut utiliser une clé de chiffrement dans le code car trop facilement retrouvable,
+ * on la stocke en utilisant le chiffrement fourni par Android !
+ *
+ * Cependant, le gestionnaire de chiffrement Android a changé d'API avant et après Android M, il faut donc gérer les deux possibilités
+ */
+public class SecurityManager {
+
+    public static final String KEYSTORE_NAME = "NitAurionWeb";
+    public static final String SEC_SHARED_PREF = "secstore";
+    public static final String ENCRYPT_KEY = "aesKey";
+
+    private static SecurityHelper secHelp;
+
+    public static SecurityHelper getSecurityHelper(Context c) throws GeneralSecurityException, IOException {
+        if(secHelp == null) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                secHelp = new SecurityHelperPostM();
+            }else{
+                secHelp = new SecurityHelperPreM(c);
+            }
+        }
+        return secHelp;
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardFragment.java b/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardFragment.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ddc0559bea5248534b0a31cb3944d9aad42f29c
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardFragment.java
@@ -0,0 +1,35 @@
+package fr.nitorac.aurionweb.ui.dashboard;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProviders;
+
+import fr.nitorac.aurionweb.R;
+
+public class DashboardFragment extends Fragment {
+
+    private DashboardViewModel dashboardViewModel;
+
+    public View onCreateView(@NonNull LayoutInflater inflater,
+                             ViewGroup container, Bundle savedInstanceState) {
+        dashboardViewModel =
+                ViewModelProviders.of(this).get(DashboardViewModel.class);
+        View root = inflater.inflate(R.layout.fragment_calendar, container, false);
+        final TextView textView = root.findViewById(R.id.text_dashboard);
+        dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
+            @Override
+            public void onChanged(@Nullable String s) {
+                textView.setText(s);
+            }
+        });
+        return root;
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardViewModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..84c5294ab9787ebaef4ae403c7c862a4772251f3
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/ui/dashboard/DashboardViewModel.java
@@ -0,0 +1,19 @@
+package fr.nitorac.aurionweb.ui.dashboard;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+public class DashboardViewModel extends ViewModel {
+
+    private MutableLiveData<String> mText;
+
+    public DashboardViewModel() {
+        mText = new MutableLiveData<>();
+        mText.setValue("This is dashboard fragment");
+    }
+
+    public LiveData<String> getText() {
+        return mText;
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeFragment.java b/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeFragment.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f3370809543327c937e651f02b18b59d1863b34
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeFragment.java
@@ -0,0 +1,35 @@
+package fr.nitorac.aurionweb.ui.home;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProviders;
+
+import fr.nitorac.aurionweb.R;
+
+public class HomeFragment extends Fragment {
+
+    private HomeViewModel homeViewModel;
+
+    public View onCreateView(@NonNull LayoutInflater inflater,
+                             ViewGroup container, Bundle savedInstanceState) {
+        homeViewModel =
+                ViewModelProviders.of(this).get(HomeViewModel.class);
+        View root = inflater.inflate(R.layout.fragment_home, container, false);
+        final TextView textView = root.findViewById(R.id.text_home);
+        homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
+            @Override
+            public void onChanged(@Nullable String s) {
+                textView.setText(s);
+            }
+        });
+        return root;
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeViewModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f8c5f8c519e56342627654d7f6b359f0ee05849
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/ui/home/HomeViewModel.java
@@ -0,0 +1,19 @@
+package fr.nitorac.aurionweb.ui.home;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+public class HomeViewModel extends ViewModel {
+
+    private MutableLiveData<String> mText;
+
+    public HomeViewModel() {
+        mText = new MutableLiveData<>();
+        mText.setValue("This is home fragment");
+    }
+
+    public LiveData<String> getText() {
+        return mText;
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsFragment.java b/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsFragment.java
new file mode 100644
index 0000000000000000000000000000000000000000..f926c6db00442d5e5dc9ebaa111efc0bef49a205
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsFragment.java
@@ -0,0 +1,35 @@
+package fr.nitorac.aurionweb.ui.notifications;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProviders;
+
+import fr.nitorac.aurionweb.R;
+
+public class NotificationsFragment extends Fragment {
+
+    private NotificationsViewModel notificationsViewModel;
+
+    public View onCreateView(@NonNull LayoutInflater inflater,
+                             ViewGroup container, Bundle savedInstanceState) {
+        notificationsViewModel =
+                ViewModelProviders.of(this).get(NotificationsViewModel.class);
+        View root = inflater.inflate(R.layout.fragment_notifications, container, false);
+        final TextView textView = root.findViewById(R.id.text_notifications);
+        notificationsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
+            @Override
+            public void onChanged(@Nullable String s) {
+                textView.setText(s);
+            }
+        });
+        return root;
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsViewModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..daea70f94234518b31b8f9ec69dce46ef76698c0
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/ui/notifications/NotificationsViewModel.java
@@ -0,0 +1,19 @@
+package fr.nitorac.aurionweb.ui.notifications;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+public class NotificationsViewModel extends ViewModel {
+
+    private MutableLiveData<String> mText;
+
+    public NotificationsViewModel() {
+        mText = new MutableLiveData<>();
+        mText.setValue("This is notifications fragment");
+    }
+
+    public LiveData<String> getText() {
+        return mText;
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/update/AsyncUpdateCheckerTask.java b/app/src/main/java/fr/nitorac/aurionweb/update/AsyncUpdateCheckerTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf295761d3520bc57268a68da0cb00f8183d7a9c
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/update/AsyncUpdateCheckerTask.java
@@ -0,0 +1,60 @@
+package fr.nitorac.aurionweb.update;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.widget.Toast;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.ref.WeakReference;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+import fr.nitorac.aurionweb.BuildConfig;
+
+public class AsyncUpdateCheckerTask extends AsyncTask<Void, Void, JsonObject> {
+
+    private WeakReference<Context> weakContext;
+
+    public AsyncUpdateCheckerTask(Context c){
+        weakContext = new WeakReference<>(c);
+    }
+
+    @Override
+    protected JsonObject doInBackground(Void... voids) {
+        try {
+            URL url = new URL(UpdateManager.CHECK_URL + URLEncoder.encode(BuildConfig.VERSION_NAME, StandardCharsets.UTF_8.toString()));
+            HttpURLConnection conn=(HttpURLConnection) url.openConnection();
+            conn.setConnectTimeout(10000); // timing out in a minute
+
+            JsonObject obj = new Gson().fromJson(new InputStreamReader(conn.getInputStream()), JsonObject.class);
+            if(!obj.get("version").getAsString().equalsIgnoreCase(BuildConfig.VERSION_NAME)){
+                return obj;
+            }else{
+                return new JsonObject();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Override
+    protected void onPostExecute(JsonObject obj) {
+        super.onPostExecute(obj);
+        if(weakContext == null){
+            return;
+        }
+        if(obj == null){
+            Toast.makeText(weakContext.get(), "Impossible de vérifier les mises à jour ...", Toast.LENGTH_SHORT).show();
+        }else if(!obj.entrySet().isEmpty()){
+            UpdateManager.updateAvailable = true;
+            UpdateManager.getInstance().spawnUpdateDialog(weakContext, obj);
+        }
+    }
+}
diff --git a/app/src/main/java/fr/nitorac/aurionweb/update/UpdateManager.java b/app/src/main/java/fr/nitorac/aurionweb/update/UpdateManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..abc3f46fee1809bfa0fca19cfbfe8ac9487b1bb6
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/update/UpdateManager.java
@@ -0,0 +1,180 @@
+package fr.nitorac.aurionweb.update;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.PowerManager;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.core.content.ContextCompat;
+import androidx.core.content.FileProvider;
+
+import com.afollestad.materialdialogs.MaterialDialog;
+import com.afollestad.materialdialogs.customview.DialogCustomViewExtKt;
+import com.downloader.Error;
+import com.downloader.OnDownloadListener;
+import com.downloader.PRDownloader;
+import com.github.lzyzsd.circleprogress.CircleProgress;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+
+import fr.nitorac.aurionweb.BuildConfig;
+import fr.nitorac.aurionweb.R;
+import fr.nitorac.aurionweb.Utils;
+
+import static android.content.Context.POWER_SERVICE;
+
+public class UpdateManager {
+    public static String CHECK_URL = "https://ranini.iiens.net/aurionweb-check/update.php?version=";
+
+    public static boolean updateAvailable = false;
+    public static int downloadId = -1;
+    private static UpdateManager instance;
+
+    public UpdateManager(){
+
+    }
+
+    public static void handleOnPause(){
+        PRDownloader.pause(downloadId);
+    }
+
+    public static void handleOnResume(){
+        PRDownloader.resume(downloadId);
+    }
+
+    public void checkUpdates(Context c){
+        AsyncUpdateCheckerTask task = new AsyncUpdateCheckerTask(c);
+        task.execute();
+    }
+
+    public void startDownload(final WeakReference<Context> weakContext, String url){
+        if(weakContext == null){
+            return;
+        }
+        String tag = "UpdateDownload";
+        Context c = weakContext.get();
+        final MaterialDialog dialog = new MaterialDialog(c, MaterialDialog.getDEFAULT_BEHAVIOR())
+                .title(null, "Téléchargement")
+                .icon(null, ContextCompat.getDrawable(c, R.drawable.ic_download))
+                .cancelable(false);
+        DialogCustomViewExtKt.customView(dialog, R.layout.dialog_download, null, false, false, true, true);
+        final WeakReference<CircleProgress> circleProgress = new WeakReference<>(dialog.findViewById(R.id.circle_progress));
+        final WeakReference<TextView> textProgress = new WeakReference<>(dialog.findViewById(R.id.progress_text));
+
+        PowerManager powerManager = (PowerManager) weakContext.get().getSystemService(POWER_SERVICE);
+        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                "AurionWeb::DownloadWakelock");
+
+        downloadId = PRDownloader.download(url, c.getCacheDir().getAbsolutePath(), "update.apk")
+                .setTag(tag)
+                .build()
+                .setOnStartOrResumeListener(() -> {
+                    if(circleProgress != null){
+                        circleProgress.get().setProgress(0);
+                        circleProgress.get().setMax(100);
+                    }
+
+                    if(textProgress != null){
+                        textProgress.get().setText("Chargement ...");
+                    }
+
+                    if(!dialog.isShowing()){
+                        dialog.show();
+                    }
+
+                    if(!wakeLock.isHeld()){
+                        wakeLock.acquire(10*60*1000L /*30 minutes*/);
+                    }
+                })
+                .setOnPauseListener(() -> {
+
+                })
+                .setOnCancelListener(() -> {
+                    if(weakContext != null){
+                        Toast.makeText(weakContext.get(), "Téléchargement annulé", Toast.LENGTH_LONG).show();
+                    }
+                    wakeLock.release();
+                })
+                .setOnProgressListener(progress -> {
+                    int frac = (int)((double)progress.currentBytes * 100.0 / (double)progress.totalBytes);
+                    if(circleProgress != null){
+                        circleProgress.get().setProgress(frac);
+                    }
+                    if(textProgress != null){
+                        textProgress.get().setText(Utils.bytesToString(progress.currentBytes) + " / " + Utils.bytesToString(progress.totalBytes));
+                    }
+                })
+                .start(new OnDownloadListener() {
+                    @Override
+                    public void onDownloadComplete() {
+                        if(weakContext != null){
+                            Context context = weakContext.get();
+                            File file = new File(weakContext.get().getCacheDir().getAbsolutePath(), "update.apk");
+                            Uri apkURI = FileProvider.getUriForFile(
+                                    context,
+                                    context.getApplicationContext()
+                                            .getPackageName() + ".provider", file);
+
+                            Intent intent = new Intent(Intent.ACTION_VIEW, apkURI);
+                            intent.setDataAndType(apkURI, "application/vnd.android.package-archive");
+                            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+                            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                            intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
+                            dialog.dismiss();
+                            context.getApplicationContext().startActivity(intent);
+                        }
+                        wakeLock.release();
+                    }
+
+                    @Override
+                    public void onError(Error error) {
+                        if(weakContext != null){
+                            error.getConnectionException().printStackTrace();
+                            Toast.makeText(weakContext.get(), "Erreur : " + error.getConnectionException().getMessage(), Toast.LENGTH_LONG).show();
+                        }
+                        wakeLock.release();
+                    }
+                });
+    }
+
+    public void spawnUpdateDialog(WeakReference<Context> weakContext, JsonObject remote){
+        if(weakContext == null){
+            return;
+        }
+        Context c = weakContext.get();
+        StringBuilder changelogs = new StringBuilder();
+
+        for(JsonElement el : remote.get("changelogs").getAsJsonArray()){
+            JsonObject obj = el.getAsJsonObject();
+            changelogs.append(obj.get("version").getAsString()).append(" :\n");
+            for(JsonElement change : obj.get("msg").getAsJsonArray()){
+                changelogs.append("  - ").append(change.getAsString()).append("\n");
+            }
+            changelogs.append("\n");
+        }
+
+        MaterialDialog dialog = new MaterialDialog(c, MaterialDialog.getDEFAULT_BEHAVIOR())
+                .title(R.string.dialog_update_title, null)
+                .icon(null, ContextCompat.getDrawable(c, R.drawable.ic_download))
+                .message(null, String.format(c.getResources().getString(R.string.dialog_update_msg), BuildConfig.VERSION_NAME, remote.get("version").getAsString(), changelogs), null)
+                .cancelable(true)
+                .positiveButton(null, "METTRE A JOUR", materialDialog -> {
+                    startDownload(weakContext, remote.get("url").getAsString());
+                    return null;
+                })
+                .negativeButton(null, "ANNULER", materialDialog -> {
+                    materialDialog.dismiss();
+                    return null;
+                });
+        dialog.show();
+    }
+
+    public static UpdateManager getInstance(){
+        return instance != null ? instance : (instance = new UpdateManager());
+    }
+}
diff --git a/app/src/main/res/drawable-anydpi/ic_calendar.xml b/app/src/main/res/drawable-anydpi/ic_calendar.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4d9567073c344e3f8e6755defadd8b4dd126181c
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_calendar.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="#FFFFFF"
+    android:alpha="0.8">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M17,12h-5v5h5v-5zM16,1v2L8,3L8,1L6,1v2L5,3c-1.11,0 -1.99,0.9 -1.99,2L3,19c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2h-1L18,1h-2zM19,19L5,19L5,8h14v11z"/>
+</vector>
diff --git a/app/src/main/res/drawable-anydpi/ic_download.xml b/app/src/main/res/drawable-anydpi/ic_download.xml
new file mode 100644
index 0000000000000000000000000000000000000000..290ec39cf69315bb1b3e48ee9ccf283aee93b3c1
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_download.xml
@@ -0,0 +1,16 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="#FFFFFF"
+    android:alpha="0.8">
+  <group android:scaleX="0.90909094"
+      android:scaleY="0.90909094"
+      android:translateX="1.0909091"
+      android:translateY="1.0909091">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM17,13l-5,5 -5,-5h3V9h4v4h3z"/>
+  </group>
+</vector>
diff --git a/app/src/main/res/drawable-anydpi/ic_login.xml b/app/src/main/res/drawable-anydpi/ic_login.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1bc2080498920cce9743e2b1d5d289b81712ad8b
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_login.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="#FFFFFF"
+    android:alpha="0.8">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z"/>
+</vector>
diff --git a/app/src/main/res/drawable-hdpi/ic_calendar.png b/app/src/main/res/drawable-hdpi/ic_calendar.png
new file mode 100644
index 0000000000000000000000000000000000000000..45900b5204d22184d3621713898f19a24b0edc88
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_calendar.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_download.png b/app/src/main/res/drawable-hdpi/ic_download.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c614590ecfaf46600b184246b291a3c1d32692d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_download.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_login.png b/app/src/main/res/drawable-hdpi/ic_login.png
new file mode 100644
index 0000000000000000000000000000000000000000..abdfc916bac5477883bbd6539fe007edd16972c3
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_login.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_calendar.png b/app/src/main/res/drawable-mdpi/ic_calendar.png
new file mode 100644
index 0000000000000000000000000000000000000000..8a4b66a35466df4297e88b716137b9941d08cab3
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_calendar.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_download.png b/app/src/main/res/drawable-mdpi/ic_download.png
new file mode 100644
index 0000000000000000000000000000000000000000..94506fcc503df3ab86404a8ec0ca1fb43d58cb63
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_download.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_login.png b/app/src/main/res/drawable-mdpi/ic_login.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ec22cf526cec302eace27ed42996384024fd162
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_login.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_calendar.png b/app/src/main/res/drawable-xhdpi/ic_calendar.png
new file mode 100644
index 0000000000000000000000000000000000000000..506e47b544918f67d3930ba134e610ce1f4bb176
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_calendar.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_download.png b/app/src/main/res/drawable-xhdpi/ic_download.png
new file mode 100644
index 0000000000000000000000000000000000000000..3caed0d3d3ecbd57e4d3e1b255da73ea3fa8c724
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_download.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_login.png b/app/src/main/res/drawable-xhdpi/ic_login.png
new file mode 100644
index 0000000000000000000000000000000000000000..469fcc0c804cf621497dce16d32b803a64d48fef
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_login.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_calendar.png b/app/src/main/res/drawable-xxhdpi/ic_calendar.png
new file mode 100644
index 0000000000000000000000000000000000000000..57e81fd2d33ec8422aceaf72024b4d5fbc3beba1
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_calendar.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_download.png b/app/src/main/res/drawable-xxhdpi/ic_download.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd7b6b75f831af271a8b027b398a3f8870a53cb3
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_download.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_login.png b/app/src/main/res/drawable-xxhdpi/ic_login.png
new file mode 100644
index 0000000000000000000000000000000000000000..635946f3249219620708901c70508fb2a2d660de
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_login.png differ
diff --git a/app/src/main/res/drawable/ic_dashboard_black_24dp.xml b/app/src/main/res/drawable/ic_dashboard_black_24dp.xml
new file mode 100644
index 0000000000000000000000000000000000000000..46fc8deec32bb06fedfe594815e568e3a6bf48b9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_dashboard_black_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
+</vector>
diff --git a/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/src/main/res/drawable/ic_home_black_24dp.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f8bb0b55633d3e41228e9e285149af5f1d839d08
--- /dev/null
+++ b/app/src/main/res/drawable/ic_home_black_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
+</vector>
diff --git a/app/src/main/res/drawable/ic_notifications_black_24dp.xml b/app/src/main/res/drawable/ic_notifications_black_24dp.xml
new file mode 100644
index 0000000000000000000000000000000000000000..78b75c39b55bc3cbbc18bfe7d9165fb3da7d03ff
--- /dev/null
+++ b/app/src/main/res/drawable/ic_notifications_black_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
+</vector>
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..38c0aa8c56c73a05036c611a0197616887e2d4de
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingTop="?attr/actionBarSize">
+
+    <com.google.android.material.bottomnavigation.BottomNavigationView
+        android:id="@+id/nav_view"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="0dp"
+        android:layout_marginEnd="0dp"
+        android:background="?android:attr/windowBackground"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:menu="@menu/bottom_nav_menu" />
+
+    <fragment
+        android:id="@+id/nav_host_fragment"
+        android:name="androidx.navigation.fragment.NavHostFragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:defaultNavHost="true"
+        app:layout_constraintBottom_toTopOf="@id/nav_view"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:navGraph="@navigation/mobile_navigation" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_download.xml b/app/src/main/res/layout/dialog_download.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0feed7dd19277f69d39f2a0fefe14180491cf807
--- /dev/null
+++ b/app/src/main/res/layout/dialog_download.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:custom="http://schemas.android.com/apk/res-auto">
+
+    <com.github.lzyzsd.circleprogress.CircleProgress
+        android:id="@+id/circle_progress"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        custom:circle_progress="0"
+        custom:layout_constraintBottom_toTopOf="@id/progress_text"
+        custom:layout_constraintEnd_toEndOf="parent"
+        custom:layout_constraintStart_toStartOf="parent"
+        custom:layout_constraintTop_toTopOf="parent" />
+    <TextView
+        android:id="@+id/progress_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:layout_marginBottom="30dp"
+        custom:layout_constraintEnd_toEndOf="parent"
+        custom:layout_constraintStart_toStartOf="parent"
+        custom:layout_constraintTop_toBottomOf="@id/circle_progress"
+        custom:layout_constraintBottom_toBottomOf="parent" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_loading.xml b/app/src/main/res/layout/dialog_loading.xml
new file mode 100644
index 0000000000000000000000000000000000000000..305c462076498c58e49c7739b23eb8bc2ad725f6
--- /dev/null
+++ b/app/src/main/res/layout/dialog_loading.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ProgressBar
+        android:id="@+id/progressBar"
+        style="?android:attr/progressBarStyle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_login.xml b/app/src/main/res/layout/dialog_login.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1d135e4f60a3475ed1fd1d19501fec16245796e0
--- /dev/null
+++ b/app/src/main/res/layout/dialog_login.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/loginLbl"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/login_login"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <com.google.android.material.textfield.TextInputEditText
+        android:id="@+id/loginInput"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:ems="60"
+        android:inputType="text"
+        android:hint="prenom.nom"
+        android:layout_marginTop="5dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/loginLbl" />
+
+    <TextView
+        android:id="@+id/passwordLbl"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/login_password"
+        android:layout_marginTop="30dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/loginInput" />
+
+    <com.google.android.material.textfield.TextInputLayout
+        android:id="@+id/passwordLayout"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        app:passwordToggleEnabled="true"
+        android:layout_marginTop="5dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/passwordLbl">
+
+        <com.google.android.material.textfield.TextInputEditText
+            android:id="@+id/passwordInput"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:inputType="textWebPassword"
+            android:hint="••••••••••••"/>
+
+    </com.google.android.material.textfield.TextInputLayout>
+
+    <CheckBox
+        android:id="@+id/rememberMe"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dp"
+        android:layout_marginBottom="50dp"
+        android:text="Enregistrer les informations"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/passwordLayout" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_calendar.xml b/app/src/main/res/layout/fragment_calendar.xml
new file mode 100644
index 0000000000000000000000000000000000000000..166ab0e9e603c1f230a7b9514d293b963ab2309e
--- /dev/null
+++ b/app/src/main/res/layout/fragment_calendar.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ui.dashboard.DashboardFragment">
+
+    <TextView
+        android:id="@+id/text_dashboard"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="8dp"
+        android:textAlignment="center"
+        android:textSize="20sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f3d9b08ffe6101e25c77c5fae7e28bb5dfa11fbd
--- /dev/null
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ui.home.HomeFragment">
+
+    <TextView
+        android:id="@+id/text_home"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="8dp"
+        android:textAlignment="center"
+        android:textSize="20sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d41793572bb3b8347ec4bced74b7bd4a43bed5d4
--- /dev/null
+++ b/app/src/main/res/layout/fragment_notifications.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ui.notifications.NotificationsFragment">
+
+    <TextView
+        android:id="@+id/text_notifications"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="8dp"
+        android:textAlignment="center"
+        android:textSize="20sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/menu/appbar_menu.xml b/app/src/main/res/menu/appbar_menu.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a219eba20b81da30855c9c342aac1480443167f2
--- /dev/null
+++ b/app/src/main/res/menu/appbar_menu.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/connect_menuitem"
+        android:icon="@drawable/ic_login"
+        android:orderInCategory="0"
+        android:title="Connexion"
+        app:showAsAction="ifRoom|withText" />
+</menu>
\ No newline at end of file
diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5485a387264f4737d0244d6064b7ed39ad81e5aa
--- /dev/null
+++ b/app/src/main/res/menu/bottom_nav_menu.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/navigation_home"
+        android:icon="@drawable/ic_home_black_24dp"
+        android:title="@string/title_home" />
+
+    <item
+        android:id="@+id/navigation_dashboard"
+        android:icon="@drawable/ic_calendar"
+        android:title="@string/title_calendar" />
+
+    <item
+        android:id="@+id/navigation_notifications"
+        android:icon="@drawable/ic_notifications_black_24dp"
+        android:title="@string/title_notifications" />
+
+</menu>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000000000000000000000000000000000000..036d09bc5fd523323794379703c4a111d1e28a04
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/ic_launcher_background"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000000000000000000000000000000000000..036d09bc5fd523323794379703c4a111d1e28a04
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/ic_launcher_background"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..575265141fe1f63ffc50a45312df7965588609f2
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..28b0ed042b42ff8b5a196c2f7a1208e9ab84fcd9
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000000000000000000000000000000000000..575265141fe1f63ffc50a45312df7965588609f2
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8a8cd4b40affd65af7fc90bea46fb93cd064341
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b990032028b98b52ab3bb357ac747fc4e07e196
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8a8cd4b40affd65af7fc90bea46fb93cd064341
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..6a12762b797a846a88371c5d8766499736b977c9
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..46253eb6d25182180367e4433fb670029bb0fb58
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000000000000000000000000000000000..6a12762b797a846a88371c5d8766499736b977c9
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..1919c7a7db0aedcd5d13eeb315daed5bb1c98b64
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..d28f2d811dcac0328512f9c2ea17a6e35339cc26
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000000000000000000000000000000000..1919c7a7db0aedcd5d13eeb315daed5bb1c98b64
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..b07abd7593365d8ebec48b9116e2bcbe98020c35
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..f72fa44cd45a3ccf7cf2459fc5a51e37d1e1b1bf
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000000000000000000000000000000000..b07abd7593365d8ebec48b9116e2bcbe98020c35
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aadbe802166818243e2501bc132466071180e66b
--- /dev/null
+++ b/app/src/main/res/navigation/mobile_navigation.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/mobile_navigation"
+    app:startDestination="@+id/navigation_home">
+
+    <fragment
+        android:id="@+id/navigation_home"
+        android:name="fr.nitorac.aurionweb.ui.home.HomeFragment"
+        android:label="@string/title_home"
+        tools:layout="@layout/fragment_home" />
+
+    <fragment
+        android:id="@+id/navigation_dashboard"
+        android:name="fr.nitorac.aurionweb.ui.dashboard.DashboardFragment"
+        android:label="@string/title_calendar"
+        tools:layout="@layout/fragment_calendar" />
+
+    <fragment
+        android:id="@+id/navigation_notifications"
+        android:name="fr.nitorac.aurionweb.ui.notifications.NotificationsFragment"
+        android:label="@string/title_notifications"
+        tools:layout="@layout/fragment_notifications" />
+</navigation>
\ No newline at end of file
diff --git a/app/src/main/res/raw/aurionweb_ensiie_fr.pem b/app/src/main/res/raw/aurionweb_ensiie_fr.pem
new file mode 100644
index 0000000000000000000000000000000000000000..4b1c5b4a412d6e7a8841bb6e09750dc288f05482
--- /dev/null
+++ b/app/src/main/res/raw/aurionweb_ensiie_fr.pem
@@ -0,0 +1,42 @@
+-----BEGIN CERTIFICATE-----
+MIIHTzCCBjegAwIBAgIQCQtdJVL7YaPr+9+02mt9CzANBgkqhkiG9w0BAQsFADBk
+MQswCQYDVQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJ
+QW1zdGVyZGFtMQ8wDQYDVQQKEwZURVJFTkExGDAWBgNVBAMTD1RFUkVOQSBTU0wg
+Q0EgMzAeFw0xODA3MDQwMDAwMDBaFw0yMDEwMDYwMDAwMDBaMIGYMQswCQYDVQQG
+EwJGUjETMBEGA1UEBxMKRVZSWSBDRURFWDFIMEYGA1UECgw/RWNvbGUgTmF0aW9u
+YWxlIFN1cMOpcmlldXJlIGQnaW5mby4gcG91ciBsJ0luZC4gZXQgbCdFbnRyZXBy
+aXNlMQwwCgYDVQQLEwNDUkkxHDAaBgNVBAMTE2F1cmlvbndlYi5lbnNpaWUuZnIw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnNDksvsGjgcM3ThkXVAx5
+xxJXoDUYbnuqdqyi0oA1uSjHVcC+4UgA2lw+ZY/FeCG7weAPejGZqqZhY6vEq54M
+hysnNZH3VDgFUeixq1D8gEjOxkdOwXm88utvplan3PgcOIckt2BjsEbfxseX1v4u
+4VDH5/99MeTBeAjxrknZPjWdILiPMx/9BgKKOHbfXhrKZoeZ6bfsEoVzKWjlAqPP
+rxBYbAeX4kFZE0VWLrlqs2VNzKfsmvfm+GAKKf8h0iRlUM1lG8bBsmfxb0pjg9Tm
+mVJgr2+8R89V1j59hFiBHjfyqYoSJNirUlhXuGFKeGOBzJm4jDReWHPe5BBthnk3
+AgMBAAGjggPGMIIDwjAfBgNVHSMEGDAWgBRn/YggFCeYxwnSJRm76VERY3VQYjAd
+BgNVHQ4EFgQU9RX+8yvm3V3rbDKQz3s6FJegGqAwHgYDVR0RBBcwFYITYXVyaW9u
+d2ViLmVuc2lpZS5mcjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUH
+AwEGCCsGAQUFBwMCMGsGA1UdHwRkMGIwL6AtoCuGKWh0dHA6Ly9jcmwzLmRpZ2lj
+ZXJ0LmNvbS9URVJFTkFTU0xDQTMuY3JsMC+gLaArhilodHRwOi8vY3JsNC5kaWdp
+Y2VydC5jb20vVEVSRU5BU1NMQ0EzLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG/WwB
+ATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAgG
+BmeBDAECAjBuBggrBgEFBQcBAQRiMGAwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3Nw
+LmRpZ2ljZXJ0LmNvbTA4BggrBgEFBQcwAoYsaHR0cDovL2NhY2VydHMuZGlnaWNl
+cnQuY29tL1RFUkVOQVNTTENBMy5jcnQwDAYDVR0TAQH/BAIwADCCAfYGCisGAQQB
+1nkCBAIEggHmBIIB4gHgAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN
+3BAAAAFkZD6SfgAABAMARzBFAiEAhqeRjwyl7IWrb46mS4n+I31HxLNhDDLn9jEi
+VN3Cip0CIDqnppqzhC6e3RHYFTXrvkdQjrzAw/LRtgJ+M9J2idNPAHYAh3W/51l8
++IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8AAAFkZD6TUwAABAMARzBFAiEA/CFX
+dd1HUPCDZjMz+oqicI6H7UCUKTO1Y9ojCJwUFzECIGOU4F7s2gyV7j8rm/xF3Vw/
+jeP1nDWDpO/bs+6JO6XtAHcA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo
+/csAAAFkZD6SwQAABAMASDBGAiEAuWbkrYVras5GeloBf4224WOv+ZRg+QV3xQGn
+MmVTFtICIQCz73qOSo/HyT1Ctak7NWYwHlW/bRIu61Ol+U7LxZr01wB1ALvZ37wf
+inG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABZGQ+k3MAAAQDAEYwRAIgcZDt
+pPgy3Jd100lSKUGqIPZ9okT8S2Q3umjmM+52DPICIBeX+iCxSIiIF3wQAo+B22Qo
+GUzYVMEqpV5jN2iI4Y5VMA0GCSqGSIb3DQEBCwUAA4IBAQASfy7UQIOWiJhSSxJj
+xwxhe1uyVn/+JNbaqNyDGGz0uL8hGZTt6SUGrjV+/RMnL0l8d5eApe73Chr5VcYn
+3kcuY4B3EKzMEonuGuMOJmPzk65YWk015lHJc0t+GOMi0BN1Ven/DweDRlxIb18w
+CM/Tvua27q0PBGPDjQ1m+QRZ9gaEU1XyqD7Cts4SFfjwxZL4EjAz/dQFsGfB4a4Z
+l3l94e7vGZfMUOoORFkrV55Qm5zqodQyRv6A46M1v6+kfVMUPyppVCM2F54EPw6M
+7r6RULICwobirLXdT4CajKB4bOIjm0e09zLzuij4TLAo34mOATG9DYV2HOFRsCem
+NJBE
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/app/src/main/res/raw/cas_ensiie_fr.pem b/app/src/main/res/raw/cas_ensiie_fr.pem
new file mode 100644
index 0000000000000000000000000000000000000000..de4efbe1faf01b92c9c4cfe23c5ce8d00d4bffb6
--- /dev/null
+++ b/app/src/main/res/raw/cas_ensiie_fr.pem
@@ -0,0 +1,41 @@
+-----BEGIN CERTIFICATE-----
+MIIHPTCCBiWgAwIBAgIQBWafOeFdJ+iHekwJBoSBCDANBgkqhkiG9w0BAQsFADBk
+MQswCQYDVQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJ
+QW1zdGVyZGFtMQ8wDQYDVQQKEwZURVJFTkExGDAWBgNVBAMTD1RFUkVOQSBTU0wg
+Q0EgMzAeFw0yMDA0MDcwMDAwMDBaFw0yMjA3MTEwMDAwMDBaMIGNMQswCQYDVQQG
+EwJGUjENMAsGA1UEBxMERVZSWTFIMEYGA1UECgw/RWNvbGUgTmF0aW9uYWxlIFN1
+cMOpcmlldXJlIGQnaW5mby4gcG91ciBsJ0luZC4gZXQgbCdFbnRyZXByaXNlMQ0w
+CwYDVQQLEwRESVNJMRYwFAYDVQQDEw1jYXMuZW5zaWllLmZyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEApH5oCBw+lp1LzM5gvsWMXB2rdTUOcyD1elfk
+lOAUvl5tkQxHhnSOQo6Ywnf6vKP7GF5yqT6sCqDZxHxITXY1YgHlkageW90Rvlga
+OkswpHT6l0wN0msQVFpUZAV94LY2LqgPzcDgdCqS9fW17S6jNlNezlCVCS4eYFos
+og//D3LU4WWOlFIbeq0BiEyR2SsSvgrtm3IVA9At5EoXL5f8nxGJetCz9K0Okm/P
+R/EK7zIEU/UsmLlUSn8mBbgd63/jBRvzvKYPZyLFhPgdLiEyLRADMLGfoKFU4IND
+aj5WiN9CnjePzbrViON7rXAoFGa6WmsIjP3FPqg/9VHti2DrdwIDAQABo4IDvzCC
+A7swHwYDVR0jBBgwFoAUZ/2IIBQnmMcJ0iUZu+lREWN1UGIwHQYDVR0OBBYEFLTb
+kMQmJI6GUM30mxKHpH0GABEYMBgGA1UdEQQRMA+CDWNhcy5lbnNpaWUuZnIwDgYD
+VR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNV
+HR8EZDBiMC+gLaArhilodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vVEVSRU5BU1NM
+Q0EzLmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL1RFUkVOQVNT
+TENBMy5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYc
+aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwbgYIKwYBBQUH
+AQEEYjBgMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wOAYI
+KwYBBQUHMAKGLGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9URVJFTkFTU0xD
+QTMuY3J0MAwGA1UdEwEB/wQCMAAwggH1BgorBgEEAdZ5AgQCBIIB5QSCAeEB3wB2
+AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABcVPmeiEAAAQDAEcw
+RQIgGnTSe4WZ+XAc94FW3+X33bHh4545LfhedHfqve1b5ncCIQDX5U6yy0UPHH/v
+sF63PRbAUQVYTwHtgjMTD+myHdxI4wB1ACJFRQdZVSRWlj+hL/H3bYbgIyZjrcBL
+f13Gg1xu4g8CAAABcVPmek4AAAQDAEYwRAIgcwGGmxrOD1rnHTNR4RJBcZWuoG2U
+h49ZVhsw+egrqm0CIDit+elupvyTGMggdjY8M5O4H3PX7eflWkX00B93Z67EAHcA
+UaOw9f0BeZxWbbg3eI8MpHrMGyfL956IQpoN/tSLBeUAAAFxU+Z6kQAABAMASDBG
+AiEA7MqBM8nCli74ADm2yZNkQNBG5maK7mz7Nt/cbSxkuGQCIQCIeCd4y+EUnoSD
+7aksYyn0qOn7SY5n4AZypyjG7UDjMgB1AEHIyrHfIkZKEMahOglCh15OMYsbA+vr
+S8do8JBilgb2AAABcVPmef8AAAQDAEYwRAIgSYstHo0iQh3A5/xtP7/pU/GvMuDK
+FEYMiEk5AG8pJzACIDp/cFGRQoeVbbzdGR+dYzhkVMmSoOpuqCCwZZNlm3hIMA0G
+CSqGSIb3DQEBCwUAA4IBAQAIGGzSixN4XaiJvG5MAW7Awo5FaXXf4jbKABuQ2x/a
+6XpOy1eh9uqYYF6MHJqdLo63KtO+aKowS7OLQHtlDw/Zgtr1mnBt6xLA8BiFzy2+
+QFiA4d46iB1dkGecbnMNftXt99WQQFC72VO4hlmZDYUcjFcjRfqceDUojgYMtq4R
+6npY8Sb0IPFWWPhWYYwIdboeRmEurKgz2nVDfFaEmQnJzKHfMclIXUSXGqgR7lV2
+FnSEJFJ3x1ef/gT4S/dIA72/mxUT8tovul4RS9pCXSOBe6VlJa4WcwkM7IrBwjsJ
+j51+5I7zk8RjE+JOxXJFfM/bUGJ1vmSW8vdXiMTybVIB
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..86ad9fe4787a22eebcd957e46c59e806f492a76d
--- /dev/null
+++ b/app/src/main/res/values-fr-rFR/strings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">AurionWeb</string>
+    <string name="title_home">Accueil</string>
+    <string name="dialog_update_title">Mise à jour</string>
+    <string name="dialog_update_msg">Une mise à jour est disponible !\n(%1$s -> %2$s)\n\nChangements :\n%3$s\n\nVoulez-vous mettre à jour ?</string>
+    <string name="login_login">Nom d\'utilisateur</string>
+    <string name="login_password">Mot de passe</string>
+    <string name="title_calendar">Emploi du temps</string>
+    <string name="loading">Chargement ...</string>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fd454c4279ee3361b6c83c1c4d2775c3a9fd5ee6
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#42A5F5</color>
+    <color name="colorPrimaryDark">#3F51B5</color>
+    <color name="colorAccent">#F44336</color>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e00c2dd143c595389b3cf8a32d9dc6aff48ec367
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35a7725424991e727b5deed53440fd837cc2584f
--- /dev/null
+++ b/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="ic_launcher_background">#3D2E27</color>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6dd03453f84cb8545fa58bd7c0ad8ef7ef76b8cf
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+<resources>
+    <string name="app_name">AurionWeb</string>
+    <string name="title_home">Home</string>
+    <string name="title_calendar">Calendar</string>
+    <string name="title_notifications">Notifications</string>
+    <string name="dialog_update_title">Update</string>
+    <string name="dialog_update_msg">An update is available !\n(%1$s -> %2$s)\n\nChangelogs:\n%3$s\n\nDo you want to update ?</string>
+    <string name="login_login">Login</string>
+    <string name="login_password">Password</string>
+    <string name="loading">Loading...</string>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f4cf47d48fee4ff8cbb75a75cb9e4c8ed2fe755f
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.DayNight">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+        <item name="md_corner_radius">16dp</item>
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml
new file mode 100644
index 0000000000000000000000000000000000000000..20c6b33c627d7eecfec34e2ea98d1d1e7c5e1bc8
--- /dev/null
+++ b/app/src/main/res/xml/provider_paths.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths>
+    <files-path name="internal_data" path="."/>
+    <cache-path name="cache_data" path="."/>
+</paths>
\ No newline at end of file
diff --git a/app/src/test/java/fr/nitorac/aurionweb/ExampleUnitTest.java b/app/src/test/java/fr/nitorac/aurionweb/ExampleUnitTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b982752841ff13d927e270d96fc36767e625b617
--- /dev/null
+++ b/app/src/test/java/fr/nitorac/aurionweb/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package fr.nitorac.aurionweb;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..bfb75dc907684dc261a7b8f6de4f6996df7dffd6
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,27 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    ext.kotlin_version = '1.4.10'
+    repositories {
+        google()
+        jcenter()
+    }
+    dependencies {
+        classpath "com.android.tools.build:gradle:4.0.1"
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+        maven { url 'https://jitpack.io' }
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c52ac9b79716c6c430b6ad840ffbafc9c3da528a
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,19 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000000000000000000000000000000000..919be2fe32fb04fb62bf796c7a98a3825419c2dd
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Oct 02 17:31:26 CEST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000000000000000000000000000000000000..cccdd3d517fc5249beaefa600691cf150f2fa3e6
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000000000000000000000000000000000000..f9553162f122c71b34635112e717c3e733b5b212
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/local.properties b/local.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ee4e8c4d1bbad491982b23a45f92b48a9a186cd8
--- /dev/null
+++ b/local.properties
@@ -0,0 +1,10 @@
+## This file is automatically generated by Android Studio.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file should *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+# For customization when using a Version Control System, please read the
+# header note.
+sdk.dir=D\:\\Users\\Nitorac\\AppData\\Local\\sdk
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..a8df4e466a60a93401b0ced0bed7b21c11dadeda
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+include ':app'
+rootProject.name = "AurionWeb"
\ No newline at end of file