From 76cd65ab544075908193b6ab7e168ae1e9ea93c6 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 19 May 2025 14:34:04 -0700 Subject: [PATCH 1/3] Create jasper_tutorial.md --- content/tutorials/jasper_tutorial.md | 107 +++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 content/tutorials/jasper_tutorial.md diff --git a/content/tutorials/jasper_tutorial.md b/content/tutorials/jasper_tutorial.md new file mode 100644 index 00000000..298d19c3 --- /dev/null +++ b/content/tutorials/jasper_tutorial.md @@ -0,0 +1,107 @@ +--- +title: My Super Awesome Tutorial +date: 1970-01-01 +authors: + - name: John Doe + - name: Mary Jane +--- + +![relevant graphic or workshop logo](image/path) + +## Introduction + +Write a short section on what the tutorial is aiming to accomplish. +What is the motivation behind the tutorial? +What do you want readers to gain from the tutorial? + +### Learning Objectives + +- Bullet list of skills/concepts to be covered + +Any additional notes from the developers can be included here. + +### Background Information + +Describe your topic here. What does it do? Why do you use it? +Are there other similar things to use? What are the pros and cons? +Explain important concepts that are necessary to understand. +Include (and cite if needed) any visuals that will help the audience understand. + +## Getting Started + +For any software prerequisites, write a simple excerpt on each +technology the participant will be expecting to download and install. +Aim to demystify the technologies being used and explain any design +decisions that were taken. Walk through the installation processes +in detail. Be aware of any operating system differences. +For hardware prerequisites, list all the necessary components that +the participant will receive. A table showing component names and +quantities should suffice. Link any reference sheets or guides that +the participant may need. +The following are stylistic examples of possible prerequisites, +customize these for each workshop. + +### Required Downloads and Installations + +List any required downloads and installations here. +Make sure to include tutorials on how to install them. +You can either make your own tutorials or include a link to them. + +### Required Components + +List your required hardware components and the quantities here. + +| Component Name | Quanitity | +| -------------- | --------- | +| | | +| | | + +### Required Tools and Equipment + +List any tools and equipment you need here. +(Ex, computer, soldering station, etc.) + +## Part 01: Name + +### Introduction + +Briefly introduce what you are teaching in this section. + +### Objective + +- List the learning objectives of this section + +### Background Information + +Give a brief explanation of the technical skills learned/needed +in this challenge. There is no need to go into detail as a +separation document should be prepared to explain more in depth +about the technical skills + +### Components + +- List the components needed in this challenge + +### Instructional + +Teach the contents of this section + +## Example + +### Introduction + +Introduce the example that you are showing here. + +### Example + +Present the example here. Include visuals to help better understanding + +### Analysis + +Explain how the example used your tutorial topic. Give in-depth analysis of each part and show your understanding of the tutorial topic + +## Additional Resources + +### Useful links + +List any sources you used, documentation, helpful examples, similar projects etc. From 2d15c6be2120e972b2f786212049c15b85fda466 Mon Sep 17 00:00:00 2001 From: jasper-hyj Date: Tue, 20 May 2025 13:17:26 -0700 Subject: [PATCH 2/3] Update tutorial --- content/tutorials/jasper_tutorial.md | 56 ++++------------------------ 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/content/tutorials/jasper_tutorial.md b/content/tutorials/jasper_tutorial.md index 298d19c3..c56f94b3 100644 --- a/content/tutorials/jasper_tutorial.md +++ b/content/tutorials/jasper_tutorial.md @@ -1,90 +1,48 @@ --- -title: My Super Awesome Tutorial -date: 1970-01-01 +title: WiFi Server +date: 2025-05-19 authors: - - name: John Doe - - name: Mary Jane + - name: Jasper Huang --- -![relevant graphic or workshop logo](image/path) +![relevant graphic or workshop logo](https://www.electronicwings.com/storage/PlatformSection/TopicContent/461/icon/How%20to%20create%20ESP32%20WiFi%20Server.jpg) ## Introduction - -Write a short section on what the tutorial is aiming to accomplish. -What is the motivation behind the tutorial? -What do you want readers to gain from the tutorial? +This is a tutorial of WiFi Server. ### Learning Objectives +- Learn how to create a WiFi Server on ESP32 +- Learn how to create websocket for immediate signal transfer -- Bullet list of skills/concepts to be covered - -Any additional notes from the developers can be included here. ### Background Information -Describe your topic here. What does it do? Why do you use it? -Are there other similar things to use? What are the pros and cons? -Explain important concepts that are necessary to understand. -Include (and cite if needed) any visuals that will help the audience understand. ## Getting Started -For any software prerequisites, write a simple excerpt on each -technology the participant will be expecting to download and install. -Aim to demystify the technologies being used and explain any design -decisions that were taken. Walk through the installation processes -in detail. Be aware of any operating system differences. -For hardware prerequisites, list all the necessary components that -the participant will receive. A table showing component names and -quantities should suffice. Link any reference sheets or guides that -the participant may need. -The following are stylistic examples of possible prerequisites, -customize these for each workshop. ### Required Downloads and Installations -List any required downloads and installations here. -Make sure to include tutorials on how to install them. -You can either make your own tutorials or include a link to them. - ### Required Components -List your required hardware components and the quantities here. - -| Component Name | Quanitity | -| -------------- | --------- | -| | | -| | | ### Required Tools and Equipment -List any tools and equipment you need here. -(Ex, computer, soldering station, etc.) ## Part 01: Name ### Introduction -Briefly introduce what you are teaching in this section. - ### Objective -- List the learning objectives of this section ### Background Information -Give a brief explanation of the technical skills learned/needed -in this challenge. There is no need to go into detail as a -separation document should be prepared to explain more in depth -about the technical skills ### Components -- List the components needed in this challenge - ### Instructional -Teach the contents of this section ## Example From 8767ade750c7e6e73f1fca47210e9d8f3a8d406f Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Fri, 6 Jun 2025 11:05:00 -0700 Subject: [PATCH 3/3] Update tutorial --- content/tutorials/jasper_tutorial.md | 375 +++++++++++++++--- .../jasper_tutorial_photos/PIO Home.png | Bin 0 -> 16507 bytes .../jasper_tutorial_photos/image.png | Bin 0 -> 18365 bytes 3 files changed, 316 insertions(+), 59 deletions(-) create mode 100644 content/tutorials/jasper_tutorial_photos/PIO Home.png create mode 100644 content/tutorials/jasper_tutorial_photos/image.png diff --git a/content/tutorials/jasper_tutorial.md b/content/tutorials/jasper_tutorial.md index 298d19c3..80449b02 100644 --- a/content/tutorials/jasper_tutorial.md +++ b/content/tutorials/jasper_tutorial.md @@ -1,107 +1,364 @@ --- -title: My Super Awesome Tutorial -date: 1970-01-01 +title: ESP32 WiFi Server & Web Socket Tutorial +date: 2025-06-06 authors: - - name: John Doe - - name: Mary Jane + - name: Jasper Huang --- -![relevant graphic or workshop logo](image/path) ## Introduction -Write a short section on what the tutorial is aiming to accomplish. -What is the motivation behind the tutorial? -What do you want readers to gain from the tutorial? +This tutorial is designed for anyone that is interested in learning more in using and hosting a WiFi server on the ESP32-S3 devboard and send and communicating realtime using websocket ### Learning Objectives -- Bullet list of skills/concepts to be covered - -Any additional notes from the developers can be included here. +- Using PlatformIO (instead of Arduino) for faster development +- Host a WiFi server (access point) on ESP32 +- Using Websocket to send realtime command ### Background Information -Describe your topic here. What does it do? Why do you use it? -Are there other similar things to use? What are the pros and cons? -Explain important concepts that are necessary to understand. -Include (and cite if needed) any visuals that will help the audience understand. +This tutorial is a summary and conclude of our group project of controlling a window cleaning bot through WiFi using phone. ## Getting Started - -For any software prerequisites, write a simple excerpt on each -technology the participant will be expecting to download and install. -Aim to demystify the technologies being used and explain any design -decisions that were taken. Walk through the installation processes -in detail. Be aware of any operating system differences. -For hardware prerequisites, list all the necessary components that -the participant will receive. A table showing component names and -quantities should suffice. Link any reference sheets or guides that -the participant may need. -The following are stylistic examples of possible prerequisites, -customize these for each workshop. - ### Required Downloads and Installations -List any required downloads and installations here. -Make sure to include tutorials on how to install them. -You can either make your own tutorials or include a link to them. +VSCode installed + - Including PlatformIO IDE extension + - Link: https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide + ### Required Components -List your required hardware components and the quantities here. +| Component Name | Quanitity | +| ----------------- | --------- | +| ESP32-S3 Devboard | 1 | -| Component Name | Quanitity | -| -------------- | --------- | -| | | -| | | ### Required Tools and Equipment +- Laptop/PC -List any tools and equipment you need here. -(Ex, computer, soldering station, etc.) - -## Part 01: Name +## Part 01: Setting Up WiFi Server ### Introduction - -Briefly introduce what you are teaching in this section. +In this part, you'll learn how to setup a WiFi server using only the ESP32 Devboard ### Objective -- List the learning objectives of this section +- Setup development environment using platformIO +- Setup a WiFi server and display a small webpage on your device ### Background Information -Give a brief explanation of the technical skills learned/needed -in this challenge. There is no need to go into detail as a -separation document should be prepared to explain more in depth -about the technical skills +Technical skill learn +- How to setup PlatformIO project +- How to setup and run a WiFi server on the ESP32 ### Components -- List the components needed in this challenge +- ESP32-S3 Devboard ### Instructional -Teach the contents of this section - -## Example +1. Open Visual Studio Code (without opening any folder) +2. Go to PlatformIO tab + + +![alt text](./jasper_tutorial_photos/image.png) + +3. Click on Create New Project + + +![alt text](./jasper_tutorial_photos/PIO%20Home.png) + +4. Click on New Project +5. Enter following information + - Name: `ESP32 Web controller` + - Board: `Espressif ESP32-S3-DevKitC-1-N8` + - Framework: `Arduino` + - Location: Pick your own preferred location + +6. Open `platformio.ini` file +Type in +```ini +[env:esp32-s3-devkitc-1] +platform = espressif32 +board = esp32-s3-devkitc-1 +framework = arduino +upload_speed = 921600 +monitor_speed = 115200 +upload_protocol = esptool +lib_deps = + Links2004/WebSockets@^2.3.6 + waspinator/AccelStepper@^1.64 + bblanchon/ArduinoJson@^7.4.1 + +build_unflags = + -std=gnu++11 + +build_flags= + -std=gnu++17 + -D ARDUINO_USB_CDC_ON_BOOT=1 + -D ARDUINO_USB_MODE=1 + -DFORMAT_SPIFFS_IF_FAILED=true + +board_build.filesystem = spiffs +extra_scripts = upload_fs.py +``` + +7. Create a new file `upload_fs.py` + +> This file is use for file uploading +```py +# upload_fs.py +Import("env") + +def before_upload_fs(source, target, env): + env.Execute("pio run --target uploadfs") + +env.AddPreAction("upload", before_upload_fs) +env.AddPreAction("program", before_upload_fs) # optional: handles manual programming +``` + +8. Create a `data` directory +9. Create a file `index.html` in the `data` directory +```html + + + + + + ESP32 Controller + + +

