From e28afb27d75cf0ca842a14aba1e1aa40971c509c Mon Sep 17 00:00:00 2001
From: Lukas Plevac <lukas@plevac.eu>
Date: Sat, 9 Sep 2023 13:58:11 +0200
Subject: [PATCH] working update

---
 docker-compose.yml                          |  12 +
 web/.htaccess                               |   4 +
 web/CONTROLERS/dashboard.php                |   8 -
 web/CONTROLLERS/dashboard.php               |  33 ++
 web/CONTROLLERS/login.php                   |  31 +
 web/CONTROLLERS/observations.php            |  15 +
 web/DAL/receiver.php                        |   2 +-
 web/DAL/station.php                         |   2 +-
 web/DAL/target.php                          |   4 +-
 web/DAL/{targetsType.php => targetType.php} |   0
 web/DAL/transmitter.php                     |   6 +-
 web/Dockerfile                              |   3 +
 web/VIEWS/blocks/alert-danger.html          |  12 +
 web/VIEWS/blocks/nav-item.html              |  10 +
 web/VIEWS/blocks/observation-item.html      |  18 +
 web/VIEWS/dashboard.html                    | 594 ++++++++++++++++++++
 web/VIEWS/layout/head.html                  |  33 +-
 web/VIEWS/layout/header.html                |  39 +-
 web/VIEWS/login.html                        |  44 ++
 web/VIEWS/observations.html                 |  63 +++
 web/dist/js/satellite.min.js                |   8 +
 web/index.php                               |  28 +-
 web/seeds.php                               |  96 ++++
 web/static/icons/antenna.svg                |  11 +
 web/static/icons/dashboard.svg              |   8 +
 web/static/icons/file-analytics.svg         |  10 +
 web/static/icons/focus-2.svg                |  11 +
 web/static/icons/radio.svg                  |  10 +
 web/static/icons/satellite.svg              |  11 +
 web/static/icons/telescope.svg              |   9 +
 web/static/icons/user.svg                   |   7 +
 web/static/icons/wave-sine.svg              |   6 +
 web/wsos                                    |   1 +
 33 files changed, 1106 insertions(+), 43 deletions(-)
 create mode 100644 docker-compose.yml
 create mode 100644 web/.htaccess
 delete mode 100644 web/CONTROLERS/dashboard.php
 create mode 100644 web/CONTROLLERS/dashboard.php
 create mode 100644 web/CONTROLLERS/login.php
 create mode 100644 web/CONTROLLERS/observations.php
 rename web/DAL/{targetsType.php => targetType.php} (100%)
 create mode 100644 web/Dockerfile
 create mode 100644 web/VIEWS/blocks/alert-danger.html
 create mode 100644 web/VIEWS/blocks/nav-item.html
 create mode 100644 web/VIEWS/blocks/observation-item.html
 create mode 100644 web/VIEWS/dashboard.html
 create mode 100644 web/VIEWS/login.html
 create mode 100644 web/VIEWS/observations.html
 create mode 100644 web/dist/js/satellite.min.js
 create mode 100644 web/static/icons/antenna.svg
 create mode 100644 web/static/icons/dashboard.svg
 create mode 100644 web/static/icons/file-analytics.svg
 create mode 100644 web/static/icons/focus-2.svg
 create mode 100644 web/static/icons/radio.svg
 create mode 100644 web/static/icons/satellite.svg
 create mode 100644 web/static/icons/telescope.svg
 create mode 100644 web/static/icons/user.svg
 create mode 100644 web/static/icons/wave-sine.svg
 create mode 160000 web/wsos

diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..e6437db
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,12 @@
+version: '3.8'
+services:
+  RadioMasterWeb:
+    image: radiomasterphp
+    build: ./web
+    volumes:
+      - ./web:/var/www/html/
+    ports:
+      - 8000:80
+
+#  RadioMasterDb:
+#
\ No newline at end of file
diff --git a/web/.htaccess b/web/.htaccess
new file mode 100644
index 0000000..f2b5913
--- /dev/null
+++ b/web/.htaccess
@@ -0,0 +1,4 @@
+RewriteEngine on
+RewriteBase /
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^(.*)$ /index.php [L,QSA]
\ No newline at end of file
diff --git a/web/CONTROLERS/dashboard.php b/web/CONTROLERS/dashboard.php
deleted file mode 100644
index 79b1da9..0000000
--- a/web/CONTROLERS/dashboard.php
+++ /dev/null
@@ -1,8 +0,0 @@
-$container = new \wsos\structs\container();
-
-$templates = $container->get("templateLoader");
-$context   = $container->get("context");
-
-$templates->load("info.html");    
-$templates->render($context);
-$templates->show();
\ No newline at end of file
diff --git a/web/CONTROLLERS/dashboard.php b/web/CONTROLLERS/dashboard.php
new file mode 100644
index 0000000..a6fdb94
--- /dev/null
+++ b/web/CONTROLLERS/dashboard.php
@@ -0,0 +1,33 @@
+<?php
+    $container = new \wsos\structs\container();
+
+    $templates = $container->get("templateLoader");
+    $context   = $container->get("context"); 
+    $auth      = $container->get("auth");
+
+    // to show this page user must be logined
+    $auth->requireLogin();
+
+    $context["successCount"]      = 75;
+    $context["planedCount"]       = 15;
+    $context["lastPlaned"]        = 2;
+    $context["failCount"]         = 5;
+    $context["observationsCount"] = 5;
+    
+    // create planed template observations
+    $planed = new \DAL\observation();
+    $planed->status->set("planed");
+
+    $observationsTable = new \wsos\database\core\table(\DAL\observation::class);
+    $planedTable       = $observationsTable->query("status=?", [$planed->status->value]);
+
+    $observationsLocators = new \wsos\structs\vector();
+    foreach($planedTable->values as $obs) {
+        $observationsLocators->append($obs->locator->get());
+    }
+
+    $context["planedLocators"] = json_encode($observationsLocators->values);
+
+    $templates->load("dashboard.html");    
+    $templates->render($context);
+    $templates->show();
\ No newline at end of file
diff --git a/web/CONTROLLERS/login.php b/web/CONTROLLERS/login.php
new file mode 100644
index 0000000..36d509a
--- /dev/null
+++ b/web/CONTROLLERS/login.php
@@ -0,0 +1,31 @@
+<?php
+    $container = new \wsos\structs\container();
+
+    $templates = $container->get("templateLoader");
+    $context   = $container->get("context");
+    $auth      = $container->get("auth");
+
+    //add basic info to context
+    $context["pagename"] = "login";
+    $context["fail"]     = false;
+    $context["failInfo"] = [];
+
+    //pass login
+    if (isset($_POST["username"]) && isset($_POST["password"])) {
+
+        if ($auth->login($_POST["username"], $_POST["password"])) {
+            header("Location: /");
+            die("logined");
+        }
+
+        $context["fail"] = true;
+        $context["failInfo"] = [
+            "title"       => "Login failed!",
+            "description" => "Login failed because the user does not exist or the correct password was not used. Please try again."
+        ];
+    }
+
+    $templates->load("login.html");    
+    $templates->render($context);
+    $templates->show();
+?>
\ No newline at end of file
diff --git a/web/CONTROLLERS/observations.php b/web/CONTROLLERS/observations.php
new file mode 100644
index 0000000..d6b216f
--- /dev/null
+++ b/web/CONTROLLERS/observations.php
@@ -0,0 +1,15 @@
+<?php
+    $container = new \wsos\structs\container();
+
+    $templates = $container->get("templateLoader");
+    $context   = $container->get("context");
+    $auth      = $container->get("auth");
+
+    // to show this page user must be logined
+    $auth->requireLogin();
+
+    $context["observations"] = new \wsos\database\core\table(\DAL\observation::class);
+
+    $templates->load("observations.html");    
+    $templates->render($context);
+    $templates->show();
\ No newline at end of file
diff --git a/web/DAL/receiver.php b/web/DAL/receiver.php
index 13bd9e9..07b0d64 100644
--- a/web/DAL/receiver.php
+++ b/web/DAL/receiver.php
@@ -17,7 +17,7 @@
             $gain            = 0
         ) {
             parent::__construct($id);
-            $this->object          = new \wsos\database\types\reference($station,     \DAL\station::class);
+            $this->station        = new \wsos\database\types\reference($station,     \DAL\station::class);
             $this->antenna         = new \wsos\database\types\reference($antenna,     \DAL\antenna::class);
 
             $this->centerFrequency = new \wsos\database\types\integer($centerFrequency);
diff --git a/web/DAL/station.php b/web/DAL/station.php
index c1aeb57..77026fd 100644
--- a/web/DAL/station.php
+++ b/web/DAL/station.php
@@ -6,7 +6,7 @@
         public \wsos\database\types\text      $description; 
         public \wsos\database\types\json      $locator; 
 
-        function __construct($id = null, $name = "", $description = "", $locator = ["tle" => null, "gps" => null, "url" => null]) {
+        function __construct($id = null, $name = "", $description = "", $locator = []) {
             parent::__construct($id);
             $this->name        = new \wsos\database\types\text($name);
             $this->description = new \wsos\database\types\text($description);
diff --git a/web/DAL/target.php b/web/DAL/target.php
index 4f84ed4..232cf2e 100644
--- a/web/DAL/target.php
+++ b/web/DAL/target.php
@@ -7,10 +7,10 @@
         public \wsos\database\types\text      $description;
         public \wsos\database\types\json      $locator;      // TLE, GPS or URL locator if avaible
 
-        function __construct($id = null, $name = "", $type = null, $description = "", $locator = ["tle" => null, "gps" => null, "url" => null]) {
+        function __construct($id = null, $name = "", $type = null, $description = "", $locator = []) {
             parent::__construct($id);
             $this->name     = new \wsos\database\types\text($name);
-            $this->type     = new \wsos\database\types\reference($type, );
+            $this->type     = new \wsos\database\types\reference($type, \DAL\targetType::class);
             
             $this->description = new \wsos\database\types\text($description);
             $this->locator     = new \wsos\database\types\json($locator);
diff --git a/web/DAL/targetsType.php b/web/DAL/targetType.php
similarity index 100%
rename from web/DAL/targetsType.php
rename to web/DAL/targetType.php
diff --git a/web/DAL/transmitter.php b/web/DAL/transmitter.php
index eded62a..459a67a 100644
--- a/web/DAL/transmitter.php
+++ b/web/DAL/transmitter.php
@@ -13,7 +13,7 @@
 
         function __construct(
             $id = null,
-            $object = null,
+            $target = null,
             $antenna = null,
             $modulation = null,
             $dataType = null,
@@ -23,11 +23,11 @@
             $processPipe = null
         ) {
             parent::__construct($id);
-            $this->object          = new \wsos\database\types\reference($object,      \DAL\object::class);
+            $this->target          = new \wsos\database\types\reference($target,      \DAL\target::class);
             $this->antenna         = new \wsos\database\types\reference($antenna,     \DAL\antenna::class);
             $this->modulation      = new \wsos\database\types\reference($modulation,  \DAL\modulation::class);
             $this->dataType        = new \wsos\database\types\reference($dataType,    \DAL\dataType::class);
-            $this->object          = new \wsos\database\types\reference($processPipe, \DAL\processPipe::class);
+            $this->processPipe     = new \wsos\database\types\reference($processPipe, \DAL\processPipe::class);
 
             $this->centerFrequency = new \wsos\database\types\integer($centerFrequency);
             $this->bandwidth       = new \wsos\database\types\integer($bandwidth);
diff --git a/web/Dockerfile b/web/Dockerfile
new file mode 100644
index 0000000..0d701a2
--- /dev/null
+++ b/web/Dockerfile
@@ -0,0 +1,3 @@
+FROM php:7-apache
+
+RUN a2enmod rewrite
\ No newline at end of file
diff --git a/web/VIEWS/blocks/alert-danger.html b/web/VIEWS/blocks/alert-danger.html
new file mode 100644
index 0000000..3e4ee41
--- /dev/null
+++ b/web/VIEWS/blocks/alert-danger.html
@@ -0,0 +1,12 @@
+<div class="alert alert-danger" role="alert">
+    <div class="d-flex">
+        <div>
+            <!-- Download SVG icon from http://tabler-icons.io/i/alert-circle -->
+            <svg xmlns="http://www.w3.org/2000/svg" class="icon alert-icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0"></path><path d="M12 8v4"></path><path d="M12 16h.01"></path></svg>
+        </div>
+        <div>
+            <h4 class="alert-title">{% BIND item.title %}</h4>
+            <div class="text-secondary">{% BIND item.description %}</div>
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/web/VIEWS/blocks/nav-item.html b/web/VIEWS/blocks/nav-item.html
new file mode 100644
index 0000000..82c1d9c
--- /dev/null
+++ b/web/VIEWS/blocks/nav-item.html
@@ -0,0 +1,10 @@
+<li class="nav-item {% IF url==item.url USE active %}">
+    <a class="nav-link" href="{% BIND item.url %}" >
+        <span class="nav-link-icon d-md-none d-lg-inline-block">
+            <img class="icon" width="24" height="24" src="{% BIND item.icon %}"></svg>
+        </span>
+        <span class="nav-link-title">
+            {% BIND item.name %}
+        </span>
+    </a>
+</li>
\ No newline at end of file
diff --git a/web/VIEWS/blocks/observation-item.html b/web/VIEWS/blocks/observation-item.html
new file mode 100644
index 0000000..319245a
--- /dev/null
+++ b/web/VIEWS/blocks/observation-item.html
@@ -0,0 +1,18 @@
+<tr onclick="location.href = '/observation/{% BIND item.id %}'">
+    <td>{% BIND item.receiver.station.name %}</td>
+    <td>{% BIND item.transmitter.target.name %}</td>
+    <td>{% BIND item.transmitter.modulation.name %}</td>
+    <td>{% BIND item.transmitter.dataType.name %}</td>
+    <td>{% BIND item.transmitter.centerFrequency %}Hz</td>
+    <td>
+      <span class="badge 
+        {% IF item.status==fail      USE bg-danger %}
+        {% IF item.status==success   USE bg-success %}
+        {% IF item.status==recording USE bg-info %}
+        {% IF item.status==decoding  USE bg-warning %}
+        {% IF item.status==planed    USE bg-primary %}
+      me-1"></span> {% BIND item.status %}
+    </td>
+    <td>{% BIND item.start %}</td>
+    <td>{% BIND item.end %}</td>
+</tr>
\ No newline at end of file
diff --git a/web/VIEWS/dashboard.html b/web/VIEWS/dashboard.html
new file mode 100644
index 0000000..495a445
--- /dev/null
+++ b/web/VIEWS/dashboard.html
@@ -0,0 +1,594 @@
+<!doctype html>
+<html lang="en">
+    {% INCLUDE layout/head.html %}
+    <body>
+        <div class="page">
+            {% BINDINCLUDE layout/header.html logined %}
+
+            <div class="page-header d-print-none mt-4">
+                <div class="container-xl">
+                    <div class="row g-2 align-items-center">
+                        <div class="col">
+                            <!-- Page pre-title -->
+                            <div class="page-pretitle">
+                                Overview
+                            </div>
+                            <h2 class="page-title">
+                                Dashboard
+                            </h2>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="page-body">
+                <div class="container-xl">
+                  <div class="row row-deck row-cards">
+                    
+                    <div class="col-sm-6 col-lg-3">
+                      <div class="card">
+                        <div class="card-body">
+                          <div class="d-flex align-items-center">
+                            <div class="subheader">Success</div>
+                            <div class="ms-auto lh-1">
+                              <span class="text-secondary">Last 7 days</span>
+                            </div>
+                          </div>
+                          <div class="h1 mb-3">{% BIND successCount %}</div>
+                        </div>
+                      </div>
+                    </div>
+
+                    <div class="col-sm-6 col-lg-3">
+                        <div class="card">
+                          <div class="card-body">
+                            <div class="d-flex align-items-center">
+                              <div class="subheader">Fail</div>
+                              <div class="ms-auto lh-1">
+                                <span class="text-secondary">Last 7 days</span>
+                              </div>
+                            </div>
+                            <div class="h1 mb-3">{% BIND failCount %}</div>
+                          </div>
+                        </div>
+                    </div>
+
+                    <div class="col-sm-6 col-lg-3">
+                        <div class="card">
+                          <div class="card-body">
+                            <div class="d-flex align-items-center">
+                              <div class="subheader">Planed</div>
+                              <div class="ms-auto lh-1">
+                                <span class="text-secondary">For {% BIND lastPlaned %} days</span>
+                              </div>
+                            </div>
+                            <div class="h1 mb-3">{% BIND planedCount %}</div>
+                          </div>
+                        </div>
+                    </div>
+
+                    <div class="col-sm-6 col-lg-3">
+                        <div class="card">
+                          <div class="card-body">
+                            <div class="d-flex align-items-center">
+                              <div class="subheader">all</div>
+                              <div class="ms-auto lh-1">
+                                <span class="text-secondary">Last 7 days</span>
+                              </div>
+                            </div>
+                            <div class="h1 mb-3">{% BIND observationsCount %}</div>
+                          </div>
+                        </div>
+                    </div>
+                    
+                    <div class="col-12">
+                      
+                    </div>
+                    
+                    <div class="col-lg-6">
+                      <div class="row row-cards">
+                        <div class="col-12">
+                          <div class="card">
+                            <div class="card-body">
+                              <p class="mb-3">Using Storage <strong>6854.45 MB </strong>of 8 GB</p>
+                              <div class="progress progress-separated mb-3">
+                                <div class="progress-bar bg-primary" role="progressbar" style="width: 44%" aria-label="Regular"></div>
+                                <div class="progress-bar bg-info" role="progressbar" style="width: 19%" aria-label="System"></div>
+                                <div class="progress-bar bg-success" role="progressbar" style="width: 9%" aria-label="Shared"></div>
+                              </div>
+                              <div class="row">
+                                <div class="col-auto d-flex align-items-center pe-2">
+                                  <span class="legend me-2 bg-primary"></span>
+                                  <span>Regular</span>
+                                  <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-secondary">915MB</span>
+                                </div>
+                                <div class="col-auto d-flex align-items-center px-2">
+                                  <span class="legend me-2 bg-info"></span>
+                                  <span>System</span>
+                                  <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-secondary">415MB</span>
+                                </div>
+                                <div class="col-auto d-flex align-items-center px-2">
+                                  <span class="legend me-2 bg-success"></span>
+                                  <span>Shared</span>
+                                  <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-secondary">201MB</span>
+                                </div>
+                                <div class="col-auto d-flex align-items-center ps-2">
+                                  <span class="legend me-2"></span>
+                                  <span>Free</span>
+                                  <span class="d-none d-md-inline d-lg-none d-xxl-inline ms-2 text-secondary">612MB</span>
+                                </div>
+                              </div>
+                            </div>
+                          </div>
+                        </div>
+                        
+                      </div>
+                    </div>
+                    <div class="col-lg-6">
+                        <div class="card">
+                            <div class="card-header border-0">
+                                <div class="card-title">Planed targets map</div>
+                            </div>
+                            <div class="position-relative">
+                                <div id="map" style="height:400px;" class="position-absolute top-0 left-0 px-3 mt-1 w-100">
+                                
+                                </div>
+
+                                <script>
+                                    var map = L.map('map').setView([0, 0], 1);
+                                    var tragetIcon = L.icon({
+                                        iconUrl: '/static/icons/satellite.svg',
+                                        iconSize:     [20, 20],
+                                        shadowSize:   [0, 0],
+                                        iconAnchor:   [10, 10],
+                                        shadowAnchor: [10, 0],
+                                        popupAnchor:  [0, 0]
+                                    });
+
+                                    L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
+                                        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
+                                    }).addTo(map);
+
+                                    var planedLocators = JSON.parse('{% BIND planedLocators %}'.replaceAll("\n", "\\\\n"));
+                                    var targetsMarkers = [];
+
+                                    for (var i = 0; i < planedLocators.length; i++) {
+                                      targetsMarkers.push(L.marker(map.getCenter(), {icon: tragetIcon}).bindPopup(planedLocators[i]["tle"].split("\\n")[0]).addTo(map));
+                                    }
+
+                                    setInterval(function () {
+                                      for (var i = 0; i < planedLocators.length; i++) {
+                                        var planedLocator = planedLocators[i]["tle"].split("\\n");
+                                        
+                                        var satrec = satellite.twoline2satrec(planedLocator[1], planedLocator[2]);
+                                        
+                                        var positionAndVelocity = satellite.propagate(satrec, new Date());
+                                        var gmst = satellite.gstime(new Date());
+
+                                        var positionEci = positionAndVelocity.position;
+                                        var positionGd = satellite.eciToGeodetic(positionEci, gmst);
+                                        
+                                        targetsMarkers[i].setLatLng([satellite.degreesLat(positionGd.latitude), satellite.degreesLong(positionGd.longitude)]);
+                                      }
+                                    }, 1000);
+                                </script>
+                            </div>
+                        </div>
+                    </div>
+                    
+                    
+                    
+                    <div class="col-md-6 col-lg-4">
+                      <div class="card">
+                        <div class="card-header">
+                          <h3 class="card-title">Social Media Traffic</h3>
+                        </div>
+                        <table class="table card-table table-vcenter">
+                          <thead>
+                            <tr>
+                              <th>Network</th>
+                              <th colspan="2">Visitors</th>
+                            </tr>
+                          </thead>
+                          <tbody>
+                            <tr>
+                              <td>Instagram</td>
+                              <td>3,550</td>
+                              <td class="w-50">
+                                <div class="progress progress-xs">
+                                  <div class="progress-bar bg-primary" style="width: 71.0%"></div>
+                                </div>
+                              </td>
+                            </tr>
+                            <tr>
+                              <td>Twitter</td>
+                              <td>1,798</td>
+                              <td class="w-50">
+                                <div class="progress progress-xs">
+                                  <div class="progress-bar bg-primary" style="width: 35.96%"></div>
+                                </div>
+                              </td>
+                            </tr>
+                            <tr>
+                              <td>Facebook</td>
+                              <td>1,245</td>
+                              <td class="w-50">
+                                <div class="progress progress-xs">
+                                  <div class="progress-bar bg-primary" style="width: 24.9%"></div>
+                                </div>
+                              </td>
+                            </tr>
+                            <tr>
+                              <td>TikTok</td>
+                              <td>986</td>
+                              <td class="w-50">
+                                <div class="progress progress-xs">
+                                  <div class="progress-bar bg-primary" style="width: 19.72%"></div>
+                                </div>
+                              </td>
+                            </tr>
+                            <tr>
+                              <td>Pinterest</td>
+                              <td>854</td>
+                              <td class="w-50">
+                                <div class="progress progress-xs">
+                                  <div class="progress-bar bg-primary" style="width: 17.08%"></div>
+                                </div>
+                              </td>
+                            </tr>
+                            <tr>
+                              <td>VK</td>
+                              <td>650</td>
+                              <td class="w-50">
+                                <div class="progress progress-xs">
+                                  <div class="progress-bar bg-primary" style="width: 13.0%"></div>
+                                </div>
+                              </td>
+                            </tr>
+                            <tr>
+                              <td>Pinterest</td>
+                              <td>420</td>
+                              <td class="w-50">
+                                <div class="progress progress-xs">
+                                  <div class="progress-bar bg-primary" style="width: 8.4%"></div>
+                                </div>
+                              </td>
+                            </tr>
+                          </tbody>
+                        </table>
+                      </div>
+                    </div>
+                    
+                    <div class="col-12">
+                      <div class="card">
+                        <div class="card-header">
+                          <h3 class="card-title">Invoices</h3>
+                        </div>
+                        <div class="card-body border-bottom py-3">
+                          <div class="d-flex">
+                            <div class="text-secondary">
+                              Show
+                              <div class="mx-2 d-inline-block">
+                                <input type="text" class="form-control form-control-sm" value="8" size="3" aria-label="Invoices count">
+                              </div>
+                              entries
+                            </div>
+                            <div class="ms-auto text-secondary">
+                              Search:
+                              <div class="ms-2 d-inline-block">
+                                <input type="text" class="form-control form-control-sm" aria-label="Search invoice">
+                              </div>
+                            </div>
+                          </div>
+                        </div>
+                        <div class="table-responsive">
+                          <table class="table card-table table-vcenter text-nowrap datatable">
+                            <thead>
+                              <tr>
+                                <th class="w-1"><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select all invoices"></th>
+                                <th class="w-1">No. <!-- Download SVG icon from http://tabler-icons.io/i/chevron-up -->
+                                  <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-sm icon-thick" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M6 15l6 -6l6 6"></path></svg>
+                                </th>
+                                <th>Invoice Subject</th>
+                                <th>Client</th>
+                                <th>VAT No.</th>
+                                <th>Created</th>
+                                <th>Status</th>
+                                <th>Price</th>
+                                <th></th>
+                              </tr>
+                            </thead>
+                            <tbody>
+                              <tr>
+                                <td><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select invoice"></td>
+                                <td><span class="text-secondary">001401</span></td>
+                                <td><a href="invoice.html" class="text-reset" tabindex="-1">Design Works</a></td>
+                                <td>
+                                  <span class="flag flag-xs flag-country-us me-2"></span>
+                                  Carlson Limited
+                                </td>
+                                <td>
+                                  87956621
+                                </td>
+                                <td>
+                                  15 Dec 2017
+                                </td>
+                                <td>
+                                  <span class="badge bg-success me-1"></span> Paid
+                                </td>
+                                <td>$887</td>
+                                <td class="text-end">
+                                  <span class="dropdown">
+                                    <button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport" data-bs-toggle="dropdown">Actions</button>
+                                    <div class="dropdown-menu dropdown-menu-end">
+                                      <a class="dropdown-item" href="#">
+                                        Action
+                                      </a>
+                                      <a class="dropdown-item" href="#">
+                                        Another action
+                                      </a>
+                                    </div>
+                                  </span>
+                                </td>
+                              </tr>
+                              <tr>
+                                <td><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select invoice"></td>
+                                <td><span class="text-secondary">001402</span></td>
+                                <td><a href="invoice.html" class="text-reset" tabindex="-1">UX Wireframes</a></td>
+                                <td>
+                                  <span class="flag flag-xs flag-country-gb me-2"></span>
+                                  Adobe
+                                </td>
+                                <td>
+                                  87956421
+                                </td>
+                                <td>
+                                  12 Apr 2017
+                                </td>
+                                <td>
+                                  <span class="badge bg-warning me-1"></span> Pending
+                                </td>
+                                <td>$1200</td>
+                                <td class="text-end">
+                                  <span class="dropdown">
+                                    <button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport" data-bs-toggle="dropdown">Actions</button>
+                                    <div class="dropdown-menu dropdown-menu-end">
+                                      <a class="dropdown-item" href="#">
+                                        Action
+                                      </a>
+                                      <a class="dropdown-item" href="#">
+                                        Another action
+                                      </a>
+                                    </div>
+                                  </span>
+                                </td>
+                              </tr>
+                              <tr>
+                                <td><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select invoice"></td>
+                                <td><span class="text-secondary">001403</span></td>
+                                <td><a href="invoice.html" class="text-reset" tabindex="-1">New Dashboard</a></td>
+                                <td>
+                                  <span class="flag flag-xs flag-country-de me-2"></span>
+                                  Bluewolf
+                                </td>
+                                <td>
+                                  87952621
+                                </td>
+                                <td>
+                                  23 Oct 2017
+                                </td>
+                                <td>
+                                  <span class="badge bg-warning me-1"></span> Pending
+                                </td>
+                                <td>$534</td>
+                                <td class="text-end">
+                                  <span class="dropdown">
+                                    <button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport" data-bs-toggle="dropdown">Actions</button>
+                                    <div class="dropdown-menu dropdown-menu-end">
+                                      <a class="dropdown-item" href="#">
+                                        Action
+                                      </a>
+                                      <a class="dropdown-item" href="#">
+                                        Another action
+                                      </a>
+                                    </div>
+                                  </span>
+                                </td>
+                              </tr>
+                              <tr>
+                                <td><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select invoice"></td>
+                                <td><span class="text-secondary">001404</span></td>
+                                <td><a href="invoice.html" class="text-reset" tabindex="-1">Landing Page</a></td>
+                                <td>
+                                  <span class="flag flag-xs flag-country-br me-2"></span>
+                                  Salesforce
+                                </td>
+                                <td>
+                                  87953421
+                                </td>
+                                <td>
+                                  2 Sep 2017
+                                </td>
+                                <td>
+                                  <span class="badge bg-secondary me-1"></span> Due in 2 Weeks
+                                </td>
+                                <td>$1500</td>
+                                <td class="text-end">
+                                  <span class="dropdown">
+                                    <button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport" data-bs-toggle="dropdown">Actions</button>
+                                    <div class="dropdown-menu dropdown-menu-end">
+                                      <a class="dropdown-item" href="#">
+                                        Action
+                                      </a>
+                                      <a class="dropdown-item" href="#">
+                                        Another action
+                                      </a>
+                                    </div>
+                                  </span>
+                                </td>
+                              </tr>
+                              <tr>
+                                <td><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select invoice"></td>
+                                <td><span class="text-secondary">001405</span></td>
+                                <td><a href="invoice.html" class="text-reset" tabindex="-1">Marketing Templates</a></td>
+                                <td>
+                                  <span class="flag flag-xs flag-country-pl me-2"></span>
+                                  Printic
+                                </td>
+                                <td>
+                                  87956621
+                                </td>
+                                <td>
+                                  29 Jan 2018
+                                </td>
+                                <td>
+                                  <span class="badge bg-danger me-1"></span> Paid Today
+                                </td>
+                                <td>$648</td>
+                                <td class="text-end">
+                                  <span class="dropdown">
+                                    <button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport" data-bs-toggle="dropdown">Actions</button>
+                                    <div class="dropdown-menu dropdown-menu-end">
+                                      <a class="dropdown-item" href="#">
+                                        Action
+                                      </a>
+                                      <a class="dropdown-item" href="#">
+                                        Another action
+                                      </a>
+                                    </div>
+                                  </span>
+                                </td>
+                              </tr>
+                              <tr>
+                                <td><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select invoice"></td>
+                                <td><span class="text-secondary">001406</span></td>
+                                <td><a href="invoice.html" class="text-reset" tabindex="-1">Sales Presentation</a></td>
+                                <td>
+                                  <span class="flag flag-xs flag-country-br me-2"></span>
+                                  Tabdaq
+                                </td>
+                                <td>
+                                  87956621
+                                </td>
+                                <td>
+                                  4 Feb 2018
+                                </td>
+                                <td>
+                                  <span class="badge bg-secondary me-1"></span> Due in 3 Weeks
+                                </td>
+                                <td>$300</td>
+                                <td class="text-end">
+                                  <span class="dropdown">
+                                    <button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport" data-bs-toggle="dropdown">Actions</button>
+                                    <div class="dropdown-menu dropdown-menu-end">
+                                      <a class="dropdown-item" href="#">
+                                        Action
+                                      </a>
+                                      <a class="dropdown-item" href="#">
+                                        Another action
+                                      </a>
+                                    </div>
+                                  </span>
+                                </td>
+                              </tr>
+                              <tr>
+                                <td><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select invoice"></td>
+                                <td><span class="text-secondary">001407</span></td>
+                                <td><a href="invoice.html" class="text-reset" tabindex="-1">Logo &amp; Print</a></td>
+                                <td>
+                                  <span class="flag flag-xs flag-country-us me-2"></span>
+                                  Apple
+                                </td>
+                                <td>
+                                  87956621
+                                </td>
+                                <td>
+                                  22 Mar 2018
+                                </td>
+                                <td>
+                                  <span class="badge bg-success me-1"></span> Paid Today
+                                </td>
+                                <td>$2500</td>
+                                <td class="text-end">
+                                  <span class="dropdown">
+                                    <button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport" data-bs-toggle="dropdown">Actions</button>
+                                    <div class="dropdown-menu dropdown-menu-end">
+                                      <a class="dropdown-item" href="#">
+                                        Action
+                                      </a>
+                                      <a class="dropdown-item" href="#">
+                                        Another action
+                                      </a>
+                                    </div>
+                                  </span>
+                                </td>
+                              </tr>
+                              <tr>
+                                <td><input class="form-check-input m-0 align-middle" type="checkbox" aria-label="Select invoice"></td>
+                                <td><span class="text-secondary">001408</span></td>
+                                <td><a href="invoice.html" class="text-reset" tabindex="-1">Icons</a></td>
+                                <td>
+                                  <span class="flag flag-xs flag-country-pl me-2"></span>
+                                  Tookapic
+                                </td>
+                                <td>
+                                  87956621
+                                </td>
+                                <td>
+                                  13 May 2018
+                                </td>
+                                <td>
+                                  <span class="badge bg-success me-1"></span> Paid Today
+                                </td>
+                                <td>$940</td>
+                                <td class="text-end">
+                                  <span class="dropdown">
+                                    <button class="btn dropdown-toggle align-text-top" data-bs-boundary="viewport" data-bs-toggle="dropdown">Actions</button>
+                                    <div class="dropdown-menu dropdown-menu-end">
+                                      <a class="dropdown-item" href="#">
+                                        Action
+                                      </a>
+                                      <a class="dropdown-item" href="#">
+                                        Another action
+                                      </a>
+                                    </div>
+                                  </span>
+                                </td>
+                              </tr>
+                            </tbody>
+                          </table>
+                        </div>
+                        <div class="card-footer d-flex align-items-center">
+                          <p class="m-0 text-secondary">Showing <span>1</span> to <span>8</span> of <span>16</span> entries</p>
+                          <ul class="pagination m-0 ms-auto">
+                            <li class="page-item disabled">
+                              <a class="page-link" href="#" tabindex="-1" aria-disabled="true">
+                                <!-- Download SVG icon from http://tabler-icons.io/i/chevron-left -->
+                                <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M15 6l-6 6l6 6"></path></svg>
+                                prev
+                              </a>
+                            </li>
+                            <li class="page-item"><a class="page-link" href="#">1</a></li>
+                            <li class="page-item active"><a class="page-link" href="#">2</a></li>
+                            <li class="page-item"><a class="page-link" href="#">3</a></li>
+                            <li class="page-item"><a class="page-link" href="#">4</a></li>
+                            <li class="page-item"><a class="page-link" href="#">5</a></li>
+                            <li class="page-item">
+                              <a class="page-link" href="#">
+                                next <!-- Download SVG icon from http://tabler-icons.io/i/chevron-right -->
+                                <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M9 6l6 6l-6 6"></path></svg>
+                              </a>
+                            </li>
+                          </ul>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+
+            <!-- Tabler Core -->
+            <script src="./dist/js/tabler.min.js?1668287865" defer=""></script>
+        </div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/web/VIEWS/layout/head.html b/web/VIEWS/layout/head.html
index b2332cb..4e00440 100644
--- a/web/VIEWS/layout/head.html
+++ b/web/VIEWS/layout/head.html
@@ -1,5 +1,28 @@
-<!-- CSS files -->
-<link href="./dist/tabler/css/tabler.min.css?1668287865" rel="stylesheet"/>
-<link href="./dist/tabler/css/tabler-flags.min.css?1668287865" rel="stylesheet"/>
-<link href="./dist/tabler/css/tabler-payments.min.css?1668287865" rel="stylesheet"/>
-<link href="./dist/tabler/css/tabler-vendors.min.css?1668287865" rel="stylesheet"/>
\ No newline at end of file
+<head>
+    <meta charset="utf-8"/>
+    
+    <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
+    <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
+    <title>{% BIND pagename %} - RadioMaster</title>
+
+    <!-- CSS files tabler -->
+    <link href="./dist/css/tabler.min.css?1668287865" rel="stylesheet"/>
+    <link href="./dist/css/tabler-flags.min.css?1668287865" rel="stylesheet"/>
+    <link href="./dist/css/tabler-payments.min.css?1668287865" rel="stylesheet"/>
+    <link href="./dist/css/tabler-vendors.min.css?1668287865" rel="stylesheet"/>
+
+    <style>
+      @import url('https://rsms.me/inter/inter.css');
+      :root {
+      	--tblr-font-sans-serif: Inter, -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
+      }
+    </style>
+
+    <!-- JS leafletmaps -->
+    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
+    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
+
+    <!-- JS sattelite.js -->
+    <script src="/dist/js/satellite.min.js"></script>
+
+</head>
\ No newline at end of file
diff --git a/web/VIEWS/layout/header.html b/web/VIEWS/layout/header.html
index c98a566..57a62db 100644
--- a/web/VIEWS/layout/header.html
+++ b/web/VIEWS/layout/header.html
@@ -8,21 +8,38 @@
       <div class="navbar-nav flex-row order-md-last">
         <div class="nav-item dropdown">
           <a href="#" class="nav-link d-flex lh-1 text-reset p-0 show" data-bs-toggle="dropdown" aria-label="Open user menu" aria-expanded="true">
-            <span class="avatar avatar-sm" style="background-image: url({% BIND user.img %})"></span>
+            <span class="avatar avatar-sm" style="background-image: url(/static/icons/user.svg)"></span>
             <div class="d-none d-xl-block ps-2">
-              <div>{% BIND user.name %}</div>
-              <div class="mt-1 small text-muted">{% BIND user.info %}</div>
+              <div>{% BIND item.userName %}</div>
+              <div class="mt-1 small text-muted">{% BIND item.realName %}</div>
             </div>
           </a>
-          <div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow show" data-bs-popper="static">
-            <a href="#" class="dropdown-item">Status</a>
-            <a href="#" class="dropdown-item">Profile</a>
-            <a href="#" class="dropdown-item">Feedback</a>
-            <div class="dropdown-divider"></div>
-            <a href="./settings.html" class="dropdown-item">Settings</a>
-            <a href="./sign-in.html" class="dropdown-item">Logout</a>
+          <div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow" data-bs-popper="static">
+            <a href="/logout" class="dropdown-item">Logout</a>
           </div>
         </div>
       </div>
     </div>
-</header>
\ No newline at end of file
+</header>
+<div class="navbar-expand-md">
+  <div class="collapse navbar-collapse" id="navbar-menu">
+    <div class="navbar navbar-light">
+      <div class="container-xl">
+        <ul class="navbar-nav">
+          {% FOREACH menu_items RENDER blocks/nav-item.html %}
+        </ul>
+        <div class="my-2 my-md-0 flex-grow-1 flex-md-grow-0 order-first order-md-last">
+          <form action="./" method="get" autocomplete="off" novalidate>
+            <div class="input-icon">
+              <span class="input-icon-addon">
+                <!-- Download SVG icon from http://tabler-icons.io/i/search -->
+                <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><circle cx="10" cy="10" r="7" /><line x1="21" y1="21" x2="15" y2="15" /></svg>
+              </span>
+              <input type="text" value="" class="form-control" placeholder="Search…" aria-label="Search in website">
+            </div>
+          </form>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
\ No newline at end of file
diff --git a/web/VIEWS/login.html b/web/VIEWS/login.html
new file mode 100644
index 0000000..1443af7
--- /dev/null
+++ b/web/VIEWS/login.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html lang="en">
+    {% INCLUDE layout/head.html %}
+    <body class=" border-top-wide border-primary d-flex flex-column">
+        <div class="page page-center">
+          <div class="container container-tight py-4">
+            <div class="text-center mb-4">
+              <a href="." class="navbar-brand navbar-brand-autodark">
+                <img src="./static/logo.svg" width="110" height="32" alt="Tabler" class="navbar-brand-image">
+              </a>
+            </div>
+            <div class="card card-md">
+              <div class="card-body">
+                <h2 class="h2 text-center mb-4">Login to your account</h2>
+                
+                {% IF fail==true USE BINDINCLUDE blocks/alert-danger.html failInfo %}
+
+                <form method="post" autocomplete="off" novalidate="">
+                  <div class="mb-3">
+                    <label class="form-label">Username</label>
+                    <input type="text" class="form-control {% IF fail==true USE is-invalid %}" placeholder="albert" name="username" autocomplete="off">
+                  </div>
+                  <div class="mb-2">
+                    <label class="form-label">Password</label>
+                    <div class="input-group input-group-flat">
+                      <input type="password" class="form-control {% IF fail==true USE is-invalid %}" name="password" placeholder="Your password" autocomplete="off">
+                    </div>
+                  </div>
+                  <div class="mb-2"></div>
+                  <div class="form-footer">
+                    <button type="submit" class="btn btn-primary w-100">Sign in</button>
+                  </div>
+                </form>
+              </div>
+            </div>
+          </div>
+          <div class="text-center text-muted mt-3">
+
+          </div>
+        </div>
+        <!-- Tabler Core -->
+        <script src="./dist/js/tabler.min.js?1668287865" defer=""></script>
+    </body>
+</html>
\ No newline at end of file
diff --git a/web/VIEWS/observations.html b/web/VIEWS/observations.html
new file mode 100644
index 0000000..e68a5db
--- /dev/null
+++ b/web/VIEWS/observations.html
@@ -0,0 +1,63 @@
+<!doctype html>
+<html lang="en">
+    {% INCLUDE layout/head.html %}
+    <body>
+        <div class="page">
+            {% BINDINCLUDE layout/header.html logined %}
+
+            <div class="page-header d-print-none mt-4">
+                <div class="container-xl">
+                    <div class="row g-2 align-items-center">
+                        <div class="col">
+                            <!-- Page pre-title -->
+                            <div class="page-pretitle">
+                                stations
+                            </div>
+                            <h2 class="page-title">
+                                Observations
+                            </h2>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="page-body">
+                <div class="container-xl">
+                  <div class="row row-deck row-cards">
+                    
+                    
+                    <div class="col-12">
+                      <div class="card">
+                        <div class="card-header">
+                          <h3 class="card-title">Planed, Successed and Faild</h3>
+                        </div>
+                        <div class="table-responsive">
+                          <table class="table card-table table-vcenter text-nowrap datatable table-hover">
+                            <thead>
+                              <tr>
+                                <th>Station</th>
+                                <th>Target</th>
+                                <th>Modulation</th>
+                                <th>Type</th>
+                                <th>Frequency</th>
+                                <th>Status</th>
+                                <th>Start</th>
+                                <th>End</th>
+                              </tr>
+                            </thead>
+                            <tbody>
+                              {% FOREACH observations RENDER blocks/observation-item.html %}
+                            </tbody>
+                          </table>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+
+            <!-- Tabler Core -->
+            <script src="./dist/js/tabler.min.js?1668287865" defer=""></script>
+        </div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/web/dist/js/satellite.min.js b/web/dist/js/satellite.min.js
new file mode 100644
index 0000000..4d2bdf7
--- /dev/null
+++ b/web/dist/js/satellite.min.js
@@ -0,0 +1,8 @@
+/*!
+ * satellite-js v4.0.0
+ * (c) 2013 Shashwat Kandadai and UCSC
+ * https://github.com/shashwatak/satellite-js
+ * License: MIT
+ */
+
+!function(o,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(o=o||self).satellite=t()}(this,function(){"use strict";var Ho=Math.PI,Yo=2*Ho,m=Ho/180,t=180/Ho,o=398600.5,Ao=6378.137,Bo=60/Math.sqrt(Ao*Ao*Ao/o),zo=Ao*Bo/60,p=1/Bo,Co=.00108262998905,s=-253215306e-14,Uo=-161098761e-14,Do=s/Co,Jo=2/3;function l(o,t){for(var s=[31,o%4==0?29:28,31,30,31,30,31,31,30,31,30,31],e=Math.floor(t),a=1,n=0;n+s[a-1]<e&&a<12;)n+=s[a-1],a+=1;var d=a,i=e-n,r=24*(t-e),c=Math.floor(r);r=60*(r-c);var h=Math.floor(r);return{mon:d,day:i,hr:c,minute:h,sec:60*(r-h)}}function r(o,t,s,e,a,n){var d=6<arguments.length&&void 0!==arguments[6]?arguments[6]:0;return 367*o-Math.floor(7*(o+Math.floor((t+9)/12))*.25)+Math.floor(275*t/9)+s+1721013.5+((d/6e4+n/60+a)/60+e)/24}function x(o,t,s,e,a,n,d){if(o instanceof Date){var i=o;return r(i.getUTCFullYear(),i.getUTCMonth()+1,i.getUTCDate(),i.getUTCHours(),i.getUTCMinutes(),i.getUTCSeconds(),i.getUTCMilliseconds())}return r(o,t,s,e,a,n,d)}function Ro(o,t){var s,e,a,n,d,i,r,c,h,m,p,l,x,g,M,f,u,z,v=o.e3,y=o.ee2,b=o.peo,q=o.pgho,w=o.pho,T=o.pinco,j=o.plo,E=o.se2,F=o.se3,L=o.sgh2,A=o.sgh3,C=o.sgh4,U=o.sh2,D=o.sh3,R=o.si2,S=o.si3,I=o.sl2,_=o.sl3,k=o.sl4,O=o.t,P=o.xgh2,Z=o.xgh3,G=o.xgh4,H=o.xh2,Y=o.xh3,B=o.xi2,J=o.xi3,K=o.xl2,N=o.xl3,Q=o.xl4,V=o.zmol,W=o.zmos,X=t.init,$=t.opsmode,oo=t.ep,to=t.inclp,so=t.nodep,eo=t.argpp,ao=t.mp;z=W+119459e-10*O,"y"===X&&(z=W),u=z+.0335*Math.sin(z);var no=E*(r=.5*(g=Math.sin(u))*g-.25)+F*(c=-.5*g*Math.cos(u)),io=R*r+S*c,ro=I*r+_*c+k*g,co=L*r+A*c+C*g,ho=U*r+D*c;return z=V+.00015835218*O,"y"===X&&(z=V),u=z+.1098*Math.sin(z),h=no+(y*(r=.5*(g=Math.sin(u))*g-.25)+v*(c=-.5*g*Math.cos(u))),l=io+(B*r+J*c),x=ro+(K*r+N*c+Q*g),m=co+(P*r+Z*c+G*g),p=ho+(H*r+Y*c),"n"===X&&(x-=j,m-=q,p-=w,to+=l-=T,oo+=h-=b,n=Math.sin(to),a=Math.cos(to),.2<=to?(eo+=m-=a*(p/=n),so+=p,ao+=x):(s=n*(i=Math.sin(so)),e=n*(d=Math.cos(so)),s+=p*d+l*a*i,e+=-p*i+l*a*d,(so%=Yo)<0&&"a"===$&&(so+=Yo),M=ao+eo+a*so,M+=x+m-l*so*n,f=so,(so=Math.atan2(s,e))<0&&"a"===$&&(so+=Yo),Math.abs(f-so)>Ho&&(so<f?so+=Yo:so-=Yo),eo=M-(ao+=x)-a*so)),{ep:oo,inclp:to,nodep:so,argpp:eo,mp:ao}}function e(o){var t=(o-2451545)/36525,s=-62e-7*t*t*t+.093104*t*t+3164400184.812866*t+67310.54841;return(s=s*m/240%Yo)<0&&(s+=Yo),s}function So(){return(arguments.length<=0?void 0:arguments[0])instanceof Date||1<arguments.length?e(x.apply(void 0,arguments)):e.apply(void 0,arguments)}function Io(o,t){var s,e,a,n,d,i,r,c,h,m,p,l,x,g,M,f,u,z,v,y,b,q,w,T,j,E;o.t=t,o.error=0;var F=o.mo+o.mdot*o.t,L=o.argpo+o.argpdot*o.t,A=o.nodeo+o.nodedot*o.t;c=L,y=F;var C=o.t*o.t;if(q=A+o.nodecf*C,f=1-o.cc1*o.t,u=o.bstar*o.cc4*o.t,z=o.t2cof*C,1!==o.isimp){i=o.omgcof*o.t;var U=1+o.eta*Math.cos(F);y=F+(M=i+o.xmcof*(U*U*U-o.delmo)),c=L-M,l=(p=C*o.t)*o.t,f=f-o.d2*C-o.d3*p-o.d4*l,u+=o.bstar*o.cc5*(Math.sin(y)-o.sinmao),z=z+o.t3cof*p+l*(o.t4cof+o.t*o.t5cof)}b=o.no;var D=o.ecco;if(v=o.inclo,"d"===o.method){x=o.t;var R=function(o){var t,s,e,a,n,d,i,r,c=o.irez,h=o.d2201,m=o.d2211,p=o.d3210,l=o.d3222,x=o.d4410,g=o.d4422,M=o.d5220,f=o.d5232,u=o.d5421,z=o.d5433,v=o.dedt,y=o.del1,b=o.del2,q=o.del3,w=o.didt,T=o.dmdt,j=o.dnodt,E=o.domdt,F=o.argpo,L=o.argpdot,A=o.t,C=o.tc,U=o.gsto,D=o.xfact,R=o.xlamo,S=o.no,I=o.atime,_=o.em,k=o.argpm,O=o.inclm,P=o.xli,Z=o.mm,G=o.xni,H=o.nodem,Y=o.nm,B=.13130908,J=2.8843198,K=.37448087,N=5.7686396,Q=.95240898,V=1.8014998,W=1.050833,X=4.4108898,$=0,oo=0,to=(U+.0043752690880113*C)%Yo;if(_+=v*A,O+=w*A,k+=E*A,H+=j*A,Z+=T*A,0!==c){(0===I||A*I<=0||Math.abs(A)<Math.abs(I))&&(I=0,G=S,P=R),t=0<A?720:-720;for(var so=381;381===so;)d=2!==c?(i=y*Math.sin(P-B)+b*Math.sin(2*(P-J))+q*Math.sin(3*(P-K)),n=G+D,y*Math.cos(P-B)+2*b*Math.cos(2*(P-J))+3*q*Math.cos(3*(P-K))):(e=(r=F+L*I)+r,s=P+P,i=h*Math.sin(e+P-N)+m*Math.sin(P-N)+p*Math.sin(r+P-Q)+l*Math.sin(-r+P-Q)+x*Math.sin(e+s-V)+g*Math.sin(s-V)+M*Math.sin(r+P-W)+f*Math.sin(-r+P-W)+u*Math.sin(r+s-X)+z*Math.sin(-r+s-X),n=G+D,h*Math.cos(e+P-N)+m*Math.cos(P-N)+p*Math.cos(r+P-Q)+l*Math.cos(-r+P-Q)+M*Math.cos(r+P-W)+f*Math.cos(-r+P-W)+2*x*Math.cos(e+s-V)+g*Math.cos(s-V)+u*Math.cos(r+s-X)+z*Math.cos(-r+s-X)),d*=n,381==(so=720<=Math.abs(A-I)?381:(oo=A-I,0))&&(P+=n*t+259200*i,G+=i*t+259200*d,I+=t);a=P+n*oo+i*oo*oo*.5,Y=S+(Z=1!==c?a-2*H+2*to:a-H-k+to,$=(Y=G+i*oo+d*oo*oo*.5)-S)}return{atime:I,em:_,argpm:k,inclm:O,xli:P,mm:Z,xni:G,nodem:H,dndt:$,nm:Y}}({irez:o.irez,d2201:o.d2201,d2211:o.d2211,d3210:o.d3210,d3222:o.d3222,d4410:o.d4410,d4422:o.d4422,d5220:o.d5220,d5232:o.d5232,d5421:o.d5421,d5433:o.d5433,dedt:o.dedt,del1:o.del1,del2:o.del2,del3:o.del3,didt:o.didt,dmdt:o.dmdt,dnodt:o.dnodt,domdt:o.domdt,argpo:o.argpo,argpdot:o.argpdot,t:o.t,tc:x,gsto:o.gsto,xfact:o.xfact,xlamo:o.xlamo,no:o.no,atime:o.atime,em:D,argpm:c,inclm:v,xli:o.xli,mm:y,xni:o.xni,nodem:q,nm:b});D=R.em,c=R.argpm,v=R.inclm,y=R.mm,q=R.nodem,b=R.nm}if(b<=0)return[!(o.error=2),!1];var S=Math.pow(Bo/b,Jo)*f*f;if(b=Bo/Math.pow(S,1.5),1<=(D-=u)||D<-.001)return[!(o.error=1),!1];D<1e-6&&(D=1e-6),T=(y+=o.no*z)+c+q;var I=D;if(w=v,h=c%=Yo,E=q%=Yo,j=y=((T%=Yo)-c-q)%Yo,n=Math.sin(v),a=Math.cos(v),"d"===o.method){var _=Ro(o,{inclo:o.inclo,init:"n",ep:I,inclp:w,nodep:E,argpp:h,mp:j,opsmode:o.operationmode});if(I=_.ep,E=_.nodep,h=_.argpp,j=_.mp,(w=_.inclp)<0&&(w=-w,E+=Ho,h-=Ho),I<0||1<I)return[!(o.error=3),!1]}"d"===o.method&&(n=Math.sin(w),a=Math.cos(w),o.aycof=-.5*Do*n,15e-13<Math.abs(a+1)?o.xlcof=-.25*Do*n*(3+5*a)/(1+a):o.xlcof=-.25*Do*n*(3+5*a)/15e-13);var k=I*Math.cos(h);M=1/(S*(1-I*I));var O=I*Math.sin(h)+M*o.aycof,P=(j+h+E+M*o.xlcof*k-E)%Yo;r=P,g=9999.9;for(var Z=1;1e-12<=Math.abs(g)&&Z<=10;)e=Math.sin(r),g=(P-O*(s=Math.cos(r))+k*e-r)/(g=1-s*k-e*O),.95<=Math.abs(g)&&(g=0<g?.95:-.95),r+=g,Z+=1;var G=k*s+O*e,H=k*e-O*s,Y=k*k+O*O,B=S*(1-Y);if(B<0)return[!(o.error=4),!1];var J=S*(1-G),K=Math.sqrt(S)*H/J,N=Math.sqrt(B)/J,Q=Math.sqrt(1-Y),V=S/J*(e-O-k*(M=H/(1+Q))),W=S/J*(s-k+O*M);m=Math.atan2(V,W);var X=(W+W)*V,$=1-2*V*V,oo=.5*Co*(M=1/B),to=oo*M;"d"===o.method&&(d=a*a,o.con41=3*d-1,o.x1mth2=1-d,o.x7thm1=7*d-1);var so=J*(1-1.5*to*Q*o.con41)+.5*oo*o.x1mth2*$;if(so<1)return{position:!(o.error=6),velocity:!1};m-=.25*to*o.x7thm1*X;var eo=E+1.5*to*a*X,ao=w+1.5*to*a*n*$,no=K-b*oo*o.x1mth2*X/Bo,io=N+b*oo*(o.x1mth2*$+1.5*o.con41)/Bo,ro=Math.sin(m),co=Math.cos(m),ho=Math.sin(eo),mo=Math.cos(eo),po=Math.sin(ao),lo=Math.cos(ao),xo=-ho*lo,go=mo*lo,Mo=xo*ro+mo*co,fo=go*ro+ho*co,uo=po*ro;return{position:{x:so*Mo*Ao,y:so*fo*Ao,z:so*uo*Ao},velocity:{x:(no*Mo+io*(xo*co-mo*ro))*zo,y:(no*fo+io*(go*co-ho*ro))*zo,z:(no*uo+io*(po*co))*zo}}}function g(o,t){var s,e,a,n,d,i,r,c,h,m,p,l,x,g,M,f,u,z,v,y,b,q,w,T,j,E,F,L,A,C,U,D,R,S,I,_,k,O,P,Z,G,H,Y,B,J,K,N,Q,V,W,X,$,oo=t.opsmode,to=t.satn,so=t.epoch,eo=t.xbstar,ao=t.xecco,no=t.xargpo,io=t.xinclo,ro=t.xmo,co=t.xno,ho=t.xnodeo;o.isimp=0,o.method="n",o.aycof=0,o.con41=0,o.cc1=0,o.cc4=0,o.cc5=0,o.d2=0,o.d3=0,o.d4=0,o.delmo=0,o.eta=0,o.argpdot=0,o.omgcof=0,o.sinmao=0,o.t=0,o.t2cof=0,o.t3cof=0,o.t4cof=0,o.t5cof=0,o.x1mth2=0,o.x7thm1=0,o.mdot=0,o.nodedot=0,o.xlcof=0,o.xmcof=0,o.nodecf=0,o.irez=0,o.d2201=0,o.d2211=0,o.d3210=0,o.d3222=0,o.d4410=0,o.d4422=0,o.d5220=0,o.d5232=0,o.d5421=0,o.d5433=0,o.dedt=0,o.del1=0,o.del2=0,o.del3=0,o.didt=0,o.dmdt=0,o.dnodt=0,o.domdt=0,o.e3=0,o.ee2=0,o.peo=0,o.pgho=0,o.pho=0,o.pinco=0,o.plo=0,o.se2=0,o.se3=0,o.sgh2=0,o.sgh3=0,o.sgh4=0,o.sh2=0,o.sh3=0,o.si2=0,o.si3=0,o.sl2=0,o.sl3=0,o.sl4=0,o.gsto=0,o.xfact=0,o.xgh2=0,o.xgh3=0,o.xgh4=0,o.xh2=0,o.xh3=0,o.xi2=0,o.xi3=0,o.xl2=0,o.xl3=0,o.xl4=0,o.xlamo=0,o.zmol=0,o.zmos=0,o.atime=0,o.xli=0,o.xni=0,o.bstar=eo,o.ecco=ao,o.argpo=no,o.inclo=io,o.mo=ro,o.no=co,o.nodeo=ho,o.operationmode=oo;var mo=78/Ao+1,po=42/Ao,lo=po*po*po*po;o.init="y",o.t=0;var xo=function(o){var t=o.ecco,s=o.epoch,e=o.inclo,a=o.opsmode,n=o.no,d=t*t,i=1-d,r=Math.sqrt(i),c=Math.cos(e),h=c*c,m=Math.pow(Bo/n,Jo),p=.75*Co*(3*h-1)/(r*i),l=p/(m*m),x=m*(1-l*l-l*(1/3+134*l*l/81));n/=1+(l=p/(x*x));var g,M=Math.pow(Bo/n,Jo),f=Math.sin(e),u=M*i,z=1-5*h,v=-z-h-h,y=1/M,b=u*u,q=M*(1-t);if("a"===a){var w=s-7305,T=Math.floor(w+1e-8),j=.017202791694070362;(g=(1.7321343856509375+j*T+(j+Yo)*(w-T)+w*w*5075514194322695e-30)%Yo)<0&&(g+=Yo)}else g=So(s+2433281.5);return{no:n,method:"n",ainv:y,ao:M,con41:v,con42:z,cosio:c,cosio2:h,eccsq:d,omeosq:i,posq:b,rp:q,rteosq:r,sinio:f,gsto:g}}({satn:to,ecco:o.ecco,epoch:so,inclo:o.inclo,no:o.no,method:o.method,opsmode:o.operationmode}),go=xo.ao,Mo=xo.con42,fo=xo.cosio,uo=xo.cosio2,zo=xo.eccsq,vo=xo.omeosq,yo=xo.posq,bo=xo.rp,qo=xo.rteosq,wo=xo.sinio;if(o.no=xo.no,o.con41=xo.con41,o.gsto=xo.gsto,(o.error=0)<=vo||0<=o.no){if(o.isimp=0,bo<220/Ao+1&&(o.isimp=1),T=mo,z=lo,(M=(bo-1)*Ao)<156){T=M-78,M<98&&(T=20);var To=(120-T)/Ao;z=To*To*To*To,T=T/Ao+1}f=1/yo,H=1/(go-T),o.eta=go*o.ecco*H,l=o.eta*o.eta,p=o.ecco*o.eta,u=Math.abs(1-l),n=(r=(i=z*Math.pow(H,4))/Math.pow(u,3.5))*o.no*(go*(1+1.5*l+p*(4+l))+.375*Co*H/u*o.con41*(8+3*l*(8+l))),o.cc1=o.bstar*n,d=0,1e-4<o.ecco&&(d=-2*i*H*Do*o.no*wo/o.ecco),o.x1mth2=1-uo,o.cc4=2*o.no*r*go*vo*(o.eta*(2+.5*l)+o.ecco*(.5+2*l)-Co*H/(go*u)*(-3*o.con41*(1-2*p+l*(1.5-.5*p))+.75*o.x1mth2*(2*l-p*(1+l))*Math.cos(2*o.argpo))),o.cc5=2*r*go*vo*(1+2.75*(l+p)+p*l),c=uo*uo,Z=.5*(P=1.5*Co*f*o.no)*Co*f,G=-.46875*Uo*f*f*o.no,o.mdot=o.no+.5*P*qo*o.con41+.0625*Z*qo*(13-78*uo+137*c),o.argpdot=-.5*P*Mo+.0625*Z*(7-114*uo+395*c)+G*(3-36*uo+49*c),B=-P*fo,o.nodedot=B+(.5*Z*(4-19*uo)+2*G*(3-7*uo))*fo,Y=o.argpdot+o.nodedot,o.omgcof=o.bstar*d*Math.cos(o.argpo),o.xmcof=0,1e-4<o.ecco&&(o.xmcof=-Jo*i*o.bstar/p),o.nodecf=3.5*vo*B*o.cc1,o.t2cof=1.5*o.cc1,15e-13<Math.abs(fo+1)?o.xlcof=-.25*Do*wo*(3+5*fo)/(1+fo):o.xlcof=-.25*Do*wo*(3+5*fo)/15e-13,o.aycof=-.5*Do*wo;var jo=1+o.eta*Math.cos(o.mo);if(o.delmo=jo*jo*jo,o.sinmao=Math.sin(o.mo),o.x7thm1=7*uo-1,225<=2*Ho/o.no){o.method="d",o.isimp=1,0,x=o.inclo;var Eo=function(o){var t,s,e,a,n,d,i,r,c,h,m,p,l,x,g,M,f,u,z,v,y,b,q,w,T,j,E,F,L,A,C,U,D,R,S,I,_,k,O,P,Z,G,H,Y,B,J,K,N,Q,V,W,X,$,oo,to,so,eo,ao,no,io,ro,co,ho,mo=o.epoch,po=o.ep,lo=o.argpp,xo=o.tc,go=o.inclp,Mo=o.nodep,fo=o.np,uo=po,zo=Math.sin(Mo),vo=Math.cos(Mo),yo=Math.sin(lo),bo=Math.cos(lo),qo=Math.sin(go),wo=Math.cos(go),To=uo*uo,jo=1-To,Eo=Math.sqrt(jo),Fo=mo+18261.5+xo/1440,Lo=(4.523602-.00092422029*Fo)%Yo,Ao=Math.sin(Lo),Co=Math.cos(Lo),Uo=.91375164-.03568096*Co,Do=Math.sqrt(1-Uo*Uo),Ro=.089683511*Ao/Do,So=Math.sqrt(1-Ro*Ro),Io=5.8351514+.001944368*Fo,_o=.39785416*Ao/Do,ko=So*Co+.91744867*Ro*Ao;_o=Math.atan2(_o,ko),_o+=Io-Lo;var Oo=Math.cos(_o),Po=Math.sin(_o);v=.1945905,y=-.98088458,w=.91744867,T=.39785416,b=vo,q=zo,m=29864797e-13;for(var Zo=1/fo,Go=0;Go<2;)to=-6*(t=v*b+y*w*q)*(n=-qo*(i=-v*q+y*w*b)+wo*(r=y*T))+To*(-24*(p=t*bo+(s=wo*i+qo*r)*yo)*(u=n*bo)-6*(x=-t*yo+s*bo)*(M=n*yo)),so=-6*(t*(d=-qo*(c=y*q+v*w*b)+wo*(h=v*T))+(e=-y*b+v*w*q)*n)+To*(-24*((l=e*bo+(a=wo*c+qo*h)*yo)*u+p*(z=d*bo))+-6*(x*(f=d*yo)+(g=-e*yo+a*bo)*M)),eo=-6*e*d+To*(-24*l*z-6*g*f),ao=6*s*n+To*(24*p*M-6*x*u),no=6*(a*n+s*d)+To*(24*(l*M+p*f)-6*(g*u+x*z)),io=6*a*d+To*(24*l*f-6*g*z),X=(X=3*(t*t+s*s)+(ro=12*p*p-3*x*x)*To)+X+jo*ro,$=($=6*(t*e+s*a)+(co=24*p*l-6*x*g)*To)+$+jo*co,oo=(oo=3*(e*e+a*a)+(ho=12*l*l-3*g*g)*To)+oo+jo*ho,J=-.5*(K=m*Zo)/Eo,B=-15*uo*(N=K*Eo),Q=p*x+l*g,V=l*x+p*g,W=l*g-p*x,1===(Go+=1)&&(j=B,E=J,F=K,L=N,A=Q,C=V,U=W,D=X,R=$,S=oo,I=to,_=so,k=eo,O=ao,P=no,Z=io,G=ro,H=co,Y=ho,v=Oo,y=Po,w=Uo,T=Do,b=So*vo+Ro*zo,q=zo*So-vo*Ro,m=4.7968065e-7);return{snodm:zo,cnodm:vo,sinim:qo,cosim:wo,sinomm:yo,cosomm:bo,day:Fo,e3:2*B*W,ee2:2*B*V,em:uo,emsq:To,gam:Io,peo:0,pgho:0,pho:0,pinco:0,plo:0,rtemsq:Eo,se2:2*j*C,se3:2*j*U,sgh2:2*L*H,sgh3:2*L*(Y-G),sgh4:-18*L*.01675,sh2:-2*E*P,sh3:-2*E*(Z-O),si2:2*E*_,si3:2*E*(k-I),sl2:-2*F*R,sl3:-2*F*(S-D),sl4:-2*F*(-21-9*To)*.01675,s1:B,s2:J,s3:K,s4:N,s5:Q,s6:V,s7:W,ss1:j,ss2:E,ss3:F,ss4:L,ss5:A,ss6:C,ss7:U,sz1:D,sz2:R,sz3:S,sz11:I,sz12:_,sz13:k,sz21:O,sz22:P,sz23:Z,sz31:G,sz32:H,sz33:Y,xgh2:2*N*co,xgh3:2*N*(ho-ro),xgh4:-18*N*.0549,xh2:-2*J*no,xh3:-2*J*(io-ao),xi2:2*J*so,xi3:2*J*(eo-to),xl2:-2*K*$,xl3:-2*K*(oo-X),xl4:-2*K*(-21-9*To)*.0549,nm:fo,z1:X,z2:$,z3:oo,z11:to,z12:so,z13:eo,z21:ao,z22:no,z23:io,z31:ro,z32:co,z33:ho,zmol:(.2299715*Fo-Io+4.7199672)%Yo,zmos:(6.2565837+.017201977*Fo)%Yo}}({epoch:so,ep:o.ecco,argpp:o.argpo,tc:0,inclp:o.inclo,nodep:o.nodeo,np:o.no,e3:o.e3,ee2:o.ee2,peo:o.peo,pgho:o.pgho,pho:o.pho,pinco:o.pinco,plo:o.plo,se2:o.se2,se3:o.se3,sgh2:o.sgh2,sgh3:o.sgh3,sgh4:o.sgh4,sh2:o.sh2,sh3:o.sh3,si2:o.si2,si3:o.si3,sl2:o.sl2,sl3:o.sl3,sl4:o.sl4,xgh2:o.xgh2,xgh3:o.xgh3,xgh4:o.xgh4,xh2:o.xh2,xh3:o.xh3,xi2:o.xi2,xi3:o.xi3,xl2:o.xl2,xl3:o.xl3,xl4:o.xl4,zmol:o.zmol,zmos:o.zmos});o.e3=Eo.e3,o.ee2=Eo.ee2,o.peo=Eo.peo,o.pgho=Eo.pgho,o.pho=Eo.pho,o.pinco=Eo.pinco,o.plo=Eo.plo,o.se2=Eo.se2,o.se3=Eo.se3,o.sgh2=Eo.sgh2,o.sgh3=Eo.sgh3,o.sgh4=Eo.sgh4,o.sh2=Eo.sh2,o.sh3=Eo.sh3,o.si2=Eo.si2,o.si3=Eo.si3,o.sl2=Eo.sl2,o.sl3=Eo.sl3,o.sl4=Eo.sl4,e=Eo.sinim,s=Eo.cosim,h=Eo.em,m=Eo.emsq,v=Eo.s1,y=Eo.s2,b=Eo.s3,q=Eo.s4,w=Eo.s5,j=Eo.ss1,E=Eo.ss2,F=Eo.ss3,L=Eo.ss4,A=Eo.ss5,C=Eo.sz1,U=Eo.sz3,D=Eo.sz11,R=Eo.sz13,S=Eo.sz21,I=Eo.sz23,_=Eo.sz31,k=Eo.sz33,o.xgh2=Eo.xgh2,o.xgh3=Eo.xgh3,o.xgh4=Eo.xgh4,o.xh2=Eo.xh2,o.xh3=Eo.xh3,o.xi2=Eo.xi2,o.xi3=Eo.xi3,o.xl2=Eo.xl2,o.xl3=Eo.xl3,o.xl4=Eo.xl4,o.zmol=Eo.zmol,o.zmos=Eo.zmos,g=Eo.nm,J=Eo.z1,K=Eo.z3,N=Eo.z11,Q=Eo.z13,V=Eo.z21,W=Eo.z23,X=Eo.z31,$=Eo.z33;var Fo=Ro(o,{inclo:x,init:o.init,ep:o.ecco,inclp:o.inclo,nodep:o.nodeo,argpp:o.argpo,mp:o.mo,opsmode:o.operationmode});o.ecco=Fo.ep,o.inclo=Fo.inclp,o.nodeo=Fo.nodep,o.argpo=Fo.argpp,o.mo=Fo.mp,0;var Lo=function(o){var t,s,e,a,n,d,i,r,c,h,m,p,l,x,g,M,f=o.cosim,u=o.argpo,z=o.s1,v=o.s2,y=o.s3,b=o.s4,q=o.s5,w=o.sinim,T=o.ss1,j=o.ss2,E=o.ss3,F=o.ss4,L=o.ss5,A=o.sz1,C=o.sz3,U=o.sz11,D=o.sz13,R=o.sz21,S=o.sz23,I=o.sz31,_=o.sz33,k=o.t,O=o.tc,P=o.gsto,Z=o.mo,G=o.mdot,H=o.no,Y=o.nodeo,B=o.nodedot,J=o.xpidot,K=o.z1,N=o.z3,Q=o.z11,V=o.z13,W=o.z21,X=o.z23,$=o.z31,oo=o.z33,to=o.ecco,so=o.eccsq,eo=o.emsq,ao=o.em,no=o.argpm,io=o.inclm,ro=o.mm,co=o.nm,ho=o.nodem,mo=o.irez,po=o.atime,lo=o.d2201,xo=o.d2211,go=o.d3210,Mo=o.d3222,fo=o.d4410,uo=o.d4422,zo=o.d5220,vo=o.d5232,yo=o.d5421,bo=o.d5433,qo=o.dedt,wo=o.didt,To=o.dmdt,jo=o.dnodt,Eo=o.domdt,Fo=o.del1,Lo=o.del2,Ao=o.del3,Co=o.xfact,Uo=o.xlamo,Do=o.xli,Ro=o.xni,So=.0043752690880113,Io=.00015835218,_o=119459e-10;mo=0,co<.0052359877&&.0034906585<co&&(mo=1),.00826<=co&&co<=.00924&&.5<=ao&&(mo=2);var ko=-_o*j*(R+S);(io<.052359877||Ho-.052359877<io)&&(ko=0),0!==w&&(ko/=w);var Oo=-Io*v*(W+X);(io<.052359877||Ho-.052359877<io)&&(Oo=0),Eo=F*_o*(I+_-6)-f*ko+b*Io*($+oo-6),jo=ko,0!==w&&(Eo-=f/w*Oo,jo+=Oo/w);var Po=(P+O*So)%Yo;if(ao+=(qo=T*_o*L+z*Io*q)*k,io+=(wo=j*_o*(U+D)+v*Io*(Q+V))*k,no+=Eo*k,ho+=jo*k,ro+=(To=-_o*E*(A+C-14-6*eo)-Io*y*(K+N-14-6*eo))*k,0!==mo){if(x=Math.pow(co/Bo,Jo),2===mo){var Zo=ao,Go=eo;M=(ao=to)*(eo=so),r=ao<=.65?(e=3.616-13.247*ao+16.29*eo,a=117.39*ao-19.302-228.419*eo+156.591*M,n=109.7927*ao-18.9068-214.6334*eo+146.5816*M,d=242.694*ao-41.122-471.094*eo+313.953*M,i=841.88*ao-146.407-1629.014*eo+1083.435*M,3017.977*ao-532.114-5740.032*eo+3708.276*M):(e=331.819*ao-72.099-508.738*eo+266.724*M,a=1582.851*ao-346.844-2415.925*eo+1246.113*M,n=1554.908*ao-342.585-2366.899*eo+1215.972*M,d=4758.686*ao-1052.797-7193.992*eo+3651.957*M,i=16178.11*ao-3581.69-24462.77*eo+12422.52*M,.715<ao?29936.92*ao-5149.66-54087.36*eo+31324.56*M:1464.74-4664.75*ao+3763.64*eo),lo=(p=17891679e-13*(l=co*co*3*(x*x)))*(t=.75*(1+2*f+(g=f*f)))*(-.306-.44*(ao-.64)),xo=p*(1.5*(m=w*w))*e,go=(p=3.7393792e-7*(l*=x))*(1.875*w*(1-2*f-3*g))*a,Mo=p*(-1.875*w*(1+2*f-3*g))*n,fo=(p=2*(l*=x)*7.3636953e-9)*(35*m*t)*d,uo=p*(39.375*m*m)*i,zo=(p=1.1428639e-7*(l*=x))*(9.84375*w*(m*(1-2*f-5*g)+.33333333*(4*f-2+6*g)))*r,vo=p*(w*(4.92187512*m*(-2-4*f+10*g)+6.56250012*(1+2*f-3*g)))*(ao<.7?(h=4988.61*ao-919.2277-9064.77*eo+5542.21*M,c=4568.6173*ao-822.71072-8491.4146*eo+5337.524*M,4690.25*ao-853.666-8624.77*eo+5341.4*M):(h=161616.52*ao-37995.78-229838.2*eo+109377.94*M,c=218913.95*ao-51752.104-309468.16*eo+146349.42*M,170470.89*ao-40023.88-242699.48*eo+115605.82*M)),yo=(p=2*l*2.1765803e-9)*(29.53125*w*(2-8*f+g*(8*f-12+10*g)))*c,bo=p*(29.53125*w*(-2-8*f+g*(12+8*f-10*g)))*h,Uo=(Z+Y+Y-(Po+Po))%Yo,Co=G+To+2*(B+jo-So)-H,ao=Zo,eo=Go}1===mo&&(Lo=2*(Fo=3*co*co*x*x)*(t=.75*(s=1+f)*(1+f))*(1+eo*(.8125*eo-2.5))*17891679e-13,Ao=3*Fo*(s*=1.875*s*s)*(1+eo*(6.60937*eo-6))*2.2123015e-7*x,Fo=Fo*(.9375*w*w*(1+3*f)-.75*(1+f))*(a=1+2*eo)*21460748e-13*x,Uo=(Z+Y+u-Po)%Yo,Co=G+J+To+Eo+jo-(H+So)),Do=Uo,co=(Ro=H)+(po=0)}return{em:ao,argpm:no,inclm:io,mm:ro,nm:co,nodem:ho,irez:mo,atime:po,d2201:lo,d2211:xo,d3210:go,d3222:Mo,d4410:fo,d4422:uo,d5220:zo,d5232:vo,d5421:yo,d5433:bo,dedt:qo,didt:wo,dmdt:To,dndt:0,dnodt:jo,domdt:Eo,del1:Fo,del2:Lo,del3:Ao,xfact:Co,xlamo:Uo,xli:Do,xni:Ro}}({cosim:s,emsq:m,argpo:o.argpo,s1:v,s2:y,s3:b,s4:q,s5:w,sinim:e,ss1:j,ss2:E,ss3:F,ss4:L,ss5:A,sz1:C,sz3:U,sz11:D,sz13:R,sz21:S,sz23:I,sz31:_,sz33:k,t:o.t,tc:0,gsto:o.gsto,mo:o.mo,mdot:o.mdot,no:o.no,nodeo:o.nodeo,nodedot:o.nodedot,xpidot:Y,z1:J,z3:K,z11:N,z13:Q,z21:V,z23:W,z31:X,z33:$,ecco:o.ecco,eccsq:zo,em:h,argpm:0,inclm:x,mm:0,nm:g,nodem:0,irez:o.irez,atime:o.atime,d2201:o.d2201,d2211:o.d2211,d3210:o.d3210,d3222:o.d3222,d4410:o.d4410,d4422:o.d4422,d5220:o.d5220,d5232:o.d5232,d5421:o.d5421,d5433:o.d5433,dedt:o.dedt,didt:o.didt,dmdt:o.dmdt,dnodt:o.dnodt,domdt:o.domdt,del1:o.del1,del2:o.del2,del3:o.del3,xfact:o.xfact,xlamo:o.xlamo,xli:o.xli,xni:o.xni});o.irez=Lo.irez,o.atime=Lo.atime,o.d2201=Lo.d2201,o.d2211=Lo.d2211,o.d3210=Lo.d3210,o.d3222=Lo.d3222,o.d4410=Lo.d4410,o.d4422=Lo.d4422,o.d5220=Lo.d5220,o.d5232=Lo.d5232,o.d5421=Lo.d5421,o.d5433=Lo.d5433,o.dedt=Lo.dedt,o.didt=Lo.didt,o.dmdt=Lo.dmdt,o.dnodt=Lo.dnodt,o.domdt=Lo.domdt,o.del1=Lo.del1,o.del2=Lo.del2,o.del3=Lo.del3,o.xfact=Lo.xfact,o.xlamo=Lo.xlamo,o.xli=Lo.xli,o.xni=Lo.xni}1!==o.isimp&&(a=o.cc1*o.cc1,o.d2=4*go*H*a,O=o.d2*H*o.cc1/3,o.d3=(17*go+T)*O,o.d4=.5*O*go*H*(221*go+31*T)*o.cc1,o.t3cof=o.d2+2*a,o.t4cof=.25*(3*o.d3+o.cc1*(12*o.d2+10*a)),o.t5cof=.2*(3*o.d4+12*o.cc1*o.d3+6*o.d2*o.d2+15*a*(2*o.d2+a)))}Io(o,0),o.init="n"}function n(o){return function(o){if(Array.isArray(o)){for(var t=0,s=new Array(o.length);t<o.length;t++)s[t]=o[t];return s}}(o)||function(o){if(Symbol.iterator in Object(o)||"[object Arguments]"===Object.prototype.toString.call(o))return Array.from(o)}(o)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function a(o){return o*t}function d(o){return o*m}function f(o){var t=o.longitude,s=o.latitude,e=o.height,a=6378.137,n=.0033528106718309306,d=2*n-n*n,i=a/Math.sqrt(1-d*(Math.sin(s)*Math.sin(s)));return{x:(i+e)*Math.cos(s)*Math.cos(t),y:(i+e)*Math.cos(s)*Math.sin(t),z:(i*(1-d)+e)*Math.sin(s)}}return{constants:Object.freeze({__proto__:null,pi:Ho,twoPi:Yo,deg2rad:m,rad2deg:t,minutesPerDay:1440,mu:o,earthRadius:Ao,xke:Bo,vkmpersec:zo,tumin:p,j2:Co,j3:s,j4:Uo,j3oj2:Do,x2o3:Jo}),propagate:function(){for(var o=arguments.length,t=new Array(o),s=0;s<o;s++)t[s]=arguments[s];var e=t[0],a=Array.prototype.slice.call(t,1);return Io(e,1440*(x.apply(void 0,n(a))-e.jdsatepoch))},sgp4:Io,twoline2satrec:function(o,t){var s=1440/(2*Ho),e=0,a={error:0};a.satnum=o.substring(2,7),a.epochyr=parseInt(o.substring(18,20),10),a.epochdays=parseFloat(o.substring(20,32)),a.ndot=parseFloat(o.substring(33,43)),a.nddot=parseFloat(".".concat(parseInt(o.substring(44,50),10),"E").concat(o.substring(50,52))),a.bstar=parseFloat("".concat(o.substring(53,54),".").concat(parseInt(o.substring(54,59),10),"E").concat(o.substring(59,61))),a.inclo=parseFloat(t.substring(8,16)),a.nodeo=parseFloat(t.substring(17,25)),a.ecco=parseFloat(".".concat(t.substring(26,33))),a.argpo=parseFloat(t.substring(34,42)),a.mo=parseFloat(t.substring(43,51)),a.no=parseFloat(t.substring(52,63)),a.no/=s,a.a=Math.pow(a.no*p,-2/3),a.ndot/=1440*s,a.nddot/=1440*s*1440,a.inclo*=m,a.nodeo*=m,a.argpo*=m,a.mo*=m,a.alta=a.a*(1+a.ecco)-1,a.altp=a.a*(1-a.ecco)-1;var n=l(e=a.epochyr<57?a.epochyr+2e3:a.epochyr+1900,a.epochdays),d=n.mon,i=n.day,r=n.hr,c=n.minute,h=n.sec;return a.jdsatepoch=x(e,d,i,r,c,h),g(a,{opsmode:"i",satn:a.satnum,epoch:a.jdsatepoch-2433281.5,xbstar:a.bstar,xecco:a.ecco,xargpo:a.argpo,xinclo:a.inclo,xmo:a.mo,xno:a.no,xnodeo:a.nodeo}),a},gstime:So,jday:x,invjday:function(o,t){var s=o-2415019.5,e=s/365.25,a=1900+Math.floor(e),n=Math.floor(.25*(a-1901)),d=s-(365*(a-1900)+n)+1e-11;d<1&&(d=s-(365*((a-=1)-1900)+(n=Math.floor(.25*(a-1901)))));var i=l(a,d),r=i.mon,c=i.day,h=i.hr,m=i.minute,p=i.sec-864e-9;return t?[a,r,c,h,m,Math.floor(p)]:new Date(Date.UTC(a,r-1,c,h,m,Math.floor(p)))},dopplerFactor:function(o,t,s){var e=Math.sqrt(Math.pow(t.x-o.x,2)+Math.pow(t.y-o.y,2)+Math.pow(t.z-o.z,2)),a=t.x+s.x,n=t.y+s.y,d=t.z+s.z,i=Math.sqrt(Math.pow(a-o.x,2)+Math.pow(n-o.y,2)+Math.pow(d-o.z,2))-e;return 1+(i*=0<=i?1:-1)/299792.458},radiansToDegrees:a,degreesToRadians:d,degreesLat:function(o){if(o<-Ho/2||Ho/2<o)throw new RangeError("Latitude radians must be in range [-pi/2; pi/2].");return a(o)},degreesLong:function(o){if(o<-Ho||Ho<o)throw new RangeError("Longitude radians must be in range [-pi; pi].");return a(o)},radiansLat:function(o){if(o<-90||90<o)throw new RangeError("Latitude degrees must be in range [-90; 90].");return d(o)},radiansLong:function(o){if(o<-180||180<o)throw new RangeError("Longitude degrees must be in range [-180; 180].");return d(o)},geodeticToEcf:f,eciToGeodetic:function(o,t){for(var s=6378.137,e=Math.sqrt(o.x*o.x+o.y*o.y),a=.0033528106718309306,n=2*a-a*a,d=Math.atan2(o.y,o.x)-t;d<-Ho;)d+=Yo;for(;Ho<d;)d-=Yo;for(var i,r=0,c=Math.atan2(o.z,Math.sqrt(o.x*o.x+o.y*o.y));r<20;)i=1/Math.sqrt(1-n*(Math.sin(c)*Math.sin(c))),c=Math.atan2(o.z+s*i*n*Math.sin(c),e),r+=1;return{longitude:d,latitude:c,height:e/Math.cos(c)-s*i}},eciToEcf:function(o,t){return{x:o.x*Math.cos(t)+o.y*Math.sin(t),y:o.x*-Math.sin(t)+o.y*Math.cos(t),z:o.z}},ecfToEci:function(o,t){return{x:o.x*Math.cos(t)-o.y*Math.sin(t),y:o.x*Math.sin(t)+o.y*Math.cos(t),z:o.z}},ecfToLookAngles:function(o,t){var s,e,a,n,d,i,r,c,h,m,p,l,x,g,M=(e=t,a=(s=o).longitude,n=s.latitude,d=f(s),i=e.x-d.x,r=e.y-d.y,c=e.z-d.z,{topS:Math.sin(n)*Math.cos(a)*i+Math.sin(n)*Math.sin(a)*r-Math.cos(n)*c,topE:-Math.sin(a)*i+Math.cos(a)*r,topZ:Math.cos(n)*Math.cos(a)*i+Math.cos(n)*Math.sin(a)*r+Math.sin(n)*c});return m=(h=M).topS,p=h.topE,l=h.topZ,x=Math.sqrt(m*m+p*p+l*l),g=Math.asin(l/x),{azimuth:Math.atan2(-p,m)+Ho,elevation:g,rangeSat:x}}}});
diff --git a/web/index.php b/web/index.php
index 2794a3c..416e9ea 100644
--- a/web/index.php
+++ b/web/index.php
@@ -1,6 +1,9 @@
 <?php
-    include __DIR__ . "/wsos/autoload.php";
-    include "DAL/user.php";
+    include __DIR__ . "/wsos/wsos/autoload.php";
+
+    foreach (glob("DAL/*.php") as $filename) {
+        include_once $filename;
+    }
 
     $container = new \wsos\structs\container();
     $db        = new \wsos\database\drivers\inAppArray();
@@ -13,12 +16,12 @@
     $context = [
         "url" => $url,
         "menu_items" => [
-            ["url" => "/",              "name" => "Dashboard"],
-            ["url" => "/observations",  "name" => "Observations"],
-            ["url" => "/stations",      "name" => "Stations"],
-            ["url" => "/targets",       "name" => "Targets"],
-            ["url" => "/modulations",   "name" => "Modulations"],
-            ["url" => "/datatypes",     "name" => "Data Types"],
+            ["url" => "/",              "name" => "Dashboard",    "icon" => "/static/icons/dashboard.svg"],
+            ["url" => "/observations",  "name" => "Observations", "icon" => "/static/icons/telescope.svg"],
+            ["url" => "/stations",      "name" => "Stations",     "icon" => "/static/icons/radio.svg"],
+            ["url" => "/targets",       "name" => "Targets",      "icon" => "/static/icons/focus-2.svg"],
+            ["url" => "/modulations",   "name" => "Modulations",  "icon" => "/static/icons/wave-sine.svg"],
+            ["url" => "/datatypes",     "name" => "Data Types",   "icon" => "/static/icons/file-analytics.svg"],
         ],
 
         "logined" => $auth->getActive()
@@ -34,8 +37,9 @@
     // do not do this in release!!
     include "seeds.php";
 
-    if      ($url == "/")             include "CONTROLLERS/dashboard.php";
-    else if ($url == "/observations") include "CONTROLLERS/observations.php";
-    else if ($url == "/stations")     include "CONTROLLERS/stations.php";
-    else                              include "CONTROLLERS/404.php";
+    if      ($url == "/")             include __DIR__ . "/CONTROLLERS/dashboard.php";
+    else if ($url == "/observations") include __DIR__ . "/CONTROLLERS/observations.php";
+    else if ($url == "/stations")     include __DIR__ . "/CONTROLLERS/stations.php";
+    else if ($url == "/login")        include __DIR__ . "/CONTROLLERS/login.php";
+    else                              include __DIR__ . "/CONTROLLERS/404.php";
 ?>
\ No newline at end of file
diff --git a/web/seeds.php b/web/seeds.php
index e69de29..f43a721 100644
--- a/web/seeds.php
+++ b/web/seeds.php
@@ -0,0 +1,96 @@
+<?php
+    /**
+     * Create default user
+     */
+    $admin = new \DAL\user();
+    $admin->userName->set("admin");
+    $admin->pass->set("admin");
+    $admin->admin->set(true);
+    $admin->commit(); /* commit changes to DB */
+
+    $satType = new \DAL\targetType();
+    $satType->name->set("sat");
+    $satType->commit();
+
+    $wetImgType = new \DAL\dataType();
+    $wetImgType->name->set("weather photo");
+    $wetImgType->commit();
+
+
+    /**
+     * Test station
+     */
+    $myStation = new \DAL\station();
+    $myStation->name->set("Medlánky");
+    $myStation->commit();
+
+    $myStation137 = new \DAL\receiver();
+    $myStation137->station->set($myStation);
+    $myStation137->commit();
+
+    /**
+     * NOAA modulations
+     */
+
+    $fm = new \DAL\modulation();
+    $fm->name->set("FM");
+    $fm->commit();
+
+
+    /**
+     * NOAA 19
+     */
+    $noaa19 = new \DAL\target();
+    $noaa19->name->set("NOAA 19");
+    $noaa19->type->set($satType);
+    $noaa19->description->set("NOAA 19 is the fifth in a series of five Polar-orbiting Operational Environmental Satellites (POES) with advanced microwave sounding instruments that provide imaging and sounding capabilities.");
+    $noaa19->locator->set([
+        "tle" => "NOAA 19\n1 33591U 09005A   23243.18101660  .00000207  00000-0  13587-3 0  9998\n2 33591  99.0938 290.2850 0014342  35.8617 324.3514 14.12812127750532"
+    ]);
+    $noaa19->commit();
+
+    $noaa19APT = new \DAL\transmitter();
+    $noaa19APT->target->set($noaa19);
+    $noaa19APT->dataType->set($wetImgType);
+    $noaa19APT->bandwidth->set(100);
+    $noaa19APT->centerFrequency->set(137100000);
+    $noaa19APT->modulation->set($fm);
+    $noaa19APT->commit();
+
+    /**
+     * NOAA 18
+     */
+    $noaa18 = new \DAL\target();
+    $noaa18->name->set("NOAA 18");
+    $noaa18->type->set($satType);
+    $noaa18->description->set("NOAA 18, known before launch as NOAA-N, is a weather forecasting satellite run by NOAA. NOAA-N (18) was launched into a sun-synchronous orbit at an altitude of 854 km above the Earth, with an orbital period of 102 minutes. It hosts the AMSU-A, MHS, AVHRR, Space Environment Monitor SEM/2 instrument and High Resolution Infrared Radiation Sounder (HIRS) instruments, as well as the SBUV/2 ozone-monitoring instrument.");
+    $noaa18->locator->set([
+        "tle" => "NOAA 18\n1 28654U 05018A   23250.34978256  .00000271  00000-0  16921-3 0  9997\n2 28654  98.9045 324.3258 0015006 144.5825 215.6347 14.13000434943172"
+    ]);
+    $noaa18->commit();
+
+    $noaa18APT = new \DAL\transmitter();
+    $noaa18APT->target->set($noaa18);
+    $noaa18APT->dataType->set($wetImgType);
+    $noaa18APT->bandwidth->set(100);
+    $noaa18APT->centerFrequency->set(137912500);
+    $noaa18APT->modulation->set($fm);
+    $noaa18APT->commit();
+
+
+    /**
+     * Plan observation
+     */
+    $noaa19Plan = new \DAL\observation();
+    $noaa19Plan->status->set("planed");
+    $noaa19Plan->locator->set($noaa19->locator->get());
+    $noaa19Plan->transmitter->set($noaa19APT);
+    $noaa19Plan->receiver->set($myStation137);
+    $noaa19Plan->commit();
+
+    $noaa18Plan = new \DAL\observation();
+    $noaa18Plan->status->set("planed");
+    $noaa18Plan->locator->set($noaa18->locator->get());
+    $noaa18Plan->transmitter->set($noaa18APT);
+    $noaa18Plan->receiver->set($myStation137);
+    $noaa18Plan->commit();
\ No newline at end of file
diff --git a/web/static/icons/antenna.svg b/web/static/icons/antenna.svg
new file mode 100644
index 0000000..13545c8
--- /dev/null
+++ b/web/static/icons/antenna.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-antenna" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <path d="M20 4v8" />
+  <path d="M16 4.5v7" />
+  <path d="M12 5v16" />
+  <path d="M8 5.5v5" />
+  <path d="M4 6v4" />
+  <path d="M20 8h-16" />
+</svg>
+
+
diff --git a/web/static/icons/dashboard.svg b/web/static/icons/dashboard.svg
new file mode 100644
index 0000000..14a9b32
--- /dev/null
+++ b/web/static/icons/dashboard.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-dashboard" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <path d="M12 13m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
+  <path d="M13.45 11.55l2.05 -2.05" />
+  <path d="M6.4 20a9 9 0 1 1 11.2 0z" />
+</svg>
+
+
diff --git a/web/static/icons/file-analytics.svg b/web/static/icons/file-analytics.svg
new file mode 100644
index 0000000..e9f19c4
--- /dev/null
+++ b/web/static/icons/file-analytics.svg
@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-analytics" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <path d="M14 3v4a1 1 0 0 0 1 1h4" />
+  <path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" />
+  <path d="M9 17l0 -5" />
+  <path d="M12 17l0 -1" />
+  <path d="M15 17l0 -3" />
+</svg>
+
+
diff --git a/web/static/icons/focus-2.svg b/web/static/icons/focus-2.svg
new file mode 100644
index 0000000..9f66b5e
--- /dev/null
+++ b/web/static/icons/focus-2.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-focus-2" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <circle cx="12" cy="12" r=".5" fill="currentColor" />
+  <path d="M12 12m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0" />
+  <path d="M12 3l0 2" />
+  <path d="M3 12l2 0" />
+  <path d="M12 19l0 2" />
+  <path d="M19 12l2 0" />
+</svg>
+
+
diff --git a/web/static/icons/radio.svg b/web/static/icons/radio.svg
new file mode 100644
index 0000000..3189074
--- /dev/null
+++ b/web/static/icons/radio.svg
@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-radio" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <path d="M14 3l-9.371 3.749a1 1 0 0 0 -.629 .928v11.323a1 1 0 0 0 1 1h14a1 1 0 0 0 1 -1v-11a1 1 0 0 0 -1 -1h-14.5" />
+  <path d="M4 12h16" />
+  <path d="M7 12v-2" />
+  <path d="M17 16v.01" />
+  <path d="M13 16v.01" />
+</svg>
+
+
diff --git a/web/static/icons/satellite.svg b/web/static/icons/satellite.svg
new file mode 100644
index 0000000..2d639fd
--- /dev/null
+++ b/web/static/icons/satellite.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-satellite" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <path d="M3.707 6.293l2.586 -2.586a1 1 0 0 1 1.414 0l5.586 5.586a1 1 0 0 1 0 1.414l-2.586 2.586a1 1 0 0 1 -1.414 0l-5.586 -5.586a1 1 0 0 1 0 -1.414z" />
+  <path d="M6 10l-3 3l3 3l3 -3" />
+  <path d="M10 6l3 -3l3 3l-3 3" />
+  <path d="M12 12l1.5 1.5" />
+  <path d="M14.5 17a2.5 2.5 0 0 0 2.5 -2.5" />
+  <path d="M15 21a6 6 0 0 0 6 -6" />
+</svg>
+
+
diff --git a/web/static/icons/telescope.svg b/web/static/icons/telescope.svg
new file mode 100644
index 0000000..293d906
--- /dev/null
+++ b/web/static/icons/telescope.svg
@@ -0,0 +1,9 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-telescope" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <path d="M6 21l6 -5l6 5" />
+  <path d="M12 13v8" />
+  <path d="M3.294 13.678l.166 .281c.52 .88 1.624 1.265 2.605 .91l14.242 -5.165a1.023 1.023 0 0 0 .565 -1.456l-2.62 -4.705a1.087 1.087 0 0 0 -1.447 -.42l-.056 .032l-12.694 7.618c-1.02 .613 -1.357 1.897 -.76 2.905z" />
+  <path d="M14 5l3 5.5" />
+</svg>
+
+
diff --git a/web/static/icons/user.svg b/web/static/icons/user.svg
new file mode 100644
index 0000000..7061db9
--- /dev/null
+++ b/web/static/icons/user.svg
@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-user" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0" />
+  <path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2" />
+</svg>
+
+
diff --git a/web/static/icons/wave-sine.svg b/web/static/icons/wave-sine.svg
new file mode 100644
index 0000000..a318081
--- /dev/null
+++ b/web/static/icons/wave-sine.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-wave-sine" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
+  <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
+  <path d="M21 12h-2c-.894 0 -1.662 -.857 -1.761 -2c-.296 -3.45 -.749 -6 -2.749 -6s-2.5 3.582 -2.5 8s-.5 8 -2.5 8s-2.452 -2.547 -2.749 -6c-.1 -1.147 -.867 -2 -1.763 -2h-2" />
+</svg>
+
+
diff --git a/web/wsos b/web/wsos
new file mode 160000
index 0000000..ff5a891
--- /dev/null
+++ b/web/wsos
@@ -0,0 +1 @@
+Subproject commit ff5a891a3dee6a9363984dde57163b142fd22c52