Parcourir la source

running ok now

Help-14 il y a 3 ans
Parent
commit
8e4a4f5cba

+ 2 - 1
.gitignore

@@ -104,4 +104,5 @@ dist
 .tern-port
 
 src/temp
-src/build
+src/build
+src/common/*.yaml

+ 2 - 2
src/common/js/core.js

@@ -1,4 +1,3 @@
-
 function loadCSS() {
     for (let c = 0; c < document.styleSheets.length; c++) {
         var declaration = document.styleSheets[c].cssRules[0];
@@ -14,4 +13,5 @@ function loadCSS() {
             return;
         }
     }
-}
+}
+loadCSS();

+ 0 - 8
src/languages/en.json

@@ -1,8 +0,0 @@
-{
-    "greeting": {
-        "morning": "Good morning!",
-        "afternoon": "Good afternoon!",
-        "evening": "Good evening!",
-        "night": "Good night!"
-    }
-}

+ 5 - 0
src/languages/en.yaml

@@ -0,0 +1,5 @@
+greeting:
+    morning: Good morning!
+    afternoon: Good afternoon!
+    evening: Good evening!
+    night: Good night!

+ 0 - 8
src/languages/vi.json

@@ -1,8 +0,0 @@
-{
-    "greeting": {
-        "morning": "Chào buổi sáng!",
-        "afternoon": "Chiều làm việc hiệu quả!",
-        "evening": "Chiều tối vui vẻ!",
-        "night": "Chúc ngủ ngon!"
-    }
-}

+ 5 - 0
src/languages/vi.yaml

@@ -0,0 +1,5 @@
+greeting:
+    morning: Chào buổi sáng!
+    afternoon: Chiều làm việc hiệu quả!
+    evening: Chiều tối vui vẻ!
+    night: Chúc ngủ ngon!

+ 52 - 9
src/main.go

@@ -1,19 +1,33 @@
 package main
 
 import (
+	"errors"
 	"html/template"
+	"io/ioutil"
 	"log"
 	"net/http"
+	"os"
 	"path/filepath"
+	"time"
 
 	"github.com/help-14/magma/modules"
 )
 
 var appConfig modules.Config
+var websiteData = struct {
+	Config   modules.WebsiteConfig
+	Language modules.Language
+	Contents []modules.GroupData
+}{}
 
 func main() {
+	prepareSampleFiles()
 	appConfig = modules.LoadConfig()
 
+	websiteData.Config = appConfig.Website
+	websiteData.Language = modules.LoadLanguage(appConfig.Website.Language)
+	websiteData.Contents = modules.LoadContent().Data
+
 	commonfs := http.FileServer(http.Dir("./common"))
 	http.Handle("/common/", http.StripPrefix("/common/", commonfs))
 
@@ -24,6 +38,7 @@ func main() {
 	themefs := http.FileServer(http.Dir("." + themePath))
 	http.Handle("/theme/", http.StripPrefix("/theme/", themefs))
 
+	http.HandleFunc("/weather", serveWeather)
 	http.HandleFunc("/", serveTemplate)
 
 	log.Println("Listening on http://localhost:7001 ...")
@@ -33,17 +48,45 @@ func main() {
 	}
 }
 
+var weatherTimeOut int64
+var weatherCache []byte
+
+func serveWeather(w http.ResponseWriter, r *http.Request) {
+	if time.Now().UnixMilli() >= weatherTimeOut {
+		resp, err := http.Get("https://api.openweathermap.org/data/2.5/weather?lat=" + appConfig.OpenWeatherMap.Latitude + "&lon=" + appConfig.OpenWeatherMap.Longitude + "&limit=1&appid=" + appConfig.OpenWeatherMap.ApiKey)
+		if err != nil {
+			log.Fatalln(err)
+			return
+		}
+		body, err := ioutil.ReadAll(resp.Body)
+		if err != nil {
+			log.Fatalln(err)
+			return
+		}
+		weatherCache = body
+		weatherTimeOut = time.Now().UnixMilli() + 1800000
+	}
+	w.Header().Set("Content-Type", "application/json")
+	w.Write(weatherCache)
+}
+
 func serveTemplate(w http.ResponseWriter, r *http.Request) {
 	lp := filepath.Join("themes", appConfig.Website.Theme, "index.html")
 	tmpl, _ := template.ParseFiles(lp)
-	tmpl.Execute(w, struct {
-		Config modules.WebsiteConfig
-	}{appConfig.Website})
+	tmpl.Execute(w, websiteData)
 }
 
-// templ.Execute(file, struct {
-//     Age int
-//     Name string
-// }{42, "Dolphin"})
-
-// {{.Age}}, {{.Name}}
+func prepareSampleFiles() {
+	files, err := ioutil.ReadDir("./sample/")
+	if err != nil {
+		log.Fatal(err)
+		return
+	}
+	for _, file := range files {
+		samplePath := filepath.Join("sample", file.Name())
+		commonPath := filepath.Join("common", file.Name())
+		if _, err := os.Stat(commonPath); errors.Is(err, os.ErrNotExist) {
+			modules.CopyFile(samplePath, commonPath)
+		}
+	}
+}

+ 47 - 0
src/modules/content.go

@@ -0,0 +1,47 @@
+package modules
+
+import (
+	"fmt"
+	"io/ioutil"
+	"path/filepath"
+
+	"gopkg.in/yaml.v2"
+)
+
+type ContentData struct {
+	Data []GroupData `yaml:"data"`
+}
+
+type GroupData struct {
+	Title   string       `yaml:"title"`
+	Columns []ColumnData `yaml:"columns"`
+}
+
+type ColumnData struct {
+	Title     string         `yaml:"title"`
+	Bookmarks []BookmarkData `yaml:"bookmarks"`
+}
+
+type BookmarkData struct {
+	Name string `yaml:"name"`
+	Icon string `yaml:"icon"`
+	Url  string `yaml:"url"`
+}
+
+func LoadContent() ContentData {
+	emptyData := ContentData{}
+
+	yamlFile, err := ioutil.ReadFile(filepath.Join("common", "data.yaml"))
+	if err != nil {
+		fmt.Printf("Error reading YAML file: %s\n", err)
+		return emptyData
+	}
+
+	var data ContentData
+	err = yaml.Unmarshal(yamlFile, &data)
+	if err != nil {
+		fmt.Printf("Error parsing YAML file: %s\n", err)
+		return emptyData
+	}
+	return data
+}

+ 27 - 0
src/modules/file.go

@@ -0,0 +1,27 @@
+package modules
+
+import (
+	"io"
+	"log"
+	"os"
+)
+
+func CopyFile(src string, dst string) {
+	fin, err := os.Open(src)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer fin.Close()
+
+	fout, err := os.Create(dst)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer fout.Close()
+
+	_, err = io.Copy(fout, fin)
+
+	if err != nil {
+		log.Fatal(err)
+	}
+}

+ 38 - 0
src/modules/language.go

@@ -0,0 +1,38 @@
+package modules
+
+import (
+	"fmt"
+	"io/ioutil"
+	"path/filepath"
+
+	"gopkg.in/yaml.v2"
+)
+
+type Language struct {
+	Greeting LanguageGreeting `yaml:"greeting"`
+}
+
+type LanguageGreeting struct {
+	Morning   string `yaml:"morning"`
+	Afternoon string `yaml:"afternoon"`
+	Evening   string `yaml:"evening"`
+	Night     string `yaml:"night"`
+}
+
+func LoadLanguage(language string) Language {
+	yamlFile, err := ioutil.ReadFile(filepath.Join("languages", language+".yaml"))
+	if err != nil {
+		fmt.Printf("Error reading YAML file: %s\n", err)
+		return LoadLanguage("en")
+	}
+
+	var data Language
+	err = yaml.Unmarshal(yamlFile, &data)
+	if err != nil {
+		fmt.Printf("Error parsing YAML file: %s\n", err)
+		return LoadLanguage("en")
+	}
+
+	fmt.Println("Loaded language: ", language)
+	return data
+}

+ 0 - 2
src/modules/language.ts

@@ -1,2 +0,0 @@
-export class Language {
-}

+ 0 - 0
src/modules/compile.go → src/modules/minify.go


+ 0 - 107
src/modules/server.ts

@@ -1,107 +0,0 @@
-import { opine, serveStatic } from "https://deno.land/x/opine/mod.ts";
-import { Language, minify } from "https://deno.land/x/minifier/mod.ts";
-import {
-  ensureDirSync,
-  ensureFileSync,
-  existsSync,
-  walkSync,
-} from "https://deno.land/std/fs/mod.ts";
-
-const tempFolder = `${Deno.cwd()}/temp`;
-let weatherCache = "";
-let weatherTimeOut = new Date().getTime();
-
-export async function startServer(): Promise<void> {
-  // Create web server
-  const app = opine();
-
-  // Add resource folder
-  app.use(serveStatic(tempFolder));
-
-  // Add route for weather
-  app.get("/weather", async (req, res) => {
-    if (new Date().getTime() >= weatherTimeOut) {
-      const lat = "21.0425886";
-      const lon = "105.8129389";
-      const apiKey = "7b093bee7461b669e34c363d887cfdec";
-      const response = await fetch(
-        `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&limit=1&appid=${apiKey}`,
-        {
-          method: "GET",
-          headers: {
-            "Content-Type": "application/json",
-            "Access-Control-Allow-Origin": "*",
-          },
-        },
-      );
-      weatherCache = await response.json();
-      weatherTimeOut = new Date().getTime() + 1800000;
-    }
-    res.send(weatherCache);
-  });
-
-  // Minify all files and copy to temp folder
-  await Compile();
-
-  // Start web server
-  app.listen(7001, () =>
-    console.log(
-      `Server has started on http://localhost:7001 🚀`,
-    ));
-}
-
-export async function Compile(): Promise<void> {
-  ensureDirSync(tempFolder);
-
-  [`private/themes/${window.config.website.theme}`, "public"].forEach(
-    (folder) => {
-      for (
-        const entry of walkSync(`${Deno.cwd()}/${folder}/`, {
-          includeDirs: false,
-        })
-      ) {
-        console.log("Preparing: " + entry.path);
-
-        let language = null;
-        if (!entry.path.includes(".min.")) {
-          if (entry.path.includes(".css")) {
-            language = Language.CSS;
-          } else if (entry.path.includes(".json")) {
-            language = Language.JSON;
-          }
-          // minifier module make error when minify js and html file 🥲
-          //else if (entry.path.includes(".js")) {
-          //  language = Language.JS;
-          //}
-          //else if (entry.path.includes(".htm")) {
-          //language = Language.HTML;
-          //}
-        }
-
-        const moveToPath = convertOutputPath(entry.path, folder);
-        ensureFileSync(moveToPath);
-
-        if (language) {
-          let content = Deno.readTextFileSync(entry.path);
-          content = minify(Language.HTML, content);
-          Deno.writeTextFileSync(moveToPath, content);
-        } else {
-          Deno.copyFileSync(entry.path, moveToPath);
-        }
-      }
-    },
-  );
-  // Copy language
-  let languagePath =
-    `${Deno.cwd()}/public/languages/${window.config.website.language}.json`;
-  const languageOutput = convertOutputPath(languagePath, "public/languages");
-  if (!existsSync(languagePath)) {
-    languagePath =
-      `${Deno.cwd()}/private/languages/${window.config.website.language}.json`;
-  }
-  Deno.copyFileSync(languagePath, languageOutput);
-}
-
-function convertOutputPath(path: string, from: string) {
-  return Deno.cwd() + path.replace(Deno.cwd(), "").replace(from, "temp");
-}

+ 8 - 5
src/sample/config.yaml

@@ -1,9 +1,12 @@
 website:
   theme: "flame"
-  title: "Help-14 Dashboard"
+  title: "Magma Dashboard"
   description: ""
-  language: "vi"
-  localization: "vi-vn"
+  language: "en"
+  localization: "en-US"
   useMetric: true
-
-addons:
+openweathermap:
+  apiKey:
+  lon:
+  lat:
+addons:

+ 4 - 4
src/sample/data.yaml

@@ -21,7 +21,7 @@ data:
             icon: fa-solid fa-server
             url: https://www.truenas.com
           - name: Kerberos
-            icon: fa-solid fa-camera-web
+            icon: fa-solid fa-video
             url: https://kerberos.io
           - name: jDownloader
             icon: fa-solid fa-cloud-arrow-down
@@ -61,10 +61,10 @@ data:
             icon: fa-solid fa-bag-shopping
             url: https://shopee.vn
           - name: Lazada
-            icon: fa-solid fa-heart-half-stroke
-            url: https://www.lazada.com
+            icon: fa-brands fa-amazon
+            url: https://www.amazon.com
       - title: Tools
         bookmarks:
           - name: Maps
             icon: fa-solid fa-map
-            url: https://www.google.com/maps
+            url: https://www.google.com/maps

+ 11 - 2
src/themes/flame/css/magma.css

@@ -68,20 +68,29 @@ body {
   font-weight: bold;
 }
 
-.group-items .icon {
+.group-items .icon-container {
   margin-top: 0px !important;
   margin-left: 0.5em !important;
   margin-right: 0.5em !important;
+  text-align: center;
+  width: 32px;
+  height: 32px;
+  align-items: center;
+}
+
+.group-items .icon {
+  vertical-align: middle;
 }
 
 .group-items a:hover {
   background-color: rgba(0, 0, 0, 0.3) !important;
   cursor: pointer;
 }
+
 @supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) {
   .group-items a:hover {
     -webkit-backdrop-filter: blur(10px);
     backdrop-filter: blur(10px);
     background-color: rgba(0, 0, 0, 0.3) !important;
   }
-}
+}

+ 94 - 8
src/themes/flame/index.html

@@ -41,22 +41,108 @@
             </div>
         </div>
         <div class="row">
-            <div id="content" class="column twelve"></div>
+            <div id="content" class="column twelve">
+            {{range .Contents}}
+                <div class="row group-title"><h4 class="strong">{{.Title}}</h4></div>
+                <div class="row">
+                {{range .Columns}}
+                    <div class="three columns group-items">
+                        <h6 class="accent">{{.Title}}</h6>
+                        {{range .Bookmarks}}
+                            <a href="{{.Url}}">
+                                <div class="icon-container">
+                                    <i class="{{.Icon}} fa-xl icon"></i>
+                                </div>
+                                <h6>{{.Name}}</h6>
+                            </a>
+                        {{end}}
+                    </div>
+                {{end}}
+                </div>
+            {{end}}
+            </div>
         </div>
         <div id="footer" class="row"></div>
     </div>
 
+    <script src="theme/js/skycons.min.js"></script>
+    <script src="common/js/core.js"></script>
     <script>
         window.config = {
-            localization: {{ .Config.Localization }},
-            language: {{ .Config.Language }},
-            useMetric: {{ .Config.UseMetric }}
+            localization: {{.Config.Localization}},
+            language: {{.Config.Language}},
+            useMetric: {{.Config.UseMetric}}
         };
-    </script>
 
-    <script src="theme/js/skycons.min.js"></script>
-    <script src="common/js/core.js"></script>
-    <script src="theme/js/magma.js"></script>
+        (function setTimer() {
+            const clock = document.querySelector("#clock");
+            const clockOptions = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' };
+            (function clockTick() {
+                clock.innerText = new Date().toLocaleTimeString(window.config.localization, clockOptions);
+                setTimeout(clockTick, 2000);
+            })();
+            //Set greeting
+            const greeting = document.querySelector("#greeting");
+            const hour = new Date().getHours();
+            if (hour >= 5 && hour < 12) {
+                greeting.innerText = {{.Language.Greeting.Morning}};
+            }
+            else if (hour >= 12 && hour < 17) {
+                greeting.innerText = {{.Language.Greeting.Afternoon}};
+            }
+            else if (hour >= 17 && hour < 20) {
+                greeting.innerText = {{.Language.Greeting.Evening}};
+            }
+            else {
+                greeting.innerText = {{.Language.Greeting.Night}};
+            }
+        })();
+
+        (async function loadWeather() {
+            // Get info from api
+            const weather = await (await fetch("./weather")).json();
+            // Parse weather id
+            let icon = null;
+            let isDay = Date.now().hour >= 6 && Date.now().hour < 18;
+            const weatherCode = weather.weather[0].id;
+            if ([200, 201, 202, 210, 211, 212, 221, 230, 231, 232].includes(weatherCode)) {
+                icon = Skycons.RAIN; //Thunderstorm
+            } else if ([300, 301, 302, 310, 311, 312, 313, 314, 321].includes(weatherCode)) {
+                icon = Skycons.RAIN; //Drizzle
+            } else if ([500, 501, 502, 503, 504, 511, 520, 521, 522, 531].includes(weatherCode)) {
+                icon = Skycons.RAIN;
+            } else if ([600, 601, 602, 611, 612, 613, 615, 616, 620, 621, 622].includes(weatherCode)) {
+                icon = Skycons.SNOW;
+            } else if (weatherCode === 800) {
+                icon = isDay ? Skycons.CLEAR_DAY : Skycons.CLEAR_NIGHT;
+            } else if ([801, 802, 803, 804].includes(weatherCode)) {
+                if (weatherCode >= 803) {
+                    icon = Skycons.CLOUDY;
+                } else {
+                    icon = isDay ? Skycons.PARTLY_CLOUDY_DAY : Skycons.PARTLY_CLOUDY_NIGHT;
+                }
+            } else if ([762, 761, 751, 731, 721].includes(weatherCode)) {
+                icon = Skycons.SLEET;
+            } else if ([771, 781].includes(weatherCode)) {
+                icon = Skycons.WIND;
+            } else if ([701, 711, 741].includes(weatherCode)) {
+                icon = Skycons.FOG;
+            } else {
+                return;
+            }
+            // Set weather icon to canvas
+            var skycons = new Skycons({ "color": window.cssRoot["--accentColor"] });
+            skycons.add("weather-icon", icon);
+            // Set weather info
+            if (window.config.useMetric) {
+                document.querySelector("#temp").innerText = Math.floor(weather.main.temp - 273.15) + "°C";
+            } else {
+                document.querySelector("#temp").innerText = Math.floor((weather.main.temp - 32) * 5 / 9) + "°F";
+            }
+            document.querySelector("#humidity").innerText = Math.floor(weather.main.humidity) + "%";
+            document.querySelector("#weather-info").style.visibility = "visible";
+        })();
+    </script>
     <script src="common/js/custom.js"></script>
 </body>
 

+ 0 - 166
src/themes/flame/js/magma.js

@@ -1,166 +0,0 @@
-// async function loadConfig() {
-//     window.config = await (await fetch("./common/config.json")).json();
-//     // Set website language
-//     document.documentElement.setAttribute("lang", window.config.website.language);
-//     // Set website title
-//     document.title = window.config.website.title;
-//     // Set website description
-//     document.querySelector('meta[name="description"]').setAttribute("content", window.config.website.description);
-// }
-
-async function loadLanguage() {
-    try {
-        window.language = await (await fetch(`./languages/${window.config.language}.json`)).json();
-    } catch {
-        console.error("Language file not found");
-        window.language = await (await fetch(`./languages/en.json`)).json();
-    }
-}
-
-async function loadWeather() {
-    return;
-    // Get info from api
-    const weather = await (await fetch("./weather")).json();
-    // Parse weather id
-    let icon = null;
-    let isDay = Date.now().hour >= 6 && Date.now().hour < 18;
-    const weatherCode = weather.weather[0].id;
-    if ([200, 201, 202, 210, 211, 212, 221, 230, 231, 232].includes(weatherCode)) {
-        icon = Skycons.RAIN; //Thunderstorm
-    } else if ([300, 301, 302, 310, 311, 312, 313, 314, 321].includes(weatherCode)) {
-        icon = Skycons.RAIN; //Drizzle
-    } else if ([500, 501, 502, 503, 504, 511, 520, 521, 522, 531].includes(weatherCode)) {
-        icon = Skycons.RAIN;
-    } else if ([600, 601, 602, 611, 612, 613, 615, 616, 620, 621, 622].includes(weatherCode)) {
-        icon = Skycons.SNOW;
-    } else if (weatherCode === 800) {
-        icon = isDay ? Skycons.CLEAR_DAY : Skycons.CLEAR_NIGHT;
-    } else if ([801, 802, 803, 804].includes(weatherCode)) {
-        if (weatherCode >= 803) {
-            icon = Skycons.CLOUDY;
-        } else {
-            icon = isDay ? Skycons.PARTLY_CLOUDY_DAY : Skycons.PARTLY_CLOUDY_NIGHT;
-        }
-    } else if ([762, 761, 751, 731, 721].includes(weatherCode)) {
-        icon = Skycons.SLEET;
-    } else if ([771, 781].includes(weatherCode)) {
-        icon = Skycons.WIND;
-    } else if ([701, 711, 741].includes(weatherCode)) {
-        icon = Skycons.FOG;
-    } else {
-        return;
-    }
-    // Set weather icon to canvas
-    var skycons = new Skycons({ "color": window.cssRoot["--accentColor"] });
-    skycons.add("weather-icon", icon);
-    // Set weather info
-    if (window.config.useMetric) {
-        document.querySelector("#temp").innerText = Math.floor(weather.main.temp - 273.15) + "°C";
-    } else {
-        document.querySelector("#temp").innerText = Math.floor((weather.main.temp - 32) * 5 / 9) + "°F";
-    }
-    document.querySelector("#humidity").innerText = Math.floor(weather.main.humidity) + "%";
-    document.querySelector("#weather-info").style.visibility = "visible";
-}
-
-async function loadBookmarks() {
-    const data = await (await fetch("./common/data.json")).json();
-    let contentHtml = "";
-
-    function splitToChunks(arr) {
-        var chunks = [[], [], [], []];
-        var i = 0;
-        for (let j = 0; j < arr.length; j++) {
-            chunks[i].push(arr[j]);
-            i++;
-            if (i === 4) i = 0;
-        }
-        return chunks;
-    }
-
-    function splitToEqualChunks(arr) {
-        var chunks = [];
-        var i = 0;
-        while (i < arr.length) {
-            chunks.push(arr.slice(i, Math.min(i + 4, arr.length)));
-            i += 4;
-        }
-        return chunks;
-    }
-
-    data.forEach(section => {
-        contentHtml += `<div class="row group-title"><h4 class="strong">${section.title}</h4></div>`
-        if (section.columns) {
-            const chunks = splitToEqualChunks(section.columns)
-            chunks.forEach(chunk => {
-                contentHtml += '<div class="row">';
-                chunk.forEach(column => {
-                    contentHtml += `
-                    <div class="three columns group-items">
-                    <h6 class="accent">${column.title}</h6>`;
-                    column.bookmarks.forEach(bookmark => {
-                        contentHtml += `
-                    <a href="${bookmark.url}">
-                        <i class="${bookmark.icon} fa-xl icon"></i>
-                        <h6>${bookmark.title}</h6>
-                    </a>`;
-                    });
-                    contentHtml += "</div>";
-                });
-                contentHtml += "</div>";
-            });
-
-        } else if (section.bookmarks) {
-            contentHtml += '<div class="row">';
-            const chunks = splitToChunks(section.bookmarks)
-            chunks.forEach(chunk => {
-                contentHtml += '<div class="three columns group-items">';
-                chunk.forEach(bookmark => {
-                    contentHtml += `
-                        <a href="${bookmark.url}">
-                            <i class="${bookmark.icon} fa-xl icon"></i>
-                            <h6>${bookmark.title}</h6>
-                        </a>`;
-                });
-                contentHtml += "</div>";
-            });
-            contentHtml += "</div>";
-        }
-    });
-
-    document.querySelector("#content").innerHTML = contentHtml;
-}
-
-function setClock() {
-    //Set clock
-    const clock = document.querySelector("#clock");
-    const clockOptions = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' };
-    (function clockTick() {
-        clock.innerText = new Date().toLocaleTimeString(window.config.localization, clockOptions);
-        setTimeout(clockTick, 2000);
-    })();
-    //Set greeting
-    const greeting = document.querySelector("#greeting");
-    const hour = new Date().getHours();
-    if (hour >= 5 && hour < 12) {
-        greeting.innerText = window.language.greeting.morning;
-    }
-    else if (hour >= 12 && hour < 17) {
-        greeting.innerText = window.language.greeting.afternoon;
-    }
-    else if (hour >= 17 && hour < 20) {
-        greeting.innerText = window.language.greeting.evening;
-    }
-    else {
-        greeting.innerText = window.language.greeting.night;
-    }
-}
-
-async function startWebsite() {
-    loadBookmarks();
-    await loadLanguage();
-    setClock();
-    loadCSS();
-    loadWeather();
-}
-startWebsite();