ESP32 Controller

+ + +``` + +10. In `src/main.cpp`, add following code +```cpp +#include +#include +#include + +#include +#include + +inline constexpr const char* WIFI_SSID = "ESP32-Access-Point"; +inline constexpr const char* WIFI_PASSWORD = "123456789"; +WiFiServer server{80}; + +void setup() { + Serial.begin(115200); + + WiFi.softAP(WIFI_SSID, WIFI_PASSWORD); + Serial.print("Access Point IP: "); + Serial.println(WiFi.softAPIP()); + + if (!SPIFFS.begin(true)) { + Serial.println("An Error has occurred while mounting SPIFFS"); + return; + } + + server.begin(); +} + +void loop() { + WiFiClient client = server.available(); + if (client) { + Serial.println("New Client."); + handleClientRequest(client); + client.stop(); + Serial.println("Client disconnected."); + } +} + +void handleClientRequest(WiFiClient& client) { + String request = client.readStringUntil('\r'); + client.read(); + + if (request.indexOf("GET / ") >= 0) { + File file = SPIFFS.open("/index.html", "r"); + if (!file) { + Serial.println("Failed to open /index.html"); + client.println("HTTP/1.1 500 Internal Server Error"); + client.println("Content-type:text/plain"); + client.println("Connection: close"); + client.println(); + client.println("Failed to load index.html"); + return; + } + + client.println("HTTP/1.1 200 OK"); + client.println("Content-type:text/html"); + client.println("Connection: close"); + client.println(); + + client.write(file); + + while (file.available()) { + client.write(file.read()); + } + + file.close(); + client.println(); + } +} +``` +This create a WiFiServer that returns the index.html file whenever user request `192.168.4.1`, which is the default address for esp32 WiFi server. + +11. Go to PlatformIO extension tab +12. Connect ESP32 devboard to your laptop, and change it to boot mode +13. Click on `esp32-s3-devkitc-1 > General > Upload and Monitor` +14. After uploading, go to your phone and look for the WiFi name `ESP32-Access-Point` +15. Enter the password `123456789` +16. Open any browser and put in `192.168.4.1` +17. You will be able to see the webpage + +## Part 02: Setting Up Web Socket server ### Introduction +In this part, you'll learn how to setup a web socket server using only the ESP32 Devboard -Introduce the example that you are showing here. +### Objective -### Example +- Setup a Websocket server and display a small webpage that you can click on button and display it on the serial monitor -Present the example here. Include visuals to help better understanding +### Background Information -### Analysis +Technical skill learn +- How to run and communicate through websocket -Explain how the example used your tutorial topic. Give in-depth analysis of each part and show your understanding of the tutorial topic +### Components -## Additional Resources +- ESP32-S3 Devboard -### Useful links +### Instructional +1. Add following to `src/main.py` +```cpp +#include + +WebSocketsServer webSocket{81}; +void setup() { + // ...previous code + webSocket.begin(); + webSocket.onEvent(onWebSocketEvent); +} + +void onWebSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { + if (type == WStype_TEXT) { + String json = (char*)payload; + + JsonDocument doc; + deserializeJson(doc, json); + Serial.printf("Recieve Input: %s\n", doc["info"]); + } +} +``` + +2. Change `data/index.html` to following: +```html + + + + + + ESP32 Controller + + +

