diff --git a/Birdmap.API/ClientApp/public/index.html b/Birdmap.API/ClientApp/public/index.html
index 337161e..fb4f5c3 100644
--- a/Birdmap.API/ClientApp/public/index.html
+++ b/Birdmap.API/ClientApp/public/index.html
@@ -22,7 +22,17 @@
-->
Birdmap
-
+
+
diff --git a/Birdmap.API/Controllers/AuthController.cs b/Birdmap.API/Controllers/AuthController.cs
index 4105a9e..4207b7d 100644
--- a/Birdmap.API/Controllers/AuthController.cs
+++ b/Birdmap.API/Controllers/AuthController.cs
@@ -60,7 +60,7 @@ namespace Birdmap.Controllers
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
- var response = _mapper.Map(user);
+ AuthenticateResponse response = _mapper.Map(user);
response.AccessToken = tokenString;
response.TokenType = "Bearer";
response.ExpiresIn = expiresInSeconds;
diff --git a/docs/birdmap-frontend-routes.drawio b/docs/birdmap-frontend-routes.drawio
new file mode 100644
index 0000000..0b23c71
--- /dev/null
+++ b/docs/birdmap-frontend-routes.drawio
@@ -0,0 +1 @@
+5Vxbd5s4EP41fjQHJG5+TOKm7W52T7ZNN7uPspENG4xckJ24v34FiIskfEkKmDo+PU0YhITmm/k0M1I8gjerl48xWvt/EA+HI6B7LyM4HQFgmACM0n+6t8sljmnlgmUceLxRJfga/MBcqHPpJvBwIjSkhIQ0WIvCOYkiPKeCDMUxeRabLUgojrpGS6wIvs5RqEofA4/6udQFTiX/hIOlX4xs2JP8zgoVjflMEh955Lkmgh9G8CYmhOa/rV5ucJgqr9DL4+fdY3j3ZH/87a/kO/p2/fvDn3+P885uX/NIOYUYR/TNXS+nK7i9T5bjHfCmD+G37+vZj7HJp0Z3hb6wx9THL0lMfbIkEQo/VNLrmGwiD6e96uyqanNHyJoJDSb8D1O647aANpQwkU9XIb+bj5kOJEF0ZH68XUI28RwfaAe5maF4iQ/2V6HIzB+TFabxjj0Y4xDRYCu+HeJ2uCzbVbpmv3B1vwJV/pZbFG74SPcx9oI5ovgL2VCsIFPpPVXisx9Q/HWNMk08M98VdbwgEeUAGGyO18sQJQmHLKExeSq9IW1dmrZewnMqGlscU/xSU5WqT34XQu5InEksmzPJc+WXRuFsfs0nTf3nIWi0fl3R8QVYf0G8x81/D1ytm3+j7sE5dM80HO/+4c9nF/+mF5pVXE5f6jenO8ElhoAZOCdlFa/ZxFkjeKsylk9Ws01ynK0E/kmp6xatgjDV/iccbjFlIzRwGgqDZcQu5gwEHDcTGxsyiJbsyq6uHjJrYWtfh1xniVxnWyrXuQ1U57ZAdQecXYDuC0MuTkOuNCIbpcRrh5SrOQvIQhJnLe3vmzTGYcqCi4Wr63pdVMO7EKYdjJMMqCvWwDDXL/Un7CX/WUpuQ7IMIqFNyO/kL1M8cmEromFLVuL0uCIe4BfBTKZ4gTYhvUM7FpVcHASWfkYIGhdG1VEXKEzUcJBNkIrqVfgwVQOjzvCK31gFnpcvpJi5J5plXaXaXZMgotlErOuRNU37YmtnwqEq1a+o9VRE9vPkCeo3G7QPutK+GpXTeHOhyjfNgSnfUsOLzSwM5kPIh9pXv+GK6i/hOBv12A3hXbAdSELaAfnAoQHgKABceasgukz1m4Oz/4mifkXpOPKu0qpkyvSpCoN5Z9n9IYo8mijCZtXXVGs1aLaQnZxO8hHu0yWs5lgSsnZRMy66yKfJn6rXLKWOTLlkNJE6yvWgdJShX077J2KxE8OBFO87NMNhdzFB3YHNQ17JC+m8s1G5WtdNcL/17/XWsa4B6LgCHKAVa7E0yxS6dTV3InZCFosEd4OwWtIYnM/bv4LPA3kxlV31VJ+HUlRqOaY2qX96ZQBHTYg/J1cb6jNos7qXd5lksG9vpGIDSy92yjhQ43boAAidGowM7N7IQM29B0cGzi9BBparwdrHaokaHEOzax9HXDfOyxSGeZwpmjeceiaLMB3uGs2fllkGcVPWeeEi+3TDJ4dzAcYnhltEWxxO2IopQm3i1G3CETnLsDXX0WsfyTS7IxtHjS1HwEarNHHL/1cuz287vRsGizotx+rALhjwhmwLluYYvcHfSBdptv9OcYamK8YTLYUTbMkw+wIVNGUTwq7aq3fLTt2Ha29XrWZiskXNCKVklZWMUEyLOIiw6Ray2yCsNtvLSGkWkvlT0YTbmfvzwVI9CGrOnI5EsYZEAGoBym4nIDJ0kcOUGtbJFRGxH0fqZk+Mw3BAu1ozTgCHBjL0Zt304ERqynVGJ/LwNpjjJJvlVfret+/bo8BAPApO2vIo2dKhe4E+1RhsnsunfIzoCq3ftyPtSdCbHak7P7Kg3Y4fWZJ1F0dJ2nejsVR36tGN1KD9vPFd8r59yBzIYmQ7LTmRI52Hkc8DXsJaZLpDcqL37UBHqnKyA4GuHAhI52WBKa0epzpQmRGV0Vx3HgSatdO9B1nqOZEvzJpwzGQ3ZLUmEY7OfVSz/fMitgTt+Y9qWk1MJmm9x/2igyd6j3JBblSD3THS6kV6qfvW9o/6PV1ScGf9uNeG+pfrwdLOPgRqQNbzgUd1w3eKEn9GUOxdLgzywdNGHGCvOAAVh7zudrkoyKdPB+ANapHoU16puVwUTGdwKKg1hjuW6F8uBLYxOAjUP0RQtH7uc0BF8HA8rmtWfl9hnaOBhuMVZVz3xjoJdIAmHOsQ++09klMTsuEZzMlFgXMajAFNzdgfokN5w/PkuoCha24tvwBiwc60pH67NphhZY4Hg7JhGwxwoZA4SsC+2WCgYx/KFXs3mF/gb1Pshi9eGZ7BmHo3DGPqg2KYYhqDNhjzRIM5a2nKAiKw0inVN9sLOGiHvdvL686+ZzsWD34QMTPxUOKX+UfNfFL5PaIUx1EmATpUsgyQb4TUtkVaNLpXfe1NX+wjoGy9daNwIvaj5EKv3ubYs7pKJXceZ++NsprfqjLVfPwTDZddVt+uljevvqMOfvgf
\ No newline at end of file
diff --git a/docs/thesis/bib/mybib.bib b/docs/thesis/bib/mybib.bib
index eb7a9a5..5072a9b 100644
--- a/docs/thesis/bib/mybib.bib
+++ b/docs/thesis/bib/mybib.bib
@@ -3,7 +3,7 @@
url = {https://kubernetes.io},
}
-@dashboard{kubernetes-dashboard,
+@misc{kubernetes-dashboard,
title = {A Kubernetes Dashboard hivatalos oldala},
url = {https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/},
}
@@ -53,11 +53,21 @@
url = {https://jwt.io/introduction/},
}
+@misc{automapper,
+ title = {Az AutoMapper hivatalos oldala},
+ url = {https://automapper.org/},
+}
+
@misc{react,
title = {A React.js hivatalos oldala},
url = {https://reactjs.org/},
}
+@misc{react-context,
+ title = {A React Context dokumentációja},
+ url = {https://reactjs.org/docs/context.html},
+}
+
@misc{material,
title = {A Material hivatalos oldala},
url = {https://material.io/},
@@ -83,6 +93,11 @@
url = {https://github.com/RicoSuter/NSwag},
}
+@misc{nswag-studio,
+ title = {Az NSwag Studio github oldala},
+ url = {https://github.com/RicoSuter/NSwag/wiki/NSwagStudio},
+}
+
@misc{swagger-ui,
title = {A Swagger UI hivatalos oldala},
url = {https://swagger.io/tools/swagger-ui/},
diff --git a/docs/thesis/content/birdmap-backend.tex b/docs/thesis/content/birdmap-backend.tex
index 40a2a2d..d58c115 100644
--- a/docs/thesis/content/birdmap-backend.tex
+++ b/docs/thesis/content/birdmap-backend.tex
@@ -33,8 +33,7 @@ Az egyik a \verb+User+, mely az alkalmazás felhasználóinak adatait tárolja.
A másik a \verb+Service+, mely a külső szolgáltatások adatainak tárolását szolgálja, amelyeket azért tárolok az adatbázisban és nem mondjuk a konfigurációs fájlban,
mert szerettem volna, hogyha a kezelőfelületen lehetne őket szerkeszteni, törölni.
-\lstset{style=sharpc, morekeywords={record, get, set}}
-\begin{lstlisting}[caption=A User és a Service modell]
+\begin{lstlisting}[style=csharp, caption=A User és a Service modell]
public record User
{
public int Id { get; set; }
@@ -51,7 +50,7 @@ mert szerettem volna, hogyha a kezelőfelületen lehetne őket szerkeszteni, tö
{
public int Id { get; set; }
public string Name { get; set; }
- public Uri Uri { get; set; }
+ public Uri Url { get; set; }
public bool IsFromConfig { get; set; }
}
@@ -74,19 +73,23 @@ Majd hozzáadja az újonnan beolvasott értékeket.
\section{Üzleti logikai réteg}
%----------------------------------------------------------------------------
Ebben a rétegben található meg a szerver legtöbb szolgáltatása. It vannak implementálva a Birdnetes Command and Control és Input komponensekkel kommunikáló szolgáltatások is,
-melyeket azok OpenAPI leírói alapján az NSwag\cite{nswag} alkalmazással generáltam. Az OpenAPI a klienseken kívül definiálja még az azok által használt modelleket is.
+melyeket azok OpenAPI leírói alapján az NSwag Studio\cite{nswag-studio} alkalmazással generáltam. Az OpenAPI a klienseken kívül definiálja még az azok által használt modelleket is.
A Command and Control által használt \verb+Device+ modell tartalmazza annak egyedi azonosítóját, státuszát, koordinátáit és a használt szenzorok listáját,
melyeknek szintén van egy modellje \verb+Sensor+ néven. Ennek szintén van azonosítója és státusza. Az Input szolgáltatásnak is van saját modellje,
amely a hangüzenetek metaadatait reprezentálja. Többek között tartalmazza a kihelyezett eszköz egyedi azonosítóját és a hangüzenet keltének dátumát.
Ugyan itt található meg a \verb+User+ és \verb+Service+ entitások létrehozásáért, olvasásáért, szerkesztéséért és törléséért felelős szolgáltatások is.
Valamint itt található még az autentikációért felelős szolgáltatás is. A felhasználók jelszavainak tárolására a HMAC (Hash-based Message Authentication Code) algorithmust,
-pontosabban annak a \verb+HMACSHA512+\cite{hmacsha512} C\# implementációját használtam.
+pontosabban annak a \verb+HMACSHA512+\cite{hmacsha512} C\# implementációját használtam.
Minden jelszóhoz generálok egy egyedi kulcsot és azzal egy hash-t, majd ezeket tárolom a \verb+User+ modell \verb+PasswordSalt+ és \verb+PasswordHash+ mezőiben.
Amikor egy felhasználó be akar jelentkezni először megvizsgálom, hogy egyáltalán létezik-e az adatbázisban az adott nevű felhasználó,
ha igen, akkor a megadott jelszóból az imént említett folyamattal generált kulcsot és hash-t összehasonlítom az adatbázisban tárolttal.
+Azért hasznos íly módon, és nem mondjuk egyszerű szöveges formában tárolni a felhasználók jelszavát, mert így a felhasználón kívül senki sem tudja, hogy mi volt az eredeti jelszava,
+az algorithmus egyirányú volta miatt\footnotemark. Ha véletlenül rossz kezekbe kerülne az adatbázis tartalma, akkor sem fognak tudni bejeletkezni a felhasználók adataival.
+
+\footnotetext{Generálni egyszerű és gyors. Visszafejteni közel lehetetlen.}
%----------------------------------------------------------------------------
\subsection{Kommunikációs Szolgáltatások}
%----------------------------------------------------------------------------
@@ -125,18 +128,17 @@ Meg lehet adni különböző szűrőket és kimeneteket, amellyel szelektálni l
Például az MQTT szolgáltalás napló bejegyzéseit a \ref{lst:nlog-config} lista alapján szűrtem.
Minden \verb+Debug+ szintől nagyobb és \verb+Error+ szinttől kisebb bejegyzés, mely tartalmazza az \verb+Mqtt+ kulcsszót az \verb+mqttFile+ azonosítójú fájlba kerül.
-\lstset{style=xml, morekeywords={targets, target, xsi:type, name, fileName, layout, rules, logger, name, minlevel, maxlevel, writeTo, final}}
-\begin{lstlisting}[caption=Az NLog.config fájl egy részlete, label=lst:nlog-config]
+\begin{lstlisting}[style=xml, caption=Az NLog.config fájl egy részlete, label=lst:nlog-config]
...
-
+
...
...
-
+
...
\end{lstlisting}
@@ -146,7 +148,11 @@ Azaz, hogy egy kérés-t milyen sorrendben dolgozzák fel a regisztrált szolgá
A szerveroldali kivételkezelésre szánt szolgáltatás, az \verb+ExceptionHandlerMiddleware+ is itt van használva,
amely elkap minden kivételt, amit a csővezeték további részei dobtak és JSON formátumban visszaadja azokat a kliensnek.
-Továbbá az NSwag\cite{nswag} szoftvercsomag segítségével regisztrálok egy szolgáltatást,
+%----------------------------------------------------------------------------
+\subsection{Swagger}
+\label{subsect:backend-swagger}
+%----------------------------------------------------------------------------
+Az NSwag\cite{nswag} szoftvercsomag segítségével regisztrálok egy szolgáltatást,
mely a szerveroldalon található kontrollereket felhasználva generál egy OpenAPI specifikációt és annak egy Swagger UI\cite{swagger-ui} felületet,
ahol a végpontok kipróbálhatóak, tesztelhetőek kliensoldal nélkül is.
@@ -161,14 +167,8 @@ ahol a végpontok kipróbálhatóak, tesztelhetőek kliensoldal nélkül is.
\subsection{Kontrollerek}
%----------------------------------------------------------------------------
A kontrollerek határozzák meg, hogy a szerveroldalon milyen végpontokat, milyen paraméterekkel lehet meghívni, ahhoz milyen jogosultságok kellenek.
-A jogosultságok kezelését a JSON Web Token-ekkel oldottam meg. A fejlasználó bejelentkezéskor kap egy ilyen token-t,
-amelyben tárolom a hozzá tartozó szerepet. A \ref{lst:devices-controller}-as listában látszik, hogy hogyan használom ezeket a szerepeket.
-A \verb+DevicesController+ végpontjait alapértelmezetten \verb+User+ és \verb+Admin+ jogosultságú felhasználó hívhatja, az "api/devices/online" végpontot azonban csak \verb+Admin+ jogosultságú.
-Hasonló képpen oldottam meg ezt a többi kontrollernél is. A \verb+User+ felhasználók csak olyan végpontokat hívhat, mely kizárolag az állapotok olvasásával jár.
-Az \verb+Admin+ felhasználók hívhatnak bármilyen végpontot.
-\lstset{style=sharpc, morekeywords={record, async}}
-\begin{lstlisting}[caption=Az eszköz kontroller és annak "online" végpontja, label=lst:devices-controller]
+\begin{lstlisting}[style=csharp, caption=Az eszköz kontroller és annak "online" végpontja, label=lst:devices-controller]
[Authorize(Roles = "User, Admin")]
[ApiController]
[Route("api/[controller]")]
@@ -184,6 +184,42 @@ Az \verb+Admin+ felhasználók hívhatnak bármilyen végpontot.
}
\end{lstlisting}
-Controllersw
-Dtos
-mapper
\ No newline at end of file
+A jogosultságok kezelését a JSON Web Token-ekkel oldottam meg. A fejlasználó bejelentkezéskor kap egy ilyen token-t,
+amelyben tárolom a hozzá tartozó szerepet. A \ref{lst:devices-controller}-as listában látszik, hogy hogyan használom ezeket a szerepeket.
+A \verb+DevicesController+ végpontjait alapértelmezetten \verb+User+ és \verb+Admin+ jogosultságú felhasználó hívhatja, az "api/devices/online" végpontot azonban csak \verb+Admin+ jogosultságú.
+Hasonló képpen oldottam meg ezt a többi kontrollernél is. A \verb+User+ felhasználók csak olyan végpontokat hívhat, mely kizárolag az állapotok olvasásával jár.
+Az \verb+Admin+ felhasználók hívhatnak bármilyen végpontot.
+
+A szerveroldalon négy különböző kontroller található, melyek mindegyikének alapvető feladata az üzleti logikát megvalósító szolgáltatások használata, a működés naplózás,
+illetve az imént említett végpontok authorizálása és kiszolgálása. Ezeken kívül a kontrollerek speciális feladata a következő:
+\begin{itemize}
+ \item Az \textbf{AuthController} felel a felhasználók bejelentkezésének lebonyolításáért, a JSON Web Token elkészítéséért. Az \verb+[Authorize]+ helyett itt az \verb+[AllowAnonymous]+ attribútum van használva, mellyel azt lehet jelezni, hogy a végpont bejelentkezés nélkül is hívható.
+ \item A \textbf{ServiceController} felel az alkalmazás által használt külső szolgáltatások állapotának lekérdezhetőségéért. Ilyenek például a Birdnetes rendszer vagy az MQTT szolgáltatás állapota.
+ \item A \textbf{DevicesController} felel a Command and Control mikroszolgáltatással való kommunikáció megvalósításáért, illetve a SignalR használatáért. Ha egy felhasználó valamelyik végpontot használva változtat valamelyik eszköz állapotán, akkor a kontroller jelez erről a klienseknek.
+ \item A \textbf{LogController} felel azért, hogy az \verb+Admin+ jogosultságú felhasználók letölthessék a szerveroldalon készült naplófájlokat.
+\end{itemize}
+
+Az adatbázisból érkező adatok gyakran túl sok vagy túl kevés információt tartalmaznak ahhoz, hogy kiolvasás után rögtön elküldjem a kliensoldalnak.
+Például amikor a felhasználó bejelentkezik a kiolvasott \verb+User+ objektum tartalmazza annak jelszavát (hash-elt formában), viszont nem tartalmazza az authorizációhoz használt token adatait.
+Ennek a megoldására adatátviteli objektumokat hoztam létre, melyek csak azokat a mezőket tartalmazzák amelyekre a felhasználónak szüksége van.
+Az adatbázisból kiolvasott objektum hasznos részeit és egyéb használni kívánt információt átmásolom az átviteli objektumba. Majd ezt küldöm el a kliensoldal felé.
+
+Hogy az adatok másolását ne kézzel kelljen csinálnom, az AutoMapper\cite{automapper} szoftvercsomagot alkalmaztam, melynek használata rendkívül egyszerű.
+Meg lehet adni profilokat, ahol két objektum közötti leképzéseket lehet felvenni. A szoftvercsomag automatikusan átmásolja az azonos nevű mezőket az egyik objektumból a másikba,
+de meg lehet adni egyedi leképzéseket is.
+\pagebreak
+\begin{lstlisting}[style=csharp, caption=Egy példa az AutoMapper használatára.]
+ // Creating maps.
+ CreateMap()
+ .ForMember(m => m.Username, opt => opt.MapFrom(m => m.Name))
+ .ForMember(m => m.UserRole, opt => opt.MapFrom(m => m.Role))
+ .ReverseMap();
+
+ CreateMap()
+ .ReverseMap();
+
+ // Using maps.
+ IMapper mapper = GetMapper();
+ User user = GetUserFromDb();
+ AuthenticateResponse response = mapper.Map(user);
+\end{lstlisting}
diff --git a/docs/thesis/content/birdmap-frontend.tex b/docs/thesis/content/birdmap-frontend.tex
index e69de29..9226f4b 100644
--- a/docs/thesis/content/birdmap-frontend.tex
+++ b/docs/thesis/content/birdmap-frontend.tex
@@ -0,0 +1,289 @@
+%----------------------------------------------------------------------------
+\chapter{Kliens oldal}
+\label{chapt:birdmap-frontend}
+%----------------------------------------------------------------------------
+Ebben a fejezetben bemutatom a kliensoldal architektúráját. Ismertetem a különböző komponensek felépítését.
+
+%----------------------------------------------------------------------------
+\section{Architektúra}
+%----------------------------------------------------------------------------
+Az alkalmazásnak minden oldala egy külön React komponens, mely mindegyikének saját mappája van a főkönyvtár alatt,
+ahol az egyes oldalak által használt szolgáltatások és egyéb komponensek találhatóak.
+A közöses használt szolgáltatások és komponensek a common mappába kerültek.
+
+A kliensoldal belépési pontja az \verb+App.js+ fájlban található \verb+App+ komponens.
+Itt egy React \verb+Switch+-ben fel van sorolva az összes oldal komponense azok elérési útvonalai szerint.
+Ezt szemlélteti a \ref{lst:react-switch}-es lista.
+Az a komponens jelenik meg a felületen, amelyiknek \verb+path+ mező értéke megegyezik az URL-ben találhatóval.
+
+\begin{lstlisting}[style=jsx, caption=Az App.js Switch tartalma., label=lst:react-switch]
+
+
+
+
+
+
+
+
+
+\end{lstlisting}
+
+Hozzáférés szempontjából három fajta oldalt különböztetünk meg:
+\begin{itemize}
+ \item \textbf{Publikus oldal}. Az oldal bejelentkezés nélkül is látogatható.
+ \item \textbf{Privát oldal}. Az oldal csak bejelentkezés után látogatható.
+ \item \textbf{Admin oldal}. Az oldalt csak bejelentkezett admin felhasználók látogathatják.
+\end{itemize}
+
+Ezek alapján készítettem két generikus komponenst. Az egyik a \verb+DefaultLayout+ komponens, mely az oldal alapértelmezett elrendezéséért felel.
+Paraméterében át lehet adni egy másik megjeleníteni kívánt komponenst, melyet a fejléc alatt jelenít meg.
+Mivel minden komponens ebbe az bázis komponensbe van csomagolva, így akárhova navigálunk az oldalon a felület mindig egységes marad.
+
+A másik komponens a \verb+PredicateRoute+, melynek paraméterében meg lehet adni egy feltételt, illetve egy másik komponenst.
+Ha a feltétel hamis akkor átírányítja a felhasználót a bejelentkező oldalra, ha igaz akkor megjeleníti a \verb+DefaultLayout+-ba csomagolt komponenst.
+Publikus oldalnál a feltétel mindig igaz.
+Privátnál a feltétel a bejelentkezéshez van kötve.
+Az admin oldal feltétele egyrészt szintén a bejelentkezés, másrészt a felhasználó \verb+Admin+ jogolsultsága.
+Ezt a folyamatot próbálja szemléltetni a \ref{fig:birdmap-frontend-architecture}-es ábra.
+Legfelül sárgával vannak feltüntetve a hívható végpontok, alattuk a hozzájuk kapcsolt megjelenítendő komponensek, azok alatt pedig a hozzáférést szabályozó komponensek.
+
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/birdmap-frontend-routes.png}
+ \caption{A Birdmap kliensoldalának architektúrája}
+ \label{fig:birdmap-frontend-architecture}
+\end{figure}
+
+%----------------------------------------------------------------------------
+\section{Kommunikáció a szerveroldallal}
+%----------------------------------------------------------------------------
+A szerveroldallal való kommunikációt rendkívül egyszerűen tudtam implementálni köszönhetően a \ref{subsect:backend-swagger}-as fejezetben bemutatott Swagger oldalnak
+és annak, hogy az NSwag Studio-val\cite{nswag-studio} a C\#-on kívül lehet TypeScript\footnotemark klienseket is generálni a leíró fájlból.
+Így készültek el a kommponensek kommunikációért felelős szolgáltatásai.
+
+\footnotetext{JavaScript-re épített statikus típusdefiníciókat tartalmazó nyelv. JavaScript és TypeScript együtt is használható.}
+%----------------------------------------------------------------------------
+\section{Komponensek}
+%----------------------------------------------------------------------------
+Ebben a szakaszban ismertete az egyes oldalak komponenseit és azok alkomponenseit,
+illetve a navigációért felelős fejlécet.
+%----------------------------------------------------------------------------
+\subsection{Navigáció}
+%----------------------------------------------------------------------------
+A fejléc két komponensből áll. Az egyik az oldal címe a másik az oldalak linkjeit tartalmazó komponens.
+Utóbbit a React \verb+NavLink+ komponenseivel készítettem, melyeknek meg lehet adni, hogy kattintásra hova irányítsa a felhasználót.
+Ha a jelenlegi webcím tartalmazza a linknek megadott címet, akkor az aktív státuszba kerül, melyre külön stílus osztályok vonatkoznak.
+Ezt használva, az aktív linkeket egy aláhúzással jelölöm.
+
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/appbar-user-admin.png}
+ \caption{A Birdmap fejléce. Felül a User, alul az Admin felhasználóké}
+ \label{fig:birdmap-appbar}
+\end{figure}
+
+A fejléc alapértelmezetten része a \verb+DefaultLayout+ komponensnek, így minden oldalon megjelenítésre kerül.
+
+%----------------------------------------------------------------------------
+\subsection{Login}
+%----------------------------------------------------------------------------
+A bejelentkező oldal viszonylag egyszerű. Két szövegdobozt és egy bejelentkező gombot tartalmaz, ahogy az a \ref{fig:birdmap-login}-as ábrán is látszik.
+
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=60mm, keepaspectratio]{figures/birdmap-login.png}
+ \caption{A Birdmap bejelentkező felülete}
+ \label{fig:birdmap-login}
+\end{figure}
+
+A generált szerverrel kommunikáló szolgáltatás be van csomagolva egy közösen használt másik szolgáltatásba.
+Ennek célja, hogy a bejelentkezés eredményét több komponens is olvashassa, hiszen az alkalmazás felületét alapvetően megkülönbözteti,
+egyrészt a bejelentkezés sikeressége, másrészt a bejelentkezett felhasználó jogosultsági köre.
+
+Sikeres bejelentkezés után a szerver elküldi a felhasználó szerepét, illetve a hozzáférési token-t, amelyre a kliens többi szolgáltatásának is szüksége lesz a kommunkációhoz.
+Ezeket az oldal \verb+sessionStorage+-ában\footnotemark tárolom és a becsomagolt szolgáltatáson keresztül elérhetőek.
+
+Kijelentkezni a navigációs fejlécben található profil ikonra való kattintással lehet.
+
+\footnotetext{Webtárhely objektum. Lehetővé teszi a kulcs-érték párok tárolását a böngészőben.}
+
+%----------------------------------------------------------------------------
+\subsection{Logs}
+%----------------------------------------------------------------------------
+Ez az oldal az \verb+Admin+ felhasználó számára lehetővé teszi a szerveren található naplófájlok letöltését \verb+zip+ fájlformátumú archív fájlokban.
+Komponense a \ref{fig:birdmap-logs}-es ábrán látható.
+
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=75mm, keepaspectratio]{figures/birdmap-logs.png}
+ \caption{A Birdmap naplófájlok letöltésének felülete}
+ \label{fig:birdmap-logs}
+\end{figure}
+%----------------------------------------------------------------------------
+\subsection{Eszköz állapot és hangüzenet kezelő szolgáltatás}
+%----------------------------------------------------------------------------
+A szakasz további komponenseinek van egy közös ismertetője. Mégpedig, hogy mindegyiknek szüksége van a kihelyezett eszközök adataira
+és az azok által publikált hangüzenetekből képzett valószínüségre.
+A Reactnek van egy beépített komponense \verb+Context+\cite{react-context} néven, mellyel különböző komponensek között lehet adatokat megosztani.
+Ezt használva készítettem egy \verb+DevicesContextProvider+ osztályt, melynek feladata a szerver eszköz kontrollerével való kommunikáció a megfelelő szolgáltatáson keresztül,
+illetve a SignalR csatornákra való feliratkozás. Ezekből az adatokból egy \verb+DevicesContext+ készül, mely a \verb+Provider+ által átadásra kerül annak minden gyerekének.
+A \ref{lst:react-switch}-es listában látható, hogy a \verb+DevicesContextProvider+ szülője a \verb+Dashboard+, \verb+Devices+ és \verb+Heatmap+ komponenseknek.
+
+%----------------------------------------------------------------------------
+\subsection{Dashboard}
+%----------------------------------------------------------------------------
+A Dashboard az alkalmazás kezdő oldala. Itt található meg a külső szolgáltatások állapotát vizsgáló komponens,
+illetve a kihelyezett eszközök működési folyamatában áttekintést nyújtó diagrammok mindegyike.
+
+Az oldal megjelenítésekor elindul egy másodpercenként ismétlődő folyamat,
+mely a \verb+DevicesContext+-ből kiolvasott értékekből legenerálja a diagrammokon megjelenítendő összes adatot.
+Ez azonban az adat mennyiségétől függően akár egy-két másodpercig is eltarthat, ami rendkívül lassúvá és használhatatlanná tenné a felületet.
+Ennek elkerülése érdekében az adatfeldolgozó folyamat egyszerre csak egy pár elemet dolgoz fel, mely alfolyamatok között 20 milliszekundum szüneteket iktattam be.
+Továbbá hogy a különböző diagrammok animációi is zökkenőmentesek legyenek, azok adatai cserélése között is van 300 milliszekundum szünet.
+Így valamivel lasabb az adatfeldolgozás, de a felület használható marad.
+%----------------------------------------------------------------------------
+\subsubsection{Külső szolgáltatások}
+%----------------------------------------------------------------------------
+Az alkalmazás használatának szempontjából van néhány olyan külső szolgáltatás, melyek elérhetősége hiányában a rendszer működésképtelen.
+Ilyen például a Birdnetes klasztere vagy a szerver MQTT szolgáltatása.
+Ezért készítettem el az \ref{fig:dashboard-services-loaded}-ös ábrán látható információs panelt, ahol a szolgáltatások állapotát lehet látni, hogy a felhasználó tudja miért nem működik esetleg az alkalmazás.
+A felület megvalósításhoz a Material UI \verb+Accordion+ elemét használtam, ami lényegében egy lenyíló lista.
+Ennek fejlécében a szolgáltatás neve, elérési útvonala és státusza látható. A lenyíló elemben a szolgáltatástól érkezett válasz van megjelenítve.
+
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/dashboard-services-loaded.png}
+ \caption{Az alkalmazás által használt külső komponensek állapotának megjelenítéséért felelős komponens}
+ \label{fig:dashboard-services-loaded}
+\end{figure}
+
+Az oldal betöltése vagy a frissítés gomb megnyomása esetén az adatok lekérésre kerülnek a szervertől.
+Ez a folyamat akár öt-hat másodpercig is eltarthat, mely közben a felhasználó egy üres listát látna.
+Ennek elkerülésére használom a Material UI \verb+Skeleton+ komponensét,
+mely egy megadható méretű töltő csíkkal helyettesíti az \verb+Accordion+-ban található elemeket a \ref{fig:dashboard-services-loading}-os ábrán látható módon.
+Azért célszerű ennek a használata, mert így a felhasználónak több információja van arról, hogy a felületen milyen adatok és hol fognak megjelenni.
+A felhasználói élmény maximalizálása érdekében a frissítés előtt lekérdezem a szervertől, hogy hány darab szolgáltatás található az adatbázisban
+és annyi darab töltőcsíkos \verb+Accordion+-t jelenítek meg.
+
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/dashboard-services-loading.png}
+ \caption{A Skeletonok alkalmazása a külső szolgáltatások állapotának betöltése közben.}
+ \label{fig:dashboard-services-loading}
+\end{figure}
+
+%----------------------------------------------------------------------------
+\subsubsection{Eszközök és szenzorok állapota}
+%----------------------------------------------------------------------------
+Ennek a komponensnek a szerepe, hogy áttekintést nyújtson az eszközök és szenzorok állapotáról.
+Úgy gondoltam, hogy erre a legcélravezetőbb eszköz a \ref{fig:dashboard-donut}-es ábrán is látható Apexcharts fánk diagrammja.
+Látható, hogy hány darab eszköz és szenzor van bekapcsolt, kikapcsolt, illetve hibás állapotban.
+Az állapotok változása esetén a \verb+DevicesContextProvider+-nek köszönhetően az adatok automatikusan frissülnek.
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/dashboard-donut-devices.png}
+ \caption{A Dashboard eszköz- és szenzor állapotok diagrammja}
+ \label{fig:dashboard-donut}
+\end{figure}
+%----------------------------------------------------------------------------
+\subsubsection{Hőtérkép diagrammok}
+%----------------------------------------------------------------------------
+Ezekkel a diagrammokkal az a célom, hogy az eszközök által küldött észleléseket időrendben vizualizáljam.
+Megvalósításukhoz az Apexcharts Heatmap típusú diagrammját használtam.
+A \ref{fig:dashboard-heatmap-second}-as ábrán látható diagram az elmúlt egy percben küldött, másodpercenként a legnagyobb, hangüzenetekből képzett valószínűségeket ábrozolja.
+A \ref{fig:dashboard-heatmap-minute}-es ábrán látható diagram pedig az elmúlt egy órában percenként a legnagyobbakat.
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/second-heatmap.png}
+ \caption{Másodperc alapú hőtérképes diagramm}
+ \label{fig:dashboard-heatmap-second}
+\end{figure}
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/minute-heatmap.png}
+ \caption{Perc alapú hőtérképes diagramm}
+ \label{fig:dashboard-heatmap-minute}
+\end{figure}
+
+A függőleges tengelyen a rendszer eszközei vannak dinamikusan megjelenítve.
+A vízszintes tengelyen pedig az említett időtartományok.
+A diagrammokon látható négyzetek a valószínüség nagyságától függően sötétebbek vagy világosabbak.
+\newpage
+%----------------------------------------------------------------------------
+\subsubsection{Riasztás számláló}
+%----------------------------------------------------------------------------
+Ez egy egyszerű oszlopdiagram, mely aggregálja az egyes eszközök által küldött hangüzeneteket 0.5 valószínűség felett a \ref{fig:dashboard-devices-column}-es ábrán látható módon.
+Segítségével megvizsgálható, hogy mely eszközök riasztanak a legtöbbet a legnagyobb valószínűséggel.
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/dashboard-column-devices.png}
+ \caption{Eszközönkénti riasztásokat számláló diagramm}
+ \label{fig:dashboard-devices-column}
+\end{figure}
+
+Az egyes oszlopok három részre vannak bontva az üzenetek öt tized, hét tized és kilenc tized fölötti valószínűsége szerint.
+\newpage
+%----------------------------------------------------------------------------
+\subsubsection{Üzenetek gyakorisága}
+%----------------------------------------------------------------------------
+Az oldalon található utolsó diagramm egy vonal diagammn, melynek célja, hogy ábrázolja a rendszer által küldött üzenetek számát másodpercenként.
+A \ref{fig:dashboard-messages-line}-es ábrán látható a komponens.
+A vízszintes tengelyen a legelső érték az alkalmazás által először észlelt üzenet időpontja.
+Az utolsó érték a legutoljára észlelt időpontja.
+A függőleges tengelyen az adott másodpercben érkező üzenetek száma van ábrázolva.
+Az előzőekkel ellentétben itt az adatok nincsennek szűrve a hangüzenet valószínűsége alapján,
+tehát a rendszer által küldött összes üzenet látható.
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/dashboard-line-messages.png}
+ \caption{A másodpercenként érkező üzenetek számát ábrázoló diagram.}
+ \label{fig:dashboard-messages-line}
+\end{figure}
+\newpage
+%----------------------------------------------------------------------------
+\subsection{Devices}
+%----------------------------------------------------------------------------
+Ez az oldal lehetővé teszi a felhasználók számára az eszközök állapotának áttekintését, \verb+Admin+ felhasználók számára azok menedszelését is.
+Az eszközök dinamikusan jelennek meg a \verb+DevicesContextProvider+ adatai alapján, melyek megjelenítésére a Material UI \verb+Accrordion+ komponensét használom.
+Ennek fejlécében az eszköz neve, egyedi azonosítója és státusza található. A lenyíló részben pedig az eszköz által használt szenzorok neve, azonosítója és státusza.
+\verb+Admin+ felhasználók számára a felület két fajta gombbal bővül, mellyekkel be és ki lehet kapcsolni az egyes eszközöket, szenzorokat.
+Az \verb+Accordion+-ok felett található egy külön panel, mellyel egyszerre lehet kezelni az összes eszközt és azok szenzorait.
+A Devices oldal felülete a \ref{fig:frontend-devices}-es ábrán,
+az \verb+Admin+ felhasználók számára nyújtott plusz funkciók a \ref{fig:frontend-devices-admin}-as ábrán láthatók.
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/devices.png}
+ \caption{A Devices oldal felülete.}
+ \label{fig:frontend-devices}
+\end{figure}
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/devices-admin.png}
+ \caption{Az Admin felhasználók számára elérhető plusz funkciók.}
+ \label{fig:frontend-devices-admin}
+\end{figure}
+%----------------------------------------------------------------------------
+\subsection{Heatmap}
+%----------------------------------------------------------------------------
+\begin{figure}[!ht]
+ \centering
+ \includegraphics[width=150mm, keepaspectratio]{figures/heatmap.png}
+ \caption{A Heatmap oldal felülete.}
+ \label{fig:frontend-heatmap}
+\end{figure}
+
+
+
+
+
+
+
+
+- felépítés architektúra
+- App and navigation
+- Components and services
+- kép minden felületről
+ - kép user és admin felhasználók különbségéről
+ - Device service
+ - dashboard systeminfo service
+ - kép a skeletonról -> igazi adat
\ No newline at end of file
diff --git a/docs/thesis/content/birdmap-introduction.tex b/docs/thesis/content/birdmap-introduction.tex
index f25b72e..3d93729 100644
--- a/docs/thesis/content/birdmap-introduction.tex
+++ b/docs/thesis/content/birdmap-introduction.tex
@@ -46,9 +46,7 @@ A \ref{fig:grafana}-es ábra egy jó példa arra, hogy hogyan néz ki egy által
\subsection{Kibana}
%----------------------------------------------------------------------------
A Kibana\cite{kibana} jelentősen hasonlít a Grafanához, azonban amíg a utóbbit inkább az időben változó metrikák vizualizálására használják például processzor leterheltség vagy memória használat,
-addig az előbbit elsődlegesen az Elasticsearch\footenotemark adatok, főként napló bejegyzések, analizálására használják.
-
-\footnotetext{Ingyenes és nyílt forráskódú index alapú keresőmotor}
+addig az előbbit elsődlegesen az Elasticsearch\footnote{Ingyenes és nyílt forráskódú index alapú keresőmotor} adatok, főként napló bejegyzések, analizálására használják.
\begin{figure}[!ht]
\centering
diff --git a/docs/thesis/figures/appbar-admin.png b/docs/thesis/figures/appbar-admin.png
new file mode 100644
index 0000000..ed06905
Binary files /dev/null and b/docs/thesis/figures/appbar-admin.png differ
diff --git a/docs/thesis/figures/appbar-user-admin.png b/docs/thesis/figures/appbar-user-admin.png
new file mode 100644
index 0000000..5620587
Binary files /dev/null and b/docs/thesis/figures/appbar-user-admin.png differ
diff --git a/docs/thesis/figures/appbar-user.png b/docs/thesis/figures/appbar-user.png
new file mode 100644
index 0000000..2699d65
Binary files /dev/null and b/docs/thesis/figures/appbar-user.png differ
diff --git a/docs/thesis/figures/birdmap-frontend-routes.png b/docs/thesis/figures/birdmap-frontend-routes.png
new file mode 100644
index 0000000..d168f86
Binary files /dev/null and b/docs/thesis/figures/birdmap-frontend-routes.png differ
diff --git a/docs/thesis/figures/birdmap-login.png b/docs/thesis/figures/birdmap-login.png
new file mode 100644
index 0000000..f8ee069
Binary files /dev/null and b/docs/thesis/figures/birdmap-login.png differ
diff --git a/docs/thesis/figures/birdmap-logs.png b/docs/thesis/figures/birdmap-logs.png
new file mode 100644
index 0000000..fe2c445
Binary files /dev/null and b/docs/thesis/figures/birdmap-logs.png differ
diff --git a/docs/thesis/figures/dashboard-column-devices.png b/docs/thesis/figures/dashboard-column-devices.png
new file mode 100644
index 0000000..354f810
Binary files /dev/null and b/docs/thesis/figures/dashboard-column-devices.png differ
diff --git a/docs/thesis/figures/dashboard-donut-devices.png b/docs/thesis/figures/dashboard-donut-devices.png
new file mode 100644
index 0000000..1a1789d
Binary files /dev/null and b/docs/thesis/figures/dashboard-donut-devices.png differ
diff --git a/docs/thesis/figures/dashboard-line-messages.png b/docs/thesis/figures/dashboard-line-messages.png
new file mode 100644
index 0000000..d3c7db6
Binary files /dev/null and b/docs/thesis/figures/dashboard-line-messages.png differ
diff --git a/docs/thesis/figures/dashboard-services-loaded.png b/docs/thesis/figures/dashboard-services-loaded.png
new file mode 100644
index 0000000..ac656ae
Binary files /dev/null and b/docs/thesis/figures/dashboard-services-loaded.png differ
diff --git a/docs/thesis/figures/dashboard-services-loading-loaded.png b/docs/thesis/figures/dashboard-services-loading-loaded.png
new file mode 100644
index 0000000..c87afbf
Binary files /dev/null and b/docs/thesis/figures/dashboard-services-loading-loaded.png differ
diff --git a/docs/thesis/figures/dashboard-services-loading.png b/docs/thesis/figures/dashboard-services-loading.png
new file mode 100644
index 0000000..ef7b03f
Binary files /dev/null and b/docs/thesis/figures/dashboard-services-loading.png differ
diff --git a/docs/thesis/figures/devices-admin.png b/docs/thesis/figures/devices-admin.png
new file mode 100644
index 0000000..1335aaa
Binary files /dev/null and b/docs/thesis/figures/devices-admin.png differ
diff --git a/docs/thesis/figures/devices.png b/docs/thesis/figures/devices.png
new file mode 100644
index 0000000..8b1a3d2
Binary files /dev/null and b/docs/thesis/figures/devices.png differ
diff --git a/docs/thesis/figures/heatmap-on.png b/docs/thesis/figures/heatmap-on.png
new file mode 100644
index 0000000..fef2546
Binary files /dev/null and b/docs/thesis/figures/heatmap-on.png differ
diff --git a/docs/thesis/figures/heatmap.png b/docs/thesis/figures/heatmap.png
new file mode 100644
index 0000000..2b9b70d
Binary files /dev/null and b/docs/thesis/figures/heatmap.png differ
diff --git a/docs/thesis/figures/minute-heatmap.png b/docs/thesis/figures/minute-heatmap.png
new file mode 100644
index 0000000..83f8514
Binary files /dev/null and b/docs/thesis/figures/minute-heatmap.png differ
diff --git a/docs/thesis/figures/second-heatmap.png b/docs/thesis/figures/second-heatmap.png
new file mode 100644
index 0000000..8979b76
Binary files /dev/null and b/docs/thesis/figures/second-heatmap.png differ
diff --git a/docs/thesis/include/packages.tex b/docs/thesis/include/packages.tex
index 6061ad0..6d0e452 100644
--- a/docs/thesis/include/packages.tex
+++ b/docs/thesis/include/packages.tex
@@ -32,7 +32,6 @@
\usepackage[unicode]{hyperref} % For hyperlinks in the generated document.
\usepackage{xcolor}
\usepackage{listings} % For source code snippets.
-\lstdefinestyle{sharpc}{language=[Sharp]C, frame=lr, rulecolor=\color{blue!80!black}}
\usepackage[amsmath,thmmarks]{ntheorem} % Theorem-like environments.
diff --git a/docs/thesis/include/preamble.tex b/docs/thesis/include/preamble.tex
index 9fbb215..c3aa13b 100644
--- a/docs/thesis/include/preamble.tex
+++ b/docs/thesis/include/preamble.tex
@@ -42,32 +42,127 @@
%--------------------------------------------------------------------------------------
% Set up listings
%--------------------------------------------------------------------------------------
+
+\definecolor{red}{rgb}{0.6,0,0}
+\definecolor{blue}{rgb}{0,0,0.6}
+\definecolor{lightblue}{rgb}{0,0.5,0.7}
+\definecolor{green}{rgb}{0,0.8,0}
+\definecolor{cyan}{rgb}{0.0,0.6,0.6}
+\definecolor{orange}{rgb}{0.8,0.6,0}
+\definecolor{white}{rgb}{0.98, 0.98, 0.98}
\definecolor{lightgray}{rgb}{0.95,0.95,0.95}
-\lstset{
+\definecolor{darkviolet}{rgb}{0.58, 0.0, 0.83}
+\definecolor{royalblue}{rgb}{0.25, 0.41, 0.88}
+
+\lstdefinestyle{csharp}{
+ language=csh,
+ basicstyle=\scriptsize\ttfamily,
+ numbers=left,
+ numberstyle=\tiny,
+ numbersep=5pt,
+ tabsize=2,
+ extendedchars=true,
+ breaklines=true,
+ frame=b,
+ stringstyle=\color{red}\ttfamily,
+ showspaces=false,
+ captionpos=b,
+ showtabs=false,
+ xleftmargin=17pt,
+ framexleftmargin=17pt,
+ framexrightmargin=5pt,
+ framexbottommargin=4pt,
+ commentstyle=\color{green},
+ morecomment=[l]{//}, %use comment-line-style!
+ morecomment=[s]{/*}{*/}, %for multiline comments
+ showstringspaces=false,
+ morekeywords={ abstract, event, new, struct,
+ as, explicit, null, switch,
+ base, extern, object, this,
+ get, set,
+ bool, false, operator, throw,
+ break, finally, out, true,
+ byte, fixed, override, try,
+ case, float, params, typeof,
+ catch, for, private, uint,
+ char, foreach, protected, ulong,
+ checked, goto, public, unchecked,
+ class, record, async, if, readonly, unsafe,
+ const, implicit, ref, ushort,
+ continue, in, return, using,
+ decimal, int, sbyte, virtual,
+ default, interface, sealed, volatile,
+ delegate, internal, short, void,
+ do, is, sizeof, while,
+ double, lock, stackalloc,
+ else, long, static,
+ enum, namespace, string},
+ morekeywords=[2]{CreateMap, ForMember, MapFrom, ReverseMap, Onlineall, GetMapper, GetUserFromDb, Map},
+ morekeywords=[3]{Id, Name, PasswordHash, PasswordSalt, Role, IsFromConfig, Url, Username, UserRole, mapper, user, response},
+ keywordstyle=\color{blue},
+ keywordstyle={[2]\color{orange}},
+ keywordstyle={[3]\color{lightblue}},
+ identifierstyle=\color{cyan},
+ backgroundcolor=\color{white}
+}
+
+\lstdefinestyle{jsx}{
+ basicstyle=\scriptsize\ttfamily,
+ numbers=left,
+ numberstyle=\tiny,
+ numbersep=5pt,
+ tabsize=2,
+ extendedchars=true,
+ breaklines=true,
+ frame=b,
+ stringstyle=\color{red}\ttfamily,
+ showspaces=false,
+ captionpos=b,
+ showtabs=false,
+ xleftmargin=17pt,
+ framexleftmargin=17pt,
+ framexrightmargin=5pt,
+ framexbottommargin=4pt,
+ commentstyle=\color{green},
+ morestring=*[d]{"},
+ morecomment=[l]{//}, %use comment-line-style!
+ morecomment=[s]{/*}{*/}, %for multiline comments
+ showstringspaces=false,
+ morekeywords={ },
+ morekeywords=[2]{AuthComponent, LogsComponent, DashboardComponent, DevicesComponent, HeatmapComponent},
+ morekeywords=[3]{exact, path, component},
+ keywordstyle=\color{blue},
+ keywordstyle={[2]\color{orange}},
+ keywordstyle={[3]\color{lightblue}},
+ identifierstyle=\color{cyan},
+ backgroundcolor=\color{white}
+}
+\lstdefinestyle{xml}{
basicstyle=\scriptsize\ttfamily, % print whole listing small
- keywordstyle=\color{black}\bfseries, % bold black keywords
- identifierstyle=, % nothing happens
% default behavior: comments in italic, to change use
% commentstyle=\color{green}, % for e.g. green comments
- stringstyle=\scriptsize,
showstringspaces=false, % no special string spaces
aboveskip=3pt,
belowskip=3pt,
- backgroundcolor=\color{lightgray},
+ stringstyle=\color{red}\ttfamily,
+ backgroundcolor=\color{white},
+ keywordstyle=\color{blue},
+ identifierstyle=\color{cyan},
columns=flexible,
keepspaces=true,
escapeinside={(*@}{@*)},
captionpos=b,
breaklines=true,
- frame=single,
+ frame=b,
float=!ht,
tabsize=2,
+ morestring=*[d]{"},
+ morekeywords={targets, target, rules, logger},
literate=*
{á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ö}{{\"o}}1 {ő}{{\H{o}}}1 {ú}{{\'u}}1 {ü}{{\"u}}1 {ű}{{\H{u}}}1
{Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ö}{{\"O}}1 {Ő}{{\H{O}}}1 {Ú}{{\'U}}1 {Ü}{{\"U}}1 {Ű}{{\H{U}}}1
}
-
%--------------------------------------------------------------------------------------
% Set up theorem-like environments
%--------------------------------------------------------------------------------------
diff --git a/docs/thesis/thesis.pdf b/docs/thesis/thesis.pdf
index 84fdd30..099f95d 100644
--- a/docs/thesis/thesis.pdf
+++ b/docs/thesis/thesis.pdf
@@ -322,36 +322,138 @@ endobj
<< /S /GoTo /D (subsection.5.4.1) >>
endobj
216 0 obj
-(\376\377\000K\000o\000n\000t\000r\000o\000l\000l\000e\000r\000e\000k)
+(\376\377\000S\000w\000a\000g\000g\000e\000r)
endobj
217 0 obj
-<< /S /GoTo /D (lstnumber.5.3.13) >>
+<< /S /GoTo /D (subsection.5.4.2) >>
endobj
220 0 obj
-(\376\377\000I\000r\000o\000d\000a\000l\000o\000m\000j\000e\000g\000y\000z\000\351\000k)
+(\376\377\000K\000o\000n\000t\000r\000o\000l\000l\000e\000r\000e\000k)
endobj
221 0 obj
-<< /S /GoTo /D (appendix*.12) >>
+<< /S /GoTo /D (chapter.6) >>
endobj
224 0 obj
-(\376\377\000F\000\374\000g\000g\000e\000l\000\351\000k)
+(\376\377\000K\000l\000i\000e\000n\000s\000\040\000o\000l\000d\000a\000l)
endobj
225 0 obj
-<< /S /GoTo /D (section.F.1) >>
+<< /S /GoTo /D (section.6.1) >>
endobj
228 0 obj
-(\376\377\000A\000\040\000T\000e\000X\000s\000t\000u\000d\000i\000o\000\040\000f\000e\000l\000\374\000l\000e\000t\000e)
+(\376\377\000A\000r\000c\000h\000i\000t\000e\000k\000t\000\372\000r\000a)
endobj
229 0 obj
-<< /S /GoTo /D (section.F.2) >>
+<< /S /GoTo /D (section.6.2) >>
endobj
232 0 obj
-(\376\377\000V\000\341\000l\000a\000s\000z\000\040\000a\000z\000\040\000,\000,\000\311\000l\000e\000t\000,\000\040\000a\000\040\000v\000i\000l\000\341\000g\000m\000i\000n\000d\000e\000n\000s\000\351\000g\000,\000\040\000m\000e\000g\000\040\000m\000i\000n\000d\000e\000n\000'\000'\000\040\000k\000\351\000r\000d\000\351\000s\000\351\000r\000e)
+(\376\377\000K\000o\000m\000m\000u\000n\000i\000k\000\341\000c\000i\000\363\000\040\000a\000\040\000s\000z\000e\000r\000v\000e\000r\000o\000l\000d\000a\000l\000l\000a\000l)
endobj
233 0 obj
-<< /S /GoTo /D [234 0 R /Fit] >>
+<< /S /GoTo /D (section.6.3) >>
+endobj
+236 0 obj
+(\376\377\000K\000o\000m\000p\000o\000n\000e\000n\000s\000e\000k)
endobj
237 0 obj
+<< /S /GoTo /D (subsection.6.3.1) >>
+endobj
+240 0 obj
+(\376\377\000N\000a\000v\000i\000g\000\341\000c\000i\000\363)
+endobj
+241 0 obj
+<< /S /GoTo /D (subsection.6.3.2) >>
+endobj
+244 0 obj
+(\376\377\000L\000o\000g\000i\000n)
+endobj
+245 0 obj
+<< /S /GoTo /D (subsection.6.3.3) >>
+endobj
+248 0 obj
+(\376\377\000L\000o\000g\000s)
+endobj
+249 0 obj
+<< /S /GoTo /D (subsection.6.3.4) >>
+endobj
+252 0 obj
+(\376\377\000E\000s\000z\000k\000\366\000z\000\040\000\341\000l\000l\000a\000p\000o\000t\000\040\000\351\000s\000\040\000h\000a\000n\000g\000\374\000z\000e\000n\000e\000t\000\040\000k\000e\000z\000e\000l\001\121\000\040\000s\000z\000o\000l\000g\000\341\000l\000t\000a\000t\000\341\000s)
+endobj
+253 0 obj
+<< /S /GoTo /D (subsection.6.3.5) >>
+endobj
+256 0 obj
+(\376\377\000D\000a\000s\000h\000b\000o\000a\000r\000d)
+endobj
+257 0 obj
+<< /S /GoTo /D (subsubsection.6.3.5.1) >>
+endobj
+260 0 obj
+(\376\377\000K\000\374\000l\000s\001\121\000\040\000s\000z\000o\000l\000g\000\341\000l\000t\000a\000t\000\341\000s\000o\000k)
+endobj
+261 0 obj
+<< /S /GoTo /D (subsubsection.6.3.5.2) >>
+endobj
+264 0 obj
+(\376\377\000E\000s\000z\000k\000\366\000z\000\366\000k\000\040\000\351\000s\000\040\000s\000z\000e\000n\000z\000o\000r\000o\000k\000\040\000\341\000l\000l\000a\000p\000o\000t\000a)
+endobj
+265 0 obj
+<< /S /GoTo /D (subsubsection.6.3.5.3) >>
+endobj
+268 0 obj
+(\376\377\000H\001\121\000t\000\351\000r\000k\000\351\000p\000\040\000d\000i\000a\000g\000r\000a\000m\000m\000o\000k)
+endobj
+269 0 obj
+<< /S /GoTo /D (subsubsection.6.3.5.4) >>
+endobj
+272 0 obj
+(\376\377\000R\000i\000a\000s\000z\000t\000\341\000s\000\040\000s\000z\000\341\000m\000l\000\341\000l\000\363)
+endobj
+273 0 obj
+<< /S /GoTo /D (subsubsection.6.3.5.5) >>
+endobj
+276 0 obj
+(\376\377\000\334\000z\000e\000n\000e\000t\000e\000k\000\040\000g\000y\000a\000k\000o\000r\000i\000s\000\341\000g\000a)
+endobj
+277 0 obj
+<< /S /GoTo /D (subsection.6.3.6) >>
+endobj
+280 0 obj
+(\376\377\000D\000e\000v\000i\000c\000e\000s)
+endobj
+281 0 obj
+<< /S /GoTo /D (subsection.6.3.7) >>
+endobj
+284 0 obj
+(\376\377\000H\000e\000a\000t\000m\000a\000p)
+endobj
+285 0 obj
+<< /S /GoTo /D (figure.caption.25) >>
+endobj
+288 0 obj
+(\376\377\000I\000r\000o\000d\000a\000l\000o\000m\000j\000e\000g\000y\000z\000\351\000k)
+endobj
+289 0 obj
+<< /S /GoTo /D (appendix*.27) >>
+endobj
+292 0 obj
+(\376\377\000F\000\374\000g\000g\000e\000l\000\351\000k)
+endobj
+293 0 obj
+<< /S /GoTo /D (section.F.1) >>
+endobj
+296 0 obj
+(\376\377\000A\000\040\000T\000e\000X\000s\000t\000u\000d\000i\000o\000\040\000f\000e\000l\000\374\000l\000e\000t\000e)
+endobj
+297 0 obj
+<< /S /GoTo /D (section.F.2) >>
+endobj
+300 0 obj
+(\376\377\000V\000\341\000l\000a\000s\000z\000\040\000a\000z\000\040\000,\000,\000\311\000l\000e\000t\000,\000\040\000a\000\040\000v\000i\000l\000\341\000g\000m\000i\000n\000d\000e\000n\000s\000\351\000g\000,\000\040\000m\000e\000g\000\040\000m\000i\000n\000d\000e\000n\000'\000'\000\040\000k\000\351\000r\000d\000\351\000s\000\351\000r\000e)
+endobj
+301 0 obj
+<< /S /GoTo /D [302 0 R /Fit] >>
+endobj
+305 0 obj
<<
/Length 537
/Filter /FlateDecode
@@ -359,31 +461,31 @@ endobj
stream
xڅSMo0Wz\Z*Ј]hI/Z$əypr$g?o Bf ,C̘PPuU.Rfy?dfqz[g7$Y+ 3S2J0^ZR{ޞR0
iq[ѽ0m{x7|C>ӯ5~9t#jbJXRaJMצm]7L]4feTt?cR%+:׆Fq)%K"E-caQpԓ&3c=D\Zήm \V.tJzw6t^hvJ0c5T0%IeDT;QI%eR=ˍvLk
[1#RPLz5lcs*#/hI_ ֫M?ɍ/!3z
-Gn7KM% zx*`%OG
7ԇ^K$y\Ӗ*e7v
+Gn7KM% zx*`%OG
7ԇ^K$y\Ӗe7v8
endstream
endobj
-234 0 obj
+302 0 obj
<<
/Type /Page
-/Contents 237 0 R
-/Resources 236 0 R
+/Contents 305 0 R
+/Resources 304 0 R
/MediaBox [0 0 595.276 841.89]
-/Parent 245 0 R
+/Parent 313 0 R
>>
endobj
-235 0 obj
+303 0 obj
<<
/Type /XObject
/Subtype /Form
/FormType 1
/PTEX.FileName (./figures/bme_logo.pdf)
/PTEX.PageNumber 1
-/PTEX.InfoDict 246 0 R
+/PTEX.InfoDict 314 0 R
/BBox [0 0 703 188]
/Resources <<
/ProcSet [ /PDF ]
/ExtGState <<
-/R7 247 0 R
+/R7 315 0 R
>>>>
/Length 17727
/Filter /FlateDecode
@@ -446,7 +548,7 @@ ZPq
'w8@:"UBZ]2zl8ɐ.rlKTgi-nl&9vĂad5xU*ND[EZ<')?yņ)@{W:tr:>-?03侀+s0p6K+o|Hx*L!#́d,Z1#KI_4o&a8]"(A okIëY_@`WJGޜ?/#Q[v6ƁM GU>_ykHG4-;uuӮ,m~s
endstream
endobj
-246 0 obj
+314 0 obj
<<
/Producer (MiKTeX GPL Ghostscript 8.60)
/CreationDate (D:20111008131830Z)
@@ -455,25 +557,25 @@ endobj
/Title (G:\\1Projects - Open\\D BME 957 Arculati utmutato\\kepuletlogo\\Logo vegleges\\BME1782.eps)
>>
endobj
-247 0 obj
+315 0 obj
<<
/Type /ExtGState
/OPM 1
>>
endobj
-238 0 obj
+306 0 obj
<<
-/D [234 0 R /XYZ 99.213 762.508 null]
+/D [302 0 R /XYZ 99.213 762.508 null]
>>
endobj
-236 0 obj
+304 0 obj
<<
-/Font << /F33 239 0 R /F32 240 0 R /F35 241 0 R /F37 242 0 R /F54 243 0 R /F55 244 0 R >>
-/XObject << /Im1 235 0 R >>
+/Font << /F33 307 0 R /F32 308 0 R /F35 309 0 R /F37 310 0 R /F54 311 0 R /F55 312 0 R >>
+/XObject << /Im1 303 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-280 0 obj
+348 0 obj
<<
/Length 1059
/Filter /FlateDecode
@@ -484,17 +586,17 @@ H
G]ws-Z2W k>Y37w]%ûStyͲ]=G
endstream
endobj
-279 0 obj
+347 0 obj
<<
/Type /Page
-/Contents 280 0 R
-/Resources 278 0 R
+/Contents 348 0 R
+/Resources 346 0 R
/MediaBox [0 0 595.276 841.89]
-/Parent 245 0 R
-/Annots [ 248 0 R 249 0 R 250 0 R 251 0 R 252 0 R 253 0 R 254 0 R 255 0 R 256 0 R 257 0 R 258 0 R 259 0 R 260 0 R 261 0 R 262 0 R 263 0 R 264 0 R 265 0 R 266 0 R 267 0 R 268 0 R 269 0 R 270 0 R 271 0 R 272 0 R 273 0 R 274 0 R 275 0 R 276 0 R ]
+/Parent 313 0 R
+/Annots [ 316 0 R 317 0 R 318 0 R 319 0 R 320 0 R 321 0 R 322 0 R 323 0 R 324 0 R 325 0 R 326 0 R 327 0 R 328 0 R 329 0 R 330 0 R 331 0 R 332 0 R 333 0 R 334 0 R 335 0 R 336 0 R 337 0 R 338 0 R 339 0 R 340 0 R 341 0 R 342 0 R 343 0 R 344 0 R ]
>>
endobj
-248 0 obj
+316 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -503,7 +605,7 @@ endobj
/A << /S /GoTo /D (chapter*.2) >>
>>
endobj
-249 0 obj
+317 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -512,7 +614,7 @@ endobj
/A << /S /GoTo /D (chapter*.3) >>
>>
endobj
-250 0 obj
+318 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -521,7 +623,7 @@ endobj
/A << /S /GoTo /D (chapter.1) >>
>>
endobj
-251 0 obj
+319 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -530,7 +632,7 @@ endobj
/A << /S /GoTo /D (section.1.1) >>
>>
endobj
-252 0 obj
+320 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -539,7 +641,7 @@ endobj
/A << /S /GoTo /D (section.1.2) >>
>>
endobj
-253 0 obj
+321 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -548,7 +650,7 @@ endobj
/A << /S /GoTo /D (section.1.3) >>
>>
endobj
-254 0 obj
+322 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -557,7 +659,7 @@ endobj
/A << /S /GoTo /D (chapter.2) >>
>>
endobj
-255 0 obj
+323 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -566,7 +668,7 @@ endobj
/A << /S /GoTo /D (section.2.1) >>
>>
endobj
-256 0 obj
+324 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -575,7 +677,7 @@ endobj
/A << /S /GoTo /D (subsection.2.1.1) >>
>>
endobj
-257 0 obj
+325 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -584,7 +686,7 @@ endobj
/A << /S /GoTo /D (subsubsection.2.1.1.1) >>
>>
endobj
-258 0 obj
+326 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -593,7 +695,7 @@ endobj
/A << /S /GoTo /D (subsubsection.2.1.1.2) >>
>>
endobj
-259 0 obj
+327 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -602,7 +704,7 @@ endobj
/A << /S /GoTo /D (subsubsection.2.1.1.3) >>
>>
endobj
-260 0 obj
+328 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -611,7 +713,7 @@ endobj
/A << /S /GoTo /D (subsection.2.1.2) >>
>>
endobj
-261 0 obj
+329 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -620,7 +722,7 @@ endobj
/A << /S /GoTo /D (subsection.2.1.3) >>
>>
endobj
-262 0 obj
+330 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -629,7 +731,7 @@ endobj
/A << /S /GoTo /D (section.2.2) >>
>>
endobj
-263 0 obj
+331 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -638,7 +740,7 @@ endobj
/A << /S /GoTo /D (subsection.2.2.1) >>
>>
endobj
-264 0 obj
+332 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -647,7 +749,7 @@ endobj
/A << /S /GoTo /D (subsubsection.2.2.1.1) >>
>>
endobj
-265 0 obj
+333 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -656,7 +758,7 @@ endobj
/A << /S /GoTo /D (subsubsection.2.2.1.2) >>
>>
endobj
-266 0 obj
+334 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -665,7 +767,7 @@ endobj
/A << /S /GoTo /D (subsubsection.2.2.1.3) >>
>>
endobj
-267 0 obj
+335 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -674,7 +776,7 @@ endobj
/A << /S /GoTo /D (subsubsection.2.2.1.4) >>
>>
endobj
-268 0 obj
+336 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -683,7 +785,7 @@ endobj
/A << /S /GoTo /D (subsubsection.2.2.1.5) >>
>>
endobj
-269 0 obj
+337 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -692,7 +794,7 @@ endobj
/A << /S /GoTo /D (chapter.3) >>
>>
endobj
-270 0 obj
+338 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -701,7 +803,7 @@ endobj
/A << /S /GoTo /D (section.3.1) >>
>>
endobj
-271 0 obj
+339 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -710,7 +812,7 @@ endobj
/A << /S /GoTo /D (section.3.2) >>
>>
endobj
-272 0 obj
+340 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -719,7 +821,7 @@ endobj
/A << /S /GoTo /D (subsection.3.2.1) >>
>>
endobj
-273 0 obj
+341 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -728,7 +830,7 @@ endobj
/A << /S /GoTo /D (subsection.3.2.2) >>
>>
endobj
-274 0 obj
+342 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -737,7 +839,7 @@ endobj
/A << /S /GoTo /D (subsection.3.2.3) >>
>>
endobj
-275 0 obj
+343 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -746,7 +848,7 @@ endobj
/A << /S /GoTo /D (chapter.4) >>
>>
endobj
-276 0 obj
+344 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -755,42 +857,45 @@ endobj
/A << /S /GoTo /D (section.4.1) >>
>>
endobj
-281 0 obj
+349 0 obj
<<
-/D [279 0 R /XYZ 99.213 762.508 null]
+/D [347 0 R /XYZ 99.213 762.508 null]
>>
endobj
-278 0 obj
+346 0 obj
<<
-/Font << /F35 241 0 R /F33 239 0 R /F32 240 0 R >>
+/Font << /F35 309 0 R /F33 307 0 R /F32 308 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-312 0 obj
+392 0 obj
<<
-/Length 1032
+/Length 1279
/Filter /FlateDecode
>>
stream
-xYo@+xB*$]LJuhRbl"LwfIT(Rƀ
{Xuzy#zn
-[x.cV[_ qqpSQy@`n 2.r s hQ6}
-eyӽE:2Ay[Jl7~d=9"ht:ghN8.mȖ$JqLlN!&pۏ*.:s
ީV鞟
-)j,!RD=n%Rha2'%RhEm"_jg^S=4C^
ޞkP(Moj#k(_wU6
n
d&(`ǐW.*CZ<{UkKCu5VS;'1=4ׄ\:ՐS
a0hT惈.K׆v 1:.Y,*EΧ/_S?t }
/OZ8̏(
irg/wcDxK tW$cESujL9{*\qs-!%H?.&D#UiyficD!!$Ų[Q{@Ҿ'sc-W ڲ^bT1GEd D㱒ͅ.Gz
-l
-4ջR࠳ w-lA+&YJe|E.;0ۻѭ֪"Qwӽ uVKt>JGeL7fy-]AXݥouX
7teiu,Q{2Z#bH-3.>Jdb"F]lm_?TaMȳL@^M_M)W"3S"55շ$6iD.PnT_Gpcvp\jWZbzsyx]]im~CѯzaSMgd4>:b%g=L3dNb1<ӿ^S@=Rq=E\5*{&V= מ
+xrF~
+CRNc'd1`F\g2ztӀ%5)]FVJTeν<+<8;Cx[ {.btf}3)ϣk֧"ؖ387CY:.bD
+8N7 UL;#=)f;?~x;LHȍ qU*aldܑD2
+q4A
`1`Ud~۠3h듩:I6ʗC*]z#zL0#D߂g\+CRm:-[ަ<8 [[F+jW ӣNsA"sr5xGWÐX&ՠ\~[8#`(fǎK\BdQ_~ٌ~@(j^&=f(sdz&`xi1B1Bi1
c;%ϵ2}*\],srCԣd)$D㙬
0=bwԕkHٖոgZQ!
b0㆟`'V>V\H+3^*8<җʓB`{[I+_v`oVDz5[3UŦӳ K7r".cQDz6iyO UFv)hqQuxHi,8TWo.w)եg|HH;C?lFrPaϠXgfr#=KXd¨V<[V"Dw
+!l(sjh(.99"_
+id|T{cƔCk{u|z#
+TKn|Tf1#z&^q%ӯQMAa%z[ŏ22$y6ZqGf
x^4_Nz$+eHzVD6"ջ+K@Bof%/avQ?wN>[̴A֥2m,4 P".I_b +*k^FI3,,#7M{%9@
+OJR#px0E< N샬QƁ+ϗUE,ob~YB!rf
+"^nQFY0dwO'@
endstream
endobj
-311 0 obj
+391 0 obj
<<
/Type /Page
-/Contents 312 0 R
-/Resources 310 0 R
+/Contents 392 0 R
+/Resources 390 0 R
/MediaBox [0 0 595.276 841.89]
-/Parent 245 0 R
-/Annots [ 277 0 R 282 0 R 283 0 R 284 0 R 285 0 R 286 0 R 287 0 R 288 0 R 289 0 R 290 0 R 291 0 R 292 0 R 293 0 R 294 0 R 295 0 R 296 0 R 297 0 R 298 0 R 299 0 R 300 0 R 301 0 R 302 0 R 303 0 R 304 0 R 305 0 R 306 0 R 307 0 R 308 0 R 309 0 R ]
+/Parent 313 0 R
+/Annots [ 345 0 R 350 0 R 351 0 R 352 0 R 353 0 R 354 0 R 355 0 R 356 0 R 357 0 R 358 0 R 359 0 R 360 0 R 361 0 R 362 0 R 363 0 R 364 0 R 365 0 R 366 0 R 367 0 R 368 0 R 369 0 R 370 0 R 371 0 R 372 0 R 373 0 R 374 0 R 375 0 R 376 0 R 377 0 R 378 0 R 379 0 R 380 0 R 381 0 R 382 0 R 383 0 R 384 0 R 385 0 R 386 0 R 387 0 R 388 0 R ]
>>
endobj
-277 0 obj
+345 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -799,7 +904,7 @@ endobj
/A << /S /GoTo /D (subsection.4.1.1) >>
>>
endobj
-282 0 obj
+350 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -808,7 +913,7 @@ endobj
/A << /S /GoTo /D (subsection.4.1.2) >>
>>
endobj
-283 0 obj
+351 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -817,7 +922,7 @@ endobj
/A << /S /GoTo /D (subsection.4.1.3) >>
>>
endobj
-284 0 obj
+352 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -826,7 +931,7 @@ endobj
/A << /S /GoTo /D (subsection.4.1.4) >>
>>
endobj
-285 0 obj
+353 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -835,7 +940,7 @@ endobj
/A << /S /GoTo /D (section.4.2) >>
>>
endobj
-286 0 obj
+354 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -844,7 +949,7 @@ endobj
/A << /S /GoTo /D (subsection.4.2.1) >>
>>
endobj
-287 0 obj
+355 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -853,7 +958,7 @@ endobj
/A << /S /GoTo /D (subsection.4.2.2) >>
>>
endobj
-288 0 obj
+356 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -862,7 +967,7 @@ endobj
/A << /S /GoTo /D (subsection.4.2.3) >>
>>
endobj
-289 0 obj
+357 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -871,7 +976,7 @@ endobj
/A << /S /GoTo /D (subsection.4.2.4) >>
>>
endobj
-290 0 obj
+358 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -880,7 +985,7 @@ endobj
/A << /S /GoTo /D (subsection.4.2.5) >>
>>
endobj
-291 0 obj
+359 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -889,7 +994,7 @@ endobj
/A << /S /GoTo /D (subsection.4.2.6) >>
>>
endobj
-292 0 obj
+360 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -898,7 +1003,7 @@ endobj
/A << /S /GoTo /D (section.4.3) >>
>>
endobj
-293 0 obj
+361 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -907,7 +1012,7 @@ endobj
/A << /S /GoTo /D (subsection.4.3.1) >>
>>
endobj
-294 0 obj
+362 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -916,7 +1021,7 @@ endobj
/A << /S /GoTo /D (subsection.4.3.2) >>
>>
endobj
-295 0 obj
+363 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -925,7 +1030,7 @@ endobj
/A << /S /GoTo /D (subsection.4.3.3) >>
>>
endobj
-296 0 obj
+364 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -934,7 +1039,7 @@ endobj
/A << /S /GoTo /D (subsection.4.3.4) >>
>>
endobj
-297 0 obj
+365 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -943,7 +1048,7 @@ endobj
/A << /S /GoTo /D (chapter.5) >>
>>
endobj
-298 0 obj
+366 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -952,7 +1057,7 @@ endobj
/A << /S /GoTo /D (section.5.1) >>
>>
endobj
-299 0 obj
+367 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -961,7 +1066,7 @@ endobj
/A << /S /GoTo /D (section.5.2) >>
>>
endobj
-300 0 obj
+368 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -970,7 +1075,7 @@ endobj
/A << /S /GoTo /D (subsection.5.2.1) >>
>>
endobj
-301 0 obj
+369 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -979,7 +1084,7 @@ endobj
/A << /S /GoTo /D (subsection.5.2.2) >>
>>
endobj
-302 0 obj
+370 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -988,7 +1093,7 @@ endobj
/A << /S /GoTo /D (section.5.3) >>
>>
endobj
-303 0 obj
+371 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -997,7 +1102,7 @@ endobj
/A << /S /GoTo /D (subsection.5.3.1) >>
>>
endobj
-304 0 obj
+372 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -1006,84 +1111,263 @@ endobj
/A << /S /GoTo /D (section.5.4) >>
>>
endobj
-305 0 obj
+373 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [139.671 345.201 235.724 354.708]
+/Rect [139.671 343.08 215.693 354.708]
/A << /S /GoTo /D (subsection.5.4.1) >>
>>
endobj
-306 0 obj
+374 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [98.216 315.735 190.458 327.475]
-/A << /S /GoTo /D (lstnumber.5.3.13) >>
+/Rect [139.671 328.766 235.724 338.273]
+/A << /S /GoTo /D (subsection.5.4.2) >>
>>
endobj
-307 0 obj
+375 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [98.216 288.391 148.963 300.131]
-/A << /S /GoTo /D (appendix*.12) >>
+/Rect [98.216 301.422 181.536 311.04]
+/A << /S /GoTo /D (chapter.6) >>
>>
endobj
-308 0 obj
+376 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [114.58 274.077 240.512 283.585]
-/A << /S /GoTo /D (section.F.1) >>
+/Rect [114.58 284.986 202.633 294.494]
+/A << /S /GoTo /D (section.6.1) >>
>>
endobj
-309 0 obj
+377 0 obj
<<
/Type /Annot
/Subtype /Link
/Border[0 0 0]/H/I/C[1 0 0]
-/Rect [114.58 255.521 420.234 269.676]
-/A << /S /GoTo /D (section.F.2) >>
+/Rect [114.58 268.551 292.996 278.059]
+/A << /S /GoTo /D (section.6.2) >>
>>
endobj
-310 0 obj
+378 0 obj
<<
-/Font << /F32 240 0 R /F33 239 0 R >>
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [114.58 249.995 208.088 261.624]
+/A << /S /GoTo /D (section.6.3) >>
+>>
+endobj
+379 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [139.671 233.56 222.936 245.188]
+/A << /S /GoTo /D (subsection.6.3.1) >>
+>>
+endobj
+380 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [139.671 217.125 203.39 228.753]
+/A << /S /GoTo /D (subsection.6.3.2) >>
+>>
+endobj
+381 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [139.671 200.69 198.603 212.318]
+/A << /S /GoTo /D (subsection.6.3.3) >>
+>>
+endobj
+382 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [139.671 184.254 406.967 195.883]
+/A << /S /GoTo /D (subsection.6.3.4) >>
+>>
+endobj
+383 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [139.671 169.94 228.027 179.448]
+/A << /S /GoTo /D (subsection.6.3.5) >>
+>>
+endobj
+384 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [174.58 151.384 318.755 163.013]
+/A << /S /GoTo /D (subsubsection.6.3.5.1) >>
+>>
+endobj
+385 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [174.58 134.949 369.24 146.578]
+/A << /S /GoTo /D (subsubsection.6.3.5.2) >>
+>>
+endobj
+386 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [174.58 118.514 327.421 130.143]
+/A << /S /GoTo /D (subsubsection.6.3.5.3) >>
+>>
+endobj
+387 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [174.58 104.2 305.269 113.707]
+/A << /S /GoTo /D (subsubsection.6.3.5.4) >>
+>>
+endobj
+388 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [174.58 85.644 323.816 98.812]
+/A << /S /GoTo /D (subsubsection.6.3.5.5) >>
+>>
+endobj
+390 0 obj
+<<
+/Font << /F32 308 0 R /F33 307 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-315 0 obj
+400 0 obj
+<<
+/Length 362
+/Filter /FlateDecode
+>>
+stream
+xO +8B"P?1q˚v3\z-;RAnGbW"QN8
+n%VHgj↳(6^uʀߩsIΝ*eJLyUI:3G=khRߤG$+Ďr"%iU0N밁<~Ie(|u$
FCl{Sr8A¡E$V,V?5\tKvw_=u.w@6|Ul:VCQwNeFu9i^Og)Ϙ2o۸AО>jIG_7)
+endstream
+endobj
+399 0 obj
+<<
+/Type /Page
+/Contents 400 0 R
+/Resources 398 0 R
+/MediaBox [0 0 595.276 841.89]
+/Parent 313 0 R
+/Annots [ 389 0 R 393 0 R 394 0 R 395 0 R 396 0 R 397 0 R ]
+>>
+endobj
+389 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [139.671 750.553 212.543 760.061]
+/A << /S /GoTo /D (subsection.6.3.6) >>
+>>
+endobj
+393 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [139.671 731.997 219.905 743.626]
+/A << /S /GoTo /D (subsection.6.3.7) >>
+>>
+endobj
+394 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [98.216 704.653 190.458 716.392]
+/A << /S /GoTo /D (figure.caption.25) >>
+>>
+endobj
+395 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [98.216 677.308 148.963 689.048]
+/A << /S /GoTo /D (appendix*.27) >>
+>>
+endobj
+396 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [114.58 662.994 240.512 672.502]
+/A << /S /GoTo /D (section.F.1) >>
+>>
+endobj
+397 0 obj
+<<
+/Type /Annot
+/Subtype /Link
+/Border[0 0 0]/H/I/C[1 0 0]
+/Rect [114.58 644.438 420.234 658.594]
+/A << /S /GoTo /D (section.F.2) >>
+>>
+endobj
+398 0 obj
+<<
+/Font << /F32 308 0 R /F33 307 0 R >>
+/ProcSet [ /PDF /Text ]
+>>
+endobj
+403 0 obj
<<
/Length 1203
/Filter /FlateDecode
>>
stream
xڍVn6}߯УxQFԵӢ"@mZYJ\w.m6@rrf8h8ۼQeʲ$=DȤ*QJuUE-U/^~$J"*`?^ڣݫ,FX'KISQ9HoLǡ-(Wp>wn!ET,'8;W,8D[jk#6ڭTSf`l_ـǶ۫"~5{hEI9h09Ϻ#Fj8M?v=ݒ_C4M#Vy0|O"ݝ 0ɳ=@уGۡTh_M4ae!gL-'W)=^a40NУhDڬ
cm@Έ׀2gRf=@j/k*2a7 ]yf)$ltMHl(ڠ(e@rvH(ere!WNG;v2CW
(gY~ҵvu,`i'Y={?C3Zt`f*kf}ƨ"A[)hϘqK<*)*x;1h0m$>%b耞Xv88%'rѹitQDL&Z)2d)0̼+gص'.mFtGOVD3,G<xr4 уz|N+y͝7'/E
-XkO2J$l]mq%R
6o$@*
-xe"Sipo>!*hk"qQl~gKeeUyge|gBȼ:^Ts;Φ
+XkO2J$l]mq%R
6o$@*
+xe"Sipo>!*hk"qQl~gKeeUyge|gBȼ:^Ts;Ў
endstream
endobj
-314 0 obj
+402 0 obj
<<
/Type /Page
-/Contents 315 0 R
-/Resources 313 0 R
+/Contents 403 0 R
+/Resources 401 0 R
/MediaBox [0 0 595.276 841.89]
-/Parent 245 0 R
+/Parent 313 0 R
>>
endobj
-313 0 obj
+401 0 obj
<<
-/Font << /F35 241 0 R /F32 240 0 R /F54 243 0 R >>
+/Font << /F35 309 0 R /F32 308 0 R /F54 311 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-318 0 obj
+406 0 obj
<<
/Length 1488
/Filter /FlateDecode
@@ -1095,27 +1379,27 @@ xڍWK
FێG<#kO/5'rf>_Ic{ˬA>0ᛆ/yjZ:褗
s۱Ržz K^r2B,e!ex0Ww;V# uirUDp5g(hR~!'(s-`!\˫h}$@# EjzʔN\C][pr5Fsxx~0{-v t!Cb$BZ{Vb> ?o(#?V/(=#C\X=tmsd7WC9Getޱ$
6͆`,)d@db tlحK݃C>>w 2."@=/w\I'n-~L~ڤT>,~<|6>s7Lb-8 린2Pdh3|ʮ,Ke7_Jb?)̼bc+ɀ}WwSQZSple{B3{0fw/G.p-W
QWr%CORoBallSQ9?|ǔI6egjw̍O\
endstream
endobj
-317 0 obj
+405 0 obj
<<
/Type /Page
-/Contents 318 0 R
-/Resources 316 0 R
+/Contents 406 0 R
+/Resources 404 0 R
/MediaBox [0 0 595.276 841.89]
-/Parent 245 0 R
+/Parent 313 0 R
>>
endobj
2 0 obj
<<
-/D [317 0 R /XYZ 99.213 762.508 null]
+/D [405 0 R /XYZ 99.213 762.508 null]
>>
endobj
-316 0 obj
+404 0 obj
<<
-/Font << /F35 241 0 R /F32 240 0 R >>
+/Font << /F35 309 0 R /F32 308 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-321 0 obj
+409 0 obj
<<
/Length 1378
/Filter /FlateDecode
@@ -1132,27 +1416,27 @@ s
~CemTPyiɑJ
endstream
endobj
-320 0 obj
+408 0 obj
<<
/Type /Page
-/Contents 321 0 R
-/Resources 319 0 R
+/Contents 409 0 R
+/Resources 407 0 R
/MediaBox [0 0 595.276 841.89]
-/Parent 245 0 R
+/Parent 410 0 R
>>
endobj
6 0 obj
<<
-/D [320 0 R /XYZ 99.213 762.508 null]
+/D [408 0 R /XYZ 99.213 762.508 null]
>>
endobj
-319 0 obj
+407 0 obj
<<
-/Font << /F35 241 0 R /F32 240 0 R >>
+/Font << /F35 309 0 R /F32 308 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-325 0 obj
+414 0 obj
<<
/Length 1634
/Filter /FlateDecode
@@ -1167,37 +1451,37 @@ xڍXKs
5)~hD)rp̍ЂƥS)rn oЦ,F8weg.9Y`mY,+ ;p$rDwCṵ)(TYlxQ5#~&qUܝ:p;slłϚϿ>BP j)s#Zau8/}v\ç dq
endstream
endobj
-324 0 obj
+413 0 obj
<<
/Type /Page
-/Contents 325 0 R
-/Resources 323 0 R
+/Contents 414 0 R
+/Resources 412 0 R
/MediaBox [0 0 595.276 841.89]
-/Parent 326 0 R
+/Parent 410 0 R
>>
endobj
10 0 obj
<<
-/D [324 0 R /XYZ 99.213 762.508 null]
+/D [413 0 R /XYZ 99.213 762.508 null]
>>
endobj
14 0 obj
<<
-/D [324 0 R /XYZ 99.213 409.018 null]
+/D [413 0 R /XYZ 99.213 409.018 null]
>>
endobj
18 0 obj
<<
-/D [324 0 R /XYZ 99.213 277.848 null]
+/D [413 0 R /XYZ 99.213 277.848 null]
>>
endobj
-323 0 obj
+412 0 obj
<<
-/Font << /F35 241 0 R /F32 240 0 R >>
+/Font << /F35 309 0 R /F32 308 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-329 0 obj
+417 0 obj
<<
/Length 820
/Filter /FlateDecode
@@ -1208,17 +1492,17 @@ x
o1Evħd]n#_>gPYt}zs:7_~ynrDlYףĘ$l1_^ su&U~s sO8EVU'KT|sOg
endstream
endobj
-328 0 obj
+416 0 obj
<<
/Type /Page
-/Contents 329 0 R
-/Resources 327 0 R
+/Contents 417 0 R
+/Resources 415 0 R
/MediaBox [0 0 595.276 841.89]
-/Parent 326 0 R
-/Annots [ 322 0 R ]
+/Parent 410 0 R
+/Annots [ 411 0 R ]
>>
endobj
-322 0 obj
+411 0 obj
<<
/Type /Annot
/Subtype /Link
@@ -1229,42 +1513,42 @@ endobj
endobj
22 0 obj
<<
-/D [328 0 R /XYZ 99.213 762.508 null]
+/D [416 0 R /XYZ 99.213 762.508 null]
>>
endobj
-327 0 obj
+415 0 obj
<<
-/Font << /F35 241 0 R /F32 240 0 R >>
+/Font << /F35 309 0 R /F32 308 0 R >>
/ProcSet [ /PDF /Text ]
>>
endobj
-334 0 obj
+422 0 obj
<<
/Length 1768
/Filter /FlateDecode
>>
stream
xڥXKs6WHAٛ&iIgzs% ) c)EnE$v>}PqPq*ϗW/^,H(ϓ,U%By!)cDkYdN?Iէ۟y[e!p[\gy$Jp/Ͱ#/!Bݮ?- DUq8-)akRG^S[=8=]4C?NQ ;+AwqÝDΰY5{tE2WPqG h|,B53}V1yƩc{\r#'Hkx"6ʶj"`Vwx#كx="g+v^GSd6nD'I)!"Vmٗ)`[