commit acea5ba561db0864b040b38e2ac59af03b807a8a
Author: PaulK <ia21a.koester.paul@bk-hennef.de>
Date:   Tue Nov 19 10:12:02 2024 +0100

    start

diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..f29d257
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,11 @@
+# editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..c664a90
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,194 @@
+## GITATTRIBUTES FOR WEB PROJECTS
+#
+# These settings are for any web project.
+#
+# Details per file setting:
+#   text    These files should be normalized (i.e. convert CRLF to LF).
+#   binary  These files are binary and should be left untouched.
+#
+# Note that binary is a macro for -text -diff.
+######################################################################
+
+## AUTO-DETECT
+##   Handle line endings automatically for files detected as
+##   text and leave all files detected as binary untouched.
+##   This will handle all files NOT defined below.
+* text=auto
+
+## SOURCE CODE
+*.bat      text eol=crlf
+*.coffee   text
+*.css      text
+*.htm      text
+*.html     text
+*.inc      text
+*.ini      text
+*.js       text
+*.json     text
+*.jsx      text
+*.less     text
+*.od       text
+*.onlydata text
+*.php      text
+*.pl       text
+*.py       text
+*.rb       text
+*.sass     text
+*.scm      text
+*.scss     text
+*.sh       text eol=lf
+*.sql      text
+*.styl     text
+*.tag      text
+*.ts       text
+*.tsx      text
+*.xml      text
+*.xhtml    text
+
+## DOCKER
+*.dockerignore text
+Dockerfile     text
+
+## DOCUMENTATION
+*.markdown   text
+*.md         text
+*.mdwn       text
+*.mdown      text
+*.mkd        text
+*.mkdn       text
+*.mdtxt      text
+*.mdtext     text
+*.txt        text
+AUTHORS      text
+CHANGELOG    text
+CHANGES      text
+CONTRIBUTING text
+COPYING      text
+copyright    text
+*COPYRIGHT*  text
+INSTALL      text
+license      text
+LICENSE      text
+NEWS         text
+readme       text
+*README*     text
+TODO         text
+
+## TEMPLATES
+*.dot        text
+*.ejs        text
+*.haml       text
+*.handlebars text
+*.hbs        text
+*.hbt        text
+*.jade       text
+*.latte      text
+*.mustache   text
+*.njk        text
+*.phtml      text
+*.tmpl       text
+*.tpl        text
+*.twig       text
+
+## LINTERS
+.babelrc      text
+.csslintrc    text
+.eslintrc     text
+.htmlhintrc   text
+.jscsrc       text
+.jshintrc     text
+.jshintignore text
+.prettierrc   text
+.stylelintrc  text
+
+## CONFIGS
+*.bowerrc       text
+*.cnf           text
+*.conf          text
+*.config        text
+.browserslistrc text
+.editorconfig   text
+.gitattributes  text
+.gitconfig      text
+.gitignore      text
+.htaccess       text
+*.npmignore     text
+*.yaml          text
+*.yml           text
+browserslist    text
+Makefile        text
+makefile        text
+
+## HEROKU
+Procfile    text
+.slugignore text
+
+## GRAPHICS
+*.ai   binary
+*.bmp  binary
+*.eps  binary
+*.gif  binary
+*.ico  binary
+*.jng  binary
+*.jp2  binary
+*.jpg  binary
+*.jpeg binary
+*.jpx  binary
+*.jxr  binary
+*.pdf  binary
+*.png  binary
+*.psb  binary
+*.psd  binary
+*.svg  text
+*.svgz binary
+*.tif  binary
+*.tiff binary
+*.wbmp binary
+*.webp binary
+
+## AUDIO
+*.kar  binary
+*.m4a  binary
+*.mid  binary
+*.midi binary
+*.mp3  binary
+*.ogg  binary
+*.ra   binary
+
+## VIDEO
+*.3gpp binary
+*.3gp  binary
+*.as   binary
+*.asf  binary
+*.asx  binary
+*.fla  binary
+*.flv  binary
+*.m4v  binary
+*.mng  binary
+*.mov  binary
+*.mp4  binary
+*.mpeg binary
+*.mpg  binary
+*.ogv  binary
+*.swc  binary
+*.swf  binary
+*.webm binary
+
+## ARCHIVES
+*.7z  binary
+*.gz  binary
+*.jar binary
+*.rar binary
+*.tar binary
+*.zip binary
+
+## FONTS
+*.ttf   binary
+*.eot   binary
+*.otf   binary
+*.woff  binary
+*.woff2 binary
+
+## EXECUTABLES
+*.exe binary
+*.pyc binary
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..427305a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+# Include your project-specific ignores in this file
+# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files
+# Useful .gitignore templates: https://github.com/github/gitignore
+node_modules
+dist
+.cache
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/RC_Car.iml b/.idea/RC_Car.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/RC_Car.iml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..639900d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..9f6c462
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/RC_Car.iml" filepath="$PROJECT_DIR$/.idea/RC_Car.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/404.html b/404.html
new file mode 100644
index 0000000..260cc4c
--- /dev/null
+++ b/404.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8">
+  <title>Page Not Found</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <style>
+    * {
+      line-height: 1.2;
+      margin: 0;
+    }
+
+    html {
+      color: #888;
+      display: table;
+      font-family: sans-serif;
+      height: 100%;
+      text-align: center;
+      width: 100%;
+    }
+
+    body {
+      display: table-cell;
+      vertical-align: middle;
+      margin: 2em auto;
+    }
+
+    h1 {
+      color: #555;
+      font-size: 2em;
+      font-weight: 400;
+    }
+
+    p {
+      margin: 0 auto;
+      width: 280px;
+    }
+
+    @media only screen and (max-width: 280px) {
+
+      body,
+      p {
+        width: 95%;
+      }
+
+      h1 {
+        font-size: 1.5em;
+        margin: 0 0 0.3em;
+      }
+
+    }
+  </style>
+</head>
+
+<body>
+  <h1>Page Not Found</h1>
+  <p>Sorry, but the page you were trying to view does not exist.</p>
+</body>
+
+</html>
+<!-- IE needs 512+ bytes: https://docs.microsoft.com/archive/blogs/ieinternals/friendly-http-error-pages -->
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..294e91d
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (c) HTML5 Boilerplate
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/arrow.png b/arrow.png
new file mode 100644
index 0000000..c3dd384
Binary files /dev/null and b/arrow.png differ
diff --git a/connect.py b/connect.py
new file mode 100644
index 0000000..620cdfc
--- /dev/null
+++ b/connect.py
@@ -0,0 +1,24 @@
+from flask import Flask, render_template, request
+import bluetooth
+
+app = Flask(__name__)
+
+# Bluetooth-Geräte in der Nähe scannen
+def scan_devices():
+    nearby_devices = bluetooth.discover_devices(duration=8, lookup_names=True)
+    devices = [(addr, name) for addr, name in nearby_devices]
+    return devices
+
+@app.route('/')
+def index():
+    devices = scan_devices()
+    return render_template('controller.html', devices=devices)
+
+@app.route('/connect', methods=['POST'])
+def connect():
+    selected_device = request.form['device']
+    # Hier fügst du den Code hinzu, um dich mit dem ausgewählten Gerät zu verbinden
+    return f"Connecting to device: {selected_device}"
+
+if __name__ == '__main__':
+    app.run(debug=True)
diff --git a/controller.html b/controller.html
new file mode 100644
index 0000000..a691132
--- /dev/null
+++ b/controller.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Bluetooth Controller Auswahl</title>
+</head>
+<body>
+<h1>Verfügbare Bluetooth-Controller</h1>
+<form action="/connect" method="post">
+  <select name="controller">
+    {% for addr, name in controllers %}
+    <option value="{{ addr }}">{{ name }}</option>
+    {% endfor %}
+  </select>
+  <button type="submit">Verbinden</button>
+</form>
+</body>
+</html>
diff --git a/controller.jpg b/controller.jpg
new file mode 100644
index 0000000..69595f2
Binary files /dev/null and b/controller.jpg differ
diff --git a/css/style.css b/css/style.css
new file mode 100644
index 0000000..654e876
--- /dev/null
+++ b/css/style.css
@@ -0,0 +1,247 @@
+/*! HTML5 Boilerplate v9.0.0-RC1 | MIT License | https://html5boilerplate.com/ */
+
+/* main.css 3.0.0 | MIT License | https://github.com/h5bp/main.css#readme */
+/*
+ * What follows is the result of much research on cross-browser styling.
+ * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
+ * Kroc Camen, and the H5BP dev community and team.
+ */
+
+/* ==========================================================================
+   Base styles: opinionated defaults
+   ========================================================================== */
+
+html {
+  color: #222;
+  font-size: 1em;
+  line-height: 1.4;
+}
+
+/*
+ * Remove text-shadow in selection highlight:
+ * https://twitter.com/miketaylr/status/12228805301
+ *
+ * Customize the background color to match your design.
+ */
+
+::-moz-selection {
+  background: #b3d4fc;
+  text-shadow: none;
+}
+
+::selection {
+  background: #b3d4fc;
+  text-shadow: none;
+}
+
+/*
+ * A better looking default horizontal rule
+ */
+
+hr {
+  display: block;
+  height: 1px;
+  border: 0;
+  border-top: 1px solid #ccc;
+  margin: 1em 0;
+  padding: 0;
+}
+
+/*
+ * Remove the gap between audio, canvas, iframes,
+ * images, videos and the bottom of their containers:
+ * https://github.com/h5bp/html5-boilerplate/issues/440
+ */
+
+audio,
+canvas,
+iframe,
+img,
+svg,
+video {
+  vertical-align: middle;
+}
+
+/*
+ * Remove default fieldset styles.
+ */
+
+fieldset {
+  border: 0;
+  margin: 0;
+  padding: 0;
+}
+
+/*
+ * Allow only vertical resizing of textareas.
+ */
+
+textarea {
+  resize: vertical;
+}
+
+/* ==========================================================================
+   Author's custom styles
+   ========================================================================== */
+
+/* ==========================================================================
+   Helper classes
+   ========================================================================== */
+
+/*
+ * Hide visually and from screen readers
+ */
+
+.hidden,
+[hidden] {
+  display: none !important;
+}
+
+/*
+ * Hide only visually, but have it available for screen readers:
+ * https://snook.ca/archives/html_and_css/hiding-content-for-accessibility
+ *
+ * 1. For long content, line feeds are not interpreted as spaces and small width
+ *    causes content to wrap 1 word per line:
+ *    https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
+ */
+
+.visually-hidden {
+  border: 0;
+  clip: rect(0, 0, 0, 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  white-space: nowrap;
+  width: 1px;
+  /* 1 */
+}
+
+/*
+ * Extends the .visually-hidden class to allow the element
+ * to be focusable when navigated to via the keyboard:
+ * https://www.drupal.org/node/897638
+ */
+
+.visually-hidden.focusable:active,
+.visually-hidden.focusable:focus {
+  clip: auto;
+  height: auto;
+  margin: 0;
+  overflow: visible;
+  position: static;
+  white-space: inherit;
+  width: auto;
+}
+
+/*
+ * Hide visually and from screen readers, but maintain layout
+ */
+
+.invisible {
+  visibility: hidden;
+}
+
+/*
+ * Clearfix: contain floats
+ *
+ * The use of `table` rather than `block` is only necessary if using
+ * `::before` to contain the top-margins of child elements.
+ */
+
+.clearfix::before,
+.clearfix::after {
+  content: "";
+  display: table;
+}
+
+.clearfix::after {
+  clear: both;
+}
+
+/* ==========================================================================
+   EXAMPLE Media Queries for Responsive Design.
+   These examples override the primary ('mobile first') styles.
+   Modify as content requires.
+   ========================================================================== */
+
+@media only screen and (min-width: 35em) {
+  /* Style adjustments for viewports that meet the condition */
+}
+
+@media print,
+  (-webkit-min-device-pixel-ratio: 1.25),
+  (min-resolution: 1.25dppx),
+  (min-resolution: 120dpi) {
+  /* Style adjustments for high resolution devices */
+}
+
+/* ==========================================================================
+   Print styles.
+   Inlined to avoid the additional HTTP request:
+   https://www.phpied.com/delay-loading-your-print-css/
+   ========================================================================== */
+
+@media print {
+  *,
+  *::before,
+  *::after {
+    background: #fff !important;
+    color: #000 !important;
+    /* Black prints faster */
+    box-shadow: none !important;
+    text-shadow: none !important;
+  }
+
+  a,
+  a:visited {
+    text-decoration: underline;
+  }
+
+  a[href]::after {
+    content: " (" attr(href) ")";
+  }
+
+  abbr[title]::after {
+    content: " (" attr(title) ")";
+  }
+
+  /*
+   * Don't show links that are fragment identifiers,
+   * or use the `javascript:` pseudo protocol
+   */
+  a[href^="#"]::after,
+  a[href^="javascript:"]::after {
+    content: "";
+  }
+
+  pre {
+    white-space: pre-wrap !important;
+  }
+
+  pre,
+  blockquote {
+    border: 1px solid #999;
+    page-break-inside: avoid;
+  }
+
+  tr,
+  img {
+    page-break-inside: avoid;
+  }
+
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3;
+  }
+
+  h2,
+  h3 {
+    page-break-after: avoid;
+  }
+}
+
diff --git a/favicon.ico b/favicon.ico
new file mode 100644
index 0000000..be74abd
Binary files /dev/null and b/favicon.ico differ
diff --git a/handy.jpg b/handy.jpg
new file mode 100644
index 0000000..f76c763
Binary files /dev/null and b/handy.jpg differ
diff --git a/icon.png b/icon.png
new file mode 100644
index 0000000..8a42581
Binary files /dev/null and b/icon.png differ
diff --git a/icon.svg b/icon.svg
new file mode 100644
index 0000000..f232922
--- /dev/null
+++ b/icon.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 192 192"><path fill="#e08524" d="M75.3 73.4H18.4l45.3 34.3L48.3 163l46.1-32.3 48.2 34.6-16.9-58.3 44.9-33.6H115l-20.5-55-19.2 55z"/><path d="m96.7 18.8 18.2 8.2 16.5 44.3h-15.1L96.7 18.8zm-47 146 18.7 9.9 42.6-29.9-16.5-11.4-44.8 31.4zm79.1-56.8 17.4 9.4 18.6 60.1-19.7-11.3-16.3-58.2z"/><path d="m173.1 74.3 17.8 9.2-44.7 34-17.4-9.4 44.3-33.8z"/></svg>
diff --git a/img/.gitkeep b/img/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..43bbd4e
--- /dev/null
+++ b/index.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="de">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Mein Menü</title>
+  <style>
+    body {
+      font-family: Arial, sans-serif;
+      margin: 0;
+      padding: 0;
+    }
+
+    .menu {
+      background-color: #333;
+      overflow: hidden;
+    }
+
+    .menu a {
+      float: left;
+      display: block;
+      color: white;
+      text-align: center;
+      padding: 14px 16px;
+      text-decoration: none;
+    }
+
+    .menu a:hover {
+      background-color: #ddd;
+      color: black;
+    }
+
+    .content {
+      padding: 20px;
+    }
+
+    .hidden {
+      display: none;
+    }
+
+    #control img {
+      max-width: 25%;
+      height: auto;
+      cursor: pointer; /* Hinzugefügt, um den Mauszeiger zu ändern */
+    }
+  </style>
+</head>
+<body>
+
+<div class="menu">
+  <a href="#" onclick="showContent('home')">Startseite</a>
+  <a href="#" onclick="showContent('control')">Steuerung</a>
+</div>
+
+<div id="home" class="content">
+  <h2>Startseite</h2>
+  <p>Willkommen auf der Startseite!</p>
+</div>
+
+<!-- Bild -->
+<div id="control" class="content hidden">
+  <h2>Steuerung</h2>
+  <p>Wählen Sie ein Steuergerät!</p>
+  <a href="joystick.html" style="position: absolute; top: 250px; left: 200px;">
+    <img src="handy.jpg" alt="Handy Bild" style="width: 250px; height: 100px;">
+  </a>
+  <a href="controller.html" style="position: absolute; top: 450px; left: 200px">
+    <img src="controller.jpg" alt="Controller Bild" style="width: 400px; height: 90px;">
+  </a>
+</div>
+
+
+<script>
+  function showContent(id) {
+    // Alle Inhalte ausblenden
+    var contents = document.getElementsByClassName("content");
+    for (var i = 0; i < contents.length; i++) {
+      contents[i].classList.add("hidden");
+    }
+
+    // Nur das angeklickte Element anzeigen
+    var element = document.getElementById(id);
+    if (element) {
+      element.classList.remove("hidden");
+    }
+  }
+</script>
+
+</body>
+</html>
diff --git a/joystick.html b/joystick.html
new file mode 100644
index 0000000..2fed6f1
--- /dev/null
+++ b/joystick.html
@@ -0,0 +1,343 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Circular Control Stick</title>
+  <style>
+    body {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      height: 100vh;
+      margin: 0;
+      background-color: #f0f0f0; /* Change the background color as needed */
+    }
+
+    #control-container {
+      position: relative;
+      width: 400px; /* Adjust the overall size as needed */
+      height: 400px; /* Adjust the overall size as needed */
+      border-radius: 50%;
+      border: 2px solid black; /* Outline style for the outer circle */
+      box-sizing: border-box;
+      touch-action: none; /* Disable touch actions to prevent scrolling on touch devices */
+      overflow: hidden; /* Hide the overflow of the lines */
+    }
+
+    #inner-stick {
+      position: absolute;
+      width: 80px; /* Adjust the inner control stick size as needed */
+      height: 80px; /* Adjust the inner control stick size as needed */
+      background-color: black; /* Filled color for the inner circle */
+      border-radius: 50%;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      touch-action: none; /* Disable touch actions on the inner stick */
+      user-select: none; /* Disable text selection on the inner stick */
+    }
+
+    .line {
+      position: absolute;
+      width: 100%;
+      height: 2px;
+      background-color: black;
+      transform-origin: 50% 50%;
+      left: 0;
+      top: 50%;
+    }
+
+    .line:nth-child(1) {
+      transform: rotate(22.5deg);
+    }
+
+    .line:nth-child(2) {
+      transform: rotate(67.5deg);
+    }
+
+    .line:nth-child(3) {
+      transform: rotate(112.5deg);
+    }
+
+    .line:nth-child(4) {
+      transform: rotate(157.5deg);
+    }
+
+    .line:nth-child(5) {
+      transform: rotate(202.5deg);
+    }
+
+    .line:nth-child(6) {
+      transform: rotate(247.5deg);
+    }
+
+    .line:nth-child(7) {
+      transform: rotate(292.5deg);
+    }
+
+    .line:nth-child(8) {
+      transform: rotate(337.5deg);
+    }
+
+    .text {
+      position: absolute;
+      width: 100%;
+      text-align: center;
+      font-size: 15px;
+      color: black;
+      transform-origin: 50% 50%;
+    }
+
+    #text-forward {
+      top: 5px;
+    }
+
+    #text-forward-right {
+      top: 25%;
+      left: 20%;
+      transform: rotate(-45deg);
+    }
+
+    #text-forward-left {
+      top: 25%;
+      right: 20%;
+      transform: rotate(45deg);
+    }
+
+    #text-right {
+      left: 45%;
+      top: 50%;
+      transform: translateY(-50%) rotate(-90deg);
+    }
+
+    #text-left {
+      right: 45%;
+      top: 50%;
+      transform: translateY(-50%) rotate(90deg);
+    }
+
+    #text-backward {
+      bottom: 5px;
+    }
+
+    #text-backward-right {
+      bottom: 25%;
+      left: 20%;
+      transform: rotate(45deg);
+    }
+
+    #text-backward-left {
+      bottom: 25%;
+      right: 20%;
+      transform: rotate(-45deg);
+    }
+  </style>
+</head>
+<body>
+<!-- Image clickable -->
+<a href="index.html" style="position: absolute; top: 10px; left: 10px;">
+  <img src="arrow.png" alt="Klickbarer Pfeil" style="width: 150px; height: 100px;">
+</a>
+
+<div id="control-container">
+
+  <!-- Lines to divide the outer circle -->
+  <div class="line"></div>
+  <div class="line"></div>
+  <div class="line"></div>
+  <div class="line"></div>
+
+  <!-- Text elements -->
+  <div class="text" id="text-forward">Forward</div>
+  <div class="text" id="text-forward-left">Forward-Left</div>
+  <div class="text" id="text-forward-right">Forward-Right</div>
+  <div class="text" id="text-left">Left</div>
+  <div class="text" id="text-right">Right</div>
+  <div class="text" id="text-backward">Backward</div>
+  <div class="text" id="text-backward-left">Backward-Left</div>
+  <div class="text" id="text-backward-right">Backward-Right</div>
+
+  <!-- Inner stick -->
+  <div id="inner-stick"></div>
+
+</div>
+
+<script>
+  // JavaScript for handling control stick movement
+  var controlContainer = document.getElementById('control-container');
+  var innerStick = document.getElementById('inner-stick');
+
+  // Variables to store the initial position and touch/mouse state
+  var initialX, initialY, isTouched = false;
+
+  // Event listeners for touch events
+  innerStick.addEventListener('touchstart', handleTouchStart);
+  innerStick.addEventListener('touchmove', handleTouchMove);
+  innerStick.addEventListener('touchend', handleTouchEnd);
+
+  // Event listeners for mouse events
+  innerStick.addEventListener('mousedown', handleMouseDown);
+  window.addEventListener('mousemove', handleMouseMove);
+  window.addEventListener('mouseup', handleMouseUp);
+
+  // Touch event handlers
+  function handleTouchStart(event) {
+    isTouched = true;
+    var touch = event.touches[0];
+    initialX = touch.clientX - controlContainer.offsetLeft;
+    initialY = touch.clientY - controlContainer.offsetTop;
+  }
+
+  function handleTouchMove(event) {
+    if (!isTouched) return;
+
+    var touch = event.touches[0];
+    var currentX = touch.clientX - controlContainer.offsetLeft;
+    var currentY = touch.clientY - controlContainer.offsetTop;
+
+    moveInnerStick(currentX, currentY);
+    sendCommandBasedOnSector(currentX, currentY);
+    event.preventDefault();
+    if (event.touches.length == 0) {
+      resetInnerStickPosition();
+    }
+  }
+
+  function handleTouchEnd() {
+    isTouched = false;
+    resetInnerStickPosition();
+  }
+
+  // Mouse event handlers
+  function handleMouseDown(event) {
+    isTouched = true;
+    initialX = event.clientX - controlContainer.offsetLeft;
+    initialY = event.clientY - controlContainer.offsetTop;
+  }
+
+  function handleMouseMove(event) {
+    if (!isTouched) return;
+
+    var currentX = event.clientX - controlContainer.offsetLeft;
+    var currentY = event.clientY - controlContainer.offsetTop;
+
+    moveInnerStick(currentX, currentY);
+    sendCommandBasedOnSector(currentX, currentY);
+    if (!event.buttons) {
+      resetInnerStickPosition();
+    }
+  }
+
+  function handleMouseUp() {
+    isTouched = false;
+    resetInnerStickPosition();
+  }
+
+  // Function to move the inner stick
+  function moveInnerStick(x, y) {
+    var deltaX = x - initialX;
+    var deltaY = y - initialY;
+
+    // Ensure the inner stick stays within the bounds of the container
+    var distance = Math.min(
+      Math.hypot(deltaX, deltaY),
+      controlContainer.clientWidth / 2 - innerStick.clientWidth / 2
+    );
+
+    var angle = Math.atan2(deltaY, deltaX);
+    var newX = Math.cos(angle) * distance + controlContainer.clientWidth / 2;
+    var newY = Math.sin(angle) * distance + controlContainer.clientHeight / 2;
+
+    innerStick.style.left = newX + 'px';
+    innerStick.style.top = newY + 'px';
+  }
+
+  // Function to reset the inner stick to the center
+  function resetInnerStickPosition() {
+    innerStick.style.left = '50%';
+    innerStick.style.top = '50%';
+    sendCommand('/move/stop');
+  }
+
+  var lastcommand;
+
+  // Function to send a command (replace with actual command logic)
+  function sendCommand(command) {
+
+    if (lastcommand !== command) {
+      lastcommand = command;
+      console.log('Command Sent:', command);
+
+      // Vollständige URL zum Flask-Server
+      var url = 'http://192.168.4.1:5000' + command;  // Bitte die IP-Adresse und Portnummer anpassen
+
+      // AJAX-Anfrage erstellen
+      var xhr = new XMLHttpRequest();
+      xhr.open('POST', url, true);  // URL anpassen, um sie an Ihren Server anzupassen
+      xhr.setRequestHeader('Content-Type', 'application/json');
+      xhr.onreadystatechange = function () {
+        if (xhr.readyState === XMLHttpRequest.DONE) {
+          if (xhr.status === 200) {
+            console.log('Command successfully sent to server:' + command);
+          } else {
+            console.error('Failed to send command to server.');
+          }
+        }
+      };
+      xhr.send();
+    }
+  }
+
+  // ich hab dich gaaaaaanz dolle lieb bubu, ich bin super stolz auf dich, du machst das echt super duper toll
+
+
+  // Function to log the inner stick position to the console
+  function sendCommandBasedOnSector(x, y) {
+    var deltaX = x - controlContainer.clientWidth / 2;
+    var deltaY = y - controlContainer.clientHeight / 2;
+
+    // Calculate the angle of the inner stick
+    var angle = Math.atan2(deltaY, deltaX);
+    var angleDeg = (angle * 180) / Math.PI;
+
+    // Convert negative angles to positive for simplicity
+    if (angleDeg < 0) {
+      angleDeg += 360;
+    }
+
+    // Determine the sector based on the angle
+    var sector = Math.floor((angleDeg + 22.5) / 45) % 8;
+
+    // Send a command based on the sector
+    switch (sector) {
+      case 0: // Right
+        sendCommand('/move/right');
+        break;
+      case 1: // Back-Right
+        sendCommand('/move/back-right');
+        break;
+      case 2: // Back
+        sendCommand('/move/back');
+        break;
+      case 3: // Back-Left
+        sendCommand('/move/back-left');
+        break;
+      case 4: // Left
+        sendCommand('/move/left');
+        break;
+      case 5: // Front-Left
+        sendCommand('/move/front-left');
+        break;
+      case 6: // Forward
+        sendCommand('/move/Front');
+        break;
+      case 7: // Front-Right
+        sendCommand('/move/front-right');
+        break;
+    }
+  }
+</script>
+
+</body>
+</html>
diff --git a/js/app.js b/js/app.js
new file mode 100644
index 0000000..e69de29
diff --git a/js/vendor/.gitkeep b/js/vendor/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..5353ddf
--- /dev/null
+++ b/package.json
@@ -0,0 +1,24 @@
+{
+  "name": " ",
+  "version": "0.0.1",
+  "description": "",
+  "private": true,
+  "keywords": [
+    ""
+  ],
+  "license": "",
+  "author": "",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "start": "webpack serve --open --config webpack.config.dev.js",
+    "build": "webpack --config webpack.config.prod.js"
+  },
+  "devDependencies": {
+    "copy-webpack-plugin": "^11.0.0",
+    "html-webpack-plugin": "^5.5.3",
+    "webpack": "^5.88.2",
+    "webpack-cli": "^5.1.4",
+    "webpack-dev-server": "^4.15.1",
+    "webpack-merge": "^5.9.0"
+  }
+}
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 0000000..d0e5f1b
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,5 @@
+# www.robotstxt.org/
+
+# Allow crawling of all content
+User-agent: *
+Disallow:
diff --git a/site.webmanifest b/site.webmanifest
new file mode 100644
index 0000000..222ae16
--- /dev/null
+++ b/site.webmanifest
@@ -0,0 +1,12 @@
+{
+  "short_name": "",
+  "name": "",
+  "icons": [{
+    "src": "icon.png",
+    "type": "image/png",
+    "sizes": "192x192"
+  }],
+  "start_url": "/?utm_source=homescreen",
+  "background_color": "#fafafa",
+  "theme_color": "#fafafa"
+}
diff --git a/webpack.common.js b/webpack.common.js
new file mode 100644
index 0000000..b502ea9
--- /dev/null
+++ b/webpack.common.js
@@ -0,0 +1,12 @@
+const path = require('path');
+
+module.exports = {
+  entry: {
+    app: './js/app.js',
+  },
+  output: {
+    path: path.resolve(__dirname, 'dist'),
+    clean: true,
+    filename: './js/app.js',
+  },
+};
diff --git a/webpack.config.dev.js b/webpack.config.dev.js
new file mode 100644
index 0000000..5953807
--- /dev/null
+++ b/webpack.config.dev.js
@@ -0,0 +1,13 @@
+const { merge } = require('webpack-merge');
+const common = require('./webpack.common.js');
+
+module.exports = merge(common, {
+  mode: 'development',
+  devtool: 'inline-source-map',
+  devServer: {
+    liveReload: true,
+    hot: true,
+    open: true,
+    static: ['./'],
+  },
+});
diff --git a/webpack.config.prod.js b/webpack.config.prod.js
new file mode 100644
index 0000000..76800e8
--- /dev/null
+++ b/webpack.config.prod.js
@@ -0,0 +1,26 @@
+const { merge } = require('webpack-merge');
+const common = require('./webpack.common.js');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const CopyPlugin = require('copy-webpack-plugin');
+
+module.exports = merge(common, {
+  mode: 'production',
+  plugins: [
+    new HtmlWebpackPlugin({
+      template: './index.html',
+    }),
+    new CopyPlugin({
+      patterns: [
+        { from: 'img', to: 'img' },
+        { from: 'css', to: 'css' },
+        { from: 'js/vendor', to: 'js/vendor' },
+        { from: 'icon.svg', to: 'icon.svg' },
+        { from: 'favicon.ico', to: 'favicon.ico' },
+        { from: 'robots.txt', to: 'robots.txt' },
+        { from: 'icon.png', to: 'icon.png' },
+        { from: '404.html', to: '404.html' },
+        { from: 'site.webmanifest', to: 'site.webmanifest' },
+      ],
+    }),
+  ],
+});