ESP32 Controller

+ + + + + +``` +3. Go to PlatformIO extension tab +4. Connect ESP32 devboard to your laptop, and change it to boot mode +5. Click on `esp32-s3-devkitc-1 > General > Upload and Monitor` +6. After uploading, go to your phone and look for the WiFi name `ESP32-Access-Point` +7. Enter the password `123456789` +8. Open any browser and put in `192.168.4.1` +9. You will be able to see the webpage +10. After pressing the button, you will be able to see `Recieve Input: Hello!` -List any sources you used, documentation, helpful examples, similar projects etc. +## Additional Resources +- [ArduinoWebSockets - Github](https://github.com/Links2004/arduinoWebSockets) +- [WiFi - Github](https://github.com/arduino-libraries/WiFi) \ No newline at end of file diff --git a/content/tutorials/jasper_tutorial_photos/PIO Home.png b/content/tutorials/jasper_tutorial_photos/PIO Home.png new file mode 100644 index 0000000000000000000000000000000000000000..f5cbd3c3bb0a989ef38123226f200a7ada55ce03 GIT binary patch literal 16507 zcmeIabyQnl-!BLiC|-&cFJ6ijcW7~!;_gxVr?32Dji+T!W{S;1YsP z`g`tk=Ur>=ns?SaGk4~X`^Q-!$vOMv?6c2ze{2(}p(c-qO@WPuhK8r8AoBqY4IPZy zbf00MJ~^)El|sFs13t)0p;eDl?V;X0v3sxj9t{l?k8^AB6!jj^k6mE_?uV9!vo~eQfVPC`lCm~zv;h3DSf_t%;4aaN7SNi7Vmz$ zJ~!t#r#3g|tbT*MbSRrXa4IqKFJE2R(rvsv*azOav~Yq&;Y%NgGq7Ar6X+B1LtjUT z0EoS`bB}0wyWFs%uwKuL9W^a`DX$$NM)~La`P5D4FFLA`1AUQ1ol-I~kJh&RqhnOj zM%5`G$=<4#uJz$Zou}y_u=)`nw=sd7t!tlDY zC06p}$n^kDGrt%##!_i=NA?5V7IxMNVBWa&hYJz|>FIlXd+^QH1NF}&2X@a|zt@6~ zL@Ge(TvQL^*VL<$2vPWN{E=}xorTDVXU4DK9dY+zs~XRE1R^3LzQ^{c$;hAyZC!u) zEHr~iIclk9#1o7in_)Bl-;K(lP{h*&beA|UGs}2@eeGl5|E35 zTo@?=x%7g?LIg)nV*exzm!niPhQ_D zJ>5%Ez5Udyq86Z|tG(rdxwNXSr%eIos)#YNvpl$Vc#>?l+TG>U5OJloF!Wr>8W}7x zc51Lnd&ELf!3rSOg1;_qu1u9?37{?*NCusfiE*QS_RilHK5Q3_Zv!9gv?Ps_7-QA7 z@GpV`!|`bznfJ~3uJBI1RgvLL?@$J~#1drVL`?3p zD0Z=X*8y;6DK&2YVs~9x_rjp%y2M)6KiK2mf;|5I`blkOj`L_gzJ{618o~TUz=C)1 zz`*iB2W0!?cMaF%A+N2Rz)0F!cbjXRoeE5Iww^`keDBD27rJIEiMln1gdZS}Aa8sv zki6fJVN5{?JF!4;79rZ9lJ3I@?|F-Xc+5t&of)jUjA4CHH@l_td&az&?0`>zq@;Wf zrg1Ni{(aZ#Xbxet*SDIgJNCnY&eQ#HvjacpbH`;7gCU=Fv!PB4o-N2VMz%+N@C~!B zq?wHKypZ{*N?jVXm)ar7YI(wAbCBiMwjV(39k+krl`S5W2=2{I4?`K^1hSSaLi#% zGqAS7(f*;y8Q1$R2XpYHDlm_V$Qjb=hnu z&&GFqX9ol~)7AP3kj$!iy$P@GOYm@0L8a(H1 zS;WX<;(_%2?A zHrpD(ndB|R7k}uIImQ210Bk32_Ou(bW7j#@W`giY5)uHQ8E76c{jq~HUk~>d8;UBK z)BI4ML&S2ab#o{ZRCmhaLjX7JYb>f_EUE9g^%R#hHQB{67VLkxXb{vk$DZ9{Rg3Gmu}09t7+xV1v&!EXsS{()aPi(y)| zu@`q|U-x^$#kuCZ5b^f*IVe8R?k8tW`#P^0Tq{RsZW!p+HW{W%%4Ue+-?M4x;}qYec+5atcr&$tg4sRFZv{HsHsk!wu(J|zgxZi1SeZm>CT@w^-3VOoZ>Gd!_M_`6N4R?cWK z%^m=OWZxgj8xv7s=G63P+6}#XB2$^L2vi{sEBFzZ^%-2iSjWRVC78FvegnL$ z47%p2uTa_xueWRMnI{b-oHiRjw7O&K0BA74wm)?qtghBgPCS)Lo1$>?qzA$H7%nD~95C7HNV^3bqPA&T$3)8y)v ziXrbHzH?(&m}Lx=Y=4pdFm@ttIPR#-kJnK`&CL*=LZ+FQ#p)aOa1}C5`Fc*9=Bnvl z_l;Gv)!cUV^O`^y%k6fVX=+nB7+-v#cy%iy@>=hb@0y|j=KgTdeju6?z0g=CN*S<^ z>JYa59+IZd{x{2FX9b-=YFirK>ix~fk}L~mr*Gmr3>F(q8f(u?XXtp=zd&Ls_3Tko z5iVvEjX7L(KKZS{%P-E1D@l<2eWHk1Rcqj%2IJ1xIX4}_WP$^RZ3II5g}g?M;UeVcaA1_@j?W^yDqm6^GNPcCH4o@Po6&Z*LV zXxYM%f~~3K^M5yYq@P!n7&Uv?#p&u$F&@7|M#el90%btO8$QSXAaEaShD*rxRGmdq z0ORKTF_`z5Kb?n{fJGGUPW3dY1=GmzcAGy}Un7ukQ;1tyP2T z)70A5_Oa=ZJ4pjY;Jj}|M{}9+9T!Y(uM;WX*74DlE17CV+r^d1D-Ln2|8SVQSw){V zA%s}$dT?P4TzPM!LaKgiSp;QzrhfX{*VcC6{){5%p2PLR*K!$${l)=0tzs)t7goX( zVCCI0TvrnHnS1mGmUBATWC^Y|fDb8Zt`&5Q5L|98SNQ+zogX7u%pz3Umg>0#g3#W-tNyeuo+U{(8} z;VAcUX%H;=P&&k9ekIF%KUlmE@%Qw~-V^iw@aGLo!8=>ksi@~*V(#QOfoX1YaT*jt z$C8pU2Rb}jV}_Naz`b)0kO3ttaHwt{4uNk7er|bdsx-v!UZSn$L?SHn3Q z{fG!P|H5|kcd-9gvHISKQJ|%zWkh^D#I~N0xUdsl#`yO#6(6WCim?@Lg3MwGu4aQM;%`yBO~e9 z*<*hF`hZU*l$%SGXi?GLp7j_LU&GK)NnigZH#heH9Xi{3FQtTEeymX^f@c6y#lenCO2`o);Be-3&5T0ti(;=7u^KbUzLIhFnV zFT?r2&1%3SxwW+kJv~xZ^|*P*F(kwiNFgLEsa0CU_k^Btl@B;=@2|JtkgB}}0+mg4 z6)Y^!%Ld{`ETr%&0yd61#ZJu8g;_TSrXDj}Ti1dVWmHrw?Bw1Hxaep0ugms#oxwSJ zHQ`;F#&R~!k0DjSUuQJdI>1c#-=FN?7^rScPtR?Aa3Cr9FRMpeWd z(DQ5)1DR)9FQ^--J~vk~t-K95tuBefpfbvOPOQ2@Y*i95*pEdc=wkeC;+uksiZ$YJ zbzt{>N_slhI|qj{(Ecx(31;4@Fz{u()2%gM{VpS~bC2R1Zvl^i;Dt(+7d7r$My<&q zK?h%%6B?{pk`o*(cE&S9*Fa~kmVTaWIl&ZTNj*nrSu&JwqrN-x4vmg70xs<@ovM0k zQ|LpOg@x0XmJF=`?>^Yr>E2K~-S){w1k!mIUlg?As1~hv2k=;$BjoX^`tgS|=@xiT zeUA?rkG}t)_%r@)WqX^3pn+)#gid$)1b%;j1(b5g-A%6XHf6W@NHr-nohH64zW^A@ zK{8QhvlZ4JGf`o-9k@dchsuLTyJ$QTh7p0w8i34-1M+Q2{da#tfzrX3@8>5U(HJF4 z4=-q$SW(j+6bJr{t#GR=TKHU0{`7dA{p_MsFBS}`j~LX@v=LNDF|n}7L)0KmQ`H85 z4?B)JfhH*?tfB-xpmxlc;`<`DDzWRop%o67BziDiAnAuR;6ypQ2!ZC&4KIVA+&uZ4gZi9be(@AHPMGv0{u z?%Q{r0H1OyKN5y2=1ut0q-yV~V0G8;OTWQ|EKmUFrj(w5lG`PZsvSQi0$+$s6c{8$ z&>nRgoO0t)3&0}Uk8u!wStfGpM3cKaF5hf#+k_%z`7m2|@9a>3II?~gIkc~goy z@)OMdhS&mz3%bU>hZa3|sPXZf$BUVDphJxeM3Dc>_Br8<)S?kS1#XSBOtnfm9HXp` zjf3L=uvdAAje|3>w{P4*Ds6+=1rouJ1;_2%GQOBQ6$Cb%e^`vo8M<|}Y8LUk6eh8? z{fNtezT*G-p)IAcx8S>n7JVYk(L`zsP7B91jsThSj!KVep)nw)Dh2N+(**32oNnfJ z=Pn!87ZZ@ODtMU+Y6&3o%9+9hrMvS1}rX zWDRU;oRmS{0ZJufdrqv^4xKdVS;UQ)7b~)ZACNcZZ$t}y_tz~sMXycM?(l!;L zh0AFPp4m_z4Y}iXE9DM7M9WTKhi_aq4&+o&o zxB>)cJ-2!on*NEd*F=4elbNkNdp~~eu4yp+XlqLmTh*qxJ+^gqO**#vz~3G#ih*uu zU`8>|=VOKYrT)~qJM~%DZy{!cJJa1)H_A+h{EY+<1V(?^&8kir)4)6XG2jJZ%Li8Y zqyB2V+n}`YN#Pd8r{ro%E#7soxBA5sEO%18r09B8L}cy@WK7TJb>&rI4*Uqt%){rK z#j8@cR|1(i1UfUH>pu!s$t0v^4GU*H&yWtI7W2|M_rRFkr@wr!YLnt^(uAn11}xNG z5O&e?coGBA3wH_d|A+~|fm`zD7D@s->)4>=vtAuyYr6yq!L0KZ^6eF0+KQmsgx3!n zm~YAe(mkV$QWSq~nWOnMx6Ysc_^#q9|JW;#dE}KFDJX9x)JBOjUflSdnw-cUV0x$( zz!VS7h#S-CzFuPnd$vRb);1x$Y^-7Rn`@Pa?y4NkpT1_KC2$L7g|?83BMKsL$wN(E zooJuL6;vZe&@M&w@1jD=r5PfWN9b8Z!!uxfz#7JL8F;%5rLB$Z9n+?b@-4~ z`@06ZYQhLFbwlBG^DRugpG!%D!{c<~ZCTSn6Lj>_FiIj8H8?kvV{&_U_w;hvl`;cU z2R486+cAi^Xl$;t(zg&-h4#*M)1sNGJ8jFsNDs5TkR zJ*p8@W^H4aND-9TD%md3Y_{@-UXNH+qXm~pTSg}A3v;RG{{?}y{SyH=E)M@oNJ#7$ zJ$eB zK}hI(VIkw6{ry-IbT*%rW_R?!o4YMYJP`$jl7|ORiF(fN_E2)bh0Z&uwwz2@+4{P9 zenEkvvhvnoA_IK6X+nt6{ORpMk4S%C-*Z~p_%U0C*RR)cObN-uL_|c~T8wAr=cgAI z?BV$K|5Aig-u@TV;nt9-co#Be`ra%TvN^#}>V(Wp6%^n@0XsfH!RfU%7b<#skA56{ zd}bb=B-Hi9Q3>}Pu7YEwQIId~EeaQY4Gq;aG#vi?7?aqOp2w-7sR^*&g|4KmjD>^4 zz|1`G_bLJw`XLZ4EveTZ>9A5&ajg?tdVa3qGsVWvjQFIP@YsQ~2+|FbI1>|NTaCd~%K@ zH!$7I2ZJq}efy+{^~w6&h|O~`mz8EIE2~$EDk@aRu4g77%crOoY?ppIh^Lm8zGf%I zxwyC(2*-^<4eibcYG!IS8`yg*JM%i|i4Xx-dx}B9rN+H)1?VP8W@4D}ghH^PNE9go z_IK(ruFmiwkw-WcwYH2ch|A;;`d)FLc4jHs7DGLHJ()wZi`~t5Svq+nY|-?IzGsL; zR>aNKUQF9^&d+6-phi(cL&L!Cr@~>E1k`A#cUf(v!I`|Upue+W+45&INF=d=H`nG8 z|0*%E7l!u;h*N_>4?K?l5yASgWPKwMbt4viT~S%E(TsPqB1U7JF1=zNphWfB;$k{f z>_(R)r0F8xJc*U8gw8OjqO|Tt8+}LpUtr>qv5M)bu0tllchLq>Kk@|8SBYwxD%rFZ?b z0_&w0lAS3^?=3jzPWju;hh$Dqcay~=z9qb}7lm(cc|-FGAwI7L<$iIruq#9}^t^cV zE~6wg%sIoiq!9mMN^`M7pLdYwOy7TZ=pyg{gM}CB{N68i5lP=kQHm(gJb0@)P z6P7z6^MI=?y9Eur4FfjcV>yD19HSA^E%*BI!1E;_KV;?( zaGKX>-YYzxT$0(@#p4?@lpQB#kqvcSUtJBlDQhl6cwKc~nl80o_D{=Z8h(Q~XLY9W za%kV32s%}IASL%@4`6GuiD$>yzfP9dIM)t9^Dc$QRpo~u`6! z{lzS6jmvRS5#fUwXsvVUbWhYW;|?mY3hcu z&8Q6|-3&%vP?8ZtdT1*x6~nR;29%VdsD+|N76RcP;p9lMX7&_~&JEK%#bg8NBrY+ZJ`UK*+1#uq4>p#;q8>A1RKkKmSoyd&=)y*={2>!4yv z;q#J7Nb;s_xtE=rUz#AZuzlqIPFYKO;?jNoOdX1CG2$3XObWy_vHvI$FP`w1Kfvz? z{qJk6jUL-UN)qZVbtVuBu3t6>4Un&dr==Z`eN8nLh9I?xjcyWyb06h_-P%8NM@Kuk zu9aJNN``V@0sO|l{N+a#ExgG+Y09ZY@)l~A#((HVy=JS)t+dD6Z*1xMp*GGgC|grm zQrPw-s*Zl{wk)hM_gV3nm>{teFOfZRtiCd+(8nXs?RBJ=oz0bMD8(`tKX&O%QP&;RXWa#KSoHFQ8x5O{m{(Y_! zId^gti~dH^*{$r@=pHaR{#2H5%+~bsuH(&cl>XVWk|7q;PHW+zrkSH8qIXbZb9Wnb zDysO^=cCWjV`+YJe6I%+nb_r;v83TFs9M)%x%t6a#iIVE_=BGAEe6+}9pN~yz%Me& zMJHWO3fAVR3AAHP?8de9ua~OwJ@Si^<0GsGy{InnTpr8@O$L2UkHWHj=jy6bnG|qUzoh)S5;?W z`Wf45q7xJwUbZs(Xamrk7q6v(=YI$Bw*!o4zK~kBJKB2dg2;Q(7-(Tn`L;^C-E8sf z`SzL!#rV6y-xYy)X5NyB?jPe(Qm#e1SDmz59iks1gmn7{_$f=dX(YsUw|RSOhCL3b z;0(*9tX`AmR4Afr25fy5fKj%E7ibc&JU!xHd67&(@r>?c{*kz_XcnU~C4aDA0nA@- zTMUJUyJeLN^7gbTOFn7Ysa-f79nbO8rD}>Vf1V4$YgZ%kZlJ-e^f{XfbLR7*xSVqI z^rFh$dHI~i=8CN|wD++mCzFlsBf6mQx1ueLM|q(dNm_o&U|qu)vJu%(tEcz^0k*%7 zKk^2Z5_~895wj5$y~ToVB(xTPTLaFyS@+)iT(Hm`HlJN|+#jor)N{>>qZ)8CC)!`o zSbv4*6^5TvY%6Hake}9>*VeWy4VR)h!d)HT8KQ!J;s|(zrkOZ*R;^qphz+LuX$8SY zO&Bv?tWvPi(TzQe%2k~W(>Zwn3OE$^_F0<7=(9MI2xRqmj}0C%hs06$mgnzV=17N~ z@cIu+xkNlwHzDCi6DnJq#@=vPN%cE4?rN4LUkDMKIk=2FtXX@sZM?A}#DYIQ11f4x zBN#zdi~A3<(wKcrC8k%|F^48XtLEtvIi9`6Um17ZdWGw8+R5UZ=daEzWjWWU z%%AQscE5($>4kFn_-`!s09oF;;|pFIzCb!|wj=%=$NWq_TUR;_SkCf-DbawpJ{pb- zLw*-pf=B#YdZdxoW2!9T4B=nGaU$F(tHG3LkHI-yiFP=Y_rLpyQpW@1y^bnk;E#0g z-ja!`McwBlo$03Q1beQZFDP^(+;!K|Wv`8)_v0Mq{Z`0T!4;Q-K$AU#mK6k-^6%^< z03oXOh=;Deas#iTRM;E5bH);P~x zr_*cOCn6PAlq&knm7S1o1 z661JFc4|z-1YpSv$tFPcFg5>A!tR)#5_Za-C)!o8ou*;8#wCTJK{~rBsa+YW?RGC$ z4d?I6k0;L$4d>DXCnm#1bp#9-= z(G)^V6sMjze`sgeEfFon?V;Aj*c53+VN|x)$Jfovp@Z|qh#8GZYHgJELHWd`3B2F7 zGH+6ynM*|egebrEk#qL+01ZlkswGOKBg?jigyGm#Z5*=GhsdCEHPZAaYCi3!_-QC>-wuFfm94Oit7bnq?D1?ThO)bWp^b8FDBB0jRjGSpMkU7@%-s+By zY!nyM@us(=KplvZ^HI{jD;!(Ddut$;jZXk0>3{Le|NrpJ#0`eMaR_UG2a^F&j5s~d z%9C5c6xhFY5w4+L0?C-!kNg5#K=2~S3bUxFXrTHtiFI#~6$Xwi6H#DnXu_-90=$VS zjK+4eK1{IjPjXrSlQKu{+xfNns)E=#X)vp|Q!#vGE<5mXkJRw5@F8U(wMEAYR$+5E zSR# z(Dh8!Vrclt!|?;(mI(e?za6;j_GjXpz)Nw97m>WMM2S6I|8hzpVdMMJ$ZS>H{Mght zn6%n+nuwxkt(Y!S(NKr7G8K`=kSxrJm$Y7yOZNBYuHS-c@nG&&&@Rx}kQGw0$jx?y z^SmmGXEG@{xvZ*+UjUO4RnWp#=cBT*P!R$gqlxHsZbe zwphXh+`Ve%_OMg`4%`WXpFjUf+hK3}Y3yz;s z135v+QK0rJ{&VDn+np*c355~C78nk3v3+xjbuiVqlNOdo0@m{m_H zg{l}8OZA3Tft*?IeLy{~Lrmh8cy=cg0@^JxtM4esH)ov|cDj?A6GFonLVDF4nT~Xt zr0l7ZC&WLp)Blo%!7=tSO#%bOGX$J@fEOd1{n3%}@vwd}Gd^Hec-9I8TcIdPFq^B# z0e(rA-9L=U+w6BkDR$$3G*}APsrGf?rIV*F81V8W3QS-5Q19iWfU1by zylP68fj$cn8Fm%_@&v6XTDWAdFD^R~(KA6$SsN%MDSe$Cu>P7eFCRVMcK5jbR$JNb{{-UY@=&`&z`S^2Da%EcUAe<`wYKZ&-H3Sk@|s~tK$kIt_~%3jJUO(h`Bns_VX}>FN;Wya+Iwg zoki)?Fu6M05|jSQAXARoT9E_`(Hl_MfAftVsE!aL7(ovTlh99BaezNkXn3jD5 z%bMh`(rJ%u{`!NaJ#QhdV`8bUm`2BHCST0u8DgE?FFS3`Q)AbkgEAP&?l@wy=A5~Q zKr4t|I6OAO9?Y`r*6B#K3tkj%{F3B7SKC;KC5ES+qF1|r%$l3xXBONKYo`t(O;j$b zC6c5mzt^4G(xCZt7IN_Oxs-7L6~UZY^PY!gfv=X$iSzdq`qhOn1Z&~lZZ zTH!SOJn2Y}RvU-+l)aF1A3tY&r{kwamy&io4#?yu-}M9B89B_%jm1#!l^Bne%iTibfP6YG1>he5|2zQIU-kH9dqoZ= zXf34o=VAO9e^(m#F^6`}q^HD^7KanY8G|{tgqy5!+u*B)yql4l&AIC-ft*Ur%HM_I zC(QXl^Eyy>wQ+vq&)KimdbjL@X1+V1=`Zk4uKPsFpv-hCr?u(=u@86>Ixc5AWhX=VHmk zgf=ApB3s^yoAR5~IMPdP|NVD*7c_>o2_9O0ofAzaL2BiQpHe;)O-0!^ z&7@ zpj1(PcG5=JM0S6h7Z;+Y>e>uNgEAN1n3vR`dT z)C)EXf6(lj{OW5=w!a~xAR;(HGa@K8Ku97QI|@!qlAtjrc^EU&fwYCFi#Sm5NAKGf zy7j^pV`$t-8h^jEWS+1*?4ct48raVS`Jb^BF_xqn$v;k(Swi#JOIN5$~0huu!e z>wNjisf+Hz-Bq$^d!yLu{$qq>4ea5r z6ef^O1SG3pHKQ(YfzYTKTBVB#Pl2mhiLh=42!RiGM46mWWLt>8Fh#1&FTs)|AupbS zIPJP3;Bz$}rFS0|yihSFj1BxZSxvXC#3=E*c~#oG3DR*$`eN{>x^*+^+t$6z)mOi7 z-{dG8gz@|?^d{e)1#t z7ixO>PXqCfB;Y9P469IZ_rejR z&n_b?3-a36-I|VwF#d+hN_}*6j2%N)Oj&)U3)HQcUGOwT`5Y)?!>Ym1_oSaJc2%!9 zm+_RwNNRY9XRggyDj8&kq4yCzv_2q#F5~AFQjxTQLvEI9=2wch^vBC=V+_15XaLASgN=zE42K?m|D31(f z2&Rks3y?{wZwg73} z7x&1C(bm@QW^3Fer}MW#I-}`Uaib?odptJFKBi>;D}QV|iA6Q(dF8r_ zaN~xUVol9a@qY1hzrr|?2j{(&lAMDt8L93^l55>PPt#ZU&L~!LW+&lTOmtwd_*pA! z%;A~vu)FHWR`4o-<)PLMJsp*Fy6z)vMhFZ4>AcCeOHQ}XJ4yEV6L-@P{vYyMYj?s9 zg(s*HAZpli0PSdSG`8M{!9RYuaK!i#yQrFC^6r`4HSxdF5y3al;4R3}mCnz0Ih=*Z zvf+p}BMmB?;MyoAa-b9i8!Iai1+=XYpbC)P_St%!HmBz$7hl6C%rx8QV=lu1@!nwz zL;BaRl#3BB75`5VvHAqSjaKw7XWLOoWvG~=Il?Lk_`&<^TPQnf_WjWKIjOg!aV9|5 zy2MQ<+STlvwuca7+&L2hkNU#jO zkdW6>pxRT$9>f-uz|^-TIc_(~7ycPo?;Q;HaKHG5d)k>Hy%Ks~gZID3ygKgoa8K?J z4=+khnSrT-P#d&)2cD7!8^g9o; z6up*k9Qk2?<`|3e$nZ93GG!;uer4bf53`lN=Cau0%CT{7!5R5R<&uE{)eOpSyn~k2 zBBr}XxLgbS5LXwHX3C+2bVL>kjzixSnrfWgg@_vRAh$+=~4yr7*2 z^uy`err}9TmcU{>eAg}Y6qsrGB8mIui$UsBPmvM`&O z13Z7$&YW*2y1vp<1OW;L?)E+Q`6y8c;auG*M6V5%NAmmeJNd_l#brBJ(K_et;-d1M zzZW+ql7=%`>3o2J3ZWZJg7C_MlxLPK{=pJK`6Lm{drR3Hi?(9J?3RyE*Z8OPJa^&q z7GmFbZ_&;`YZI>7?%VLoV;qZvvTjSw~XdEuoa*4mI0;L z=IL5);~iYLrXqQt_TvCa-K?Gymd1yy{-q9|1n-Gxwc0PHZ}sRd=#=y-5MW1`&iI0`;sTGkTWn7(%JNN zzr<8^Ffv3t@RlayK|?rVp2Tz=;jznC66=h?F}nr`Z09hUCvVgRo%GxJ>^0fUG=wE3 zrA(AV^y=QuT{+SB=JcrH{@d9|G5WW&ku$sCpib$=@60h!UJfYB?|$rtJwg5~i?3my zYApdLiUBrGSxe1nbyh6^hqfkrJ}e3n?ItJMcQ-h5Oo(-c39c38n>W*cZpNgF*8TuGVs z-g(WV!V1Sooc(BXve|Dk(!U}BKXw1mUP96{-CUI>THVJn+(omU=i)t4#(8f%>u=vJ zHLSYUYa3XRXQ{^)qt4Kj=9M*~gvzok7eyLbV-b^TV_b$|Gk-5&Pg$RC>d z890Vh;eD^vFPLrZwo#yZ!XBy8tueIqF72BTI~quM8)cAOTQg)3pjDByoxOidcNw~p zzN;KHk;&)zN!*di*I*4|$6?anThIRU<(z<Tc6rEfu3eU*2eN7uE$|pypE*)f=)vbyYCl>?ly8RQBCd;n^fh?oC!&o z0r>CeaY?8&YQk??jz!(4>0(t>)P*wKxJ87*tuiP*HU%#xLYajP6>)>(CWYXC0G-&F z{(+1Rg>BAOvR0p(DyODMtD(#Xa#op~>H?<{=wdbMN$fNXDQGS8H;Hy(W`d&_Oi+_% zML>A$ET@#ED~f1DH&5LON4$Km)abf;Kk_AAKLoygZza+=rxbPDSaMMy3EELmKy0W? zkP0}J=H`vbDaqjrN0ag}6eeBN1g-#z_dbcpt{w&T4+QG*+G*koFB%kv(LxLwv(uoJ zZO49y{}9hRbvet=P>ggbICNcwQ4q`s3)`qN_cocisNolH+%;4p?}|)&UwiCKHPPVy zYNA=MK;>8Zb9vz?jns~6&MTt6wzhUZZ1Qnn=V&*P?07Gmg5(F8jf|85wHEzr(#PcQ zuIEBrPzlz=<%7fWV-W(o>zv;Gzu6jpG25#r)Fx>JKYg#Y93mr7#U1>9m)1wOB4x4O zE~oxVFQ|8X^vUL@uy&CV26{bC>H(_0-tV>~DLU^+`DYTlE(Dp)0nQdjh0QxFe)3TlwyL~=ReJJ;at`3 z|Ni|-NNC}oMFmeWF{h{8J6zH6+5ZQ0Z5B3vi;;;6?V%z+D3+$Z8X4j61QQb#$Kwk) zY7u?*-_|fL2U;?UVgl2*<=Loz7=WfIt0q$|W&Y)V1397wfdBvi literal 0 HcmV?d00001 diff --git a/content/tutorials/jasper_tutorial_photos/image.png b/content/tutorials/jasper_tutorial_photos/image.png new file mode 100644 index 0000000000000000000000000000000000000000..7a73fb6db86265da274dc419ef7ed4413f1be75c GIT binary patch literal 18365 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 Q;fzFCUgK5yi`Vb}8v!KoX8-^I literal 0 HcmV?d00001