wer das liest ist doof

This commit is contained in:
Niklas 2022-08-08 15:43:30 +02:00
commit bfaf0e4e7d
29 changed files with 1639 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

0
.gitkeep Normal file
View File

10
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"C_Cpp.errorSquiggles": "Disabled"
}

200
data/css/font.css Normal file
View File

@ -0,0 +1,200 @@
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 300;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 300;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 300;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WZhyzbi.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 300;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 300;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WZhyzbi.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WZhyzbi.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 500;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WZhyzbi.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 600;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WRhyzbi.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459W1hyzbi.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459WZhyzbi.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUSjIg1_i6t8kCHKm459Wlhyw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

378
data/css/style.css Normal file
View File

@ -0,0 +1,378 @@
:root{
--clr-accent-200: hsl(144, 75%, 65%);
--clr-accent-400: hsl(144, 75%, 55%);
--clr-accent-400-05: hsla(144, 75%, 61%, 0.5);
--clr-accent-600: hsl(144, 75%, 40%);
--clr-primary-400: hsl(0, 0%, 20%);
--clr-primary-200: hsl(0, 0%, 36%);
--ff-primary: 'Montserrat', sans-serif;
--ff-body: var(--ff-primary);
--fw-light: 300;
--fw-regular: 400;
--fw-medium: 500;
--fw-semi-bold: 600;
--fw-bold: 700;
--fs-100: 0.5rem;
--fs-200: 0.5625rem;
--fs-300: 0.625;
--fs-400: 0.6875rem;
--fs-500: 0.75rem;
--fs-600: 0.8125rem;
--fs-700: 0.875rem;
--fs-800: 0.9375rem;
--fs-900: 1rem;
--fs-large-100: 1.25rem;
--fs-large-200: 2.25rem;
--fs-body: var(--fs-900);
--fs-button: var(--fs-500);
}
.ff-priamry {font-family: var(--ff-primary);}
.bg-primary{background-color: white;}
.fc-primary-400{color: var(--clr-primary-400);}
.fc-primary-200{color: var(--clr-primary-200);}
.fc-accent{color: var(--clr-accent-400);}
.fw-light {font-weight: var(--fw-light);}
.fw-regular {font-weight: var(--fw-regular);}
.fw-medium {font-weight: var(--fw-medium);}
.fw-semi-bold {font-weight: var(--fw-semi-bold);}
.fw-bold {font-weight: var(--fw-bold);}
.fs-100 {font-size: var(--fs-100);}
.fs-200 {font-size: var(--fs-200);}
.fs-300 {font-size: var(--fs-300);}
.fs-400 {font-size: var(--fs-400);}
.fs-500 {font-size: var(--fs-500);}
.fs-600 {font-size: var(--fs-600);}
.fs-700 {font-size: var(--fs-700);}
.fs-800 {font-size: var(--fs-800);}
.fs-900 {font-size: var(--fs-900);}
.fs-large-100 {font-size: var(--fs-large-100);}
@media (min-width: 50em){
.fs-700{font-size: var(--fs-800);}
.fs-800{font-size: var(--fs-900);}
.wifi-form{
width: 800px;
margin: 0 auto;
}
#bottom-graphic{
max-width: 800px;
}
}
/* Box sizing rules */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Remove default margin */
body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
margin: 0;
}
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
ul[role='list'],
ol[role='list'] {
list-style: none;
}
/* Set core root defaults */
html:focus-within {
scroll-behavior: smooth;
}
/* Set core body defaults */
body {
min-height: 100vh;
text-rendering: optimizeSpeed;
line-height: 1.5;
}
/* Make images easier to work with */
img,
picture {
max-width: 100%;
display: block;
}
/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
font: inherit;
}
/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
html:focus-within {
scroll-behavior: auto;
}
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
/* Utility classes */
.text-primary-400 {
color: var(--clr-primary-400);
}
body {
margin: auto;
}
body > header > .container {
display: flex;
justify-content: center;
}
.wifi-form > .button {
margin: 0 auto;
}
body > main > .container > .form-wrapper > .wifi-form > .input-wrapper > .label {
/* font-size: var(--fs-800); */
font-weight: var(--fw-semi-bold);
color: var(--clr-primary-400);
}
body > main > .container > .form-wrapper {
display: flex;
justify-content: center;
flex-direction: column;
}
body > main > .container > .form-wrapper > .wifi-form {
display: flex;
flex-direction: column;
justify-content: center;
gap: 20px;
padding: 40px;
z-index: 2;
}
body > main > .container > .form-wrapper > .wifi-form > .input-wrapper {
display: flex;
flex-direction: column;
}
.option-wrapper{
display:flex;
flex-direction: column;
gap: 10px;
}
.option-wrapper .option-child {
display: flex;
justify-content: space-between;
align-items: center;
}
.option-wrapper .option-child > .text {
font-weight: var(--fw-regular);
text-align: center;
display: inline-block;
white-space: nowrap;
overflow: hidden !important;
text-overflow: ellipsis;
}
.option-wrapper > #div-static-ip {
visibility: hidden;
}
#static-ip{
width: 160px;
}
#save-btn{
margin-top: 20px;
}
.button:disabled{
background-color: rgb(177, 177, 177);
box-shadow: none;
}
.button {
cursor: pointer;
font-size: var(--fs-800);
background-color: var(--clr-accent-400);
width: min-content;
border:none;
border-radius: 50px;
color: white;
font-weight: var(--fw-medium);
padding: 10px 75px;
text-transform: uppercase;
letter-spacing: 1px;
box-shadow: 2px 2px 10px var(--clr-accent-400-05);
}
.button:hover:enabled{
background-color: var(--clr-accent-200);
outline: none;
border: none;
-webkit-tap-highlight-color: transparent;
}
input {
border: #E6E6E6 1px solid;
background-color: #FBFBFB;
border-radius: 10px;
padding: 5px 20px;
font-weight: var(--fw-regular);
font-size: var(--fs-800);
color: var(--clr-primary-400);
box-shadow: 1px 1px 3px hsla(0, 0%, 0%, 0.2);
}
input:focus {
outline: var(--clr-accent-400) solid 1px;
border-color: var(--clr-accent-400);
}
input[type="checkbox"] {
outline: none;
}
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: var(--clr-accent-400);
}
input:focus + .slider {
box-shadow: 0 0 1px var(--clr-accent-400);
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
#bottom-graphic{
position: fixed;
bottom: 0;
width : 100%;
height: auto;
z-index: 1;
opacity: 0.8;
}
h1 {
font-size: var(--fs-large-100);
font-weight: var(--fw-semi-bold);
color: var(--clr-primary-400);
}
#logo {
width : 250px;
height: auto;
}
#uid {
text-align: center;
font-weight: var(--fw-medium);
font-size: var(--fs-900);
color: var(--clr-accent-400);
}
.text-wrapper{
margin-top: 50px;
display: flex;
flex-direction: column;
align-items: center;
}
h1, h2, p{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

60
data/index.html Normal file
View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>OnTop - WiFi Manager</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" type="text/css" href="css/font.css">
</head>
<body onload="getUID()">
<header class="primary-header">
<div class="container">
<a href="#"><img src="static/svg/logo.svg" id="logo" alt="OnTop-Logo"></a>
</div>
</header>
<main>
<div class="container fc-primary-400 ff-priamry">
<div class="form-wrapper">
<div class="text-wrapper">
<h1>WiFi-Konfiguration</h1>
<p id="uid"></p>
</div>
<form class="wifi-form" action="/" method="POST">
<div class="input-wrapper">
<p class="label fs-700">SSID</p>
<input placeholder="Heimnetzwerk" id="ssid" class="fs-800" maxlength="32" type="text" on="validate(this)" onchange="validate(this)">
</div>
<div class="input-wrapper">
<p class="label fs-700">Passwort</p>
<input type="password" id="password" maxlength="32" class="fs-800" onchange="validate(this)">
</div>
<div class="input-wrapper">
<p class="label fs-700">Gateway</p>
<input placeholder="192.168.10.1" id="gateway" class="fs-800" maxlength="15" type="text" onchange="validate(this)">
</div>
<div class="input-wrapper">
<p class="label fs-700"> IP-Adresse</p>
<div class="option-wrapper">
<div class="option-child">
<p class="text fs-700">Dynamische IP-Adresse</p>
<label class="switch">
<input type="checkbox" id="cb-static-ip" checked onchange="changeVisibility(this)">
<span class="slider round"></span>
</label>
</div>
<div id="div-static-ip" class="option-child">
<p class="text fs-700">Statische IP-Adresse</p>
<input placeholder="192.168.10.53" class="fs-800" type="text" maxlength="15" id="static-ip" onchange="validate(this)">
</div>
</div>
</div>
<input type ="submit" disabled class="button fw-bold" id="save-btn" value ="Speichern">
</form>
</div>
</div>
</main>
<img src="static/svg/graphic.svg" id="bottom-graphic" alt="">
<script src="js/index.js"></script>
</body>
</html>

71
data/js/index.js Normal file
View File

@ -0,0 +1,71 @@
let sessionValid = {ssid: false, password: false, gateway: false, "static-ip": true};
const isStaticIPEnabled = document.getElementById("cb-static-ip");
function getUID() {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const uid = document.getElementById("uid");
const urlUID = urlParams.get('uid')
uid.innerHTML = urlUID || "";
}
function changeVisibility(e) {
document.getElementById("div-static-ip").style.visibility = "visible";
if (e.checked) {
document.getElementById("div-static-ip").style.visibility = "hidden";
}
validate(e);
}
function validate(e){
let rgx;
const element = document.getElementById(e.id);
const newValue = element.value;
const oldValue = newValue.slice(0, newValue.length - 1);
const lastValue = newValue[newValue.length - 1];
switch(e.id){
case "gateway":
rgx = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
break;
case "static-ip":
rgx = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
break;
case "ssid":
rgx = /^[^!#;+\]\/"\t][^+\]\/"\t]{0,30}[^ +\]\/"\t]$|^[^ !#;+\]\/"\t]$[ \t]+$/;
break;
case "password":
sessionValid.password = false;
if (newValue.length >= 5){
sessionValid.password = true;
}
case "cb-static-ip":
sessionValid["static-ip"] = false;
if (isStaticIPEnabled.checked) {
sessionValid["static-ip"] = true;
}
break;
default:
break;
}
if(rgx) {
sessionValid[e.id] = false;
if(newValue.match(rgx)){
sessionValid[e.id] = true;
}
}
updateSession();
}
function updateSession(){
document.getElementById("save-btn").disabled = true;
if (!Object.keys(sessionValid).some(key => sessionValid[key] === false)) {
document.getElementById("save-btn").disabled = false;
}
console.log(sessionValid);
}

View File

@ -0,0 +1,20 @@
<svg width="341" height="289" viewBox="0 0 341 289" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_14)">
<path d="M97.6014 340.701C86.4596 340.701 75.3344 340.476 64.2259 340.026C48.3532 339.382 31.94 338.717 16.6845 329.164C6.01266 322.483 -3.43891 311.763 -10.6481 298.162C-15.4042 289.12 -18.9463 279.094 -21.1235 268.512C-22.1886 263.421 -22.9616 258.234 -23.4359 252.995C-24.735 238.84 -23.8145 224.489 -20.7301 210.809C-19.2322 204.263 -17.1913 197.948 -14.6432 191.976C-3.51806 165.966 16.7735 148.507 41.0286 144.075C41.2291 144.045 41.4314 144.041 41.6327 144.06C41.7417 144.067 41.8505 144.074 41.9613 144.069L42.104 144.017C42.4719 143.873 42.8474 143.764 43.2275 143.692C80.6353 137.405 120.181 150.126 157.586 180.479C186.507 203.951 224.836 216.591 274.764 219.12L275.472 219.162C289.371 220.063 302.815 226.532 314.353 237.87C325.627 248.861 334.214 263.857 339.08 281.049C339.668 283.129 340.208 285.293 340.684 287.483C341.585 291.624 340.54 295.808 337.818 298.993V298.997L337.693 299.141C337.394 299.477 337.079 299.799 336.757 300.099L336.378 300.452C333.188 303.419 330.668 305.763 327.652 307.584C325.616 308.8 323.48 309.71 321.285 310.297C309.118 313.646 296.763 316.751 284.562 319.526C260.867 324.92 236.547 329.369 212.279 332.75C174.189 338.05 135.909 340.704 97.6014 340.701V340.701ZM41.349 144.981C41.2745 144.981 41.2001 144.986 41.1263 144.998C17.0979 149.389 -3.00151 166.677 -14.0164 192.429C-16.5393 198.342 -18.56 204.595 -20.043 211.076C-23.0994 224.634 -24.0113 238.857 -22.7236 252.885C-22.2534 258.079 -21.4873 263.22 -20.4315 268.266C-18.2756 278.747 -14.7679 288.677 -10.0577 297.633C-2.91904 311.1 6.43588 321.713 16.9958 328.324C32.1144 337.791 48.4502 338.453 64.2483 339.093C113.636 341.088 163.071 338.659 212.203 331.824C236.455 328.444 260.759 323.998 284.438 318.607C296.631 315.834 308.978 312.732 321.136 309.385C323.278 308.813 325.363 307.925 327.35 306.738C330.305 304.954 332.801 302.632 335.961 299.693L336.34 299.341C336.616 299.083 336.888 298.807 337.148 298.52L337.223 298.432C339.82 295.477 340.829 291.578 339.993 287.736V287.736C339.523 285.57 338.989 283.428 338.406 281.37C328.624 246.526 303.319 221.901 275.438 220.093L274.733 220.051C251.927 218.896 231.97 215.695 213.724 210.266C191.943 203.785 172.927 194.029 157.206 181.27C119.943 151.033 80.5633 138.359 43.3189 144.617C42.9726 144.684 42.6305 144.784 42.2954 144.916L42.0382 144.997C41.8901 145.008 41.7447 145 41.5997 144.991C41.5138 144.986 41.4304 144.981 41.349 144.981Z" fill="#F0F0F0" fill-opacity="0.5"/>
<path d="M337.459 298.783V298.788C337.168 299.114 336.864 299.427 336.548 299.72C331.284 304.62 327.687 308.056 321.21 309.841C309.018 313.197 296.781 316.273 284.5 319.066C260.542 324.521 236.455 328.928 212.241 332.287C163.094 339.137 113.642 341.567 64.2372 339.559C47.7844 338.893 31.9161 338.184 16.8402 328.744C5.82029 321.845 -3.43891 310.941 -10.3528 297.898C-17.3636 284.672 -21.6274 269.023 -23.0797 252.94C-19.666 251.003 -16.0393 249.776 -12.3323 249.304C0.534445 247.71 13.1968 253.835 24.8981 260.963C36.603 268.086 48.0963 276.412 60.7695 279.698C79.4456 284.542 98.7243 277.955 116.629 269.522C134.535 261.089 152.16 250.674 171.044 247.49C196.373 243.216 221.787 252.264 246.38 261.224C272.576 270.766 298.774 280.311 324.972 289.856C328.716 291.217 332.6 292.677 335.519 296.014C336.243 296.841 336.893 297.77 337.459 298.783Z" fill="#E6E6E6" fill-opacity="0.5"/>
<path d="M337.459 298.783V298.788C337.168 299.114 336.864 299.427 336.548 299.72C333.249 302.788 330.606 305.286 327.5 307.16C316.825 308.526 306.135 309.709 295.43 310.708C267.879 313.277 240.273 314.643 212.614 314.806C156.503 315.179 97.5086 317.463 48.3796 282.034C32.0324 270.245 8.35204 294.42 -7.8426 281.493C-12.5107 277.755 -16.8484 273.36 -20.7775 268.389C-21.8387 263.321 -22.6082 258.157 -23.0798 252.94C-24.3798 238.848 -23.4635 224.56 -20.3866 210.943C-18.898 204.428 -16.867 198.144 -14.3298 192.203C-6.80622 195.713 0.408925 200.766 7.27623 206.118C19.8705 215.921 32.1168 227.054 46.1419 232.666C66.8155 240.941 89.1818 236.391 110.16 229.548C131.139 222.704 151.977 213.586 173.598 212.817C202.594 211.786 230.505 225.823 257.497 239.636C284.575 253.495 311.657 267.353 338.743 281.209C339.338 283.311 339.87 285.445 340.339 287.609C341.296 292.01 339.908 295.996 337.459 298.783Z" fill="#F2F2F2" fill-opacity="0.5"/>
<path d="M73.4417 119.819C69.3634 116.245 69.7624 108.425 74.0752 105.351C74.163 105.289 74.249 105.224 74.3334 105.157C74.5495 103.811 74.7657 102.466 74.9818 101.12C76.2541 102.838 78.7559 102.514 79.7423 100.503C76.303 90.9664 71.7805 82.156 66.3262 74.3671C65.1373 72.6608 64.4702 70.4476 64.451 68.1456C64.4318 65.8436 65.0619 63.6121 66.2221 61.8728C66.2429 61.8412 66.2636 61.8093 66.2841 61.7773C69.364 60.4251 72.2805 58.5106 74.9459 56.0913C65.8051 36.9998 48.3748 21.8329 44.2318 -3.05176e-05C31.7679 17.3996 30.3687 23.5277 17.9047 40.9273C17.9047 40.9273 6.10279 54.7713 3.55543 62.2113C4.18134 63.066 9.78493 65.117 10.0004 66.7974C14.2738 67.2427 21.6773 61.1537 21.6773 61.1537C21.6773 61.1537 5.51789 83.549 0.611702 97.3435C0.169899 98.5857 -0.249707 100.004 0.120414 101.285C0.415905 102.308 1.47597 102.898 2.1587 102.491C1.34313 103.514 0.688287 104.733 0.230628 106.08C1.65432 107.262 3.34299 107.785 5.02368 107.565C6.70437 107.345 8.27888 106.395 9.49269 104.868C8.80934 106.527 8.12598 108.187 7.44262 109.847L7.44383 109.851C8.36704 110.243 9.19556 110.941 9.84753 111.877C10.4995 112.813 10.9524 113.954 11.1614 115.187C11.3704 116.42 11.3283 117.702 11.0393 118.908C10.7503 120.113 10.2243 121.2 9.51341 122.06C5.27282 127.187 1.39802 132.576 -0.0217899 136.125C-1.35747 139.464 12.357 143.488 15.4417 143.323C18.5264 143.158 21.4098 141.396 24.1958 139.667C24.0601 141.318 24.3031 142.985 24.8942 144.457C26.42 144.939 28.0044 145.019 29.5543 144.693C31.1043 144.367 32.5885 143.642 33.9199 142.56C33.797 145.863 37.0018 147.687 39.2262 146.752C38.1157 169.589 38.928 201.659 39.9949 234.95H42.6419V148.068C43.3463 148.532 44.0997 148.858 44.8776 149.034C50.2933 150.284 56.8286 151.044 60.3526 145.554C64.4086 150.87 71.8412 150.769 75.8737 145.472C75.4769 146.386 76.0843 147.924 76.9828 148.166C78.0418 148.452 79.072 147.634 79.9711 146.852C84.0411 143.315 88.1111 139.778 92.1812 136.241C87.1586 131.839 80.0238 125.587 73.4417 119.819Z" fill="#E6E6E6" fill-opacity="0.5"/>
<path d="M195.618 109.19C202.677 109.19 208.399 101.752 208.399 92.576C208.399 83.4002 202.677 75.9617 195.618 75.9617C188.56 75.9617 182.838 83.4002 182.838 92.576C182.838 101.752 188.56 109.19 195.618 109.19Z" fill="#F2F2F2" fill-opacity="0.5"/>
<path d="M224.225 84.7098C223.485 81.491 221.397 79.3896 218.874 78.9287C218.846 78.9236 218.819 78.9303 218.792 78.928C218.756 78.9138 218.72 78.9029 218.683 78.8953C215.108 78.329 211.491 79.3524 208.421 81.799C205.463 84.1998 202.016 85.2857 198.531 85.4621C198.511 85.4631 198.49 85.4643 198.47 85.4656C197.174 85.5778 195.937 86.2062 194.926 87.2652C193.916 88.3242 193.181 89.7624 192.821 91.384C192.783 91.5825 192.794 91.7916 192.854 91.9812C192.913 92.1707 193.017 92.3307 193.151 92.4381C193.537 92.8633 193.995 93.1651 194.486 93.3192C195.548 93.6115 196.613 93.8793 197.682 94.1225C199.768 94.5971 201.865 94.9807 203.973 95.2735C208.251 95.8695 212.556 96.0811 216.857 95.9066C218.29 95.8486 219.671 95.7868 220.984 94.9649C221.939 94.3519 222.754 93.4265 223.351 92.2796C223.913 91.1773 224.283 89.9284 224.433 88.6206C224.584 87.3128 224.513 85.9779 224.225 84.7098V84.7098Z" fill="#E6E6E6" fill-opacity="0.5"/>
<path d="M197.661 106.862C196.922 103.643 194.833 101.542 192.31 101.081C192.282 101.076 192.256 101.083 192.228 101.08C192.192 101.066 192.156 101.055 192.119 101.048C188.544 100.481 184.927 101.505 181.857 103.952C178.899 106.352 175.452 107.438 171.968 107.615C171.947 107.616 171.926 107.617 171.906 107.618C170.611 107.73 169.373 108.359 168.363 109.418C167.352 110.477 166.617 111.915 166.257 113.536C166.219 113.735 166.231 113.944 166.29 114.134C166.349 114.323 166.453 114.483 166.587 114.591C166.973 115.016 167.431 115.318 167.923 115.472C168.984 115.764 170.049 116.032 171.118 116.275C173.204 116.75 175.301 117.133 177.409 117.426C181.688 118.022 185.993 118.234 190.294 118.059C191.726 118.001 193.108 117.939 194.42 117.117C195.375 116.504 196.191 115.579 196.787 114.432C197.349 113.33 197.719 112.081 197.87 110.773C198.021 109.465 197.949 108.13 197.661 106.862V106.862Z" fill="#E6E6E6" fill-opacity="0.5"/>
<path d="M305.818 176.225C301.74 172.651 302.139 164.831 306.452 161.758C306.54 161.695 306.626 161.631 306.71 161.564C306.926 160.218 307.142 158.873 307.358 157.527C308.631 159.245 311.133 158.921 312.119 156.91C308.68 147.373 304.157 138.563 298.703 130.774C297.514 129.068 296.847 126.854 296.828 124.552C296.808 122.25 297.438 120.019 298.599 118.28C298.619 118.248 298.64 118.216 298.661 118.184C301.741 116.832 304.657 114.917 307.322 112.498C298.182 93.4066 280.751 78.2396 276.608 56.4067C264.144 73.8064 262.745 79.9344 250.281 97.3341C250.281 97.3341 238.479 111.178 235.932 118.618C236.558 119.473 242.161 121.524 242.377 123.204C246.65 123.65 254.054 117.56 254.054 117.56C254.054 117.56 237.894 139.956 232.988 153.75C232.546 154.992 232.127 156.411 232.497 157.692C232.792 158.715 233.853 159.305 234.535 158.898C233.72 159.921 233.065 161.14 232.607 162.487C234.031 163.669 235.72 164.192 237.4 163.972C239.081 163.752 240.655 162.802 241.869 161.275C241.186 162.934 240.503 164.594 239.819 166.254L239.82 166.257C240.744 166.65 241.572 167.348 242.224 168.284C242.876 169.22 243.329 170.361 243.538 171.594C243.747 172.827 243.705 174.109 243.416 175.315C243.127 176.52 242.601 177.606 241.89 178.467C237.649 183.594 233.775 188.983 232.355 192.532C231.019 195.87 244.734 199.895 247.818 199.73C250.903 199.565 253.786 197.803 256.572 196.074C256.437 197.725 256.68 199.392 257.271 200.864C258.797 201.345 260.381 201.426 261.931 201.1C263.481 200.774 264.965 200.049 266.296 198.967C266.173 202.27 269.378 204.094 271.603 203.158C270.492 225.996 271.305 258.066 272.371 291.357H275.018V204.475C275.723 204.939 276.476 205.265 277.254 205.441C282.67 206.691 289.205 207.451 292.729 201.961C296.785 207.277 304.218 207.176 308.25 201.878C307.853 202.792 308.461 204.33 309.359 204.573C310.418 204.858 311.449 204.041 312.348 203.259C316.418 199.722 320.488 196.185 324.558 192.647C319.535 188.246 312.4 181.994 305.818 176.225Z" fill="#E6E6E6" fill-opacity="0.5"/>
<path d="M-1.41851 264.794C-1.15312 264.81 -0.890386 264.719 -0.665914 264.534C-0.441442 264.349 -0.26608 264.079 -0.163589 263.761C-0.0610978 263.442 -0.0364322 263.09 -0.0929304 262.753C-0.149429 262.415 -0.284362 262.109 -0.479448 261.874C-0.512121 261.705 -0.535557 261.584 -0.56823 261.415C-0.556539 261.379 -0.544779 261.342 -0.532953 261.305C-0.265587 260.484 0.182427 259.784 0.754819 259.293C1.32721 258.802 1.99845 258.542 2.68423 258.545C3.37001 258.549 4.03975 258.815 4.60932 259.312C5.17888 259.808 5.62288 260.513 5.88555 261.336C6.93533 264.623 8.27187 267.915 8.60097 271.391C8.74591 272.927 8.68477 274.484 8.42026 275.993C10.8859 269.001 12.1663 261.402 12.1745 253.71C12.175 251.78 12.0925 249.852 11.9274 247.933C11.791 246.361 11.6016 244.8 11.3595 243.25C10.0379 234.839 7.20056 226.956 3.08034 220.248C1.08616 218.834 -0.526562 216.658 -1.5405 214.016C-1.90783 213.066 -2.16744 212.052 -2.31126 211.005C-2.08632 211.044 -1.85767 211.068 -1.63272 211.087C-1.56264 211.091 -1.48889 211.096 -1.41881 211.101L-1.39238 211.103C-1.14514 211.117 -0.899976 211.038 -0.686384 210.876C-0.472793 210.713 -0.299884 210.474 -0.188481 210.187C-0.0770767 209.899 -0.0319284 209.576 -0.058463 209.257C-0.0849976 208.937 -0.182086 208.634 -0.338044 208.384C-0.435173 208.228 -0.532361 208.073 -0.629608 207.918C-0.777138 207.678 -0.928326 207.443 -1.07584 207.204C-1.09286 207.181 -1.10887 207.157 -1.12378 207.132C-1.29344 206.858 -1.46305 206.59 -1.63272 206.317C-1.32306 205.692 -0.90657 205.168 -0.415728 204.787C1.28436 203.493 3.62982 204.389 4.85788 206.389C6.08961 208.388 6.32192 211.192 5.89416 213.69C5.47348 215.815 4.7776 217.832 3.83633 219.654C3.92855 219.807 4.02444 219.956 4.11662 220.109C5.80197 222.926 7.27087 225.951 8.50227 229.141C8.20281 225.568 8.56022 221.953 9.5451 218.594C10.5433 215.464 12.4142 212.828 14.0617 210.121C16.0407 206.871 20.0988 208.29 20.4475 212.41C20.4509 212.45 20.4541 212.49 20.4574 212.53C20.2126 212.709 19.9731 212.9 19.7387 213.101C19.4443 213.357 19.2161 213.722 19.0842 214.149C18.9522 214.577 18.9226 215.046 18.9992 215.495C19.0758 215.944 19.255 216.353 19.5134 216.668C19.7718 216.983 20.0973 217.189 20.4473 217.259L20.4832 217.266C20.396 218.413 20.2419 219.549 20.0222 220.665C19.3856 223.781 18.2607 226.693 16.718 229.217C15.1753 231.741 13.248 233.824 11.0571 235.335C10.9133 235.431 10.7731 235.527 10.6293 235.618C11.2893 238.035 11.8167 240.51 12.2077 243.024C12.5575 245.241 12.8013 247.485 12.9378 249.741C13.1051 252.583 13.0952 255.439 12.9083 258.279L12.9194 258.178C13.3915 255.02 14.6876 252.17 16.5888 250.11C19.4126 247.094 23.4021 245.984 26.4485 243.56C26.7722 243.29 27.1487 243.146 27.5334 243.145C27.9182 243.143 28.2952 243.285 28.6199 243.553C28.9447 243.821 29.2037 244.205 29.3664 244.658C29.5291 245.111 29.5887 245.616 29.5381 246.111C29.534 246.147 29.5299 246.182 29.5257 246.217C29.0715 246.458 28.6294 246.735 28.2018 247.046C27.957 247.226 27.7175 247.416 27.4831 247.618C27.1887 247.874 26.9605 248.239 26.8286 248.666C26.6966 249.093 26.667 249.562 26.7436 250.012C26.8201 250.461 26.9994 250.87 27.2578 251.185C27.5162 251.5 27.8417 251.706 28.1917 251.776L28.2276 251.783C28.2534 251.788 28.2755 251.793 28.3013 251.797C27.5254 254.206 26.4363 256.423 25.0819 258.351C23.4086 260.685 21.3863 262.55 19.1389 263.832C16.8915 265.114 14.4664 265.785 12.0122 265.805H12.0085C11.3423 269.569 10.3771 273.232 9.1283 276.736H-1.16069C-1.19759 276.587 -1.23076 276.434 -1.26396 276.285C-0.31159 276.363 0.644532 276.289 1.58306 276.065C0.819671 274.847 0.0563083 273.62 -0.707084 272.402C-0.724108 272.379 -0.740118 272.355 -0.755029 272.33C-1.14224 271.707 -1.53316 271.088 -1.92037 270.465L-1.92058 270.464C-1.94122 268.554 -1.77259 266.648 -1.41884 264.794L-1.41851 264.794Z" fill="#E6E6E6" fill-opacity="0.5"/>
<path d="M305.189 277.846C305.455 277.862 305.718 277.772 305.942 277.587C306.166 277.402 306.342 277.132 306.444 276.814C306.547 276.495 306.572 276.143 306.515 275.806C306.459 275.468 306.324 275.161 306.129 274.927C306.096 274.758 306.072 274.637 306.04 274.468C306.051 274.431 306.063 274.395 306.075 274.358C306.342 273.537 306.79 272.837 307.363 272.346C307.935 271.855 308.606 271.595 309.292 271.598C309.978 271.602 310.648 271.868 311.217 272.365C311.787 272.861 312.231 273.566 312.493 274.389C313.543 277.676 314.88 280.968 315.209 284.443C315.354 285.979 315.293 287.537 315.028 289.046C317.494 282.054 318.774 274.454 318.782 266.763C318.783 264.833 318.7 262.904 318.535 260.986C318.399 259.414 318.21 257.853 317.967 256.302C316.646 247.892 313.808 240.009 309.688 233.301C307.694 231.886 306.081 229.711 305.067 227.069C304.7 226.119 304.441 225.105 304.297 224.058C304.522 224.096 304.75 224.12 304.975 224.139C305.045 224.144 305.119 224.149 305.189 224.154L305.216 224.155C305.463 224.17 305.708 224.091 305.922 223.929C306.135 223.766 306.308 223.527 306.419 223.239C306.531 222.952 306.576 222.629 306.549 222.309C306.523 221.989 306.426 221.686 306.27 221.437C306.173 221.281 306.076 221.126 305.978 220.971C305.831 220.731 305.68 220.496 305.532 220.256C305.515 220.234 305.499 220.21 305.484 220.184C305.315 219.911 305.145 219.643 304.975 219.369C305.285 218.745 305.701 218.221 306.192 217.84C307.892 216.546 310.238 217.442 311.466 219.441C312.698 221.44 312.93 224.245 312.502 226.743C312.081 228.868 311.386 230.885 310.444 232.706C310.537 232.86 310.632 233.008 310.725 233.162C312.41 235.979 313.879 239.004 315.11 242.194C314.811 238.62 315.168 235.006 316.153 231.647C317.151 228.517 319.022 225.88 320.67 223.174C322.649 219.924 326.707 221.342 327.055 225.463C327.059 225.503 327.062 225.543 327.065 225.582C326.821 225.762 326.581 225.952 326.347 226.154C326.052 226.41 325.824 226.775 325.692 227.202C325.56 227.629 325.531 228.098 325.607 228.548C325.684 228.997 325.863 229.406 326.121 229.721C326.38 230.036 326.705 230.242 327.055 230.312L327.091 230.319C327.004 231.465 326.85 232.602 326.63 233.718C325.994 236.834 324.869 239.745 323.326 242.27C321.783 244.794 319.856 246.877 317.665 248.388C317.521 248.483 317.381 248.579 317.237 248.67C318.474 253.228 319.25 257.976 319.546 262.794C319.713 265.636 319.703 268.491 319.516 271.332L319.527 271.231C319.999 268.073 321.296 265.223 323.197 263.163C326.021 260.147 330.01 259.037 333.056 256.613C333.38 256.343 333.757 256.199 334.141 256.197C334.526 256.196 334.903 256.338 335.228 256.606C335.553 256.874 335.812 257.258 335.974 257.711C336.137 258.164 336.197 258.668 336.146 259.164C336.142 259.199 336.138 259.235 336.134 259.27C335.68 259.51 335.237 259.787 334.81 260.099C334.565 260.279 334.325 260.469 334.091 260.671C333.797 260.926 333.569 261.292 333.437 261.719C333.305 262.146 333.275 262.615 333.352 263.065C333.428 263.514 333.607 263.923 333.866 264.238C334.124 264.552 334.45 264.758 334.8 264.829L334.836 264.836C334.861 264.841 334.883 264.845 334.909 264.85C334.133 267.259 333.044 269.475 331.69 271.404C330.017 273.738 327.994 275.603 325.747 276.885C323.5 278.166 321.074 278.838 318.62 278.858H318.616C317.95 282.622 316.985 286.285 315.736 289.789H305.447C305.41 289.64 305.377 289.487 305.344 289.338C306.296 289.416 307.253 289.342 308.191 289.117C307.428 287.9 306.664 286.672 305.901 285.455C305.884 285.432 305.868 285.408 305.853 285.383C305.466 284.76 305.075 284.141 304.688 283.518L304.687 283.517C304.667 281.607 304.835 279.701 305.189 277.847L305.189 277.846Z" fill="#E6E6E6" fill-opacity="0.5"/>
<path d="M182.905 239.154C183.17 239.17 183.433 239.08 183.657 238.895C183.882 238.71 184.057 238.44 184.16 238.121C184.262 237.803 184.287 237.451 184.23 237.113C184.174 236.776 184.039 236.469 183.844 236.235C183.811 236.066 183.788 235.945 183.755 235.776C183.767 235.739 183.779 235.703 183.79 235.666C184.058 234.845 184.506 234.145 185.078 233.654C185.651 233.163 186.322 232.903 187.008 232.906C187.693 232.909 188.363 233.176 188.933 233.673C189.502 234.169 189.946 234.873 190.209 235.697C191.259 238.984 192.595 242.276 192.924 245.751C193.069 247.287 193.008 248.844 192.744 250.353C195.209 243.362 196.49 235.762 196.498 228.071C196.498 226.141 196.416 224.212 196.251 222.294C196.114 220.722 195.925 219.16 195.683 217.61C194.361 209.2 191.524 201.317 187.404 194.609C185.41 193.194 183.797 191.019 182.783 188.376C182.416 187.426 182.156 186.412 182.012 185.366C182.237 185.404 182.466 185.428 182.691 185.447C182.761 185.452 182.835 185.457 182.905 185.462L182.931 185.463C183.178 185.478 183.423 185.399 183.637 185.236C183.851 185.074 184.024 184.835 184.135 184.547C184.246 184.26 184.291 183.937 184.265 183.617C184.238 183.297 184.141 182.994 183.985 182.744C183.888 182.589 183.791 182.434 183.694 182.278C183.546 182.039 183.395 181.804 183.248 181.564C183.231 181.541 183.215 181.517 183.2 181.492C183.03 181.219 182.86 180.95 182.691 180.677C183 180.052 183.417 179.529 183.908 179.148C185.608 177.854 187.953 178.75 189.181 180.749C190.413 182.748 190.645 185.553 190.218 188.05C189.797 190.176 189.101 192.192 188.16 194.014C188.252 194.168 188.348 194.316 188.44 194.47C190.125 197.287 191.594 200.312 192.826 203.502C192.526 199.928 192.884 196.313 193.869 192.955C194.867 189.824 196.738 187.188 198.385 184.482C200.364 181.232 204.422 182.65 204.771 186.771C204.774 186.81 204.778 186.85 204.781 186.89C204.536 187.07 204.297 187.26 204.062 187.462C203.768 187.717 203.54 188.083 203.408 188.51C203.276 188.937 203.246 189.406 203.323 189.856C203.399 190.305 203.578 190.714 203.837 191.029C204.095 191.343 204.421 191.549 204.771 191.62L204.807 191.627C204.719 192.773 204.565 193.91 204.346 195.026C203.709 198.142 202.584 201.053 201.041 203.577C199.499 206.102 197.571 208.185 195.38 209.695C195.237 209.791 195.096 209.887 194.953 209.978C196.19 214.536 196.966 219.283 197.261 224.101C197.428 226.944 197.419 229.799 197.232 232.639L197.243 232.539C197.715 229.38 199.011 226.531 200.912 224.47C203.736 221.455 207.725 220.345 210.772 217.921C211.096 217.651 211.472 217.506 211.857 217.505C212.242 217.504 212.619 217.646 212.943 217.914C213.268 218.182 213.527 218.565 213.69 219.019C213.852 219.472 213.912 219.976 213.862 220.472C213.857 220.507 213.853 220.542 213.849 220.578C213.395 220.818 212.953 221.095 212.525 221.407C212.28 221.587 212.041 221.777 211.806 221.979C211.512 222.234 211.284 222.6 211.152 223.027C211.02 223.454 210.99 223.923 211.067 224.372C211.144 224.822 211.323 225.231 211.581 225.546C211.84 225.86 212.165 226.066 212.515 226.136L212.551 226.144C212.577 226.148 212.599 226.153 212.625 226.158C211.849 228.566 210.76 230.783 209.405 232.711C207.732 235.045 205.71 236.91 203.462 238.192C201.215 239.474 198.79 240.146 196.336 240.166H196.332C195.666 243.929 194.7 247.592 193.452 251.096H183.163C183.126 250.948 183.093 250.794 183.059 250.646C184.012 250.724 184.968 250.65 185.906 250.425C185.143 249.208 184.38 247.98 183.616 246.763C183.599 246.74 183.583 246.716 183.568 246.691C183.181 246.067 182.79 245.449 182.403 244.826L182.403 244.825C182.382 242.915 182.551 241.009 182.905 239.155L182.905 239.154Z" fill="#E6E6E6" fill-opacity="0.5"/>
</g>
<defs>
<clipPath id="clip0_1_14">
<rect width="365" height="350.686" fill="white" transform="translate(-24)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 21 KiB

11
data/static/svg/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

39
include/README Normal file
View File

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

98
lib/Display/display.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "display.h"
#define LED_BUILTIN GPIO_NUM_25
#define PIN_35 GPIO_NUM_35
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SCREEN_H_CENTER SCREEN_WIDTH / 2
#define SCREEN_V_CENTER SCREEN_HEIGHT / 2
#define SCREEN_PADDING 7
#define SCREEN_TOP_PADDING SCREEN_PADDING
#define SCREEN_BOTTOM_PADDING SCREEN_HEIGHT - SCREEN_PADDING
#define SCREEN_TOP_RIGHT_CURSOR_POSITION SCREEN_WIDTH
#define SCREEN_BOTTOM_RIGHT_CURSOR_POSITION SCREEN_WIDTH
#define SCREEN_TOP_LEFT_CURSOR_POSITION 0
#define SCREEN_BOTTOM_LEFT_CURSOR_POSITION 0
#define TEXT_START_LINE 2
#define TEXT_END_LINE 7
#define VIEW_TYPE_MENU 0
#define VIEW_TYPE_CUSTOM 1
#define BTN_SHORT_PRESS 1
#define BTN_LONG_PRESS 2
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_HEIGHT, SCREEN_WIDTH, &Wire, OLED_RESET);
Display *Display::instance = nullptr;
Display *Display::getInstance()
{
if (instance == nullptr)
{
instance = new Display();
}
return instance;
}
Display::Display()
{
pinMode(LED_BUILTIN, OUTPUT);
pinMode(PIN_35, INPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{ // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}
delay(2000);
loop();
}
void Display::viewController()
{
Serial.println(">viewController()");
int inputType = BTN_SHORT_PRESS;
if (btnPressTime > 800)
{
inputType = BTN_LONG_PRESS;
}
switch (inputType)
{
case BTN_SHORT_PRESS:
{
break;
}
case BTN_LONG_PRESS:
{
break;
}
}
reqUpdate = 1;
btnPressTime = 0;
}
uint8_t Display::checkScreenState()
{
if (reqUpdate == 0)
{
return -1;
}
display.stopscroll();
display.clearDisplay();
display.setTextSize(0);
display.setTextColor(WHITE);
reqUpdate = 0;
return 0;
}

44
lib/Display/display.h Normal file
View File

@ -0,0 +1,44 @@
#pragma once
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMono9pt7b.h>
#include <map>
class Display
{
public:
static Display *getInstance();
protected:
int time = 0;
int menuCursor = 0;
int btnConfirm = 0;
int isBtnConfirmPressed = 0;
int btnPressStartTime;
int btnPressTime = 0;
private:
void renderView();
void viewController();
void renderHomeScreen();
void renderMenuScreen();
Display();
uint8_t checkScreenState();
static Display *instance;
Adafruit_SSD1306 display;
// Utils *util = Utils::getInstance();
uint8_t SCREEN_TEXT_LINE[8] = {0, 8, 16, 24, 32, 40, 48, 56};
int16_t text_x_position, text_y_position;
uint16_t text_width, text_height;
int8_t reqUpdate = 1;
};

View File

@ -0,0 +1,47 @@
#include <input_controller.h>
#define LED_BUILTIN GPIO_NUM_25
#define PIN_35 GPIO_NUM_35
InputController *InputController::instance = nullptr;
InputController::InputController()
{
}
InputController *InputController::getInstance()
{
if (instance == nullptr)
{
instance = new InputController();
}
return instance;
}
int InputController::setup()
{
btnConfirm = digitalRead(PIN_35);
if (btnConfirm == HIGH && isBtnConfirmPressed == 0)
{
btnPressStartTime = millis();
isBtnConfirmPressed = 1;
Serial.println("Button 1: HIGHT");
digitalWrite(LED_BUILTIN, HIGH);
}
if (btnConfirm == LOW && isBtnConfirmPressed == 1)
{
btnPressTime = millis() - btnPressStartTime;
isBtnConfirmPressed = 0;
Serial.println("Button 1: LOW");
digitalWrite(LED_BUILTIN, LOW);
}
if (btnPressTime > 0)
{
// viewController();
}
return 0;
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <Arduino.h>
class InputController
{
public:
static InputController *getInstance();
protected:
int btnConfirm = 0;
int isBtnConfirmPressed = 0;
int btnPressStartTime;
int btnPressTime = 0;
private:
static InputController *instance;
InputController();
int setup();
};

46
lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@ -0,0 +1,84 @@
#include "file_handler.h"
FileHandler *FileHandler::instance = nullptr;
FileHandler *FileHandler::getInstance()
{
if (instance == nullptr)
{
instance = new FileHandler();
}
return instance;
}
FileHandler::FileHandler()
{
initSPIFFS();
}
int FileHandler::read(char *filePath, byte *buffer, size_t size)
{
if (exists(filePath))
{
File file = SPIFFS.open(filePath, FILE_READ);
Serial.println(file.size());
if (file)
{
file.read(buffer, size);
file.close();
}
else
{
Serial.println("[FileHandler::read - Failed to open file.");
return 1;
}
return 0;
}
return 1;
}
int FileHandler::remove(char *filePath)
{
if (exists(filePath))
{
SPIFFS.remove(filePath);
return 0;
}
return 1;
}
int FileHandler::exists(char *filePath)
{
return SPIFFS.exists(filePath);
}
int FileHandler::write(char *filePath, byte *data, size_t size)
{
File file = SPIFFS.open(filePath, FILE_WRITE);
/* for (int i = 0; i < size; i++)
{
Serial.print(data[i], HEX);
} */
if (file)
{
file.write(data, size);
file.close();
return 0;
}
else
{
Serial.println("FileHandler::write - Failed to open file.");
return 1;
}
}
void FileHandler::initSPIFFS()
{
if (!SPIFFS.begin(true))
{
Serial.println("An error has occurred while mounting SPIFFS");
}
Serial.println("SPIFFS mounted successfully");
}

20
lib/Utils/file_handler.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include "SPIFFS.h"
#include <ArduinoJson.h>
class FileHandler
{
public:
static FileHandler *getInstance();
int read(char *filePath, byte *buffer, size_t size);
int write(char *filePath, byte *data, size_t size);
int exists(char *filePath);
int remove(char *filePath);
private:
static FileHandler *instance;
FileHandler();
void initSPIFFS();
protected:
};

View File

@ -0,0 +1,16 @@
#include "../Model/view_controller.h"
ViewController *ViewController::instance = nullptr;
ViewController *ViewController::getInstance()
{
if (instance == 0)
{
instance = new ViewController();
}
return instance;
}
ViewController::ViewController()
{
}

8
lib/View/Model/view.h Normal file
View File

@ -0,0 +1,8 @@
class View
{
public:
virtual void render() = 0;
protected:
private:
};

View File

@ -0,0 +1,13 @@
#pragma once
#include "../Display/display.h"
class ViewController
{
public:
static ViewController *getInstance();
protected:
private:
static ViewController *instance;
ViewController();
};

View File

@ -0,0 +1,25 @@
#include "home_view.h"
Display *display = Display::getInstance();
void HomeView::render()
{
/*
Serial.println(">renderHomeScreen()");
// Draw Header
display.getTextBounds("00:00", 0, SCREEN_TEXT_LINE[0], &text_x_position, &text_y_position, &text_width, &text_height);
display.setCursor(0, SCREEN_TEXT_LINE[0]);
display.println("00:00");
display.drawRect(SCREEN_WIDTH - 16, SCREEN_TEXT_LINE[0], 16, 8, WHITE);
display.drawFastHLine(0, SCREEN_TEXT_LINE[1] + 2, SCREEN_WIDTH, WHITE);
// Draw Footer
display.getTextBounds("v0.1-2a43c", SCREEN_WIDTH, SCREEN_TEXT_LINE[7], &text_x_position, &text_y_position, &text_width, &text_height);
display.setCursor(SCREEN_WIDTH - text_width, SCREEN_TEXT_LINE[7]);
display.println("v0.1-2a43c");
display.display();
*/
}

14
lib/View/View/home_view.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "../Model/view.h"
#include <Adafruit_SSD1306.h>
#include <display.h>
class HomeView : public View
{
public:
void render();
private:
protected:
Display *display;
};

View File

@ -0,0 +1,207 @@
#include "wifi_manager.h"
AsyncWebServer server(80);
IPAddress localIP;
IPAddress localGateway;
IPAddress subnet(255, 255, 0, 0);
unsigned long previousMillis = 0;
const long interval = TIMEOUT_MS;
const char *WEB_INPUT_SSID = "ssid";
const char *WEB_INPUT_PASSWORD = "password";
const char *WEB_INPUT_GATEWAY = "gateway";
const char *WEB_INPUT_STATIC_IP = "static-ip";
const char *WEB_CHECKBOX_STATIC_IP = "cb-static-ip";
char const *CONFIG_PATH = NETWORK_CONFIG;
WifiManager *WifiManager::instance = nullptr;
WifiManager *WifiManager::getInstance()
{
if (instance == nullptr)
{
instance = new WifiManager();
}
return instance;
}
WifiManager::WifiManager()
{
this->fh = FileHandler::getInstance();
connectionStatus = 0;
setup();
}
int WifiManager::initWifi()
{
if (networkConfig.ssid == "" || networkConfig.staticAddress == "")
{
Serial.println("Undefined SSID or IP address.");
return 1;
}
WiFi.mode(WIFI_STA);
// localIP.fromString(networkConfig.);
localGateway.fromString(networkConfig.gateway);
if (!WiFi.config(localIP, localGateway, subnet))
{
Serial.println("STA Failed to configure");
return 1;
}
WiFi.begin("231313", "123");
Serial.println("Connecting to WiFi...");
unsigned long currentMillis = millis();
previousMillis = currentMillis;
while (WiFi.status() != WL_CONNECTED)
{
currentMillis = millis();
if (currentMillis - previousMillis >= TIMEOUT_MS)
{
Serial.println("Failed to connect.");
return 1;
}
}
Serial.println(WiFi.localIP());
return 0;
}
void WifiManager::initSPIFFS()
{
if (!SPIFFS.begin(true))
{
Serial.println("An error has occurred while mounting SPIFFS");
}
Serial.println("SPIFFS mounted successfully");
}
void WifiManager::httpListener()
{
server.onNotFound([](AsyncWebServerRequest *request)
{ request->send(404); });
server.on("/test", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(SPIFFS, "/index.html", "text/html"); });
server.serveStatic("/", SPIFFS, "/");
Serial.println(SPIFFS.exists("/index.html"));
server.on("/", HTTP_POST, [](AsyncWebServerRequest *request)
{
int params = request->params();
Serial.println(params);
for(int i=0;i<params;i++){
Serial.println(i);
AsyncWebParameter* p = request->getParam(i);
if(p->isPost()){
// HTTP POST ssid value
if (p->name() == WEB_INPUT_SSID) {
Serial.print("SSID set to: ");
Serial.println(p->value().c_str());
// Write file to save value
//writeFile(SPIFFS, ssidPath, ssid.c_str());
}
// HTTP POST pass value
if (p->name() == WEB_INPUT_PASSWORD) {
Serial.print("Password set to: ");
Serial.println(p->value().c_str());
// Write file to save value
//writeFile(SPIFFS, passPath, pass.c_str());
}
// HTTP POST ip value
if (p->name() == WEB_INPUT_STATIC_IP) {
Serial.print("IP Address set to: ");
Serial.println(p->value().c_str());
// Write file to save value
//writeFile(SPIFFS, ipPath, ip.c_str());
}
if (p->name() == WEB_CHECKBOX_STATIC_IP) {
Serial.print("CBset to: ");
Serial.println(p->value().c_str());
// Write file to save value
//writeFile(SPIFFS, ipPath, ip.c_str());
}
// HTTP POST gateway value
if (p->name() == WEB_INPUT_GATEWAY) {
Serial.print("Gateway set to: ");
Serial.println(p->value().c_str());
// Write file to save value
//writeFile(SPIFFS, gatewayPath, gateway.c_str());
}
//Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
}
}
request->send(200, "text/plain", "Done. ESP will restart, connect to your router and go to IP address: ");
delay(3000);
ESP.restart(); });
}
void WifiManager::setup()
{
initSPIFFS();
IPAddress localIP;
IPAddress localGateway;
IPAddress subnet(255, 255, 0, 0);
// Load values saved in SPIFFS
if (true) //! initWifi()
{
// Connect to Wi-Fi network with SSID and password
Serial.println("Setting AP (Access Point)");
WiFi.softAP("ESP-WIFI-MANAGER", "12345");
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
// Web Server Root URL
server.on("/hello", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(200, "text/plain", "Hello World"); });
httpListener();
server.begin();
}
}
int WifiManager::writeNetworkConfig()
{
return true;
}
int WifiManager::removeNetworkConfig()
{
return fh->remove((char *)CONFIG_PATH);
}
int WifiManager::checkNetworkConfig()
{
strcpy(networkConfig.ssid, "PROGRAM 1");
strcpy(networkConfig.gateway, "123.123.123.123");
strcpy(networkConfig.password, "Test123");
strcpy(networkConfig.staticAddress, "124.124.124.124");
networkConfig.isDynamicAddress = 0;
// Serial.println(fh->write(CONFIG_PATH, (byte *)&config, sizeof(config)));
/* NetworkConfig readConfig = {};
fh->read(CONFIG_PATH, (byte *)&readConfig, sizeof(readConfig));
Serial.println(readConfig.ssid);
Serial.println(readConfig.gateway);
Serial.println(readConfig.password);
Serial.println(readConfig.staticAddress);
Serial.println(readConfig.isDynamicAddress);
Serial.println(fh->exists(CONFIG_PATH)); */
Serial.println(fh->exists((char *)CONFIG_PATH));
Serial.println(fh->remove((char *)CONFIG_PATH));
Serial.println(fh->exists((char *)CONFIG_PATH));
// Serial.println(fh->remove(CONFIG_PATH));
return 0;
}

View File

@ -0,0 +1,44 @@
#pragma once
#include <Arduino.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include <string>
#include "SPIFFS.h"
#include "../Utils/file_handler.h"
#define NETWORK_CONFIG "/config/network.txt"
#define TIMEOUT_MS 10000
struct NetworkConfig
{
char ssid[33];
char password[33];
char gateway[16];
bool isDynamicAddress;
char staticAddress[16];
};
class WifiManager
{
public:
static WifiManager *getInstance();
private:
static WifiManager *instance;
int connectionStatus;
FileHandler *fh;
NetworkConfig networkConfig;
WifiManager();
void setup();
unsigned long previousMillis;
void initSPIFFS();
int initWifi();
void httpListener();
int checkNetworkConfig();
int removeNetworkConfig();
int writeNetworkConfig();
protected:
};

23
platformio.ini Normal file
View File

@ -0,0 +1,23 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_ldf_mode=deep
lib_deps =
Wire
SPI
adafruit/Adafruit NeoPixel@^1.10.5
adafruit/Adafruit SSD1306@^2.5.6
monitor_filters = esp32_exception_decoder

27
project.json Normal file
View File

@ -0,0 +1,27 @@
{
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/datacollector/src",
"projectType": "application",
"targets": {
"build": {
"executor": "nx:run-commands",
"options": {
"command": ""
}
},
"serve": {
"executor": "nx:run-commands",
"options": {
"command": "pio run -t exec"
}
},
"version": {
"executor": "@jscutlery/semver:version",
"options": {
"preset": "conventional",
"commitMessageFormat": "chore(${projectName}): release version ${version}"
}
}
},
"tags": []
}

96
src/main.cpp Normal file
View File

@ -0,0 +1,96 @@
#include <Adafruit_GFX.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_SSD1306.h>
#include <Arduino.h>
#include <Wire.h>
#define BUTTON_IN_1 GPIO_NUM_27
#define RGB_PIN GPIO_NUM_15
#define LED_COUNT 1
Adafruit_NeoPixel pixels(1, RGB_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_SSD1306 display(128, 64, &Wire, -1);
bool i2c_scanner() {
uint8_t error, address;
int nDevices;
Serial.println("Scanning sensors on I2C Bus...");
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
} else if (error == 4) {
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
return true;
}
void setup() {
Serial.begin(115200);
Serial.println("Main.setup");
Wire.begin();
pixels.begin();
pixels.clear();
pixels.show();
pixels.setBrightness(10);
i2c_scanner();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 0);
display.println(F("Hallo Welt"));
display.display();
}
uint16_t hsv = 0;
uint32_t hsvUpdate = 0;
uint32_t btnPressStartTime = 0;
uint8_t isBtnPressed = 0;
void loop() {
uint32_t now = millis();
int btnIn1 = digitalRead(BUTTON_IN_1);
if (btnIn1 == HIGH && isBtnPressed == 0) {
btnPressStartTime = now;
isBtnPressed = 1;
Serial.println("BTN pressed");
}
if (btnIn1 == LOW && isBtnPressed == 1) {
isBtnPressed = 0;
}
if (now - hsvUpdate >= 100) {
hsv += 100;
if (hsv >= 65535) hsv = 0;
pixels.setPixelColor(0, pixels.ColorHSV(hsv));
pixels.show();
hsvUpdate = now;
}
}

11
test/README Normal file
View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html