<!DOCTYPE html><html><head>
<title>README.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<style>
/*
Arduino® Light Theme - Stefania Mellai <s.mellai@arduino.cc>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #FFFFFF;
}
.hljs,
.hljs-subst {
color: #434f54;
}
.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-doctag,
.hljs-name {
color: #00979D;
}
.hljs-built_in,
.hljs-literal,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #D35400;
}
.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #00979D;
}
.hljs-type,
.hljs-string,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
color: #005C5F;
}
.hljs-title,
.hljs-section {
color: #880000;
font-weight: bold;
}
.hljs-comment {
color: rgba(149,165,166,.8);
}
.hljs-meta-keyword {
color: #728E00;
}
.hljs-meta {
color: #434f54;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-function {
color: #728E00;
}
.hljs-number {
color: #8A7B52;
}
</style>
<style>
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
body {
font-family: "HelveticaNeue-Light", sans-serif, "宋体","Segoe WPC", "Segoe UI", "SFUIText-Light","Droid Sans Fallback";
font-size: 18px;
padding: 0 12px;
line-height: 1.6;
word-wrap: break-word;
color: #333333;
}
.content-wrapper{
max-width: 860px;
margin: 0 auto;
padding: 0 30px;
}
#code-csp-warning {
position: fixed;
top: 0;
right: 0;
color: white;
margin: 16px;
text-align: center;
font-size: 12px;
font-family: sans-serif;
background-color:#444444;
cursor: pointer;
padding: 6px;
box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}
#code-csp-warning:hover {
text-decoration: none;
background-color:#007acc;
box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}
body.scrollBeyondLastLine {
margin-bottom: calc(100vh - 22px);
}
body.showEditorSelection .code-line {
position: relative;
}
body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
content: "";
display: block;
position: absolute;
top: 0;
left: -12px;
height: 100%;
}
body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
left: -30px;
}
.vscode-light.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(0, 0, 0, 0.15);
}
.vscode-light.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(0, 0, 0, 0.40);
}
.vscode-dark.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 255, 255, 0.4);
}
.vscode-dark.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 255, 255, 0.60);
}
.vscode-high-contrast.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 160, 0, 0.7);
}
.vscode-high-contrast.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 160, 0, 1);
}
img {
max-width: 100%;
max-height: 100%;
}
a {
color: #4080D0;
text-decoration: none;
}
a:focus,
input:focus,
select:focus,
textarea:focus {
outline: 1px solid -webkit-focus-ring-color;
outline-offset: -1px;
}
hr {
border: 0;
height: 2px;
border-bottom: 2px solid;
}
h1 {
padding-bottom: 0.3em;
line-height: 1.2;
border-bottom: 1px solid #eee;
}
h2{
padding-bottom: .3em;
font-size: 2em;
line-height: 1.225;
border-bottom: 1px solid #eee;
}
h3{
font-size: 1.75em;
line-height: 1.225;
}
h1, h2, h3 {
font-weight: bold;
}
h1 code,
h2 code,
h3 code,
h4 code,
h5 code,
h6 code {
font-size: inherit;
line-height: auto;
}
a:hover {
color: #4080D0;
text-decoration: underline;
}
table {
border-collapse: collapse;
}
table > thead > tr > th {
text-align: left;
border-bottom: 1px solid;
}
table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
padding: 5px 10px;
}
table > tbody > tr + tr > td {
border-top: 1px solid;
}
blockquote {
margin: 0 7px 0 5px;
padding: 0 16px 0 10px;
border-left: 5px solid;
}
code {
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
font-size: 14px;
line-height: 19px;
}
body.wordWrap pre {
white-space: pre-wrap;
}
.mac code {
font-size: 12px;
line-height: 18px;
}
pre:not(.hljs),
pre.hljs code > div {
padding: 16px;
border-radius: 3px;
overflow: auto;
}
/** Theming */
.vscode-light,
.vscode-light pre code {
color: rgb(30, 30, 30);
}
.vscode-dark,
.vscode-dark pre code {
color: #DDD;
}
.vscode-high-contrast,
.vscode-high-contrast pre code {
color: white;
}
.vscode-light code {
color: #A31515;
}
.vscode-dark code {
color: #D7BA7D;
}
.vscode-light pre:not(.hljs),
.vscode-light code > div {
background-color: rgba(220, 220, 220, 0.4);
}
.vscode-dark pre:not(.hljs),
.vscode-dark code > div {
background-color: rgba(10, 10, 10, 0.4);
}
.vscode-high-contrast pre:not(.hljs),
.vscode-high-contrast code > div {
background-color: rgb(0, 0, 0);
}
.vscode-high-contrast h1 {
border-color: rgb(0, 0, 0);
}
.vscode-light table > thead > tr > th {
border-color: rgba(0, 0, 0, 0.69);
}
.vscode-dark table > thead > tr > th {
border-color: rgba(255, 255, 255, 0.69);
}
.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
border-color: rgba(0, 0, 0, 0.18);
}
.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
border-color: rgba(255, 255, 255, 0.18);
}
.vscode-light blockquote,
.vscode-dark blockquote {
background: rgba(127, 127, 127, 0.1);
border-color: rgba(0, 122, 204, 0.5);
}
.vscode-high-contrast blockquote {
background: transparent;
border-color: #fff;
}
</style>
<style>
pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
border-radius: 3px;
overflow-x: auto;
white-space: pre-wrap;
overflow-wrap: break-word;
}
pre:not(.hljs) {
padding: 23px;
line-height: 19px;
}
blockquote {
background: rgba(127, 127, 127, 0.1);
border-color: rgba(0, 122, 204, 0.5);
}
.emoji {
height: 1.4em;
}
/* for inline code */
:not(pre):not(.hljs) > code {
color: #C9AE75; /* Change the old color so it seems less like an error */
font-size: inherit;
}
/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
page-break-after: always;
}
.table-of-contents li{
list-style-type: initial;
}
</style>
<style>
@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.2"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}
</style>
</head>
<body>
<div class="content-wrapper">
<h1 id="%F0%9F%8C%8D-nodemap-%E2%80%93-kartenvisualisierung-f%C3%BCr-talas.web-(next.js%2C-leaflet%2C-redux)" tabindex="-1">🌍 NodeMap – Kartenvisualisierung für TALAS.web (Next.js, Leaflet, Redux)</h1>
<p>NodeMap ist eine modulare Kartenanwendung zur Visualisierung und Bearbeitung von GIS-Daten, POIs und
Gerätestatus in einer interaktiven Leaflet-Karte.</p>
<blockquote>
<p>📘 Für Entwickler:<br>
Die technische Dokumentation (Architektur, Redux, Komponenten, etc.) befindet sich in:<br>
<a href="docs/README.md"><code>/docs/README.md</code></a></p>
</blockquote>
<h2 id="%F0%9F%8C%8D-live-vorschau-der-karte" tabindex="-1">🌍 Live-Vorschau der Karte</h2>
<p><img src="docs/screenshots/overview1.png" alt="Startansicht der NodeMap Karte"></p>
<hr>
<blockquote>
<p>🖥 Entwicklung & Test unter Windows 11 mit Node.js v18.17.1 und IIS<br>
📦 MySQL 8.0 läuft lokal in einem Docker-Container (nur für Entwicklung)<br>
🗄 Produktionsumgebung: TALAS.web und MySQL Server unter Windows Server</p>
</blockquote>
<hr>
<h2 id="technologie-stack" tabindex="-1">Technologie-Stack</h2>
<table>
<thead>
<tr>
<th>Technologie</th>
<th>Zweck</th>
</tr>
</thead>
<tbody>
<tr>
<td>Next.js</td>
<td>React-Framework (Frontend/SSR)</td>
</tr>
<tr>
<td>Leaflet</td>
<td>Kartendarstellung</td>
</tr>
<tr>
<td>Redux Toolkit</td>
<td>Zustandverwaltung</td>
</tr>
<tr>
<td>Tailwind CSS</td>
<td>Styling</td>
</tr>
<tr>
<td>MySQL</td>
<td>Datenbank</td>
</tr>
<tr>
<td>Node.js / IIS</td>
<td>Server und Auslieferung</td>
</tr>
</tbody>
</table>
<h2 id="%F0%9F%A7%AD-zielumgebung" tabindex="-1">🧭 Zielumgebung</h2>
<ul>
<li>Windows-Produktionsserver (offline, kein Internet)</li>
<li>Kommunikation nur im lokalen Netzwerk</li>
<li>Nutzerzugriff per VPN + Remote Desktop (RDP)</li>
<li>Integration per iFrame in TALAS.web</li>
</ul>
<hr>
<h2 id="%F0%9F%94%84-wie-funktioniert-das-system%3F" tabindex="-1">🔄 Wie funktioniert das System?</h2>
<p>Die Anwendung wird von TALAS.web im iFrame geladen. Die URL enthält Parameter für Map- und
User-ID.<br>
NodeMap lädt anschließend Daten über WebServices und MySQL.<br>
➡ Details zur Architektur: <a href="docs/architecture.md">docs/architecture.md</a></p>
<hr>
<h2 id="%E2%9A%99%EF%B8%8F-kartenquellen-konfiguration-(public%2Fconfig.json)" tabindex="-1">⚙️ Kartenquellen-Konfiguration (public/config.json)</h2>
<p>Die Datei <code>public/config.json</code> steuert, welche Kartenquelle (z.B. OSM oder lokale Tiles) für die
Leaflet-Karte verwendet wird.</p>
<p><strong>Beispiel:</strong></p>
<pre class="hljs"><code><div><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"//info"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"tileSources: 'local' für offline, 'osm' für online"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"tileSources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"local"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"http://localhost/talas5/TileMap/mapTiles/{z}/{x}/{y}.png"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"osm"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"active"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"osm"</span>
<span class="hljs-punctuation">}</span>
</div></code></pre>
<ul>
<li>Mit <code>active</code> kann zwischen Online- und Offline-Karten umgeschaltet werden.</li>
<li>Die Datei wird beim Start der App automatisch geladen.</li>
<li>Für Offline-Betrieb muss das lokale Kartenmaterial vorhanden sein (siehe Installationsanleitung).</li>
</ul>
<hr>
<h2 id="%F0%9F%A7%B0-erstinstallation-auf-server" tabindex="-1">🧰 Erstinstallation auf Server</h2>
<h3 id="voraussetzungen" tabindex="-1">Voraussetzungen</h3>
<ul>
<li>Windows Server mit IIS</li>
<li>Sicherstellen, dass alle TALAS.web API-Endpunkte(WebService) erreichbar sind</li>
<li>Node.js & npm installiert (z. B. v18–20)</li>
<li>MySQL (lokal oder erreichbar)</li>
<li>Port 3000 freigegeben (Firewall)</li>
<li>IIS-Datei <code>mapTypC.aspx</code> vorhanden in C:\inetpub\wwwroot\talas5\MessagesMap\
(Server-IP mit Port 3000)</li>
<li>Browser: Chrome ab Version 125.0.6420.142 empfohlen</li>
<li>Karten Material vorhanden in: <code>C:\inetpub\wwwroot\talas5\TileMap\mapTiles</code>
<img src="docs/screenshots/mapTiles.png" alt="mapTiles"> Falls nicht vorhanden hier downloaden:
http://10.10.0.28/produkte/TALAS.map/mapTiles.zip</li>
</ul>
<hr>
<h2 id="%F0%9F%94%97-integration-in-talas.web" tabindex="-1">🔗 Integration in TALAS.web</h2>
<p><img src="docs/screenshots/iframe-in-talas2.png" alt="iFrame-Integration"></p>
<ul>
<li>Die App wird in einem <strong>iFrame</strong> geladen</li>
<li>Startet über <code>?m=X&u=Y</code> für Map-/User-ID</li>
<li>Rechte und Inhalte werden automatisch geladen<pre class="hljs"><code><div>z.B.
`http://10.10.0.13/talas5/MessagesMap/mapTypC.aspx?m=12&u=484`
</div></code></pre>
</li>
</ul>
<hr>
<h2 id="%F0%9F%AA%9B-schritt-f%C3%BCr-schritt%3A-nodemap-auf-dem-server-installieren" tabindex="-1">🪛 Schritt-für-Schritt: NodeMap auf dem Server installieren</h2>
<hr>
<h2 id="%F0%9F%93%A6-schnelles-deployment-%C3%BCber-zip-paket" tabindex="-1">📦 Schnelles Deployment über ZIP-Paket</h2>
<p>Ein fertiges Deployment-Bundle für jede Version (z. B. <code>NodeMap V1.1.260.zip</code>) ist auf dem internen
SharePoint verfügbar:</p>
<p>📁
<a href="https://littwinsystemtechnik.sharepoint.com/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Forms/AllItems.aspx?id=%2Fsites%2FLittwinSystemtechnik%2FFreigegebene%20Dokumente%2FProjekte%2FMasterkarte%20V2%20setup%20files&csf=1&web=1&e=Sm1wwt&CID=9291bb06%2Dc869%2D4e30%2D8efa%2D8cda40df3cd6&FolderCTID=0x0120009C4F8227D6A11D4E89F1CCB9E517F488">Masterkarte V2 setup files</a></p>
<h4 id="%F0%9F%93%82-ablauf%3A" tabindex="-1">📂 Ablauf:</h4>
<ol>
<li>
<p>🛑 <strong>Dienst beenden</strong></p>
<ul>
<li>Vor dem Update muss der bestehende Windows-Dienst <code>NodeMapService</code> beendet werden,<br>
um Dateikonflikte beim Löschen zu vermeiden.
<img src="docs/screenshots/Dienst-beenden.png" alt="Dienst beenden"></li>
</ul>
</li>
<li>
<p>🔍 <strong>Prüfen, ob passende <code>node_modules-v1.1.xxx.zip</code> Datei vorhanden ist</strong></p>
<ul>
<li>Wenn <strong>nicht vorhanden</strong> → <code>C:\inetpub\wwwroot\talas5\nodeMap</code> komplett löschen</li>
<li>Wenn <strong>vorhanden</strong> → nur <code>node_modules-v1.1.xxx.zip</code> und <code>node_modules</code> Verzeichnis behalten,
Rest löschen<br>
💡 <strong>Tipp:</strong> <code>node_modules-v1.1.xxx.zip</code> nach Entpacken und in node_modules umbenennen!</li>
</ul>
</li>
<li>
<p>📦 <strong>ZIP entpacken</strong></p>
<ul>
<li><code>NodeMap V1.1.260.zip</code> entpacken<br>
Nach dem alles entpakt ist, dann sieht das so aus
<img src="docs/screenshots/nodeMap-inhalt.png" alt="NodeMap Inhalt"></li>
</ul>
</li>
<li>
<p>🚀 <strong>Dienst starten</strong></p>
<ul>
<li>Windows-Dienst <code>NodeMapService</code> wieder starten</li>
</ul>
</li>
</ol>
<hr>
<h2 id="%F0%9F%93%A6-oder-%C3%BCber-git" tabindex="-1">📦 Oder über Git</h2>
<ol>
<li>
<p><strong>Projekt lokal klonen und kompilieren:</strong></p>
<pre class="hljs"><code><div>git <span class="hljs-built_in">clone</span> http://10.10.0.12:3000/ISA/nodeMap
<span class="hljs-built_in">cd</span> nodeMap <span class="hljs-comment"># zu den Verzeichnis wechseln</span>
npm install <span class="hljs-comment"># Abhängigkeiten installieren (lädt alle Pakete aus package.json)</span>
npm run build <span class="hljs-comment"># Erstellt ein optimiertes Produktions-Build im Ordner .next/</span>
</div></code></pre>
</li>
<li>
<p><strong>ZIP-Paket vorbereiten (lokal):</strong></p>
</li>
</ol>
<ul>
<li>Verzeichnis <code>.next/</code></li>
<li>Verzeichnisse <code>public/</code>, <code>node_modules/</code> falls auf dem Server nicht vorhanden sind oder etwas
hinzugefügt wurde (Bilder oder Bibliothek)</li>
<li>Dateien <code>.env.production</code>, <code>package.json</code> falls auf dem Server nicht vorhanden sind oder etwas
hinzugefügt wurde (Umgebungsvariablen oder Bibliothek)</li>
<li><code>nssm.exe</code>, <code>StartNodeApp.bat</code>, <code>Start-Dev.ps1</code> um Windows Dienst zu erstellen falls noch nicht
vorhanden ist Download:
<a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&web=1&e=Sm1wwt">nssm</a></li>
</ul>
<ol start="3">
<li>
<p><strong>Auf Server kopieren nach:</strong> Ein Ordner temp auf dem Desktop erstellen->ZIP-Paket
einfügen->entpacken->Inhalt in folgende Verzeichnis einfügen</p>
<pre class="hljs"><code><div>C:\inetpub\wwwroot\talas5\nodeMap\
</div></code></pre>
</li>
<li>
<p><strong>Kartenmaterial hinzufügen (falls nicht vorhanden):</strong></p>
<p>Muss noch in Download-Server eingefügt werden, damit eine zentrale Stelle verfügbar ist</p>
<pre class="hljs"><code><div>C:\inetpub\wwwroot\talas5\TileMap\
</div></code></pre>
</li>
<li>
<p><strong>.env.production konfigurieren</strong></p>
<p>Die Datei <code>.env.production</code> enthält alle benötigten Verbindungs- und Betriebsvariablen wie z. B.
Datenbank-Zugang, Pfade und Mock-Option.</p>
<p>➡ Vollständige Anleitung & Beispieldatei: <a href="docs/guide/env.md">.env.production</a></p>
</li>
<li>
<p><strong>Dienst registrieren falls nicht vorhanden</strong></p>
</li>
</ol>
<ul>
<li>Mit <code>nssm.exe</code> Windows-Dienst „nodeMapService“ erstellen</li>
<li>Ziel: <code>StartNodeApp.bat</code></li>
<li>Anleitung:
<a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&web=1&e=Sm1wwt">nssm</a></li>
</ul>
<ol>
<li>
<p><strong>Starten:</strong> Dienst starten , falls vorhanden einmal beenden und neustarten</p>
</li>
<li>
<p><strong>Im Browser testen:</strong></p>
<pre class="hljs"><code><div>http://<ip>/talas5/MessagesMap/mapTypC.aspx?m=IdMap&u=IdUser
z.B.
http://<ip>/talas5/MessagesMap/mapTypC.aspx?m=12&u=484
</div></code></pre>
</li>
</ol>
<hr>
<h2 id="%F0%9F%94%81-update-richtlinien" tabindex="-1">🔁 Update-Richtlinien</h2>
<table>
<thead>
<tr>
<th>Art</th>
<th>Ersetzte Dateien</th>
<th>Bemerkung</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Kleines Update</strong></td>
<td><code>.next/</code></td>
<td><code>node_modules</code> nicht nötig</td>
</tr>
<tr>
<td><strong>Großes Update</strong></td>
<td>alle Dateien (wie Neuinstallation)</td>
<td>Dienst ggf. neu registrieren</td>
</tr>
</tbody>
</table>
<h3 id="empfohlener-ablauf-f%C3%BCr-kleines-update%3A" tabindex="-1">Empfohlener Ablauf für kleines Update:</h3>
<ol>
<li><code>.next/</code> Verzeichnis nach Kompilieren kopieren und auf dem Server einfügen</li>
<li>Dienst neu starten</li>
<li>Im Browser testen: <code> http://<ip>/talas5/MessagesMap/mapTypC.aspx?m=IdMap&u=IdUser</code></li>
</ol>
<hr>
<h2 id="%E2%9C%85-tests-%26-qualit%C3%A4tssicherung" tabindex="-1">✅ Tests & Qualitätssicherung</h2>
<ul>
<li><strong>E2E-Tests:</strong> Cypress (nur in der Entwicklungsumgebung)</li>
<li><strong>Unit-Tests:</strong> Aktuell keine Jest-Tests aufgrund Leaflet-Komplexität</li>
<li><strong>Empfehlung:</strong> Manuelle Tests nach jedem Deployment durchführen (Checkliste vorbereiten)</li>
</ul>
<hr>
<h2 id="%F0%9F%8F%B7-versionierung" tabindex="-1">🏷 Versionierung</h2>
<p>wird mit husky Bibliothek automatisch erhöht bei "git commit message"</p>
<p>→ Wird in der Fußzeile angezeigt. Die Version wird automatisch erhöht über ein Script
(<code>scripts/bumpVersion.js</code>), das per Husky vor jedem Commit ausgeführt wird.<br>
Die Version steht sowohl in <code>package.json</code> als auch in <code>config/appVersion.js</code>.</p>
<hr>
<h2 id="%F0%9F%92%BE-setup%3A-installationen-%26-tools" tabindex="-1">💾 Setup: Installationen & Tools</h2>
<table>
<thead>
<tr>
<th>Tool</th>
<th>Version</th>
<th>Link</th>
</tr>
</thead>
<tbody>
<tr>
<td>Node.js</td>
<td>20.12.1</td>
<td><a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&web=1&e=Sm1wwt">nodejs</a></td>
</tr>
<tr>
<td>Chrome</td>
<td>optional</td>
<td><a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&web=1&e=Sm1wwt">Chrome</a></td>
</tr>
<tr>
<td>NSSM.exe</td>
<td>2.24</td>
<td><a href="https://littwinsystemtechnik.sharepoint.com/:f:/r/sites/LittwinSystemtechnik/Freigegebene%20Dokumente/Projekte/Masterkarte%20V2%20setup%20files?csf=1&web=1&e=Sm1wwt">nssm</a></td>
</tr>
</tbody>
</table>
<blockquote>
<p>Hinweis: Die Datei <code>MapTypC.aspx</code> in TALAS lädt NodeMap als iFrame über Port 3000.<br>
Wenn die Seite nicht angezeigt wird, bitte sicherstellen:</p>
<ul>
<li>Port 3000 ist in der Firewall freigegeben</li>
<li>Die IP im Scriptteil von <code>MapTypC.aspx</code> ist aktuell (z. B. <code>10.10.0.13</code>)</li>
<li>Windows-Dienst <code>NodeMapService</code> ist aktiv oder <code>npm start</code> in Terminal ausgeführt</li>
</ul>
</blockquote>
<h2 id="%F0%9F%93%81-dokumentation-%26-technische-leitf%C3%A4den" tabindex="-1">📁 Dokumentation & technische Leitfäden</h2>
<table>
<thead>
<tr>
<th>Thema</th>
<th>Link</th>
</tr>
</thead>
<tbody>
<tr>
<td>Benutzeranleitung</td>
<td><a href="docs/guide/user-guide.md">docs/guide/user-guide.md</a></td>
</tr>
<tr>
<td>Architekturübersicht</td>
<td><a href="docs/architecture.md">architecture.md</a></td>
</tr>
<tr>
<td>Projektstruktur</td>
<td><a href="docs/guide/project-structure.md">project-structure.md</a></td>
</tr>
<tr>
<td>Webservices (TALAS)</td>
<td><a href="docs/guide/webservices.md">webservices.md</a></td>
</tr>
<tr>
<td>Umgebungsvariablen</td>
<td><a href="docs/guide/env.md">env.md</a></td>
</tr>
<tr>
<td>Mockdaten-Modus</td>
<td><a href="docs/guide/mock-data.md">mock-data.md</a></td>
</tr>
<tr>
<td>Zustandverwaltung (Redux)</td>
<td><a href="docs/guide/redux-zustand.md">redux-zustand.md</a></td>
</tr>
<tr>
<td>Abhängigkeiten</td>
<td><a href="docs/guide/dependencies.md">dependencies.md</a></td>
</tr>
<tr>
<td>Lokale Entwicklung</td>
<td><a href="docs/guide/setup-dev.md">setup-dev.md</a></td>
</tr>
<tr>
<td>FAQ & Fehlerbehandlung</td>
<td><a href="docs/guide/faq.md">faq.md</a></td>
</tr>
<tr>
<td>Glossar</td>
<td><a href="docs/guide/glossar.md">faq.md</a></td>
</tr>
</tbody>
</table>
</div>
</body></html>