From 0789a5a597773253c310406b3509367796db1586 Mon Sep 17 00:00:00 2001 From: root <root@LAPTOP-UNSSMRBP.localdomain> Date: Thu, 17 Nov 2022 10:41:18 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20fichier=20docker=20+=20m=C3=A9mo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 48 ++++---- docker-compose.yml | 20 ++++ log/acces.log | 0 log/access.log | 25 +++++ log/error.log | 5 + nginx.conf | 44 ++++++++ note.txt | 28 +++++ www/data/memo.json | 1 + www/index.php | 184 +++++++++++++++++++++++++++++++ www/ressources/css/styles.css | 118 ++++++++++++++++++++ www/ressources/images/coche.svg | 1 + www/ressources/images/delete.svg | 1 + 12 files changed, 451 insertions(+), 24 deletions(-) create mode 100644 docker-compose.yml create mode 100644 log/acces.log create mode 100644 log/access.log create mode 100644 log/error.log create mode 100644 nginx.conf create mode 100644 note.txt create mode 100644 www/data/memo.json create mode 100644 www/index.php create mode 100644 www/ressources/css/styles.css create mode 100644 www/ressources/images/coche.svg create mode 100644 www/ressources/images/delete.svg diff --git a/README.md b/README.md index a849509..68e3dda 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -# Projet nosql - -Le but de ce projet est de constituer une application web simple, avec au moins une page avec un formulaire qui puisse récupérer des données écrites par un utilisateur et qui les persiste dans **au moins deux systemes différents** parmi : -- postgresql -- redis -- mongodb -- neo4j -- elasticsearch - -Le projet doit avoir au moins un fichier docker compose qui orchestre donc au moins 3 docker (un pour la partie server, et un par techno de stockage) - -Je doit pourvoir **git clone**, jouer **docker compose up** pour interagir avec l'interface web, **lancer au moins deux terminaux pour me connecter à chacun des systemes de persistance et constater la persistance**. -La date limite de publication du projet sur github est le 23 novembre. - -### Membres du groupe -DEJEAN Dorian -HESSINI Yanis - -### Choix des technologies -Web : Serveur Nginx avec développement sous PHP -Système de DB : Postgresql et Redis - -### Application développée -Système de mémos partagés (pas de compte utilisateur) +# Projet nosql + +Le but de ce projet est de constituer une application web simple, avec au moins une page avec un formulaire qui puisse récupérer des données écrites par un utilisateur et qui les persiste dans **au moins deux systemes différents** parmi : +- postgresql +- redis +- mongodb +- neo4j +- elasticsearch + +Le projet doit avoir au moins un fichier docker compose qui orchestre donc au moins 3 docker (un pour la partie server, et un par techno de stockage) + +Je doit pourvoir **git clone**, jouer **docker compose up** pour interagir avec l'interface web, **lancer au moins deux terminaux pour me connecter à chacun des systemes de persistance et constater la persistance**. +La date limite de publication du projet sur github est le 23 novembre. + +### Membres du groupe +DEJEAN Dorian +HESSINI Yanis + +### Choix des technologies +Web : Serveur Nginx avec développement sous PHP +Système de DB : Postgresql et Redis + +### Application développée +Système de mémos partagés (pas de compte utilisateur) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..777b4d4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3.8' + +services: + + nginx: + image: nginx:stable-alpine + container_name: nginx + volumes: + - "./www:/usr/share/nginx/html:ro" + - "./log:/var/log/nginx" + - "./nginx.conf:/etc/nginx/nginx.conf:ro" + ports: + - published: 80 + target: 80 + + php: + image: php:7.4-fpm-alpine + container_name: php + volumes: + - "./www:/script:ro" \ No newline at end of file diff --git a/log/acces.log b/log/acces.log new file mode 100644 index 0000000..e69de29 diff --git a/log/access.log b/log/access.log new file mode 100644 index 0000000..c30a4e5 --- /dev/null +++ b/log/access.log @@ -0,0 +1,25 @@ +172.18.0.1 - - [17/Nov/2022:09:19:15 +0000] "GET / HTTP/1.1" 403 548 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.18.0.1 - - [17/Nov/2022:09:19:15 +0000] "GET /favicon.ico HTTP/1.1" 404 548 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.18.0.1 - - [17/Nov/2022:09:19:54 +0000] "GET / HTTP/1.1" 200 87 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:26:33 +0000] "GET / HTTP/1.1" 200 98 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:26:58 +0000] "GET / HTTP/1.1" 200 119 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:31:17 +0000] "GET / HTTP/1.1" 200 76089 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:31:23 +0000] "GET / HTTP/1.1" 200 76055 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:31:35 +0000] "GET / HTTP/1.1" 200 76052 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:45 +0000] "GET / HTTP/1.1" 200 5251 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:45 +0000] "GET /ressources/css/styles.css HTTP/1.1" 200 1822 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:45 +0000] "GET /ressources/images/coche.svg HTTP/1.1" 200 158 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:45 +0000] "GET /ressources/images/delete.svg HTTP/1.1" 200 2550 "http://localhost/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:49 +0000] "GET /index.php?action=supprimer&id=5defb94651ea3 HTTP/1.1" 200 4783 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:49 +0000] "GET /ressources/css/styles.css HTTP/1.1" 304 0 "http://localhost/index.php?action=supprimer&id=5defb94651ea3" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:49 +0000] "GET /ressources/images/coche.svg HTTP/1.1" 304 0 "http://localhost/index.php?action=supprimer&id=5defb94651ea3" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:49 +0000] "GET /ressources/images/delete.svg HTTP/1.1" 304 0 "http://localhost/index.php?action=supprimer&id=5defb94651ea3" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:34:50 +0000] "GET /index.php?action=supprimer&id=5defb9a88e9a3 HTTP/1.1" 200 4791 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:35:17 +0000] "GET /index.php HTTP/1.1" 200 5251 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:35:17 +0000] "GET /ressources/images/coche.svg HTTP/1.1" 304 0 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:35:17 +0000] "GET /ressources/css/styles.css HTTP/1.1" 304 0 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:35:17 +0000] "GET /ressources/images/delete.svg HTTP/1.1" 304 0 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:35:27 +0000] "GET /index.php HTTP/1.1" 200 5251 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:35:27 +0000] "GET /ressources/images/coche.svg HTTP/1.1" 304 0 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:35:27 +0000] "GET /ressources/css/styles.css HTTP/1.1" 304 0 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" +172.19.0.1 - - [17/Nov/2022:09:35:27 +0000] "GET /ressources/images/delete.svg HTTP/1.1" 304 0 "http://localhost/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" "-" diff --git a/log/error.log b/log/error.log new file mode 100644 index 0000000..366fd20 --- /dev/null +++ b/log/error.log @@ -0,0 +1,5 @@ +2022/11/17 09:19:15 [error] 30#30: *1 directory index of "/usr/share/nginx/html/" is forbidden, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost" +2022/11/17 09:19:15 [error] 30#30: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.18.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/" +2022/11/17 09:22:24 [emerg] 1#1: host not found in upstream "web-php" in /etc/nginx/nginx.conf:39 +2022/11/17 09:25:07 [emerg] 1#1: host not found in upstream "web-php" in /etc/nginx/nginx.conf:39 +2022/11/17 09:25:55 [emerg] 1#1: host not found in upstream "web-php" in /etc/nginx/nginx.conf:39 diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..861c0b4 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,44 @@ +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + + sendfile on; + keepalive_timeout 65; + server_tokens off; + + server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.php index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location ~ \.php$ { + root /usr/share/nginx/html; + include fastcgi_params; + fastcgi_pass php:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME /script$fastcgi_script_name; + } + } +} \ No newline at end of file diff --git a/note.txt b/note.txt new file mode 100644 index 0000000..fa6d1c7 --- /dev/null +++ b/note.txt @@ -0,0 +1,28 @@ + + postgres: + image: postgres:latest + restart: unless-stopped + container_name: postgres + environment: + HOSTNAME: postgres + POSTGRES_USER: user + POSTGRES_PASSWORD: password + ports: + - published: 5432 + target: 5432 + volumes: + - postgres_data:/var/lib/postgresdata/data:rw + + redis: + image: redis:latest + restart: unless-stopped + container_name: redis + ports: + - published: 6379 + target: 6379 + volumes: + - redis_data:/var/lib/redisdata/data:rw + +volumes: + postgres_data: + redis_data: \ No newline at end of file diff --git a/www/data/memo.json b/www/data/memo.json new file mode 100644 index 0000000..1e39478 --- /dev/null +++ b/www/data/memo.json @@ -0,0 +1 @@ +{"5defb94651ea3":{"texte":"finir le tp de prog web","accomplie":true,"dateAjout":"2019-12-10T15:27:02.000Z"},"5defb9a88e9a3":{"texte":"finir le tp d'animation ","accomplie":false,"dateAjout":"2019-12-10T15:28:40.000Z"},"5defbc36499e1":{"texte":"finir le tp de design","accomplie":true,"dateAjout":"2019-12-10T15:39:34.000Z"},"5defbc3f62e43":{"texte":"finir le tp de 3D","accomplie":false,"dateAjout":"2019-12-10T15:39:43.000Z"},"5defbc4b20c23":{"texte":"finir le tp de bdd","accomplie":false,"dateAjout":"2019-12-10T15:39:55.000Z"},"5defbc7418ff8":{"texte":"finir le tp de vid\u00e9o ","accomplie":true,"dateAjout":"2019-12-10T15:40:36.000Z"}} \ No newline at end of file diff --git a/www/index.php b/www/index.php new file mode 100644 index 0000000..cf4a8f7 --- /dev/null +++ b/www/index.php @@ -0,0 +1,184 @@ +<script> + + + if(typeof window.history.pushState == 'function') { + window.history.pushState({}, "Hide", '<?php echo $_SERVER['PHP_SELF'];?>'); + } + +</script> + +<?php + +/************************************************* + * + * 0) Récupérer les tâches du fichier de données + * + * **********************************************/ + +$tachesFichier = "data/memo.json"; +$tachesJSON = file_get_contents($tachesFichier); + + +$tachesArray = json_decode($tachesJSON, true); +$tachesFilter = $tachesArray; + + + + +/*********************** + * + * 1) Ajouter une tâche + * + * ********************/ + + + +if (isset($_POST["texteTache"])) { + $texte = $_POST["texteTache"]; + + + $idTache = uniqid(); + + + + $dateHeureTache = gmdate('Y-m-d\TH:i:s.v\Z'); + + + + + $tachesArray[$idTache] = [ + "texte" => $texte, + "accomplie" => false, + "dateAjout" => $dateHeureTache, + ]; + + + + + $tachesJSON = json_encode($tachesArray); + + + file_put_contents($tachesFichier, $tachesJSON); +} + + +/************************************************************* + * + * 2) Afficher les tâches : Voir ci-dessous dans le code HTML + * + * **********************************************************/ + + +/************************ + * + * 3) Filtrer les tâches + * + * *********************/ + + + + +if (isset($_GET["action"]) && $_GET["action"] == "filtrer") { + + + + + + + + if(isset($_GET["accomplie"]) && $_GET["accomplie"]==="1"){ + $tachesArray=array_filter($tachesArray,function($p){ + return ($p["accomplie"] == true); + }); + } + if(isset($_GET["accomplie"]) && $_GET["accomplie"]==="0"){ + $tachesArray=array_filter($tachesArray,function($p){ + return ($p["accomplie"] == false); + }); + } +} + +/********************************* + * + * 4) Basculer l'état d'une tâche + * + * ******************************/ + + +if (isset($_GET["action"]) && $_GET["action"]=="basculer" && isset($_GET["id"])) { + + $tachesArray[$_GET["id"]]["accomplie"] = !$tachesArray[$_GET["id"]]["accomplie"]; + + + $tachesJSON = json_encode($tachesArray); + + + file_put_contents($tachesFichier, $tachesJSON); +} + +if (isset($_GET["action"]) && $_GET["action"]=="supprimer" && isset($_GET["id"])) { + + unset($tachesArray[$_GET["id"]]); + + + $tachesJSON = json_encode($tachesArray); + + + file_put_contents($tachesFichier, $tachesJSON); +} + +?> + +<!DOCTYPE html> +<html> + +<head> + <meta charset="UTF-8"> + <title>MEMO | Liste de tâches à compléter</title> + <meta name="description" content="Application Web de gestion de tâches à compléter."> + <link rel="stylesheet" href="ressources/css/styles.css"> +</head> + +<body> + <div class="conteneur"> + <a href="index.php"> + <h1>MEMO</h1> + </a> + <form method="post" autocomplete="off"> + <input autofocus class="quoi-faire" type="text" name="texteTache" placeholder="Tâche à accomplir ..."> + </form> + <div class="filtres"> + <!-- Les liens suivants permettent de filtrer les tâches --> + <a href="index.php?action=filtrer&accomplie=1">Complétées</a> + <a href="index.php?action=filtrer&accomplie=0">Non-complétées</a> + <a href="index.php">Toutes</a> + </div> + <ul class="liste-taches"> + <!-- + Utilisez les éléments LI suivants comme gabarits pour l'affichage + des "tâches". + + Remarquez la présence de la classe "accomplie" sur l'élément LI pour le montrer + biffé (complété) ou non (dépend de la valeur du champ "accomplie" dans le fichier JSON). + --> + + <?php + foreach ($tachesArray as $idTache => $infoTache) : + + ?> + + <li class="<?= ($infoTache["accomplie"] === true)?"accomplie":""; ?>"> + <span class="coche done"><a href="?action=basculer&id=<?= $idTache; ?>" title="Cliquez pour faire basculer l'état de cette tâche."><img src="ressources/images/coche.svg" alt=""></a></span> + <span class="texte"><?= $infoTache["texte"]; ?></span> + <span class="ajout"><?= $infoTache["dateAjout"]; ?></span> + <span class="coche"><a href="?action=supprimer&id=<?= $idTache; ?>" title="Cliquez pour supprimer cette tâche."><img src="ressources/images/delete.svg" alt=""></a></span> + </li> + + + <?php endforeach; ?> + + </ul> + </div> +</body> + +</html> \ No newline at end of file diff --git a/www/ressources/css/styles.css b/www/ressources/css/styles.css new file mode 100644 index 0000000..d2db488 --- /dev/null +++ b/www/ressources/css/styles.css @@ -0,0 +1,118 @@ +html { + box-sizing: border-box; +} + +*, *:before, *:after { + box-sizing: inherit; +} + +body { + font-family: Verdana; + font-size: 36px; + color: #444; + background-color: #d5d5d5; + padding: 20px; +} + +a, a:visited, a:link, a:hover { + text-decoration: none; + color: inherit; +} + +.conteneur { + width: 100%; + height: 100%; +} + +h1 { + margin: 0; + margin-bottom: 30px; + text-align: center; + opacity: 0.6; +} + +h1:hover { + opacity: 0.9; +} + +input.quoi-faire { + width: 99%; + padding: 15px; + font-size: 36px; + padding-left: 50px; + box-shadow: 10px 10px 15px 1px #ababab; + border: none; + margin: 20px 0; +} + +div.filtres { + margin-bottom: 0px; + text-align: right; + padding-right: 10px; + font-size: 0.5em; +} + +div.filtres a { + display: inline-block; + padding: 10px; + margin: 5px; + background-color: #333; + color: #eee; + border-radius: 5px; + box-shadow: 5px 5px 10px 1px lightslategrey; +} + +div.filtres a:hover { + background-color: #000; + color: #fff; +} + +ul.liste-taches { + margin-top: 10px; + list-style: none; + padding: 0; + background-color: white; + width: 99%; +} + +ul.liste-taches li { + cursor: default; + border-bottom: 5px solid #d5d5d5; + padding: 40px; + position: relative; +} + +ul.liste-taches li:hover { + background-color: khaki; +} + +ul.liste-taches li span.coche img { + vertical-align: middle; + width: 70px; +} + +ul.liste-taches li.accomplie { + text-decoration: line-through; + opacity: 0.5; +} + +ul.liste-taches li span.ajout { + font-size: 0.5em; + font-family: Georgia; + font-style: italic; + opacity: 0.5; + position: absolute; + bottom: 5px; + right: 5px; +} +.coche { + position: absolute; + top: 10%; + right: 2%; +} + +.done { + position: relative; + left: 0%; + top: 10%; +} \ No newline at end of file diff --git a/www/ressources/images/coche.svg b/www/ressources/images/coche.svg new file mode 100644 index 0000000..18c0051 --- /dev/null +++ b/www/ressources/images/coche.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="-10 -18 100 135"><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg> \ No newline at end of file diff --git a/www/ressources/images/delete.svg b/www/ressources/images/delete.svg new file mode 100644 index 0000000..63e2bd5 --- /dev/null +++ b/www/ressources/images/delete.svg @@ -0,0 +1 @@ +<svg height="427pt" viewBox="-40 0 427 427.00131" width="427pt" xmlns="http://www.w3.org/2000/svg"><path d="m308.601562 62.300781c15.464844 0 28 12.535157 28 28 0 15.464844-12.535156 28-28 28h-270.402343c-15.460938 0-28-12.535156-28-28 0-15.464843 12.539062-28 28-28zm0 0" fill="#00acea"/><path d="m308 118.703125v254.796875c0 25.089844-17.910156 43-40 43h-189.199219c-22.089843 0-40-17.910156-40-43v-255.199219h269.199219zm0 0" fill="#00efd1"/><g fill="#083863"><path d="m232.402344 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.519531 0 10-4.480469 10-10v-189c0-5.523437-4.480469-10-10-10zm0 0"/><path d="m114.402344 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.519531 0 10-4.480469 10-10v-189c0-5.523437-4.480469-10-10-10zm0 0"/><path d="m28.402344 127.121094v246.378906c0 14.5625 5.335937 28.234375 14.667968 38.050781 9.28125 9.839844 22.203126 15.425781 35.730469 15.449219h189.199219c13.527344-.023438 26.449219-5.609375 35.730469-15.449219 9.332031-9.816406 14.671875-23.488281 14.671875-38.050781v-246.367188c6.503906-1.816406 12.445312-5.246093 17.277344-9.96875 10.8125-10.964843 14-27.347656 8.089843-41.570312-5.910156-14.222656-19.765625-23.519531-35.167969-23.59375h-51.199218v-12.5c.058594-10.511719-4.097656-20.605469-11.542969-28.03125-7.441406-7.421875-17.546875-11.5546875-28.058594-11.46875h-88.800781c-10.511719-.0859375-20.617188 4.046875-28.058594 11.46875-7.445312 7.425781-11.601562 17.519531-11.539062 28.03125v12.5h-51.203125c-21.015625.21875-37.996094 17.210938-38.199219 38.226562.101562 17.285157 11.71875 32.378907 28.402344 36.894532zm239.597656 279.878906h-189.199219c-17.101562 0-30.398437-14.6875-30.398437-33.5v-245.5h250v245.5c0 18.8125-13.300782 33.5-30.402344 33.5zm-158.597656-367.5c-.066406-5.207031 1.980468-10.21875 5.671875-13.894531 3.695312-3.675781 8.71875-5.695313 13.925781-5.605469h88.800781c5.207031-.089844 10.230469 1.929688 13.925781 5.605469 3.691407 3.671875 5.738282 8.6875 5.675782 13.894531v12.5h-128zm-83.9375 37.929688c3.355468-3.429688 7.9375-5.382813 12.734375-5.429688h270.402343c9.964844.082031 18 8.1875 18 18.152344-.003906 4.757812-1.90625 9.316406-5.285156 12.667968-3.382812 3.351563-7.957031 5.214844-12.714844 5.179688h-270.402343c-9.921875.023438-17.980469-8.003906-18-17.921875-.007813-4.753906 1.886719-9.308594 5.265625-12.648437zm0 0"/><path d="m173.402344 154.703125c-5.523438 0-10 4.476563-10 10v189c0 5.519531 4.476562 10 10 10 5.519531 0 10-4.480469 10-10v-189c0-5.523437-4.480469-10-10-10zm0 0"/></g></svg> \ No newline at end of file -- GitLab