From b47a267dc00b5f358f123d725361cc8797d1fd09 Mon Sep 17 00:00:00 2001
From: "D. Arnodo" <124083497+darnodo@users.noreply.github.com>
Date: Wed, 19 Feb 2025 19:46:53 +0100
Subject: [PATCH] Hextra theme (#1)
* Adapt theme
* Update Contents to match with new theme
* chore: few updates
* adapt HomePage
* Add icons and french version
* fix fr homepage
* Fix Netlab view
* Fix Netlab articles
* devpod post
* French version of DevPod
* my_first_lab
---
.gitmodules | 3 +
content/_index.fr.md | 45 +++
content/_index.md | 45 +++
.../NetOps.md => about/index.fr.md} | 11 +-
.../NetOps.md => about/index.md} | 10 +-
.../VXLAN/Beginners}/media_layers.png | Bin
.../VXLAN/Beginners}/transports.png | Bin
.../Beginners/vxlan-for-beginners.fr.md} | 48 +--
.../VXLAN/Beginners/vxlan-for-beginners.md} | 44 +--
content/documentation/VXLAN/_index.fr.md | 0
content/documentation/VXLAN/_index.md | 0
content/documentation/_index.fr.md | 16 +
content/documentation/_index.md | 16 +
content/documentation/devpod/_index.fr.md | 317 ++++++++++++++++++
content/documentation/devpod/_index.md | 317 ++++++++++++++++++
content/documentation/devpod/aws_options.png | Bin 0 -> 193004 bytes
.../documentation/devpod/delete_instance.png | Bin 0 -> 42765 bytes
content/documentation/devpod/devpod_user.png | Bin 0 -> 190164 bytes
content/documentation/devpod/new_provider.png | Bin 0 -> 120135 bytes
.../documentation/devpod/new_worskapce.png | Bin 0 -> 248388 bytes
content/documentation/devpod/provider.png | Bin 0 -> 188300 bytes
.../documentation/devpod/stopped_instance.png | Bin 0 -> 37139 bytes
content/documentation/devpod/vscode.png | Bin 0 -> 215895 bytes
content/documentation/stepca.fr.md | 316 +++++++++++++++++
content/documentation/stepca.md | 316 +++++++++++++++++
content/en/archives.md | 6 -
content/fr/archives.md | 6 -
.../VXLAN/couches_materielles.png | Bin 29006 -> 0 bytes
.../posts/Documentation/VXLAN/transports.png | Bin 29992 -> 0 bytes
content/netlab/_index.fr.md | 5 +
content/netlab/_index.md | 16 +
content/netlab/first_lab/Graph_view.png | Bin 0 -> 71168 bytes
content/netlab/first_lab/VXLAN.svg | 1 +
content/netlab/first_lab/_index.fr.md | 217 ++++++++++++
content/netlab/first_lab/_index.md | 214 ++++++++++++
.../netlab/first_lab/devpod_configuration.png | Bin 0 -> 205524 bytes
.../first_lab/devpod_configuration_local.png | Bin 0 -> 249408 bytes
content/netlab/first_lab/edge_wireshark.png | Bin 0 -> 258195 bytes
content/netlab/first_lab/edgeshark.png | Bin 0 -> 140433 bytes
.../netlab/first_lab/edgeshark_interface.png | Bin 0 -> 24038 bytes
.../NetLab/index.md => netlab/netlab.fr.md} | 10 +-
.../NetLab/index.md => netlab/netlab.md} | 13 +-
data/icons.yml | 118 +++++++
hugo.yaml | 104 +++---
i18n/en.yaml | 1 +
i18n/fr.yaml | 1 +
layouts/partials/footer.html | 139 --------
static/images/documentation.png | Bin 0 -> 131468 bytes
static/images/logo.svg | 27 ++
static/images/netlab.png | Bin 0 -> 41125 bytes
static/img/cover_vxlan_dummies.webp | Bin 670390 -> 0 bytes
themes/hextra | 1 +
52 files changed, 2059 insertions(+), 324 deletions(-)
create mode 100644 content/_index.fr.md
create mode 100644 content/_index.md
rename content/{fr/posts/Documentation/NetOps.md => about/index.fr.md} (95%)
rename content/{en/posts/Documentation/NetOps.md => about/index.md} (95%)
rename content/{en/posts/Documentation/VXLAN => documentation/VXLAN/Beginners}/media_layers.png (100%)
rename content/{en/posts/Documentation/VXLAN => documentation/VXLAN/Beginners}/transports.png (100%)
rename content/{fr/posts/Documentation/VXLAN/index.md => documentation/VXLAN/Beginners/vxlan-for-beginners.fr.md} (95%)
rename content/{en/posts/Documentation/VXLAN/index.md => documentation/VXLAN/Beginners/vxlan-for-beginners.md} (95%)
create mode 100644 content/documentation/VXLAN/_index.fr.md
create mode 100644 content/documentation/VXLAN/_index.md
create mode 100644 content/documentation/_index.fr.md
create mode 100644 content/documentation/_index.md
create mode 100644 content/documentation/devpod/_index.fr.md
create mode 100644 content/documentation/devpod/_index.md
create mode 100644 content/documentation/devpod/aws_options.png
create mode 100644 content/documentation/devpod/delete_instance.png
create mode 100644 content/documentation/devpod/devpod_user.png
create mode 100644 content/documentation/devpod/new_provider.png
create mode 100644 content/documentation/devpod/new_worskapce.png
create mode 100644 content/documentation/devpod/provider.png
create mode 100644 content/documentation/devpod/stopped_instance.png
create mode 100644 content/documentation/devpod/vscode.png
create mode 100644 content/documentation/stepca.fr.md
create mode 100644 content/documentation/stepca.md
delete mode 100644 content/en/archives.md
delete mode 100644 content/fr/archives.md
delete mode 100644 content/fr/posts/Documentation/VXLAN/couches_materielles.png
delete mode 100644 content/fr/posts/Documentation/VXLAN/transports.png
create mode 100644 content/netlab/_index.fr.md
create mode 100644 content/netlab/_index.md
create mode 100644 content/netlab/first_lab/Graph_view.png
create mode 100644 content/netlab/first_lab/VXLAN.svg
create mode 100644 content/netlab/first_lab/_index.fr.md
create mode 100644 content/netlab/first_lab/_index.md
create mode 100644 content/netlab/first_lab/devpod_configuration.png
create mode 100644 content/netlab/first_lab/devpod_configuration_local.png
create mode 100644 content/netlab/first_lab/edge_wireshark.png
create mode 100644 content/netlab/first_lab/edgeshark.png
create mode 100644 content/netlab/first_lab/edgeshark_interface.png
rename content/{fr/posts/NetLab/index.md => netlab/netlab.fr.md} (97%)
rename content/{en/posts/NetLab/index.md => netlab/netlab.md} (96%)
create mode 100644 data/icons.yml
create mode 100644 i18n/en.yaml
create mode 100644 i18n/fr.yaml
delete mode 100644 layouts/partials/footer.html
create mode 100644 static/images/documentation.png
create mode 100644 static/images/logo.svg
create mode 100644 static/images/netlab.png
delete mode 100644 static/img/cover_vxlan_dummies.webp
create mode 160000 themes/hextra
diff --git a/.gitmodules b/.gitmodules
index e69de29..dd62212 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "themes/hextra"]
+ path = themes/hextra
+ url = https://github.com/imfing/hextra.git
diff --git a/content/_index.fr.md b/content/_index.fr.md
new file mode 100644
index 0000000..d50472e
--- /dev/null
+++ b/content/_index.fr.md
@@ -0,0 +1,45 @@
+---
+
+title: Damien's NoteBook
+layout: hextra-home
+
+---
+
+
+
+
+{{< hextra/hero-headline >}}
+ Bloc Note Personnel
+ pour les NetDevOps et SRE
+{{< /hextra/hero-headline >}}
+
+
+
+{{< hextra/hero-subtitle style="margin:.3rem 0 2rem 0">}}
+ Documentation et NetLab à déployer,
+ Pour tester et pratiquer 🚀
+{{< /hextra/hero-subtitle >}}
+
+
+
+
+{{< hextra/feature-grid >}}
+ {{< hextra/feature-card
+ title="Documentations"
+ subtitle="Liste des documents et explications sur le concept de réseau ou de système"
+ link="documentation"
+ class="hx-aspect-auto md:hx-aspect-[1.1/1] max-md:hx-min-h-[340px]"
+ image="/images/documentation.png"
+ imageClass="hx-top-[40%] hx-left-[24px] hx-w-[180%] sm:hx-w-[110%] dark:hx-opacity-80"
+ style="background: radial-gradient(ellipse at 50% 80%,rgba(58, 56, 113, 0.1),hsla(0,0%,100%,0));"
+ >}}
+ {{< hextra/feature-card
+ title="NetLab"
+ subtitle="Des Labs pour s'entraîner"
+ link="netlab"
+ class="hx-aspect-auto md:hx-aspect-[1.1/1] max-lg:hx-min-h-[340px]"
+ image="/images/netlab.png"
+ imageClass="hx-top-[40%] hx-left-[36px] hx-w-[180%] sm:hx-w-[110%] dark:hx-opacity-80"
+ style="background: radial-gradient(ellipse at 50% 80%,rgba(203, 28, 66, 0.1),hsla(0,0%,100%,0));"
+ >}}
+{{< /hextra/feature-grid >}}
diff --git a/content/_index.md b/content/_index.md
new file mode 100644
index 0000000..a97f877
--- /dev/null
+++ b/content/_index.md
@@ -0,0 +1,45 @@
+---
+
+title: Damien's NoteBook
+layout: hextra-home
+
+---
+
+
+
+
+{{< hextra/hero-headline >}}
+ Personal Notebook
+ for NetDevOps and SRE
+{{< /hextra/hero-headline >}}
+
+
+
+{{< hextra/hero-subtitle style="margin:.3rem 0 2rem 0">}}
+ Documentation and NetLab to Deploy,
+ Tests and Practice 🚀
+{{< /hextra/hero-subtitle >}}
+
+
+
+
+{{< hextra/feature-grid >}}
+ {{< hextra/feature-card
+ title="Documentations"
+ subtitle="List of documentation and explanation about Network or System concept"
+ link="documentation"
+ class="hx-aspect-auto md:hx-aspect-[1.1/1] max-md:hx-min-h-[340px]"
+ image="/images/documentation.png"
+ imageClass="hx-top-[40%] hx-left-[24px] hx-w-[180%] sm:hx-w-[110%] dark:hx-opacity-80"
+ style="background: radial-gradient(ellipse at 50% 80%,rgba(58, 56, 113, 0.1),hsla(0,0%,100%,0));"
+ >}}
+ {{< hextra/feature-card
+ title="NetLab"
+ subtitle="Labs to practice"
+ link="netlab"
+ class="hx-aspect-auto md:hx-aspect-[1.1/1] max-lg:hx-min-h-[340px]"
+ image="/images/netlab.png"
+ imageClass="hx-top-[40%] hx-left-[36px] hx-w-[180%] sm:hx-w-[110%] dark:hx-opacity-80"
+ style="background: radial-gradient(ellipse at 50% 80%,rgba(203, 28, 66, 0.1),hsla(0,0%,100%,0));"
+ >}}
+{{< /hextra/feature-grid >}}
diff --git a/content/fr/posts/Documentation/NetOps.md b/content/about/index.fr.md
similarity index 95%
rename from content/fr/posts/Documentation/NetOps.md
rename to content/about/index.fr.md
index 8955ea1..10e3d40 100644
--- a/content/fr/posts/Documentation/NetOps.md
+++ b/content/about/index.fr.md
@@ -1,14 +1,7 @@
---
-title: "NetOps"
-date: 2024-08-01T15:19:38+02:00
-draft: false
-categories: "Documentations"
-UseHugoToc: true
-TocOpen: false
-showToc: true
-weight: 1
+title: A Propos
+toc: false
---
-
## Travail et missions d'un NetDevOps 🖥️🛠️📡
Le métier de NetDevOps est relativement nouveau dans l'industrie informatique. Il combine les compétences des développeurs et des opérations réseau pour fournir une infrastructure réseau agile et robuste, et améliorer la qualité de l'expérience utilisateur. Dans cet article, nous allons explorer les missions et les compétences d'un NetDevOps.
diff --git a/content/en/posts/Documentation/NetOps.md b/content/about/index.md
similarity index 95%
rename from content/en/posts/Documentation/NetOps.md
rename to content/about/index.md
index 858da8e..cde5b09 100644
--- a/content/en/posts/Documentation/NetOps.md
+++ b/content/about/index.md
@@ -1,12 +1,6 @@
---
-title: "NetOps"
-date: 2024-08-01T15:19:38+02:00
-draft: false
-categories: "Documentations"
-UseHugoToc: true
-TocOpen: false
-showToc: true
-weight: 1
+title: About
+toc: false
---
## Job and Missions of a NetDevOps 🖥️🛠️📡
diff --git a/content/en/posts/Documentation/VXLAN/media_layers.png b/content/documentation/VXLAN/Beginners/media_layers.png
similarity index 100%
rename from content/en/posts/Documentation/VXLAN/media_layers.png
rename to content/documentation/VXLAN/Beginners/media_layers.png
diff --git a/content/en/posts/Documentation/VXLAN/transports.png b/content/documentation/VXLAN/Beginners/transports.png
similarity index 100%
rename from content/en/posts/Documentation/VXLAN/transports.png
rename to content/documentation/VXLAN/Beginners/transports.png
diff --git a/content/fr/posts/Documentation/VXLAN/index.md b/content/documentation/VXLAN/Beginners/vxlan-for-beginners.fr.md
similarity index 95%
rename from content/fr/posts/Documentation/VXLAN/index.md
rename to content/documentation/VXLAN/Beginners/vxlan-for-beginners.fr.md
index af3da25..923480a 100644
--- a/content/fr/posts/Documentation/VXLAN/index.md
+++ b/content/documentation/VXLAN/Beginners/vxlan-for-beginners.fr.md
@@ -1,18 +1,8 @@
---
-title: "VXLAN Pour les débutants"
+title: "VXLAN pour les débutants"
date: 2024-08-01T20:00:00+02:00
-draft: false
-categories: "Documentations"
-tags:
- - Network
- - VXLAN
- - Architecture
-UseHugoToc: true
-TocOpen: false
-showToc: true
-cover:
- image: "/img/cover_vxlan_dummies.webp"
- caption: "Building the Future of Networking: Exploring VLANs and VXLANs Across Scalable Digital Landscapes"
+cascade:
+ type: docs
---
## Comprendre VLAN et VXLAN : Simplifié pour les non-techniciens
@@ -23,8 +13,6 @@ Nous aborderons également leurs limites, leurs cas d’usage concrets, ainsi qu
Allons-y ! 🚀
----
-
## Qu'est-ce qu'un VLAN ? 🏢
**VLAN (Virtual Local Area Network)**, ou Réseau Local Virtuel, c'est comme organiser un grand immeuble de bureaux avec plusieurs départements : Marketing, Ventes, RH, et Informatique. Pour maintenir l'ordre, chaque département obtient son propre étage. De cette manière, les personnes du Marketing restent à leur étage, celles des Ventes au leur, et ainsi de suite.
@@ -42,8 +30,6 @@ Un **VLAN** fonctionne de manière similaire pour les réseaux informatiques. Il
- **Limite d’ID :** Historiquement, un VLAN est identifié sur 12 bits, permettant jusqu’à 4094 VLANs (de 1 à 4094). Pour une grande entreprise ou un datacenter, cela peut s’avérer insuffisant.
- **Isolation locale :** Les VLANs sont plutôt conçus pour un usage local (un même site ou un ensemble de switches connectés localement). Dès qu’on veut étendre ce concept à plusieurs sites, on a besoin de solutions plus avancées.
----
-
## Qu'est-ce que le VXLAN ? 🌆
**VXLAN (Virtual Extensible LAN)** va plus loin. Imaginez que votre entreprise grandisse et s'étende à plusieurs immeubles à travers la ville. Vous voulez toujours que les départements se sentent comme s'ils étaient sur leurs propres étages, même s'ils sont maintenant répartis dans différents endroits. Pour ce faire, vous créez un système virtuel qui connecte tous les étages à travers les bâtiments, de sorte que le Marketing au 3e étage d'un bâtiment soit toujours virtuellement connecté au Marketing du 3e étage d'un autre bâtiment.
@@ -56,8 +42,6 @@ Le **VXLAN** fait cela pour les réseaux. Il étend les VLANs à travers plusieu
- **Flexibilité :** Permet des conceptions de réseau plus grandes et dynamiques.
- **Connectivité :** Assure une communication fluide à travers des réseaux dispersés.
----
-
## Plongée technique dans le VXLAN 🔍
Le **VXLAN** a été développé pour répondre aux limites des VLANs traditionnels (scalabilité, étendue géographique). Il utilise un identifiant de réseau VXLAN (**VNI**) de 24 bits pour identifier jusqu'à **16 millions** de segments logiques, surpassant ainsi largement la limite de 4094 VLANs.
@@ -70,19 +54,15 @@ L’objectif du **VXLAN** est de **prolonger la couche 2** à travers un réseau
> **En clair :** On encapsule les trames Ethernet (couche 2) dans un paquet UDP (couche 4), lui-même transporté par IP (couche 3).
----
+
-
-
-> ✏️ **Les couches “matérielles”**
+> [!NOTE]**Les couches “matérielles”**
>
> - La couche **Liaison (2)** est communément gérée par des switches.
> - La couche **Réseau (3)** est communément gérée par des routeurs.
En encapsulant la couche 2 dans la couche 3, on profite des avantages du routage IP (souplesse, scalabilité) tout en conservant l’isolation et la simplicité de la couche 2 pour les applications et machines virtuelles.
----
-
### VXLAN expliqué par l’analogie du transport de conteneurs 🚚 🚂
#### 1. Les camions (couches basses)
@@ -97,8 +77,6 @@ Quand il s’agit de couvrir de plus longues distances ou de traverser des infra
Le train roule sur des rails (le **réseau IP**, couche 3). Les voies ferrées sont déjà construites et gérées pour trouver le meilleur itinéraire : elles assurent la convergence des routes et peuvent rediriger le trafic en cas de problème (panne, congestion, etc.). De la même façon, le réseau IP choisit automatiquement le chemin le plus optimal pour transporter les paquets VXLAN.
----
-
### Points clés à retenir
- **Superposition (Overlay)** : VXLAN est un système de transport « par-dessus » la couche 3 (les rails). Il permet d’interconnecter plusieurs réseaux de niveau 2 (les camions) comme s’ils n’en formaient qu’un seul.
@@ -110,8 +88,6 @@ Le train roule sur des rails (le **réseau IP**, couche 3). Les voies ferrées s

----
-
## Cas d'usage concrets 🏭
- **Multi-datacenter :** Pour connecter plusieurs centres de données géographiquement dispersés, tout en gardant la sensation d’un réseau unique au niveau 2.
@@ -119,8 +95,6 @@ Le train roule sur des rails (le **réseau IP**, couche 3). Les voies ferrées s
- **Migration de machines virtuelles :** Permettre la migration (VM Mobility) entre sites distants sans perdre la connectivité de couche 2.
- **Virtualisation massive :** Dans les environnements très denses (par ex. des centaines de milliers de machines virtuelles), l’identifiant VNI de 24 bits est indispensable.
----
-
## Contrôle du VXLAN : BGP EVPN et autres protocoles 🤝
Dans les déploiements modernes, surtout en datacenter, le VXLAN n’est pas simplement configuré de manière statique. Il est souvent associé à un **contrôle de plan** via le protocole **BGP EVPN (Ethernet VPN)**.
@@ -128,15 +102,11 @@ Dans les déploiements modernes, surtout en datacenter, le VXLAN n’est pas sim
- **BGP EVPN :** Permet d’échanger les informations de tables MAC et IP entre les équipements, facilitant l’automatisation et l’évolutivité.
- **Autres technologies :** Historiquement, on pouvait croiser d’autres protocoles d’overlay (NVGRE, STT), mais VXLAN s’est imposé comme standard de fait.
----
-
## Considérations de performance ⚙️
- **Surcharge d’encapsulation :** Le VXLAN ajoute un en-tête supplémentaire (8 octets + en-tête UDP/IP). Cela peut impacter la **taille maximale de trame (MTU)** et il faut souvent configurer un **Jumbo MTU** (généralement 9000 octets) pour éviter la fragmentation des paquets.
- **Résilience du réseau IP :** La fiabilité du tunnel VXLAN dépend de la qualité du réseau IP sous-jacent (routes, congestion, etc.).
----
-
## Exemple de configuration (pour les plus curieux) 💡
Voici un **extrait simplifié** d’une configuration VXLAN sur un équipement Cisco NX-OS (les syntaxes varient selon les constructeurs) :
@@ -156,8 +126,6 @@ interface nve1
*Note :* Dans les environnements plus complexes, on configure également le plan de contrôle (par ex. BGP EVPN).
----
-
## En résumé 🎯
- **VLAN**
@@ -170,17 +138,13 @@ interface nve1
Le **VXLAN** répond aux besoins d'isolation à grande échelle, dépasse les limitations des tables d'adresses MAC des commutateurs et permet un déploiement flexible des services. De plus, associé à un plan de contrôle efficace (BGP EVPN), il simplifie grandement la gestion des réseaux modernes en **overlay**.
----
-
### Conclusion 🏁
En bref, si vous recherchez une **segmentation de base** pour votre réseau local, un **VLAN** est largement suffisant. Mais dès lors que vous voulez relier plusieurs sites, créer un réseau hautement virtualisé, ou dépasser la limite traditionnelle de 4094 VLANs, le **VXLAN** devient incontournable.
Que vous soyez un passionné de **Lab réseau**, un ingénieur NetOps, ou tout simplement curieux des dessous de l’infrastructure informatique, comprendre ces deux notions vous aidera à mieux appréhender la magie qui se déroule lorsque vos données circulent de plus en plus loin, tout en conservant l’illusion d’être “chez soi” sur le même réseau local !
----
-
-> **Envie d’aller plus loin ?**
+> [!TIP] **Envie d’aller plus loin ?**
>
> - Regardez du côté du **BGP EVPN** pour le plan de contrôle du VXLAN.
> - Explorez la **configuration Jumbo MTU** pour optimiser vos performances.
diff --git a/content/en/posts/Documentation/VXLAN/index.md b/content/documentation/VXLAN/Beginners/vxlan-for-beginners.md
similarity index 95%
rename from content/en/posts/Documentation/VXLAN/index.md
rename to content/documentation/VXLAN/Beginners/vxlan-for-beginners.md
index ecd36f7..c193bff 100644
--- a/content/en/posts/Documentation/VXLAN/index.md
+++ b/content/documentation/VXLAN/Beginners/vxlan-for-beginners.md
@@ -1,18 +1,8 @@
---
title: "VXLAN for Beginners"
date: 2024-08-01T20:00:00+02:00
-draft: false
-categories: "Documentation"
-tags:
- - Network
- - VXLAN
- - Architecture
-UseHugoToc: true
-TocOpen: false
-showToc: true
-cover:
- image: "/img/cover_vxlan_dummies.webp"
- caption: "Building the Future of Networking: Exploring VLANs and VXLANs Across Scalable Digital Landscapes"
+cascade:
+ type: docs
---
## Understanding VLAN and VXLAN: Simplified for Non-Technicians
@@ -25,8 +15,6 @@ We’ll also cover their limitations, real-world use cases, and some technical p
Let’s go! 🚀
----
-
## What is a VLAN? 🏢
**VLAN (Virtual Local Area Network)** is like organizing a large office building with multiple departments: Marketing, Sales, HR, and IT. To keep things orderly, each department gets its own floor. This way, Marketing stays on its floor, Sales stays on theirs, and so on.
@@ -44,8 +32,6 @@ A **VLAN** works similarly for computer networks. It divides a large physical ne
- **ID Limit:** Historically, a VLAN is identified by a 12-bit field, allowing up to 4094 VLANs (1 to 4094). For a large company or a datacenter, this might be insufficient.
- **Local Isolation:** VLANs are primarily designed for local use (on the same site or a connected set of switches). Extending this concept to multiple sites requires more advanced solutions.
----
-
## What is VXLAN? 🌆
**VXLAN (Virtual Extensible LAN)** goes further. Imagine your company grows and expands to multiple office buildings across the city. You still want each department to feel as if it’s on its own floor, even though they’re now spread out across different locations. To do this, you create a virtual system that connects all floors across buildings so that Marketing on the 3rd floor of one building is still virtually connected to Marketing on the 3rd floor of another building.
@@ -58,8 +44,6 @@ A **VLAN** works similarly for computer networks. It divides a large physical ne
- **Flexibility:** Enables larger, more dynamic network designs.
- **Connectivity:** Ensures seamless communication across dispersed networks.
----
-
## Technical Dive into VXLAN 🔍
**VXLAN** was developed to address the limitations of traditional VLANs (scalability, geographic reach). It uses a **VNI** (VXLAN Network Identifier) with 24 bits to identify up to **16 million** logical segments, far exceeding the 4094 VLAN limit.
@@ -72,19 +56,15 @@ The goal of **VXLAN** is to **extend Layer 2** across a Layer 3 (IP) network. Es
> **In simple terms:** Ethernet frames (Layer 2) are encapsulated inside a UDP packet (Layer 4), which is then carried by IP (Layer 3).
----
-

-> ✏️ **The “Physical” Layers**
+> [!NOTE] **The “Physical” Layers**
>
> - The **Link Layer (Layer 2)** is typically managed by switches.
> - The **Network Layer (Layer 3)** is typically managed by routers.
By encapsulating Layer 2 inside Layer 3, you benefit from the advantages of IP routing (flexibility, scalability) while preserving the isolation and simplicity of Layer 2 for applications and virtual machines.
----
-
### VXLAN Explained by the Container Transport Analogy 🚚 🚂
#### 1. Trucks (lower layers)
@@ -99,8 +79,6 @@ When it’s time to travel longer distances or through different infrastructures
The train runs on rails (the **IP network**, Layer 3). The railroad is already built and managed to find the best path; it ensures route convergence and can reroute traffic in case of issues (breakdowns, congestion, etc.). Similarly, the IP network automatically selects the optimal path to transport VXLAN packets.
----
-
### Key Takeaways
- **Overlay:** VXLAN is a transport system “on top of” Layer 3 (the rails). It interconnects multiple Layer 2 networks (the trucks) as if they were just one.
@@ -112,8 +90,6 @@ The train runs on rails (the **IP network**, Layer 3). The railroad is already b

----
-
## Real-World Use Cases 🏭
- **Multi-datacenter:** For connecting multiple geographically dispersed data centers while preserving the feel of a single Layer 2 network.
@@ -121,8 +97,6 @@ The train runs on rails (the **IP network**, Layer 3). The railroad is already b
- **Virtual Machine Migration:** Enabling VM mobility between distant sites without losing Layer 2 connectivity.
- **Massive Virtualization:** In highly dense environments (e.g., hundreds of thousands of virtual machines), the 24-bit VNI is indispensable.
----
-
## VXLAN Control: BGP EVPN and Other Protocols 🤝
In modern deployments, especially in data centers, VXLAN isn’t just configured statically. It’s often paired with a **control plane** via **BGP EVPN (Ethernet VPN)**.
@@ -130,15 +104,11 @@ In modern deployments, especially in data centers, VXLAN isn’t just configured
- **BGP EVPN:** Exchanges MAC and IP table information between devices, facilitating automation and scalability.
- **Other Technologies:** Historically, other overlay protocols (NVGRE, STT) existed, but VXLAN has become the de facto standard.
----
-
## Performance Considerations ⚙️
- **Encapsulation Overhead:** VXLAN adds an extra header (8 bytes + UDP/IP header). This can affect the **Maximum Transmission Unit (MTU)** size, often requiring **Jumbo MTU** (usually 9000 bytes) to avoid packet fragmentation.
- **Resilience of the IP Network:** The tunnel’s reliability depends on the underlying IP network’s quality (routes, congestion, etc.).
----
-
## Example Configuration (for the curious) 💡
Below is a **simplified excerpt** of a VXLAN configuration on a Cisco NX-OS device (syntax can vary by vendor):
@@ -158,8 +128,6 @@ interface nve1
*Note:* In more complex environments, the control plane (e.g., BGP EVPN) is also configured.
----
-
## Summary 🎯
- **VLAN**
@@ -172,17 +140,13 @@ interface nve1
**VXLAN** addresses the need for large-scale isolation, overcomes the limitations of switch MAC address tables, and allows for flexible deployment of services. Paired with an efficient control plane (BGP EVPN), it greatly simplifies the management of modern overlay networks.
----
-
### Conclusion 🏁
In short, if you need **basic segmentation** for your local network, **VLAN** is more than enough. But as soon as you want to connect multiple sites, build a highly virtualized network, or exceed the traditional 4094 VLAN limit, **VXLAN** becomes essential.
Whether you’re a **network lab** enthusiast, a NetOps engineer, or simply curious about the underlying infrastructure, understanding these two concepts will help you better grasp the magic that happens when your data travels farther and farther while preserving the illusion of being “at home” on the same local network!
----
-
-> **Want to learn more?**
+> [!TIP] **Want to learn more?**
>
> - Check out **BGP EVPN** for VXLAN’s control plane.
> - Look into **Jumbo MTU configuration** to optimize performance.
diff --git a/content/documentation/VXLAN/_index.fr.md b/content/documentation/VXLAN/_index.fr.md
new file mode 100644
index 0000000..e69de29
diff --git a/content/documentation/VXLAN/_index.md b/content/documentation/VXLAN/_index.md
new file mode 100644
index 0000000..e69de29
diff --git a/content/documentation/_index.fr.md b/content/documentation/_index.fr.md
new file mode 100644
index 0000000..33f2895
--- /dev/null
+++ b/content/documentation/_index.fr.md
@@ -0,0 +1,16 @@
+---
+title: Documentation
+cascade:
+ type: docs
+
+---
+
+
+{{< hextra/hero-subtitle >}}
+ Documentation complète et guides pratiques étape par étape
+{{< /hextra/hero-subtitle >}}
+
+{{< cards >}}
+ {{< card link="https://containerlab.dev/install/" title="ContainerLab" subtitle="Comment Installer ContainerLab" icon="endpoints" >}}
+ {{< card link="https://devpod.sh" title="DevPod" subtitle="Une manière simple de déployer Lab" icon="git" >}}
+{{< /cards >}}
diff --git a/content/documentation/_index.md b/content/documentation/_index.md
new file mode 100644
index 0000000..bb87841
--- /dev/null
+++ b/content/documentation/_index.md
@@ -0,0 +1,16 @@
+---
+title: Documentation
+cascade:
+ type: docs
+---
+
+
+
+{{< hextra/hero-subtitle >}}
+ Comprehensive Documentation and Step-by-Step "How-To" Guides
+{{< /hextra/hero-subtitle >}}
+
+{{< cards >}}
+ {{< card link="https://containerlab.dev/install/" title="ContainerLab" subtitle="How to install ContainerLab" icon="endpoints" >}}
+ {{< card link="https://devpod.sh" title="DevPod" subtitle="Easy way to deploy Lab" icon="git" >}}
+{{< /cards >}}
diff --git a/content/documentation/devpod/_index.fr.md b/content/documentation/devpod/_index.fr.md
new file mode 100644
index 0000000..ca0a74a
--- /dev/null
+++ b/content/documentation/devpod/_index.fr.md
@@ -0,0 +1,317 @@
+---
+title: "DevPod sur AWS"
+date: 2025-02-11T20:00:00+02:00
+weight: 1
+cascade:
+ type: docs
+---
+
+## Sources
+
+- [DevPod](https://devpod.sh/docs/what-is-devpod) ⚙️
+- [DevContainer](https://containers.dev) 🐳
+
+## Introduction 🚀
+
+Dans cet article, je souhaite présenter un outil fantastique qui fait partie de la même famille que GitPod et Codespaces : **DevPod** ! Il vous permet de créer des environnements de développement sans effort — sans se retrouver bloqué par un fournisseur. 🔒❌
+
+DevPod est basé sur l'architecture **DevContainer** et utilise les spécifications contenues dans un fichier [devcontainer.json](https://containers.dev) pour lancer votre environnement de développement. Personnellement, je l'utilise pour déployer rapidement des maquette réseau avec ContainerLab. 💻🧰
+
+## Qu'est-ce qu'un DevContainer ? 🤔
+
+Un conteneur de développement (souvent appelé « dev container ») vous permet d'utiliser un conteneur comme un environnement de développement complet. (Consultez la documentation officielle de [containers.dev](https://containers.dev) pour plus de détails.)
+
+Décomposons cela :
+
+Avez-vous déjà entendu l'expression « Ça marche sur ma machine » ? Si vous êtes développeur, vous avez sans doute rencontré ce problème en collaborant avec d'autres. Mais devinez quoi ? Les **DevContainers** résolvent le problème de la dérive des environnements en fournissant des environnements Docker cohérents et reproductibles. Adieu les maux de tête liés à l'installation ! 💆♀️
+
+Avec les DevContainers, il vous suffit de :
+
+1. Un dossier `.devcontainer` dans votre projet.
+2. Un fichier `devcontainer.json` qui indique à VS Code comment configurer le conteneur.
+3. Docker installé localement
+
+La pierre angulaire du DevContainer est le fichier `devcontainer.json`. Par exemple :
+
+```json
+{
+ "name": "Python DevContainer",
+ "image": "mcr.microsoft.com/devcontainers/python:3.10",
+ "features": {
+ "docker-in-docker": "latest"
+ },
+ "extensions": [
+ "ms-python.python",
+ "ms-azuretools.vscode-docker"
+ ]
+}
+```
+
+**Que se passe-t-il ici ?** 🕵️♀️
+
+- **"image"** – Cela utilise un environnement Python 3.10 prêt à l'emploi.
+- **"features"** – Cela ajoute la prise en charge de Docker dans le conteneur.
+- **"extensions"** – Installe des extensions utiles pour Python et Docker dans VS Code.
+
+Les DevContainers sont formidables pour le développement local, mais parfois vous avez besoin de plus de puissance — peut-être que vos charges de travail sont énormes, ou que vous souhaitez exécuter des laboratoires spécialisés. C'est là qu'intervient **DevPod**. 💪
+**Pour pouvoir déployer facilement des laboratoires sur le Cloud**
+
+## Qu'est-ce que DevPod ? 🤖
+
+**DevPod** est un outil open-source qui vous permet de lancer des environnements de développement soit sur votre machine locale, soit dans le cloud de votre choix. Imaginez une version auto-hébergée et ultra-personnalisable de GitHub Codespaces. 🎉
+
+Dans mes aventures quotidiennes en réseau, je déploie des configurations basées sur ContainerLab avec des DevContainers sur AWS. Voyons comment vous pouvez utiliser DevPod pour faire exactement cela (les détails sur ContainerLab suivront dans un autre article, promis !). 😜
+
+## Fournisseur AWS 🌐
+
+DevPod utilise des **Providers** (fournisseurs), qui sont des modules de configuration définissant où et comment DevPod lance votre environnement. Voici la liste des fournisseurs :
+
+
+
+Nous allons nous concentrer sur le **Provider AWS** — bien qu'il existe de nombreuses options de configuration :
+
+
+
+Avant de paniquer devant tous ces réglages, ne vous inquiétez pas. Si vous ne faites que quelques expérimentations, les valeurs par défaut conviennent généralement. 🙌
+
+> [!NOTE] **Les avantages de l'open-source** 🎁
+>
+> Le fait que DevPod soit open-source signifie que vous pouvez jeter un œil sous le capot pour voir exactement comment il fonctionne. Consultez le code AWS [ici](https://github.com/loft-sh/devpod-provider-aws/tree/main) si vous êtes curieux.
+
+## Fonctionnement du code AWS
+
+Examinons ce que fait DevPod sur AWS en regardant le [code aws.go](https://github.com/loft-sh/devpod-provider-aws/blob/main/pkg/aws/aws.go). À un niveau global, il gère :
+
+1. **Initialisation** : Lecture de la configuration et mise en place des clients du SDK AWS (avec des identifiants personnalisés si nécessaire).
+2. **Réseautage** : Recherche ou création du sous-réseau, VPC et groupes de sécurité appropriés.
+3. **Sélection de l'AMI** : Choix d'une AMI adaptée (par défaut, une image Ubuntu 22.04 récente) et détermination du périphérique racine.
+4. **Configuration IAM** : Vérification qu'un rôle d'instance approprié et un profil d'instance existent, avec les politiques associées.
+5. **Cycle de vie de l'instance** : Création, démarrage, arrêt, vérification du statut et suppression des instances.
+6. **Injection de données utilisateur** : Génération d'un script (encodé en Base64) qui configure l'instance (ajoute des utilisateurs et des clés SSH) au premier démarrage.
+7. **DNS optionnel** : Gestion des enregistrements Route 53 pour l'instance si la configuration l'exige.
+
+De mon point de vue, deux points se distinguent comme étant potentiellement les plus critiques :
+
+- **(#4) Configuration IAM**
+- **(#6) Injection de données utilisateur**
+
+### Pourquoi les points #4 et #6 sont-ils « délicats » ?
+
+- **Configuration IAM** est principalement gérée par la fonction `CreateDevpodInstanceProfile`. Elle crée un rôle nommé `devpod-ec2-role` qui peut effectuer les opérations suivantes :
+ - **Opérations EC2** : Par exemple, il peut décrire ou arrêter des instances — en particulier l'instance qui lui est associée.
+ - **Opérations SSM** : En attachant la politique AmazonSSMManagedInstanceCore, l'instance peut être gérée par AWS Systems Manager.
+ - **Opérations KMS (optionnel)** : Si configuré, il peut exécuter `kms:Decrypt` sur une clé KMS spécifique, ce qui est utile pour gérer les données de session ou les secrets.
+
+- **Injection de données utilisateur** est essentiellement un script de démarrage inséré dans l'instance sous forme de Base64. Ce script configure un utilisateur `devpod` avec des droits sudo, crée les dossiers SSH et insère votre clé publique dans le fichier approprié. Dans le code, [cela ressemble à](https://github.com/loft-sh/devpod-provider-aws/blob/9d2730c34ecee40cb42596c602381b92ad9c6682/pkg/aws/aws.go#L967-L980) :
+
+ ```bash
+ useradd devpod -d /home/devpod
+ mkdir -p /home/devpod
+ if grep -q sudo /etc/groups; then
+ usermod -aG sudo devpod
+ elif grep -q wheel /etc/groups; then
+ usermod -aG wheel devpod
+ fi
+
+ echo "devpod ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/91-devpod
+ mkdir -p /home/devpod/.ssh
+ echo " + string(publicKey) + " >> /home/devpod/.ssh/authorized_keys
+ chmod 0700 /home/devpod/.ssh
+ chmod 0600 /home/devpod/.ssh/authorized_keys
+ chown -R devpod:devpod /home/devpod
+ ```
+
+Comme DevPod est open-source, vous pouvez facilement vérifier par vous-même. C'est un excellent outil d'apprentissage si vous souhaitez comprendre tous les rouages ! 🔩
+
+## Rôles et politiques IAM
+
+Vous devrez créer un utilisateur IAM et lui attacher une politique IAM qui accorde juste assez de permissions pour DevPod. Par exemple :
+
+- **Actions EC2 :**
+ - Description : `ec2:DescribeSubnets`, `ec2:DescribeVpcs`, `ec2:DescribeImages`, `ec2:DescribeInstances`, `ec2:DescribeSecurityGroups`
+ - Gestion des instances : `ec2:RunInstances`, `ec2:StartInstances`, `ec2:StopInstances`, `ec2:TerminateInstances`, `ec2:CancelSpotInstanceRequests`
+ - Groupes de sécurité & Tags : `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTags`
+- **Actions IAM :**
+ - `iam:GetInstanceProfile`, `iam:CreateRole`, `iam:PutRolePolicy`, `iam:AttachRolePolicy`, `iam:CreateInstanceProfile`, `iam:AddRoleToInstanceProfile`
+- **Route 53 (optionnel) :**
+ - `route53:ListHostedZones`, `route53:GetHostedZone`, `route53:ChangeResourceRecordSets`
+
+## Configuration AWS 🏗️
+
+J'utilise généralement la console web AWS pour configurer cela, mais vous pouvez tout à fait le faire via la CLI.
+
+### Étape 1 : Connectez-vous à la console AWS
+
+1. Rendez-vous sur [AWS Management Console](https://aws.amazon.com/console/).
+2. Utilisez un compte disposant des droits appropriés pour créer des ressources IAM.
+
+### Étape 2 : Créer une politique IAM personnalisée
+
+#### **A. Accédez à la console IAM**
+
+- Dans le menu AWS, trouvez **IAM**.
+
+#### **B. Créer une nouvelle politique**
+
+1. Cliquez sur **Policies** dans le menu de gauche.
+2. Cliquez sur **Create policy**.
+
+#### **C. Passez à l'onglet JSON**
+
+- Collez quelque chose comme ceci, en ajustant si nécessaire :
+
+```json
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Sid": "EC2Actions",
+ "Effect": "Allow",
+ "Action": [
+ "ec2:DescribeSubnets",
+ "ec2:DescribeVpcs",
+ "ec2:DescribeImages",
+ "ec2:DescribeInstances",
+ "ec2:DescribeSecurityGroups",
+ "ec2:RunInstances",
+ "ec2:StartInstances",
+ "ec2:StopInstances",
+ "ec2:TerminateInstances",
+ "ec2:CancelSpotInstanceRequests",
+ "ec2:CreateSecurityGroup",
+ "ec2:AuthorizeSecurityGroupIngress",
+ "ec2:CreateTags",
+ "ec2:DeleteTags"
+ ],
+ "Resource": "*"
+ },
+ {
+ "Sid": "IAMActions",
+ "Effect": "Allow",
+ "Action": [
+ "iam:GetInstanceProfile",
+ "iam:CreateRole",
+ "iam:PutRolePolicy",
+ "iam:AttachRolePolicy",
+ "iam:CreateInstanceProfile",
+ "iam:AddRoleToInstanceProfile"
+ ],
+ "Resource": "*"
+ },
+ {
+ "Sid": "Route53Actions",
+ "Effect": "Allow",
+ "Action": [
+ "route53:ListHostedZones",
+ "route53:GetHostedZone",
+ "route53:ChangeResourceRecordSets"
+ ],
+ "Resource": "*"
+ }
+ ]
+}
+```
+
+- Cliquez sur **Next** (les tags sont optionnels), puis sur **Next: Review**.
+
+#### **D. Vérifier et créer**
+
+1. Nommez-la `DevpodToolPolicy` (ou comme vous le souhaitez).
+2. Ajoutez une description facultative.
+3. Cliquez sur **Create policy**.
+
+### Étape 3 : Créer ou mettre à jour l'utilisateur IAM
+
+#### **A. Créer un nouvel utilisateur (si nécessaire)**
+
+1. Cliquez sur **Users** dans IAM.
+2. Cliquez sur **Add user**.
+3. Donnez-lui un nom (par exemple, `devpod-tool-user`).
+4. Choisissez **Programmatic access** si vous souhaitez un accès via la CLI. 🤖
+5. Cliquez sur **Next**.
+
+#### **B. Attacher votre nouvelle politique**
+
+1. Sur la page des permissions, choisissez **Attach policies directly**.
+2. Cochez `DevpodToolPolicy`.
+3. Cliquez sur **Create**.
+4. Et voilà !
+
+### Étape 4 : Vérifier et c'est fini
+
+Retournez dans **Users** → **devpod-tool-user** → **Permissions** pour confirmer que `DevpodToolPolicy` est bien attachée. ✅
+
+### Étape 5 : Utilisez ces identifiants
+
+- Si vous avez créé un utilisateur programmatique, n'oubliez pas de noter l'**Access Key ID** et le **Secret Access Key**.
+
+
+
+**Bonus** : Notez votre **ID VPC** (dans la section VPC sur AWS). Vous en aurez besoin lors de la configuration de DevPod.
+
+## Configurer DevPod 🛠️
+
+### 1. Configurer le profil AWS
+
+```bash
+aws configure --profile Devpod
+```
+
+Lorsqu'on vous le demande :
+
+1. L'Access Key ID
+2. Le Secret Access Key
+3. La région par défaut (par exemple, `eu-west-1`)
+4. Le format de sortie (je le laisse généralement vide)
+
+### 2. Ajouter le profil à DevPod
+
+1. Dans DevPod, créez un nouveau provider et choisissez **AWS**.
+2. Sélectionnez la **région AWS** (par exemple, `eu-west-1`).
+3. Développez les options AWS.
+4. **Taille du disque AWS** : par exemple, 40 GB pour commencer.
+5. **Type d'instance** : par exemple, `t2.small`.
+6. **Profil AWS** : sélectionnez `Devpod` (ou le nom que vous avez choisi).
+7. **ID VPC AWS** : ajoutez votre VPC.
+8. Vous pouvez laisser le reste par défaut.
+
+Cliquez sur **Add Provider**.
+
+
+
+## Tester un déploiement 🧪
+
+### Déployer
+
+Nous allons effectuer un test rapide en utilisant l'une des images Docker préconstruites :
+
+1. Rendez-vous dans **Workspaces** dans DevPod.
+2. Cliquez sur **Create Workspace**.
+3. Choisissez votre nouveau provider **AWS**.
+4. Choisissez votre IDE préféré (VS Code, etc.).
+5. À droite, sélectionnez un exemple de démarrage rapide (par exemple, Python). 🐍
+6. Cliquez sur **Create Workspace**.
+
+
+
+Attendez quelques instants, et votre environnement basé sur le cloud apparaîtra dans VS Code. 🎊
+
+
+
+### Arrêter
+
+Lorsque vous n'utilisez pas l'environnement, cliquez sur **Stop** pour éteindre l'instance EC2. Vous ne paierez que pour le stockage — aucun temps de calcul. Idéal pour votre portefeuille. 💰
+
+
+
+### Supprimer
+
+Supprimer le workspace supprime toutes les ressources AWS associées à cet environnement, vous ne paierez donc pas un centime. Mais vous devrez redéployer si vous souhaitez l'utiliser à nouveau. ♻️
+
+
+
+## Conclusion 💡
+
+En combinant **DevContainers** et **DevPod** sur **AWS**, vous pouvez créer des environnements de développement flexibles et autogérés qui évoluent avec votre croissance — sans être enfermé dans des plateformes spécifiques à un fournisseur. Dites adieu aux problèmes du « Ça marche sur ma machine ! » et accueillez un codage sans friction. 🚀✨
+
+Amusez-vous bien ! 🎉
diff --git a/content/documentation/devpod/_index.md b/content/documentation/devpod/_index.md
new file mode 100644
index 0000000..4dabc37
--- /dev/null
+++ b/content/documentation/devpod/_index.md
@@ -0,0 +1,317 @@
+---
+title: "DevPod on AWS"
+date: 2025-02-11T20:00:00+02:00
+weight: 1
+cascade:
+ type: docs
+---
+
+## Sources
+
+- [DevPod](https://devpod.sh/docs/what-is-devpod) ⚙️
+- [DevContainer](https://containers.dev) 🐳
+
+## Introduction 🚀
+
+In this article, I’d like to showcase a fantastic tool that sits in the same family as GitPod and Codespaces: **DevPod**! It empowers you to create development environments effortlessly—without getting locked into any particular vendor. 🔒❌
+
+DevPod is based on **DevContainer** architecture and uses the specs found in a [devcontainer.json](https://containers.dev) file to spin up your dev setup. Personally, I love it for quickly and reliably deploying Network Labs with ContainerLab. 💻🧰
+
+## What a DevContainer Is 🤔
+
+A development container (often called a “dev container”) lets you use a container as a full-featured dev environment. (Check out the official [containers.dev documentation](https://containers.dev) for more details.)
+
+Let’s break it down:
+
+Have you ever heard the phrase “It works on my machine”? If you’re a developer, you’ve probably run headfirst into this problem when collaborating with others. But guess what? **DevContainers** solve the mystery of environment drift by providing consistent, reproducible Docker-based environments. Bye-bye setup headaches! 💆♀️
+
+Using DevContainers, you just need:
+
+1. A `.devcontainer` folder in your project.
+2. A `devcontainer.json` file that tells VS Code how to configure the container.
+3. Docker installed locally
+
+The backbone of the DevContainer is the `devcontainer.json` file. For example:
+
+```json
+{
+ "name": "Python DevContainer",
+ "image": "mcr.microsoft.com/devcontainers/python:3.10",
+ "features": {
+ "docker-in-docker": "latest"
+ },
+ "extensions": [
+ "ms-python.python",
+ "ms-azuretools.vscode-docker"
+ ]
+}
+```
+
+**What’s happening here?** 🕵️♀️
+
+- **"image"** – This uses a Python 3.10 environment that’s ready to go.
+- **"features"** – This adds Docker support inside the container.
+- **"extensions"** – Installs useful Python and Docker extensions in VS Code.
+
+DevContainers are awesome for local dev, but sometimes you need more muscle—maybe your workloads are huge, or you want to run specialized labs. That’s where **DevPod** comes in. 💪
+**To be able to deployed lab easily on Cloud**
+
+## What DevPod Is 🤖
+
+**DevPod** is an open-source tool that lets you spin up dev environments either on your local machine or in the cloud of your choice. Imagine a self-hosted, super-customizable version of GitHub Codespaces. 🎉
+
+In my day-to-day networking escapades, I deploy ContainerLab-based setups with DevContainers on AWS. Let’s see how you can use DevPod to do exactly that (ContainerLab details will follow in another post, I promise!). 😜
+
+## AWS Provider 🌐
+
+DevPod uses **Providers**, which are like configuration modules that define where and how DevPod launches your environment. Here’s the Provider list:
+
+
+
+We’ll focus on the **AWS Provider**—though there are many config options:
+
+
+
+Before you freak out at all those toggles, don’t worry. If it’s just you tinkering, the defaults are usually fine. 🙌
+
+> [!NOTE] **Open Source Perks** 🎁
+>
+> Being open-source means you can pop the hood and see exactly how DevPod works. Check out the AWS code [here](https://github.com/loft-sh/devpod-provider-aws/tree/main) if you’re curious.
+
+## How the AWS Code Works
+
+Let’s break down what DevPod will do on AWS by looking at the [aws.go code](https://github.com/loft-sh/devpod-provider-aws/blob/main/pkg/aws/aws.go). From a high-level, it handles:
+
+1. **Initialization**: Reading configuration and setting up AWS SDK clients (with custom credentials if needed).
+2. **Networking**: Finding or creating the appropriate subnet, VPC, and security groups.
+3. **AMI Selection**: Choosing a suitable AMI (defaulting to a recent Ubuntu 22.04 image) and determining the root device.
+4. **IAM Setup**: Ensuring an appropriate instance role and instance profile exist, complete with policies.
+5. **Instance Lifecycle**: Creating, starting, stopping, checking status, and deleting instances.
+6. **User Data Injection**: Generating a script (embedded as Base64) that configures the instance (sets up users and SSH keys) on first boot.
+7. **Optional DNS**: Managing Route 53 records for the instance if the configuration calls for it.
+
+From my perspective, two points stand out as potentially the most critical:
+
+- **(#4) IAM Setup**
+- **(#6) User Data Injection**
+
+### Why are #4 and #6 “Tricky”?
+
+- **IAM Setup** is primarily handled by the `CreateDevpodInstanceProfile` function. It creates a role named `devpod-ec2-role` that can do the following:
+ - **EC2 Operations**: For example, it can describe or stop instances—particularly the instance associated with itself.
+ - **SSM Operations**: By attaching the AmazonSSMManagedInstanceCore policy, the instance can be managed by AWS Systems Manager.
+ - **KMS Operations (Optional)**: If configured, it can perform `kms:Decrypt` on a specific KMS key, helpful for handling session data or secrets.
+
+- **User Data Injection** is basically a startup script inserted into the instance as Base64. That script sets up a `devpod` user with sudo rights, creates SSH folders, and plops your public key in place. In the code, [it looks like](https://github.com/loft-sh/devpod-provider-aws/blob/9d2730c34ecee40cb42596c602381b92ad9c6682/pkg/aws/aws.go#L967-L980):
+
+```bash
+useradd devpod -d /home/devpod
+mkdir -p /home/devpod
+if grep -q sudo /etc/groups; then
+ usermod -aG sudo devpod
+elif grep -q wheel /etc/groups; then
+ usermod -aG wheel devpod
+fi
+
+echo "devpod ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/91-devpod
+mkdir -p /home/devpod/.ssh
+echo " + string(publicKey) + " >> /home/devpod/.ssh/authorized_keys
+chmod 0700 /home/devpod/.ssh
+chmod 0600 /home/devpod/.ssh/authorized_keys
+chown -R devpod:devpod /home/devpod
+```
+
+Since DevPod is open source, you can easily check this out yourself. It’s a great learning tool if you’re curious about the nuts and bolts! 🔩
+
+## IAM Roles and Policies
+
+You’ll need to set up an IAM user and attach an IAM policy that grants just enough permissions for DevPod. For example:
+
+- **EC2 Actions:**
+ - Describe: `ec2:DescribeSubnets`, `ec2:DescribeVpcs`, `ec2:DescribeImages`, `ec2:DescribeInstances`, `ec2:DescribeSecurityGroups`
+ - Manage Instances: `ec2:RunInstances`, `ec2:StartInstances`, `ec2:StopInstances`, `ec2:TerminateInstances`, `ec2:CancelSpotInstanceRequests`
+ - Security Groups & Tags: `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`, `ec2:CreateTags`
+- **IAM Actions:**
+ - `iam:GetInstanceProfile`, `iam:CreateRole`, `iam:PutRolePolicy`, `iam:AttachRolePolicy`, `iam:CreateInstanceProfile`, `iam:AddRoleToInstanceProfile`
+- **Route 53 (Optional):**
+ - `route53:ListHostedZones`, `route53:GetHostedZone`, `route53:ChangeResourceRecordSets`
+
+## AWS Configuration 🏗️
+
+I typically use the AWS web console to set this up, but you can absolutely do it all via CLI.
+
+### Step 1: Log in to the AWS Console
+
+1. Head to [AWS Management Console](https://aws.amazon.com/console/).
+2. Use an account with the proper rights to create IAM resources.
+
+### Step 2: Create a Custom IAM Policy
+
+#### **A. Go to the IAM Console**
+
+- In the AWS menu, find **IAM**.
+
+#### **B. Create a New Policy**
+
+1. Click **Policies** on the left.
+2. Press **Create policy**.
+
+#### **C. Switch to the JSON Tab**
+
+- Paste in something like this, adjusting if needed:
+
+```json
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Sid": "EC2Actions",
+ "Effect": "Allow",
+ "Action": [
+ "ec2:DescribeSubnets",
+ "ec2:DescribeVpcs",
+ "ec2:DescribeImages",
+ "ec2:DescribeInstances",
+ "ec2:DescribeSecurityGroups",
+ "ec2:RunInstances",
+ "ec2:StartInstances",
+ "ec2:StopInstances",
+ "ec2:TerminateInstances",
+ "ec2:CancelSpotInstanceRequests",
+ "ec2:CreateSecurityGroup",
+ "ec2:AuthorizeSecurityGroupIngress",
+ "ec2:CreateTags",
+ "ec2:DeleteTags"
+ ],
+ "Resource": "*"
+ },
+ {
+ "Sid": "IAMActions",
+ "Effect": "Allow",
+ "Action": [
+ "iam:GetInstanceProfile",
+ "iam:CreateRole",
+ "iam:PutRolePolicy",
+ "iam:AttachRolePolicy",
+ "iam:CreateInstanceProfile",
+ "iam:AddRoleToInstanceProfile"
+ ],
+ "Resource": "*"
+ },
+ {
+ "Sid": "Route53Actions",
+ "Effect": "Allow",
+ "Action": [
+ "route53:ListHostedZones",
+ "route53:GetHostedZone",
+ "route53:ChangeResourceRecordSets"
+ ],
+ "Resource": "*"
+ }
+ ]
+}
+```
+
+- Click **Next** (tags optional), then **Next: Review**.
+
+#### **D. Review and Create**
+
+1. Name it `DevpodToolPolicy` (or whatever you like).
+2. Optional description.
+3. Click **Create policy**.
+
+### Step 3: Create/Update the IAM User
+
+#### **A. Create a New User (If Needed)**
+
+1. Click **Users** in IAM.
+2. **Add user**.
+3. Name it (e.g., `devpod-tool-user`).
+4. Choose **Programmatic access** if you want CLI access. 🤖
+5. **Next**.
+
+#### **B. Attach Your New Policy**
+
+1. On the permissions page, pick **Attach policies directly**.
+2. Check `DevpodToolPolicy`.
+3. Click **Create**.
+4. That’s it!
+
+### Step 4: Verify & Done
+
+Head back to **Users** → **devpod-tool-user** → **Permissions** to confirm `DevpodToolPolicy` is attached. ✅
+
+### Step 5: Use Those Credentials
+
+- If you created a programmatic user, make sure you note the **Access Key ID** and **Secret Access Key**.
+
+
+
+**Bonus**: Keep track of your **VPC ID** (under the VPC service in AWS). You’ll need it when setting up DevPod.
+
+## Configure DevPod 🛠️
+
+### 1. Configure AWS Profile
+
+```bash
+aws configure --profile Devpod
+```
+
+When prompted:
+
+1. Access Key ID
+2. Secret Access Key
+3. Default region (e.g., `eu-west-1`)
+4. Output format (I usually leave it blank.)
+
+### 2. Add Profile to DevPod
+
+1. In DevPod, create a new provider and pick **AWS**.
+2. Select the **AWS region** (e.g., `eu-west-1`).
+3. Expand AWS options.
+4. **AWS Disk Size**: maybe 40GB to start.
+5. **Instance Type**: e.g., `t2.small`.
+6. **AWS Profile**: select `Devpod` (or the name you chose).
+7. **AWS VPC ID**: add your VPC.
+8. You can leave the rest as defaults.
+
+Click **Add Provider**.
+
+
+
+## Testing a Deployment 🧪
+
+### Deploy
+
+We’ll run a quick test using one of the prebuilt Docker images:
+
+1. Go to **Workspaces** in DevPod.
+2. Click **Create Workspace**.
+3. Pick your new **AWS** provider.
+4. Choose your preferred IDE (VS Code, etc.).
+5. On the right, pick a quickstart example (e.g., Python). 🐍
+6. Click **Create Workspace**.
+
+
+
+Wait a few moments, and your cloud-based environment will pop up in VS Code. 🎊
+
+
+
+### Stop
+
+When you’re not using it, click **Stop** to shut down the EC2 instance. You’ll only pay for storage—no compute time. Great for the wallet. 💰
+
+
+
+### Delete
+
+Deleting the workspace removes all AWS resources for that environment, so you won’t pay a dime. But you’ll have to redeploy if you want to use it again. ♻️
+
+
+
+## Conclusion 💡
+
+By combining **DevContainers** and **DevPod** on **AWS**, you can build flexible, self-managed dev environments that scale as you grow—without getting boxed in by vendor-specific platforms. Wave goodbye to “It works on my machine!” woes, and say hello to frictionless coding. 🚀✨
+
+Happy building and exploring! 🎉
diff --git a/content/documentation/devpod/aws_options.png b/content/documentation/devpod/aws_options.png
new file mode 100644
index 0000000000000000000000000000000000000000..894b6fd83550e6e4dd86ff40e5ff19a9744c2411
GIT binary patch
literal 193004
zcmce8cUV)|);C$^|
zLZ|_R0D%xl_{F*3+?j8_x%bcC^PF&UlJo5BwO85ide=GxKhsj7xXyf?h=_5>A(#byXCIN(XOm5iX>xj8tE1Y7*TeyeA{N6lhCC^6M7D
zi<$5uBD$P@`HxRXj?#($cu)M>uP^UMkt-7sJt9(7daUnpX(yF5#pLu?~qc;vQ%yfXYLpK=cwFBPj)@`AQ
z?rW|<{B=QWW2D8s=%KG$qAE=Xo(=NQHOpRj%Y#rP;`;_PDCTtYaD51r7;3b-!I0{_
zuM2cMIn9G;oSy5wZbj+(q&({u;nu?5C|v9Y+`ad&K_*^x>c2X4>pVOK&;s!;#haCR
zLn*z&y)Xc)^Ef}e_Us%4%soHlugnKVK=2=)Cc=P@a|efpVVh8p@a0oLtSk?SR+9ZG
zK>C(C&kLk&x65Unl+2n}+Ao~ORSIUu
RK%uiiRyb`4tWGup4@w_Ho@(d4ZOgdx1(Bf
z4qo3S?&in3)rol7+`7UOjFq4TPudE<
zLH5M$Edl5(efzo3xzqj4=>njG{vKiS>3-2b8LaH-q2cRjQC(9=2f44s<{@lI{x-Sv
z(C2R6ZI6tdLn?X*ez|V=t73QHppbOHDyQk2c*4)LZvfy>saq~Pf4y(ytG}gUHz{AP
zn>@ursKJ2&zcPlVv9=gx{>Gm3Rcnr=rONMCvm_$|h^UAy@!jHr(abW8_2
z@O*eHx@>fv|&ycGul?6k&3BB=+
zg48k(fFi;bqf#9lLztxa6|ZwYRV7P&lcK
zF6MKHc0U$NOf~|+J--cT#vh?;p-{|8JQR9sDH?0KzX#n07-zM-9q^BQQ{;;4L_KNn
z9kaV{((oJr9YOn7LfYoM^xbZg)j#7J=zDJ#JtFuWVkCloEhE-Dx=MqBGlt}U%{5Rv
zu;t>HJ_*Z*!79otxKb={3xS|W=_t#`QxR%DxEIXi9*Yk{0NQE=KG$4bYvmZn|TQnh%s#zZ~{cG`Sc9K4-Gg!JtP?6
z(uz#mlKk49D)a)2ZJz>ldbUo%oAJkcuocMW5@^lN8kc*tH+106Wvzib=0@-B9k`Rp
z7R$S6L5Ia3w#>M`+B#A5hRdgxWekbrFMZ9fqTwv#sXHTvKE^q2*tC
zN1aNh(vCgUS>jQ{;l_^7K=wy+QP4chSuF%d%+o(b(D{$qsi~GuM{*z?L;`}_+SdN%
zE@M;h6q-=y%+ivWpS@FXh`h^h7pQhK10S4f;$7}iX&Nmqo{15qZsztXL~4e?sGeQXT>sN2rf@>`3*1}io+rHmR7uVr)VLDQQd^_
z;<-x{e~#7ehu~r<89-3w8xUX2JOYD
zUDfWHC@ryK2x|rELt2`eI4t{l?5})m+9TmU9o9d
zQ%vm^nofYWKJHGAV2$-T@1#-}^KtvNd+z@VuF#7roYv&S@uik#{60FqOx_1)0;JkZ
z*<1qPajjoRT3XJ}LJ^NzBwcs24+am;=rS~0IA&^*hwx)#KH!db^F@WxD75ZpZg}0%
zhu&WeP-}j*LvY}
zQ{8e6F{YBvb-Sx@6!U(dnZfv@go>&-S+p@tOE~{OTJq`HRm}
zUG8+bOJBwh-M<}3_m1o3VLa201({mw`=+mHMkR!3vVvo1M4z6bYB(GU^C;zY-4Z^E
zGc4Y>8_amaiAJlOO6&cKBL{?)C&=B?d>plpb<4_d#$VA*sghn$YCY60ct575Le3NIo7oiP28EPF3SljJrr;m@R
z3*pK~p9dwLaFk(0jA<|R*g;khc_m&KhqwbwtgJb=>55V+{`KlWi&V{>>i}rv2cWwe
z?vx+yeK4el-necGywFe6en&XP2)Pk_xRmJ}r+4Z(f@WBH0=!VjIERzp=082{*jVxl
z94z{uz5Cu!-s!0VoDTWBlZ%l@T)DstNGZ|J?VJcz6v;y&ptbXd?pxTv#!~3ruI11z
zZxB>+Wi)qBJ{C2A=mWW8^lB$^uYq0PPwPaNMm)B6qi+w?l*x69Eu;WZz6opY)iaO{
zH#CW(D$qb|f6PQpq;>y*eWC$mIi|%srd7k+BK{cD~T
zy?TIOh%anYHftzWcLISR0Hl^*v!>d(l-R5;B~J*X=~2*)^?^+K
za=_b?1m&LhIkAs@{e);I2(0EiIB;kYoA>+2BAJK9Ktr|XFsg0}xQOlx-}`HDd29ur
zgeT}b&%)zuWhZA5CGs81hfF%Iz8Xs13)k0hN7GC`Hju{XhSF8eRN(~
z3-0VAh$(i1^a9UYn)8EzWbnAyZ6TStJ?&%CqDer=>;bCmfiLZT%myR_Usa$H;?%?u
zP>5*kL$GeDumTwi!~{BZjNeTsL2D$4aO3f+6?C(g)*rK2xdns<%fj~LoTFKNe9f7`r`D`f!*Oj%2LvntHXmjmnscV|85z
z-5vwt|Ft(0V%UDkGraHdi6d@XXpo^9&l_>m#JN?;69m0UK!80=ol|hE>^FrLM+k0r
z+i@@+kJEv06Wnbk1L8YPQ`UlE$-J@!$=j1R;je(+-ectR&F*z}7|(64D5R&8uh!E}
z8=?-K`M!Zb6fvG+Fy;r{WqP^ksYv=%@oT#-l&VDfc|9X4EC?NVEuXgheIfo_!Co=P
zaBVp}V{?qS3i80|IUy#jWHnlhX{CusQGeg2%4TGS>mv}!urjHTqUPOj?PRPc*0MI?mn%#6u3%}2^-SRxjr~gi#H(~;=im=Q;Cjj&Evo^|L)}+79oAW8
z>x#*<6G8^A^P7$0aVM5$no4{kGa`cbg*B7h+!Xjvo{Av%C#Y^A*VI9YSRECaF3f?B
zoNGvdTW^SJ%DIFYj%E`+RYWBsydGHAl}iaAh|PkZy+EQ0PB5`4gzymnIe*T^@GBPb
zpsJP+ht>}Zhgxn^_@DlYhXiE-$(!-_pdbvk64QJ{KzF|5)iM8rO%3pa`+GyFCntHO
zu%aPoJw+TpsTiO%V_IK`BGB$S)&lDz7)}c4(^i`EX)dlu6PO;g11b
zYcoWTI_Tj9_v+jX<-1x@4JzarIJ1Qp^c`YsAvl!2N(f)X`YMWCkYI!?|1!e7^PJqn
ztij}ojaP7J-;zm+Dh{Uyxi~wk#cdOkl9)1?@29`e4Ay~=!n8oYmVP53hqnY*TXR>!
z`((&wLvYnTr7bRUdN3&d;d-S2)MrrjVb@56)J62D3JV^oQYh<-EE1t7jue)hML*PS
zS}6)Q!s2ygPbW3MPVa`2slKq
zNN_v&ASCWOgk*SR>&jb7;4bZtoF}NT8RPQDFsp|?G|zNrg*)>leO>RvKzQR|R;clz
zP~Ep|Y(hqVg+?J_q#N{!Mzi~~Jhbzx0h}}Sq7cRfheGfp)=%K9zo1dpVL%J?9A}J6
z{T<8yo(kb{%S#}cvpwxy0J
zT-747J3p^q*>|ZfmAN6+X*E)XQtCX2(`!e<{v@Nx3q3Dab!_86QS#BEVSq$~owMAx
zy-WBvcCT8()&Hej(z8gsjy5YEU`rRu&D&SF)Z^|q?bghB^(Tl}y4u-oqbu;*PTsN(
zHXtn3J6&6|@hnGM*EAQQDq*pTS7*9VWK3R*2KwHVCfD}~*Zh%30I){dhwAH}KHQ9s
zanqE2tq%Swe}^qsil^heVhjdc|0Fu-fvTIf(s+ZG=Qg{%OIw~kCCDb3^!{4H-;PJt
zWc@8a>$lez-t`Gcc52mj><&38B1YT9#e~4LYcaaoYy;}}(Vn{pBZ3r~3TY4vy)$l+
z5}&fn*dMeTVvnz8Mm)H~nybo?WASd{avJwj(AtYH9%?t-cjgxH#|Wy2F0&OCw&i|O
z;+N=b;NNoN;)ZKsz<}Me`iXyBD3i+{d9+fb+(xri<$gAw{fw)7S@zIN{+1+ee-JHn
zzzC+@8E!1}xqFb|pV6Z_&KcV>YV>?b`rhW+M`0#EON~dwkyA=o`%;*yf7v-o@f)Y0
z>$I2e@gSJR=sgI7JsX9mnFjZ!PPdh{w@-+r>1cVd{FM(
zYY3GF64@Li)q7`{^!hXd;NABOC#y7qg``)K+~0JKOTcOVUt2NjBcVo5mKaZ2E;f2@
zXP)>tMF*)^9||#
z18uA~U)y8&weOh-yjEXfJ5A#LQ2N@^K-CO#_~WZopqYwHbo+iguN~7JI;*jSS)E?G
zTx~c|IM)*KTJ#c~@IM|Olf^1+@HSO)N>ZByM|w9u^05^lpHj)#&x*~02`2u}
z$M9Q{2-$dS8Nzka=BXjt{mN(;nSzq){m3@YMViy;ha%g}&Z|n4F*IDSq|!UR70)VhQhBy)w)&t-$%8
zm&)w&T=b(d)22+fo5~#mQ!T^w)GNa+*{&JUYbz-oa$B|)4{hy^CX_+g$aNpfijw8=
zG}V00I=_{&FSEhztJzgO@xg_Z0PHdkRChM8Biwp(Lfl|GwP+E+5G8r-d%=D~PMmVJ}gwdCv9uLHe}F9(CXFb+M;a*J{6
zdv5>9CK)0g+1c@jj!>s&+h&B?iX@9kxCnwVs{DF@lICdN07p5TfW(9Zg+W7g0zLR(
z>_@hJkXvt-)`M#WG5HZOwmepC9XhENQ7dDm=&eetNUclKD|0mPT_$Zy8A9CqA5Zw8
zd{=m5S)~o+ST8Qyw3(=!lD6^NpN2aZLUhN}H~x(ZT46uT_=b|uFWQp?b?s4?(`WRbRw&6=v469-8c|0F%)WZ?f>=5fbdD0r3j1*
zcN*kR*WZDVI5gk}-y)VA_;!sTZ0gg_1l_{7-yI!qSpQMZSGVZQm9!+iWH8<*vue*VG4@4ZXKOKkkD
zh74Fnu5xHvvefk@
z=xjNv%tz+_i!WmLz19<}9=x5n*HtGV`_R$1{syazn~M|*V>#N_rJIKtN_Agic|DlK
zI$3JM5Ru@PU-+lFBz!AXCR$KWGAs?&fz<`_KEYw@RO#9Q(Qa|%ZbyBR!M+Ct1&OM4
z>N=HB#*_#~AW58>ve{Z9H5hXo%%Yr%9aByOzI^>OEn(-ja$3Dxc<6k@OBIOBN*3yO
z=NRmWF4OzBYnXf_vRFWMv&Fg{Z{>w$s6L1;&q;SvxhN@-?_m!EI;o#CAVxi
zg%j)ud=R+Y9_YVuONbICd+dRn8Xcu&^Dxsg`r`6p+HOeB&QFo-wscH
zcZj5_)BXWpK$YkV&8XHb7$L>6Law!IRoQJ%mQb)r+6G}uSrABBNbPUoY>w)O?hSw7
zvTuVbW*uw|d8uC9rK5`F$)eT{v^%-1Zf~VdVyy!YLGBKW@(%Vt{OQ#Zhp1eQMfuZ8
zFDm1@w>tGDZhO}dnNoQdcAA=7@VGce(PN+WL~A|IBU4VxhY_gx6=C!9y8U(XAu2~N
z#Hl&q?y)+mPEs2S
zbyW25Yg-8>eq-9HuP6O6v0_1;f8+a06p{r&?GgikA{d
zfe+z@58fg7UnkU^M@kz>|rITBGUVh%U
z+hoh18P*-^^$M^H4|eY1!z)4s>+2TW+AtN%=>seC0Ti9A)Jw**^v{4gaXdeV*=IltH2LB|L0;Jp1T*!uSv}8#
zpRh2PA_0{*J$rkQ*Sy5m{Zg)S$Fc`%3y$)Y<$OwFx6Fs>Vtd7$V&^nzb}*pVH9yOh
zVNa5e%(m$5i**&xP<={E
zHrztdMl|EFR}F|QqAfH?nzo_tia)-3$s%C23$uSwB?H&{uAD3O#lwno7F=xT2goX0
z6bpDYCq9x^1(%%~sn(%qTzrq^!!{G^^u7-D)zObw>SZyJ(Ro83OV^}qZY}5mBQWML
zVSMf{gT}L$d!dmoMLPs7wbfNvwpDa%P?bSW6HzrYE41OyJ<2>M`Ve#W?&P(LZYp&m
z%_cPun<-A_4bx)NQhA<6uZSLc1YgCyS#aQQd0EiKNaJ|e1YIY#<-AC82C@0Ktw=0o
zMWniof
z$5j=JCYR`I>x4T*D`g)Un9!nZ@;LcEMonc;=koUiVgI6l
zZzP3e<8(8H^Y!{WdMe-bo*59mL8l{A{$kaFPak>3f07V;a3rWCCnjtQvUx)YPQM*x
z$k!*#+NPI@JG({v8|s
zc*7k2{zypIML+|~Fw5Zjm0E=jMY*evjX$@1j#R$~ep6RAl1SY?IW)Y^*Rr2NGAaQ+-!$^E3*l
zFr&)Q&Mqpw;>=a(e@eSF(otmk+o1af(TiL-azNFCEek?AjvpP%j_fSdS4rA-99_;A
zdNI(eYbTNcp}wk@_=C~nHeEEYipKf7tOz&cnu-iA$ofCeUzvy9N8K-_Lwen$1iFSz
za1om*0MsW)blxqQTnYkx@$yT%{Db#H#D^Gb+5>Z<*>NqVtT44;X;oAFLHKjkdCpw7
z5b1yU=ijKS-!H}PT(W(Y&B#Zv&$w9&iM6$l$Ntp3xX>?R5&{stL}0J_cAzlGjb*?chWp$#5Ws07
ze(0HtjX&@+;|;{vd?9lxuF6W2z9ACvMd=}OqO@l??yTEFb-0}r`d=pg;F6eNmB_*7I+;kXrK4Ai7ie`kDnTge0;ZFnCD1GDHhiN&NI1KufNuL8AwiWlkmH+>0HQ-dpNfA0!DEAam$@
z<71>x->9HezO{=9`r2zu{})%)c!Z62sSwx#jdo^3b>alOd}*~sY&pvkj(P~3KzUMZ
zMKF=eXgW#z-S2!8=~c_xiNLQSSMeIkLf^mpY$}5O+j4v;MS^TB>}{+F?2{wfrD68o
z()xRsD6?*&7@D>G_Pc|T*0jt@(HU%@f{>~WV3jIkRXT(De{67LPI^=dRvl76jE4SZ
z8^7qUY)}F%X!#`Diz%NNT@q8a7fkkxu?xA4c6sK_Mo%?crx|xG%6g7kG7LCAHmLO5
zYQfZMejXs#DJ1IR&m8{m-rvPZs0u5{v}b$s<&?(Z{cm+CC;!TVlV>xHXWkfey}sHh
zmTrL1nfzqrnJ4S??h=*!F1yh8&m$_9qlQ+yRp);R=6^HqM_DxAmxxE0aOAt{eyK+_
z5u1(&B|q4mN;2O$KPHY`=|)N)Ft%1n!ydGyT>VV7oA61lv)wS4(3&v&Uk2r**(}8S
z1G(kGa8ahpFV&$%1q&0!VV9nfRr3j3o$AHc>J4>$%D3LwkKE5|Rufm%#qv7z{{?FN
zu`~P+PDtmtR+R@8F}Hn}#l=$vH5b58>{zk$a^N3)<3pr}DI=B*w5HCNr$6V_p
zs>DwroK}`R)aT#T=iB4ISd2w1^FM}39}voDd}{cq|2!P**KjVPVxprFNJlX5Qy052
zYJP%yz3-4bKLqwhue2-O9W4l#>M#qmwdB;6VX->xD*i7n7WMmh4GH+EZ_o!6=O^hZd2%rF5<`UoXLj(p7Memu43aBzRxvP
zZwu$DO9~29HfP4^lg^Gbwn{bIy&eCuV-Ba1NPt787Fi&>3#l6J6Gk~p0!@g$xHJ<}
zy#Ty_1eXpaE))<*VvySVW(=l+4lPwR&Y}V%fWm7%=$?$vc
znXi1{FoqW_5)RjkrtHal&W^78tT1H%@Aauy`!=;`!nKKi_+fM}u6p61;ffqN=Njo}
zu?K`$XF6UM%HkU2nvKbV76`spcQ1{K&sUK>u-|kR7Z*)=!}L*oEvTaR_wW?1^8Ti0kSFok$u&(mshk=1_xU}O^LgUMUcNr(
zOQjZ_X$GRnEdi=_V4UA+`qaamj8wmkhvtxcY(7c-W@O2c(^Wb*E;
zPOheF$P;hP_OEdxG!+7Sydb{M8bO-eou7e0ZU@#67;*V}8U;~RJ%NqC3(g!tR6FzK
z@_>cut~|x7AH+QWJI1;Azb|WQP#E%=;~ds(F|IF!W`wKiaXu01gFaQ&j*f`4bIe&N
zs#TzR45QF9{Xo6?D=9I9h_SoUqQ~Q7dX_^074JsM)>kuO;6Uzg@R?%;S{tzVA-K~U
z(G|yQgue0m75r^kowVa_{VmZ#*mr@y;w)D7a#0iSll=ubR!nG1xuC3q?XI-#J7aOT
zQu7Sx+H5=l+#Lzonx7kW$2X6w8b*WIh(Wy=UO;86f%dQ-sqS$Up^M{Nf~F_dj#?L@
zZ)i7K)h8y>>)ABR0tAP9W6tSz+-9&aM+&(EdGJ?T(xKhY&`j2puX#&PNnRpsdqG{h
z7f=4SDBmJf%w`U5nji0wwvUCTT?>uBPu?C#L6M~#euGpakv@Qu>D=$<@Sw|XlQ{Y1
z^9IW~Hiw1%27iE@{U&H$Efk+4z4iK(igV&g?P}m~U_wk$2u2;+hyG$@a;9QHU>GS$
zh6`naU9*`P0TX&WAnr$|6_K^$5%RgL6O`*Rh8{aa7o}cxe8mX`3zQk2N_LFpRM76!
z)}y=`rsK}D{|i%}!M@3z4BQ|vMP=q=xd(eQIqLBNUtzMh9GZ3`-p&^A_$yMSy)0|k
zZb*DoO=k0ct&c26Q=)%86I~dseYgHgg~&*hMth
zp`xU1GoM{-_=T0<=c(+3Aa14J_KPYy%o@IefYY10xP_pz?qqXSz)#Pqg25tdt)vx2
zGGD3#_@eVVEhk3}?s(i;BcGXCuXJ4PhbMv@NmjO+c0bZlOm
z8C5Ul?GjotT!gvlZ)RpktA1A$YQH)nz%2s?M9_Wu!C9
zOd=y5qoRrEc?J_=@hk`vF=mbd4(KacKD2<>@o~Ez&1Be5eALW%vd0@Nx+j^-bu^>-
z-7ViFI9g!crw!HZucs}?)m-r|aLmwM>_=MJKg_a9J>B{oJm@z3nAD$`Qi^@v0};MF
zY3!)!<965Fad)=bwqjVT%IqnYL4nN^d=9=lslzkD3&Q#1{d41{3R=Xfr&Eq3AlVIT
z_^Nn=o*abmhoU6S8162|Vmt|A3s+ACs}~Xu^SV_l;}r%kF<8UdAU@w$o_~
zKCQG15z1q!IQwb7lQ3ew`dzMG*3#l)y%u_dz+6QgMVL2GP|%$$N!|be?Taix2NRBg
zTPj-QJgFY`$$0s*&a(D)XMm<98aW{ftaVb7GCSyS={958=qh@|NJxT@xhf*)D_~wO
z;t*j12%E|-(iucco@T*mitaCV_!Sqc734m3n*8SSx}EX;hl5tG`H_eo6*|rc>}PAv
zG^MtLg$nz%o!sGGHgJuvckQP|;^(tEqrHerj~$28Ssi%X=%>^2{y{S?!QZ}pAZ}mn
ziPj6dqAkbzT7LhTQH!sM(N~M-bz5Rp#>=Ju}3
zH|`Xc?{7URXqLHn+~3Ykg2hY~%0-=M*r#ogG?;o(p?tnqx2>rlb6w
zkl5Rl(Z990qP*eNMHJ*nk}K+|do@xxp7eP#B+J1VSqyEQc*W$n#JtZm6q}k673*Kl*8{`xb4kU@}(SxRMOJ=PF;7h8&7W!0TW@Hi=H_bIk-{iJgX_
z#ey_wnva7MEsOEXm+i}Al!6mey<(D*d7i20(J{Tl1!#-V`Eo$ZCj#Bo;WI5tC=jrk
zU-+C*Y70Q5iHLtj)w+QR;741Nu-m%xz*wZxT0f%iCh>{gHMz6cKI3R_-+@DOEy%aE
zkehw&NgHt3^|OF%EoU>TpzG)PI^F?Jh%WcBs4@Ekr!TYd1j^oVV0_^p(cX_McZBT|
z9K1`;!9!W!wB&cQF|SutBty-!+7zAHuC<&`IJRYDM%8x?_{*-9NpI|w4*}`gMsxZQ
zZ<@W^Kj`uBRP3dl{nWwa08825o8C@WW7@7Ee8_9DiL?w)D}cz(y}0x
ztmge<_n83B4!py=pw3q@+_V`O$GxoOI@-CfqKKIB#zb|`26^hMrEr3V#&zf-$?}5r
zCfPf__l@i2mboS9ds_TZtX}}*qS%&aWwPzsF_0;yxWw?1YQ4EO
zG_*|&Xty0vc&mP><6YAyq4b{RIg`>D^6DIWygahua_O
z4!}Au2Tq>80!vyQ;4=yeK3jV<2=X6FbUb$wwU$pf7^4(0m|Ji;+}-l@*=RaWp+CVc
zEl?Yd4v?v^i3rSlU+lOv>?8|$`7lcV_SWO5f~Rd_>io;3iymvyE@L3rlm13<`;y_$gbbD1hrPg7?k&OHe(VyquQfK|5YCbhi%5BtM@nV8X
z9BIisICV7Ea;-joHi6r-Q&Fk6Z***PPT8!GXOrfJwJvuKJ7#+sQe{|ZRBDb8NN
z9RW4%ir183tehK)TgtP&<;)0qrmotb^|})myGzW|eawq2NqK&%AqO!W{7Hj_h065t
zE7iA7mVp326P&yuCTPXww$R1f0XLXtd-BmVQ!-30?}!?b|CZVPe%VMw^2XLH$kB%M
zBPo?y=B#rl18EJ?_TUGWAQTKxOe*jqv`Xt}jybsco(=lJK{FNz6h&=x|uxKchhoT1v^ZcZoU`m`qsdFn7q*w>c7afNW&ikTjBcuOxbhlPh1q01MWyaOXSl}Q|!
z7AXVL{5fu^@^iuh0`N~7dJmqYM0N$NE6adKm*`1x;jvx`*jqUR7d1Sas^fYpR|lSR
z%s%JN=~vd!-6itm<^^$2-IiQ=$0E4P%=x+&Ruas=H!0t(e|=lDSp0}3i!ZR;O$S!~
zbLO4*kZ+0YmBmBYF&T?t?Dj;9l@F}^pfy+cZt3`Taq4lVXxmSx#I4?ZEuj}*q~@VZ
zO^*SMYp8GuLsL9rzs4P}xcT+PL&NhmRNR8fI`FnZC)LU@<`Og0UJ2mgm%0{TJ^dyI
zAUft%yF&v7IqvL4C^l8(Z~6T1m(xzy`n}AwlFrjmniaCdFt8fLa_3q%>%!~2q$IEG
z8Upf*Q>x%_5>HKQ;Mu5cI;GI5*rEwg`taF^ksp(ECJ`uZH~C#){cE3?(ucQ?MwvVc
zu962D*`7ck#YWztK|u}OKii3ih7p?0{U3eN_CLNUbm!lOYSQv-qi2-S8nl|^BPB1>
z34~P$pzSjW@WAG`@omkzYNeJh?9ValYtz*@V+V2eRHbOu2h`k=5fT#TRdiJ%FM7`>
zX0GXWW~Wu#B~dre4R~0B(a46@K;elm&ugh>&+mlAQjw`F_o+X4In!WMv?1Yt>8$3H
zDRIaYE>ES*wVfbXi=gAu&GQqMvH1q90lbX{`WKY=?GN-fdL3x>0TlFRI}`ADpoP{31vQ695~u{Kj};?k8%FioaA*M*^P(^uf`P1
z(GDC!bpK~*kg>_54$BlT%jai@x|9Yer@6f?AtXau$k_n7sMflh`W2Lm7F~QxMcaej~!n^vUa|r
zau|Ysn^qr`5)Wg3_~4aqr}%R664tl=xf?ceOzlkKUg_!_xHiLl=3os>(iEi^e#5C7
z2A~6ZIGJEjH{~^JF=-8_;D-4mZx4vxPao6^FGExGp^J=z9(qpMu4BjM<`5ZVx5zZo
z;EM0bnLH)5nNR^-j8vf~Pm^ZO3-ukXrv5bDds(;pNa&g>GVpV@CZR2x^H(3875}70
zTwgCAkyVG(6^l`lyNsR_qQUbpudubi;=w+DMNK0g8$vbNsAZspOE6;9)BQn&D52Vf
zXm&}9jAzMY#Tm%yKL?zl*+!WS*E{Fl8ZwAX^*dhQj<34vu)G^m;o{nYJEp39y$EmX
zhsz7)z~qjf*6l5N>!n#0@T9rCo3>uUwYB+^w-XxJ=UkS~qqTuF{!KIHy)ndXChm)o
z5V-fxnR1tzQ4f%}HM}#v{_HQ6@;`gtKI|&}=*)xDP9qo6dRJJ}gu0EvlHl2xst@b0
z(|iqV_dK@!V{cY`GV3-N3iAHRA6nNq?)T0?NE)3z8uGBC^OaIR?)$}@d`o40p*|ZU
z9Cd;}!KoJ%-zYj-#IBRK5&9Pp>W{pptk^HWpYQCmW7Dl7trbCI$i@WCT#4&sPh(tJ
z1g#`i(#uA2A9zlvj%Ss&y)CuUt+L6B?!6I4Bjq@@TQy!G!trk!T#&^VW6ywydy(eO
zqh9-+QlIbB2A~L{Y`T}xS&262+(2+3dyFQgtZO}B9`nhssI!}}RxHS|8JFqu&SZP$3xZY#ss=pv+6zP}wGS)0-v^6}7Olr&dh6fSRcc4oWp
zu)Ie6AELx58G9k2d91!ZucPGFA$_z&4cK;Iz^5iKp<9q6Gu^5J9FBi-0SWD-FN(wG
zI_(#fd+{HUwPjb)!stPlN0gb`16w}N7Fg>-ZJYgL~;HD}wTHT~2l6
zAKCQbA0$Vc_YF28%WBoiTHP&G($YGZTm+Bq>w>FLvT`?;gWRfwz%i(du)$n^=W&E~
zB7KFL2)}>P^m_u6x2f?qj0i)M!ai>IwwL*n7sPgK&d!$e7TQz8qGFN`1gS};NSddO
zTNn_#ju@zFhgo`|;%1qLzHiHX5x?J5#J3NTebI8wDR_%LR>A1-H&|4Hionq1c42}_
ziZz449o0!5!Pwog25lp{B}Pu~gJ7P^#sbC_jUG&0k4XW#v`5qj9;#i6RKRCNq1%7f
zi~qvjx;?vm>#Sx5K#41&j<}8s{g6$oD%00DIy|m|kI6|apu~lrJ)Yok?9TfQO(J*u
zZk1|KR&ndoEq)rI*U|Do`=mO^s?eH-NI`c?lV`^|*t)Y%;AMMPtOn<&YI5&Su0zLU
zO)HiAZ{#=~+k1JZzxS&=x+EN};#n$i2
zneW9|du|h&B$`^he}1)|_BoML19}D+gFV@P5Ym-g$xXpm7=7IX>wzTO$3moQjsK81
zy1f4uoY!=}ajWgH-B{4eM{~~_ZhU(XijZk*SVZOSBb`kR#`5@MZ|&48l&SmBe5UrL
z_9nD>3SaZ7TF#nqJK%hB;kHrP`p5qQXafMy?S?EO-^Y~I0O2<)t%`WEY2H(C27P+S
z_lb7>;1ZM4?oqU@ikObU9-jm-Dg7KY95ZJXsMHEZ4b0|X`Ww8HM+@s;4t+O%XZI>K
ze!%yeuRw-j%R$UoVYB#-u6gm|HXXcS>ZUic;L7qW=)CdnJdNE;h%%dmMaTDj3<8z|
zS;8XJ^XI3viWaLC#5jrC;wEe|&M??mU{6`hVCp*|GEPv?zUB-S=>
z`GrITd6qrAD5)qFPl2>m+ypP^eD7?OU1F_pKV}RzjLNL>(jIA{_PzHcUcp20)o7oH
z&5%zvw15(1QK7>_Xfcj%R%X&H$*tzu98vxFSywqG`oMoQU$)@t$X#C17w6O{UP9HU
zKt6ijVbXnQ^6rlk?*P8e>hQi5(Y+OJ#UsN0x*dN^W_QbmVP&wRiCL;Z7OjcW?&^E+
zn=N{A{9OaGHfAvCp=du`Qm9$l>xIY98SC~em@KU}^_o;PxAwKOF3A}S(%T+ps>9wp
zBP#8&hOcf>!Yr0PV~%GDt$hJpp$vg4Y>6ygVXQ2a@{QD&^0ef5&$nREpfXQWOA$wP
z=#AQcfclRpE*JMJ-o}21Lbdt*vcQ
zWl=`z^k!3~ON>{KEEi@BjH}z4>g!b}S`}u66M#N9we9`duCFe1qY(YT#3BeT_c!9=_
zhu48Gy^p~Z#3w>$hxSby0DgqV?hLZ&T}MeD1)$m6W9x-=Ao=23a|n|%lWiG>dGio-
z(IxD(lI=!Z_NwAe@zQy*-0eJV`NE&uIdc?M9|;U<2Z!M_fp%!yyTHVkJFpg+gH1Th
z;!H9&n*RpAWFA~nYJ!=ZS4=eW`h+pA&o+!~foUY~b-IC0k
z_t|*mT4tI>%=5U-@}{u4HVRKeR*yek4b<`8y&1pxlWqALc=F-v
zvrcP5=H56Jm{Y;S{Z
zTwsJQnDAa>CCi{C+~7WZ&*!8jO`*0E>hUvcIY9nGydQp{FSWk8B7to7Np8;wyiFfK
zHCHm%wWX0hSPmIc2i;sBFs2s7VHw&~=YG7PO--!z`8$1^E<;xSV2>Ykq2)nnk8Jm6
zXmm?1?Kf_I1IGFcIYPjvz||JqA=c#K()c)Mum>^rm{QK$04ZbK`eZgiiFusklazpc
zR$90;6VL`U+L7?7O1QH%-mCXb^kS|EO4UI7U9ULXE}!eF>NTxGS*zKEbY$?r`}vrA
z^16^!ZM7Gc9XrROrVb)2Pb>`5x|2?0hsL+Xg-h4xl1=#LhTCV$1tc9frt-Am1cvJj
z+-lc1(AXMRQr>$yLA%}EExDGt;%LVO$6R33r~=@)gL(-|)_42k`wNb~4+p(F;@scz
z%Q<{?RmM#709lL%Jl54s>9wFEJ$$1ve01$4wM$ILOOEi8utuMH6L%b-&AMejRt$6E
z>+z)XE~WHaHOyj8e1{|xtT=yZ(toi06@iN|x>>8qGUq#4gO+7o`a5k@pZo~b-&p&J
z<0C1T$ll?_Nwu)lx~q(XJ52I7v!$rd@uBXXKtQFb&rbv-kL>A%Lb>7%g}FOVmI%)c
zW!~@|k5;4V>tsfrniorB%{@V#_g;R1ZeR1#@JnZYMQm*{MuO6NtH}(Ad!;i;=;n{+
zY{qukTQVz5ha{Tu&i$y1f-zX_B?7?8dDd%7c;?I{^@o$A$OB!+|3GuOF@O
z2)WMQwzHq`oA`q%<2IZqfUHb&L2pJ_%Cfo{L0vQ2}6sDi%+a66xzE
zp4Uu>g3JjR>ml|v*cGn-4F-w=!NswkUesiMIzbOJrbnuRjC^356Z2Zd2yJ*Y_p3@|
zxvgTd;n`hri2jWg^8T%Ll-
zy2iX-iq3E9v{cO0ajeH$JbN_{&=E7yd*Qor;O<>RVV99nlMz;><3lkX_4P04XJXeO|&xw$9xopeOw79TAnusiq}
z;x&OA?aSz|cnG7(*mp}^*ZoBBG|=^Jk6jsCCnrZ;w$WSVBXyKx+UMW7wN4SbzJzW?
z@ccrJXj>YLFY3H<;SK|%dOd`$7W;2X&)a?NJAcnod_GEt)J5WJTsZgst550dk$pwK
zRFl%fbEiQ`ti9MQSLqz64
zlf=D>v*;uc^gbTQaJ?XL?0nX5hk1-K%Gj;s3|EFTnOve3k
zqLd+{?}txt%Gxh0?KFAw`jLD{tJkNu{sQvS0{o8v{FjXHV|?#E!a*gzo~PFLw{!?W
zDts>;Y@0A$Tb*RQm;TjQr!jP1oN14PRm{S7or$eLzaF`l+rUl{Yi>FXvbL*#q3@_5O%SG5&o8&+-hv&92Pwo>g0CrN#BmOED?|H_nlHKFYEiEi}ViW`7
zm088MYVckQ2sbY=qW!}6jINLTeQ0uojfu7Ph069qopbAB%f@KaX`zW=|MO}ctwi>+
zbL;CCajw_t6uwj+WCY*cgxqGU2U~C%)7gtUvJz6j+D$1y>dR_aDgYnP^$K)8>-=KA
zt{TwLvS~;svuwA)VeP#7S6lgV-plqZv`APoJaj9Yz1kx`jm_j%X4896usxzVcvQ;e
zr5}AuQ={40z>=N^ApEHVCAO~%C2FE=VhQFg$?@>IVug}~!|@%MAe$14A{FEhWHmWHKh>50vA|B_$V*%Fw!RIS-EXB(Kp1#b%H&L@wDQMYX=3NI~!xM>MWy
zJJ%v*xPY5=n=t&4)wj=&eEvx8$3WoNP2rdqMM?LAk_QNauA|+>2XY4t0N12ce)WaA
ziU4@XAzwzYKaHO+$N`w2`rKbAJa}LLp_`OVrSo&Gpq2U<>+i_)YoOZDZ$FE&+xx1{
zRX*M9(0NhX@)PLK%!ycgI{Wv}MOSb{(*;otm#+jO6zzZG;awhe-VEQ+nvwLBW62
zQS-c;%Fx8Fm%)lvxevs)Dh_h)%6Lf`+-uIJHrjdiz;lir4mc_AyC;h(m`WFGk=)mHP-)*9qG*?bGoueBx+uZ?=(F
z16$equb?caPY~8#Q%7BLWp}bGpLGZhH6Lo|{GM;uj8or4m)FVs;4*QCY?OKxv=L+?
zT8Vj?HR8Qi+DAeZ0!;+axpuQ(9KY#3Zw?1db@twq>#GZGTR4oe@xnXhm
zc%BTsrdnm?aXa)!oo_^XF|LTJHA8M)*^ISRnMl4;+3iZn%H6BIF5lIucTV2r>k4Bl
zZB|SoY$*+1Zb?>^&J%(Xbd^?YL(7jp@-;FV^4%uC!W%d5Z^!X5!UWTAq0jf>0T_>~
zZe1GcQW?+iwOwT-&bMdRmw)x`(KG~oBNB^%T5GwIGR-4;(eI0Z|J=Hh(Yd3nf%0VHM52O*)CH6N?z?GfR5
zj89iDmTY4%rSE)gp>w6)S$j!f3kY33Z!Ev{1A%D9Jr%COt+~#&)?1+iB~?mU?w6$V
zfiVw;6;5f)2@E6zq$u^whLeYNU-+OC|Mft=UV9h@NCB5}P4^MQgIQBxyzXCssPimP
z&8IVE%bO7wdZJ6RVsF4`Dnp+XW=3XOW;)ixxt?&&Zq9E{6K&r=SLKP=Y}W)uxNI*V
z=9`%r89EZW8T78hwTl}6_$mgJpvaJeh=%_sqAE-x*-7B%_ffsBo7x!!7Ju|v46EAK
z9Cg7A-IP+ZbgSU@bphX)ua)3wHcdl*ylvH%8ToNsY$V)
zOOkgbKOu@w*E|Z5AB*fC%C-WNS%5!-5KYtLh}EOAxCpbAR6
zyWPDhdEPCNf?Q+5i(^g;bN26NQZV1I5ypgtGq)0!KH{gKWH{GT&O?|CUAml
zK(T2m)(^cqruj~m;B>oH(bJ-{S=&z82=%%ZY
ztYkT}b;;Jzt@r}vP~5DJY@O_X{qlH%V%@~U1?>h1D|$e@lB`=Y8iW51$O{F!(i%3r
z=d1(rq{g(@ogZx0E|qNjb{dZzB!acejMsQAn;%h)OXGw-A7^(z*mtX0#kYV5LGtaX
z(U5vtes&(kulmg+7}0Tc#8r!z^ZF6eD|9dC0Aj-P!6Gkom6?H?xZR)=Uv!xAJ1#
z9IjNyM|sNDdi{KbzD$%8WOtyaDiG;5_7=8{Yc#Ai?8~rm8&2z$zuc}6`=8ON{}?=#+avX}
zP+!p-YFIq&eif$n?j
zgtNL0zkzy{k!2(9T@Og++mlSiT6ddaO*)44PH*Y!%BKTEVlq7KWu>7CZ_uosv{$zw
z3m*0+DHX+GcRpqM3OIG<}H@%35P?+3S&VQ?28R6
z7yBq$F-lb{;9{q%{0=$DnDb6_IkH=wZOrvVWFu7jMbyK#Zy4NqYt`)yYnrOMbjdmV
zxb}L6Rl20G%IVSJS{6Y!d1vY}<7y30mf@lS=5ZD~Y|Azq0$&nXRtq^B{
zXIR`fG7GarOK{Hh8HJHVWc^^=g_;y6AwHag;CK&j@}nWriL-Ihi4~&x)76poy$13r
ztHp8>u%j0iAJNI>pdF2`k(s9{>>0>y`f9Uq+Y0n>RqbGDyK{7FT`n4PRrSC=N}Pg4
zt0lo#%3krBI_rG(IwacAUVV;WPLu;YwQVjrgvvV>onVgw99^dT_wr`6xg+6y_HyJi
zg>Vjk?mW6l9lwrPKNAF}4R8Fy2NYCS7J~`gN4E!ZPs(ok=jATuOk-*KJ==t!9(e7x
z?J6`n62jA~yO>YHv|&r82x*)oJ4er5_McoI&sA-;U3PK5s3<5zp0`+Q#sG~IZ;!0t
ziyyXVdY))pI6fA^e}uz97)jsInm}oM$Irjk{kIJJSz;)#*P(NUh&?q
zRqZ6F2mp^j>3t=Vgu=R%cami2`Uv9d#kg);CL%pDMqCG*#kYPTXg^gzGt@Z3zI{Fj
z(Lv5Z#d5?mx3mma_YgB%=6xQBEOJfFU#@jM^Q`LZ2Xi^^Z1op$Lq8kXG?n<}I;A&d
zfes2XpaD(yvkpb1RApC{pRDqDPDu9h>)KY``?M*6Cv^-kaj@vraPB88zfQ5Wxfoe)
z;@NY=z&K-eT+E^b1iAtYW*eRTwYG~L+!_xq^^ZAup!fKV{&g)cD~AfsaV|=rh{d%h@vBtiidMnjUYY=
zc+Z$BzwE1TfMr41e?u~J!-GNJ{MnjcST+E>7q3`)K%n2hnG+_pJCPAQOLgKre5N|j
z4Q3GN=BTDWG&D;D%jPgt>%g~hv+l5hLH1qp@5sv`xq}@jseU?Ts=?)g#ir!AM8Vir
zQzoAi+4anK1%7MV&W%g4{7Hq
zjrDmEeQYH5CGSDwb&|I*oYA#s==10VDbJ@7=|!AtFfZK{vMU*NLJp<>eLHJMHh%tt
z2Y)ybNY>C}0X5_0PlVn7gJ%3;EG7mJ>O}y;XvmX0?b;9Kwj=IV)8AF{I)oc5d{X>h!w~3jg993KWT%t#1V+B|8nU2znk?DB^}3o
zNW5aWiEVbMxVfr>Aw}Myq^uI8?UbmW$_%ng@@w$0f%fnhBZQcgZFw?5fxP&yPd!7T0xrbQ*WYg1ySR{tAg%lD0&lJZrV1_Dt8q@byl*&If$B{g6`WHpF95J~z6u3%u2&EdMvB=2)?49LbL$0Zp
znxx*P{s|;2p{OlzC2%F7+@$FiLcDuC8MZP@ow)f^H{(oP%U$_k=EXgSIc8
z?+RqM=#J7J&R40fnn}Zu{V%&k0D-)lG&y^yy>EbgR&8E$#m3CiYp&m5qr4I{-kU$V
zO)@XRK}`Nm?}8*xwslc{lVDvpBsh{Z4eRMoiWdK5f&AkKX7b-m%YB0eJTdN`-0)^*
z7UrsDHgs4phdY&cS|W@HgH%Aa@Izj>0QnRdTW@>DKql`b@Nqn_^}pPy0fgpETW)Ap
zd^8yzMWbrXi;`SjQOSiRyf7KG6J&nc$3*teMX@>s0?e3)2a))q?x#Yjegd#=h?W1z
zpO_haG?rq3Gnmg(&m`OOR&szT3^Zxf+-yelp9Q{)(A4sDMhe(tGeS{ak>PbtI#*dh
zr-%M&ZHnuZxZddhla~2gYA|7jSjhuq`BzvEYy$!D5!5V+-nD$qs6Dfs-1!noJFT#{VwUEOX6YE
zH}~Ta67ve&!raMv+m2@TX8#7T_m7@IxNv3>m}y(f9l>0s_Mk3vQfg$F>nC0yBS0~f
z(b$~s#tO-Kn2gGs`%3};sh=t@{U2Pkzd|(rhXv2?e4yPOT`L-*lwfX5|25geze2h^
zfw1!6Mn#wdLLm`bpisdk;eAYB{YV01;i7)+v@G|El@vJp{bi>8kB?1|J|dy${#inS
z0eC!axh1o*Qvo%#35Ky?{i0br#}!zqH!ZL-Qlay+Jsz~94A=+yli(qv1OkzWG7;W0
znu4dkVx@+%g62xREhJ&mhq$DIoS?XH0g^jHct)t!>Ir-WI1d(z!wcwv|H_~K@`o84
znHc5b&a5rkMD5S!6Do;2=)VcJzT5MRBkKta7Qa%!whhV({4gmCbgI>O3KjWVt^QBv
zU?%>DTUhMtT7b!%+3I-`4n@T@-5jLiUzKKee4`3zK0o~IisTGqr0XJxHxbh^q#?=;
zE7X?1X#2OX>Gvkgr-Ry_+Z!dyu@4)E)JlU7K
zO)~B4zDU+EmH)4oRaHbzu8J$t@yJl!g1dYUKMjMd9J;||s6fJ5iZPu#`Q7(m4RScq
z7GW;E@rVpk2^@i+Y?1qV|2fA55R7X+e8$3buA7}&8y}pWHR?NpHvRVgGU7tSPbh3E
zKl2;hL5}hE1Su%e>)znp7)P2{WZ?DxbSVCH0-D6X^#{wCl~hJ1bj41SdTwodDd0!i
zFKom`6MZ5&A32I_+|&=bK#6`61-`rsl6+x-@QhnUxPt%uBE=!?KAD^U#=!^+R5LI$
zRWs;G@+t5XUezU)FoSjGDw~;n5mkJ)<;D*m-9YlVD8r8w8Ml4-3Tkmr|Bh=0-gmIl
z4_NmK8|ZN{P;RkMSv}WuQmc-^W~E_bWwq*0evH@@5~JO?elP2>
zS34+hI{=&5^CfrdAG$cm{8am2p`i(OqEHohyeym
zS0SrZ8ObDZ*c;7POR%v8lp74hlzZG?&^sPZkC$n;r8~|!cRvqa)4k|SHjcN^Lwju7
zpM)~1VSBx1v=n()71gh}gnJ8Mu%*Z!VB-QXqCcNQadbIFPZ)BHsIU2H*i+BQ
z5#u>OV!$xbVQO&+?id^CDc^@HCe6#qJQKr%JsaVW#awO6N$Z~fv*{V;D
zosN0_lXbQ-5$$z5ZQ|?E+6waUC8XeGu(r%4`o%L6j0~c-)6o$Xh|&$xQ`2%}4ks1)
zsHFIUxf-hrTz?Lg|M%y?flySGjGpGbZk#kTUrI6(=I5YmJhX;-?FlWx!7ey|a3e
z5j&NyODJ#un(dbs(LaUc09Qreyg@x|DduS6>y>Yc_ux7XOr4I+{I5&>ekLTJ_Kgee
z?f#@hKimeU3w=2Ib`6=A@B?nM;MAa^qpO(T9UF
zwY#P#I+G#~D2JsI2^9Mp|9a7X-F$SP*?>QGVfo+<+oBoNs}k(H^hkB8
z4m5$uh-_h;0XFpfZrm<4B+x^_)Z~~;K2sTxUh{hDgX6wh#lN$rKP^{n1iAc_WT&xR
z+iXYvng_Caks6bj!pPS?i3ZpQ#>){I=P#$Z;6jV#P9#ONPI0shZ;-w*$F!GzfVKVn
zbBEluKzDIHi)^1s7x!Nb_D@Uvk2&)fiSWBt2!V}hTE4%Sw-_n9g$RW@V!VQgcY)EFc(c+E{;erhx3NyIR_RzbiYGy
z5#AIktedBk&lI8i;A-5i{V;`ok>!1pSFp8azcVhaUnQlvk{hE9_
zG+OBL7f-(GKdq@cdd*~azO0z1rZb1r&|`Oe;+$|n)et>?SjuPF+_C)$ZQ1_0E>^iEpezr`H>
zA|ZaRUxUUIGrp!;+Tkn2xb8jN{Q&tuuL}#w7Y5)1+>~Nxq|-qe$p#dUQNAqU<-pgpy2qtXW-%n*w{g1SPd499_(ex_7dknSg&Yg7RZ*Q^d|Cvf
zc9dcnnk)T%Z|bPu#00x7$?EGxBJ(atJd%KS$#?!c!VOIczeXxl?zQ1uN624uOQs@W
zJ1wm%4a_|qj4NG;o$+b8ok>cdo3ybC2U9rFYcG;#N?*DxZrk*Xf|0g5G>1}x7mWt2
zVYAXV#{;vTZu5tWUt=)xDy0zoD>mI<9RK`o5h32nR_*jRClFtzZMewph!2BKWCKAF
zM-lqf!Fd5WN3g$2#d@#EoG;eb%}(stf8DhG?e^jc&MoihoIF=Na83$k@+ZpDb?uC-
zG@&_>8NbDtcqi{qLWRr6MJXu58e&~z8sXKI!yQh+2f{P1lyq?qoBt`r`3UiQoA37I
z1-i%M|H$h4>e%1Ze$>p+&wWDJJ;;G(HN!is`+d~tpSJzKX_y%oVl4s8;}6roe0Bs`
z>vBDAAe%&)O3s_k%bZehkeLOPE2yhs_A<4Nel%)S4>Xm8QxlYHFaPJh`3MPkW9wA6
zvRuMj8vtWmkA;QB5wfzwc>k7De3SycQq4#Q(a;FN9%`4-9Q7gadJ
zJ7~5>s~luz+u(3czKEndh`*ucf4_XU?q1CL>RDK;w1Ao*fIA~DCZdq`bc$B?9@jlvL*$-1KJy%I}Zqs0>0l(n1SCsrv&Vu^N
zwY%}r_AKQ(|M(|n2#D>;>L$rkDQMmc^+V;Dh=b`FumY$8o=lAI9a}(h;KBB?NltzH*PA
z3nkT8pLZWN^HZ&?;vLOT;>~0k$8@qZb7$ehN-{(;;UQ;n-|U`1&IUDAy&)%$m91J{
zl3*;z(}x-7ddHr{L!W7x`A##CBh>)Ogc*{zp%t-6i@d}zGUw7va-fw`x~T;!mG@@z
z_?2YHNc!ox>L2zLVG3DY<8Y~s165#vx8=Hz>;M^xgV{j0(>`;m9Q?5{>rg`82CK^2p00i~i%NC0kSVdl`eGexu|JExv5tHhmqb#j
z{ODrEa6U_^W3JUjxuDdTx_AA-3JWIelp5FICJG!6QlNb5#zwmmwOQVe@Si|B)?y^wHmfYlQjeTfI=p#BidmYX3aE
ztpiGYbQ7I)7i4Fw0-iSkEMJbg
zrYJYl(513k_x^Yv8U+MeQO3r``s#KCWV_c{(P%dyvdlL+rcSeb8Wn6P~z)P8B$SjJqM4Kr@cTEw~Ysvq1Z{2c&bjJe4fWt84jt;&NqkR-WEaG4P_3
z-JC_R%Qxj(GB@_jmEh;kD`E4vbDb}hdCRfkxS`#mza4{t?$^%@n|o;RV&3)8<$OPmNF~_i;CfCx{XsLI0e@=$n~5)IdIn7qQ_S;Fz8Z&Y8sfD9^0rjd
zeZ1|})?}?Uy|ANHv#G-CS=8ZZR#7&S6qrTT;C!ZqnaqfbLe~H_ArH?Suc+wqc;Y-!
z;7kXH=h4i!1qN$YSUx(X@w`X_ma|-xiZ%Sbo*&c%&%W|kHPVE+K@$x#;-^r}*3U_IST<_Pgm<(M
zZtQJLY}8dVl~B_@?T3j&<%h2KyVGSH8K=o|#Jc0Rn?LM&^M!TVWh(Yr39-g*1_fN@
z*H2eDsvxQW3SqGT=j}RIG?E$i`bK0|Y^seB=TQdHQJxwxV#WuNFO;piYu*Cu3%@gs
z4K+dL)8_$p*(%3aTW-LGHVX#>E2G8tegFf$zZLmQIOpQ|FR5n&Ta1ECa)9>-mAB3$
zDoIM-At|DXpkgRZycAKcG^e5FVkiW!LdNuuU?W)FMYDG0NT5~?0c+~}b}uEAw8!KP
z{h$Q(Vq539-&zHPg+|M|Yfh3fq2S&7KY($xCW+~m-*3;BtkDx!THGV&p|)3>tnn9X
z>>VH~W{r{9-H-^f>MZb6gS}DR79erdI}tWWQkz}QYq*Qo3WuoKF{n}XtS5yY$D4$h
zPg@z$`kW&xh?pZvmU3p&EJI^mONvc@Ch!X0Px_yaJ}uUxsk2Hc)7;&M2Zf4F+rC4z
z?}X|O!|?wJY*8P%wm1$M)~rFncHSlIBwFE0&Pl9uVOh-J6L9lBh6uSU)vjrXhS2Se
zEncCTx<}tu)H6`i)RfmRRD4Zs5(*k&^BHLf*B&ud_a>BkBbSCCjWvIFQ_`c4@Yc#(
zw|l15iHE5XJ$X+wfar$SgAda>+&+O=PtA|}#vY%#cYJ9RDRIMncO_Y^p-p8LlDMJa
zbcFF3sP02~+ZtEe=)MhGyAni>*@6-3rQG+0u&9SuRkNm23w-p+j3;RCjl{2A%&zp&
zQ5oQLvSCj5+L>D}6;6Gs?(k(b73*5uhXnA4{*bKKimM%_mZlQUQDdK4fyABa=cioi
zp?7b9o130O$t&9VS|DODa#*9%rmLTB7`vY%t6_oj;S<)^0;}9U-{NBFOPk654N{rc3VUwjQ4e7ekrdO;9+93THb533`qt*=c!8Yt)!{ny}Y!UqFHgE3HMby{!E-B4TMa<8|(nJYKV1l5yI>6FX^Z*QWC7d@&Ii#*;G}z&{l0inJS8uH+*n@?J9E!#hSf
zLu`ju*ZMH(a1uF=F2y<`y8vJ8Y8)lnX6926CTnGchM3VL7t?HZ%1K@1I29ea;6y%+
z`0?sUS`^_$^~7xh%Ro!vBUOZn;F)iY;BL#?xblz7!kseArLIG&p=YD=GT(z(+@%T1
zcbMpI=!#Zu*>_$Z=3vk4MB(%lh`uK5aSzYv1$<jFpRl>o;~I@d+3AU7IU$wED=^e*)IWN;BL;RLq_RQ>H9i0o(LO1VC^^N?2nEI
zd#T=DEWH!X)cjr3x{c`4%4>MUcl!lWJo)m>WhiF7uf+3Ml%Hls5~5wXoQ|(j!DTj~
z&_^OZKKv&C@}t=rSoq!D!9GbA#;V0k!Tb~H3|5q2iC_$#2UNma$?~tW7ne{R^JUif
z-xa?T(zU%YpDpc*>hO(<`LdKf6Ll}RiZ&2{2gY#!dh6I5rfL$q@S!UZq07hjBWUEf
zL0n1-g^~WID*cGlW6Uq+-sRkU51vj`tzMhB#J+K;n
z@AjztJ8;ZL|=NC(?0N;hSaNUKS!;6f!&
ztKbF;0~<}DV7pW|h9YPkNqBX0vSKWHAu>p}#N~V{C}B#`o6dnQAMNM=E!-bA5kqjy
zFZVN>-d!-E^NMDp1;>TmrR@V|LCVuH_uhbPi?9Ealys1opof@&CjHxJuciDqVK^Lu
zK|WAI#~cjcBU`2^QqG@mm67L$-`u|r!)LI
zhEJOa_*{qvLhpzn&R(?PH?>E5#z^zmf5ajq5;cv3`wGmcZ(Fe`DX9!Rl|41*MkPAi
zb*Ivp$&TGsrP{e0M8&p#;<*3|GX?5sw}$eLH)FnZ_YE|fGKw&fr}v}`w?2_pI6bE@
zFl>zECLQsUdc)c$p$6%@FheYZ9#
z&8f)_Wl@{_bEFJPS(cWV?ezoJx(Dcfm2!Bfq?-bBqcKOcY37+}%EHiKbtB4EzEyd3
zW4pzea-0OM-tB9VZ@1Du6u-_{_PC|0zce6`ObO*bUDo;O^e~KSu&IY9;S1umzM~-9r$9*
zy8O9QpGR;CoF4f6N=X}5rl-GmcMA_W%;Bg~HDRb)R{61C_Pe>Bl-uoKhQT_xI=>
zUf7>5L=mTVI-c&BA9ph{$dz&ht|KtWRF{gZBOZVd*y*0B9Fza-{ITLQ
zs-L@@`06Z(vzbHGUUNnM)E>$OBS8`4T;`?d_v)cR02y*-kgfp#*rpt4Gh%ClzUak2
zyXt;7;_j#vgLfjT&33OJ@OU`Xb2k+
zGQU5c>D)goQU%($k{jN?aBp+3LmXwOWYS~dO#wl#-XD4vFEy?{jrUCKrB`w38oX}Q
zKOBSG=Mrp|J`|z;_xPA?1q*a~6ZWqnAXqsTvj%g@rHu_a&P}ojGz_*(-7)tZrA(yo
z7AE@^rWGaH=mt-ZDJv?2ZoovZ4C6^{lS0Zeo80V74C0+C8V!J8Nb}e
zI97d?P!AUs$}~}q-&ilYmKrv8-MfOZsaDezoIGp4z{)VU6GA^LWK^(j$k#GQZS~~^
ze)o2?c0o#qOuJt*xJu1+XU0@KtZ!w#Z&T$6bak>`Ve4fk6tz2S%
zHWP=vNTz?!s0q#2dn8ea+en=jKNV78F_IHsG?5_rzghqZKX>C>D=&{DEV;gJrnq6_
z<45icDSuET)|ws5u@ds1vXWRtLq&zjnjJNel8{Y6NQc_q-H}-Ig2Q2N?^Yg+Tk6NM
z-{(HY3H?4m&KGj#K6JP83gbU4B`evhm%PhpHa+l?i$oNV9PPa<65*PGF{DGqBrxEYalI|W`1U04$m8cl%qGT+({Dn94@wd0u@b|XT-IucUQ*B0E
zyDZg4a$tRw$=dw+_#PwG$Q%i730%Nm368_`d9)Ybx@9hkmgBzR&TiEq2QZOzIbL8+
zce!btt;`CzJ4+qQ9zNne+7eBRh>dhEfhDUuv&U}@GdxlzpyE;R(g|TTSUt<|c#|=j
zjP?CvOo+OZC5u>A*nHFF!;%a_7b4$FpSLh#6Z{AriFMoJoq^UN0XOru9C=|#htOFf
zp@8^Ztb5&QEj7+X{Dsfc%W-%N^>YwZjJ;iYZtS-ac{jn$-2u0D=#|FzjhW2Eb2H;E
zZl2-hUl=SiKCklH25|_AHazJ`cCohar@!Tqx^9Y6Tl$kh;#G)fzAMfM6#H
z85toF4{k-pr&p1{ra7zC<{oL!leM*lJ?uvZer@HvUJPc
zw$%8N#r#Ez5ivw^{KknqbW-!Srmk
zymcB@VML*js3a}kMj*Y!*v-cnc}<|yuEp?|<2D=3A$uj*P!^Ndvi2RzJPviXlWh&6nWpkI^pkNmC{)BZhZE=W
zEV`OPV=@*!AiejTlQ?n4c^l^>2xBk}TJ}Z5NFR{ED^WMH{`gW?|H8RSui}*7@+OGK
z?{+$w$Gc+1XU+4|lK{Lw)pt{-S_tc*Ez!zymj1T~`MZM?TB7)*ehpzy(dM2&d#w}y
ze(88xmI7R+2(lsiOZ*7b0m%H7N*ssk^%W(HK3s^?K!w%l6f%Y--?W)0ZrB9Ps+J@>
zp|_)6TB0cf`sxa-Ui&@MuT;gDmYvHR2^wDJsHMq$rnNZ9b1DWvAX%`$qKCe8DMilK
zPx7XG;17Mx(Dn-7H`+7Y^DuUlG}tQP3aeqdXyN)vpkv6&nHeOHO%~8#oBUe(+DSoa
zbYqGR);N$9Hv4U(TDgmi3RO;H@tbF})H20@mHQ+y1keX0e>k?H;dC~9ocK9Wr^u7(
z3L-tdbltsG#GiPx@)JObcI8uGM&figMjb+joo#n^;IC&-4Br~T1ndb7pW!yLrK#OqxM
ze5~fDjt7gFS_>1i>RP%%5-i`pU|WNAWg$Ebr#@Nb>w>#^I8b+d#~S`D4qtoMb~%Y2
zSJjV1vg+PMW)R^|juLHG&Q`8c-ha!e5^Xip=!{sO!!tE8}HOj9dJoxGek1C!Ih|`
zU9|3$ys$q}NJZOtZAR!v#b6G?5!(NBxPp&ac)*^N=zC9vzHtbh$khVX@cwg|s?l-v
zm_?xGqqF{i8kzKa-nr0OYKAG(LWjezuF8_j%V?J}Kyp?1%^PzsGpFyy9@QQog#8Kp
zXLl&rz;%2`Sc9zVHjnL|jL3G8nKfX8eEw3UR9}VbWIgCd
z1D#)W7sAatMp}%#^IT0VpZ`Hb$xsF?5@dqPsKPG>f?>1InM1DjOprE1K43AqN6zAjH@pj^X6{0Tn*e
zZ1CWr+18b!tn#xo(VQsH;W&JkWb#RH(r;y6K|
zQ)~SGa;K!`l_p0Nl`G-$3H5!4Rm*#1W^l?d2Q9D6n^^#)Jdoy5rxqq}q}81czi!9|9a%~W7w
zfkFoA=73z9e3vJu=+^yGRk=uc{Y6L1OBnTqca*nk%vgvBKhk&&i22xQ$++fSa0{-x
zlipFOC225GpV%i3XnYTzg|PN5_+yQ>c6(2!vvrv`%XYhRC1th~
zyv|7}Yb^_>+?MO@qwcnr1iqCeh^L}2l#s==-l7m|utFDQxP3xU)_^U0y&YM{fn`(H
zd+C)-o8Rhp1y|%rGmrMH$zE_{y$uez*WI59S2!0=Sidl$yH=_y>(yC_cI=;LxOFSi
zS)P+7)z-nSQZDS1-6`tDs1LREH2I9N&T6J&=Pfza8vvIsa(&uUo<~i1oST>0zKIu`
z+BE@JXKXLo0?0tkg`u!uG`bQaP`7#C_goKJ|7`OL|YXiyBS_c
zTs9Xw**^wfXLK#%5W=;+VYPG6{@Y)_CMhTv&&uCu$R|IK!xg^?HxW^xzpOx}_5)4t2=Gw}CuXxI
ziM2J~ljj9VgM5>I`tS~MCYMgKTr!s^xiwO&F*S~@JuZHS*s73J*f&N8&|
z+@PSlvZk$S$z52r!|#Da+z_V-&dB-;;?@VuL~SRD5^j`HOng)^h;hQV{=^5XGdOvI
zi?+V-msE{XsW*Wc?9<17R9fJg{sSSsHWbAz9)hJ`CN>4})H`EHXPpNF7n|lNl>+Ba
z4p-veZ7o~)fWRO|EZrjl+rkRGgJos?1FgM=sSpRWnDX@EGBMTtMGc{;*Oqd~*bm*c
zzqHqstv;RZSC*D}YWlgCN_I)LS%d~^jddk$>DwOi8-pbe(}(8)OECFqY3a6RsBp>Tuf&W~#nhazlQ?^aWfviL8V)q>gocHlR@%gq)1G!n?8o@|cE=rq^Q)WK<5mh~q^}yFXvnb*qQt^Eyz`;yXi+
zV%g>=KMd_@XTNKKbo110GjGJmpU;0K<61y(1H~xF8n9$@q7qeFLURYBRibB3mk^*&
z5YdV*8{R_c?r^s`Dh?81hvGQ*Mbd95+;3P2oHz+wwz5|}1%0{7r&|ktzOPJ3IA9ll
zHySD;CKqIXw*9bIwnjQ-^`8Aj#{~HZFH4zx%F1{^%}u}Z-5DIqg4*(4!n9^=tEKmA
znsVJ}R_==t+<6bF&cp0^1N(Db19Xe>Tz?9nDoqN%)d+rpO-`I8A`X`99b{GXi4R8;
zPPlUS4T3+a%+IYOznr($DGgOosrAcbJjiw8ujAqLvqY
ze^@?2+T(3e84rqjIYzm{yuW`4j#W6%u($`)@cBTDBh}YDRXvsRJr@O1c_jf0BT8dg
zgtTn0nZi91U9
zWVwFGZVi18eBE3c#r=Ooy#-qvToZafjl?o#2$>?(XjHPH}e#
zZoz`P1pCtGJ?DHsAy;DL~XdQy-9Kr`eyo~cQ@ExidG+#5TDU6uAn7=8z75d87(`K5{<C_h42Yy;prc(Wwb%4)R01i<6+V
zNC2v4k22^{x@{rhzKd=U7xV2ZQ>*3vNHu=k{0dA5=O*gDNVDe6QP|$VNfD>tFNN=2|;M4Z?{^3lnz$C8&GBciw
z@NC?NDOiRc^S&EhO?;9G$_+Rt6W?GP>698YHW){A488JhN-lS-M2@WB;!|;P=U28b
zaVB_b#G;eOH0DD;kNxNwS9IG^j2HJ->1zd=2~MG22DRY7>M=KWC-PGC9{Ol-$D-Z@)O-o{0%5zoH!`^*@Yo%&4E%Cu=uE7Nt{t-l<5%SLF;u>p8*
zXUJL_=dBkXi>(o|7qRHdQAZ&@o4m=|r%qUF145alO*)0)tlq(Lnd|!n`oP~KOwGf_
z1<<EanE*anOJ)KNPbHAjpNVPbx(FN+r^^F@1G;B`l
zqw%5ZA@(|dE5!42%u-giIZFKS5<9?VN}kd}o<oqNLpM;P
z`xCWLdvkakIBe40v=wL2?l}F=_&{gVeUyGm3!u{1l6ZxEjq6
zfzg<*Awr2bH!KcI#aY}ceWNoK%s`5d$k)q`)*Fu7@@_W=(LZmtRB}W#ZPr>56}#UU
zsn-EaW-M=m?yp+#d=KI&I{MEOR10eQTJtXw1zx^FM!`e~V*8JlDzW}$nNvBA8`7#a
z4~;k0q9WJYfUGGS(IW@F>L0yxUbb!bF+8(~rsbueQPci)`0J)oi8#b2_N%Iu7RR8V
z`FsW%x?_l_D{s`rux&Gg1|N@Kb!@fSQ+1~lfT+5&UvU#8QR<1{rjk8PzGOfnzSy+2
zS^vio4NKX|s5_@b5;0>2g|}42O{G0RL(7TG%fq<%SymF((X!%G@q8C`KBi1hWUPli
z3+zU`Ip3VF9l^Vdl*+Viz5V0u3y37xS2W}54uLA$4&!R-Rsa^bU2Pwg(;;28II$r)vXseDyN|=~&lakqEJ7#L1GjS${7wH2JG$eq5SL4N6Io-RDD(
zUpQ&{p6lto$l=iS&(eli!rE=(mP5(xn@2Gt)6WqkQflOFdUP
z*;2Hx;ox~1!=b^%XS_aa$6sQ*O~hBH(x7c|9d|A{J+3_LIaZsJ?5Y)0i8Y#D&i_ou
zN(>VL?|@JQTbDOSqFHz?f|n;O#Jn!E+@NWU-_bXDf!-*_AXczuNysXtf2yEZJ=aniIINs%Hm2wB5|9-!PO&_Q;gJB<5mV&3a2|?QQO~Dlyswlf_$|Y;
za=nALUf-UCHr}pv9!>#g19bih+>f%O-!FpANx$0qowPA~oFMR;kN|-uJtbVHBACwM
zQ;AIc*-2MRzLq(viTRe-eI>fA3T=AiI9HCT;I%>j&nB5=_E+G#PivRo>B5eFiS+K-
zOg>a6pZ5M0wa{6I%_6`3Gt!AL>GWB-+Ws2VZCCV4n_rwni1OC5Kh>Tq%(UcIj{H_T
ze;ix1gn4@(OP=cX)I^{-tBp&&vnBr2T<60g^T~TJK#cQ)*v-}uz$K*dx2qfJ^(O6Z
z_9(S`hI2sn;Ebu$1u)Pr=`9+w?3;=l$Y;22Oi9vK%yl^}fCC1Qv>)qurOM10R#P8c!`8v~v@Uc2BY{?eDCs
zX#=k7d@`>H+}V6JtH)0?m)wb+pYzuU&%aJsyOwV!o~I(DDH?-s^yMU}E>+Evn&35f
zs3)ErPQ&3Js2Nz~`E<6XZ&>eh8~|AyUOgE{e_q_1H~;zQ(>mdP>NOh!ZYa~q7ErnX
z&1)r^tCz5BDQu$Jb08;@qQ!FkK60yQqlCe|RkeA1FM4D*@QqA(&VQ_^D6c-|2SXN9
zABPZ{(HYFZ@am5zrwTVa?4;LrtSPkdfeaBWihKh~<`+Ti)1Yh5`rDDe3yCqCIx#L@
zs`Z#rlssBR$PXWnfBy5s@=~KuH-8aPUMJEJdt~7*fKcZ%t&~Rleop*pA#Ej>k5x&j
zLx)p@ZLZ1iMgPrS6oNnHyua|dsN82I2lfA*9i^gR9}gFTQ9U6@LJC5`Xq$^z{kr_`
zXL|bfN_{fQ#b||y`)rKRZW8v)n|c`wv(L!X7yd#L+ylekLwbfZ3i(MryNK54fDDyG
zu392?ZPwi1cB+L#6H8ltNs>cgH&quQH-sGCcV!o(c^V@GehE;g(J);_Z>Az?e@HLlX%Bt1cgRMlT;lw9BfQk^U%mW$*n3s5fqg(A!itKsK
z=n?D);7!HZ`!aO6-e||eZM|vD%4&7|xH0a`uFO7ehDYRgzuhphlw7}g5(2%@CdPDL
z9XKMOA{;2*PIxG)Q((fjr5KriB)iJao#RaL=0!XT?bc7|gP3E-o@tkJ@VM~?J*MER
zZ7_=pg@D@e`8Sud2s=Bj+Uy&n4>o$V{=}yFIS`YP#qWaGjkqFsz-JNZc@3UwYhuXX
zXB$TuuY4N$e5(F(^qMP{m`we%2u4CmZ;|BSSDhIXV{tNfNELg+
zumH92>;mn_islqMjdd?34>L}^1<085Mw^N3I*j=7sE4!#p(T3onMGZ&32gwo)T|y;
zG)D1_a!b+1CyU+|=B&}Vu?6^>?=X|+7zn}FnPe(Ht)cLy^&Q_^VQgE#=TVEb*COOP
z(n93>`$DQl!yT#J^dF;lnMsy;DQ4|&B-+bk+M}`^qB1V#+&CtZtiX-xBk`GibQYaQ
zc20y(M4J0qkMEABU4MxQ*AljWT+D(>0@LFNzl?{2f;$OFo@w`;VTvp=+Ay*EJzGIw
z4bSgK7AbdN^S=M3O@J$`Fp1zgWy=5vn^3aFr6jv6JMI!9@WrMIotP?PN-!d7I
zC?5mdWe!Wb2HV%853v2(cc8%<`#GdUG*jS8ErkM?)zW3FcDE_T+2g^vk`lOMviW>D
z^!bk$rPIBR%t5{P5n^!)U1Rn*WG!WzQ%B|sAkV9P4oX$I*Z`8I-2CVGvx^wxUXj0?x^6y{U5g>K@Q9?;
zczS7P!n}0s&@A%KTS-tD7%+LS<2HDZ`Go1oHcB?vLk1F
zAI)UTv4)T@zwT9~^AhtCdIbrIXAhC5r9WwFp1Pcj5a5e&yhsM&oU@QA1Xh)XqCM_Nmyc?@1B6>7hq3q%v?Y
z?qB#{-o<*8VhfxM&NJc5V6^=w?hg`rPsruuV6tQ7Gw3$^e
zp`bDq&&-n4613*j+rgzOd3Q_(TzGUabd$s~JKc+3_%gollo_r^p`a|Xz6e3+)L>4$
zUD^Fbr?e}UWMFPIOcacrde%lIWAFIsIA^?%9h+SxDJD-h`Fz4f;Yup~w*hMMM6Sv2
z%egAL7X02@ZWCvcN_!1`Y|NMm*hHM=FK4f&iJGsfh>P9F*zDD=I&-!rSP*^uVCZ}i
z7}XG-L`oF(=99sv3D%I@H+sAJ?q#R(kXtNE!ZMJiF;*kSeOnr8tqhOWW`OSht+}7P
zJyBu8g&+^7RlMoPzZv6D^mjFmqc-KbC8qQD(V0RLLQ|@TLmH_;H|~O)>l_rDj%8E!
zb!rE?d6!^$6KFIlRGW;0jUy1QhU}A`yb8zzQ_k2F-wa<6vCT66GD9T~y9~;frTpJH
z#d&{!vyxOPV-LP$Z@in3RWS|t%`N{IJV6XK)~p^+Q^jB8AI`6)Y0HQ{2;I(cQ>U3^
zeQ#(;qZytzC84K0If^5GVlYk9(UbSoYqeRK@&5{Y_BK*|xuxPe0K7Ign)2)14~Y&R
z3Q#iNj!L%`Yp~X>G3vAAaI`zQU_&k4hsn`-Vm8x09hEP~pdr+YAR;qZ?6}>{nWHO*
zfjEOBBL%q0>Bwak2L&c%Sm~o?0W58BiX*m7R!voZA*aXQNyIcle8lmS9p5D#MhIL@
zE+3@&2G7$M@e}efU=ra}`8Z*h-2}W`q
zrHX4B;o)boU+g+FKykF&84-HE6|5Jls9%PwW|63FzD&p48~|jbvWr$rueA2Fwx>Ti
z5^*T_+3!=ibQoc#m9~;D>oa%j+FoaTf}Gp@(iM%yy)nbDcuL~LX7rykHqb=0uk1qO
z`N({)_F|&?6{d>-b(EUq%!@|mCEASK%;2p7A^dgwSrgNCnw2MFNvIh8`c*Yz295G(
z&qOdcf$OQ2X^M|I##Qr0d=%y{l#H5)-lWpDu`F7yp`P=8!|_c_3?>mv&S3jK)bCnR
zi!9Eiy4Poe3x2oZYO+%MFAY1>%a+i~GKahJKVL*6LXCOf1`#0<gQ2Iy(sz=TXi=cvwb;|EG4S2pXi4lM`qK*Wg$-RI`Fv
z-5qzM^UvP~ea~gsz4Ho4K9o|Gc`0S5sEh4iKH~;1sol5L${cP=6b*lBT^wi(XS$U&
zfl}q0nLHU-_aAucm4>IY{I=0DsBa$gFgZG#jMJql2kH@B3S`x>HXhV;tXK4+7FOvm
z#*5+7OxEC(ab*wTzB!J=jl(xTkI7m2OWAfCgmic>)j6d{#K?-F;TPhP6Y8flS9i2#
zzn+3-jZ4@9^>-{l27s4|l2T^9M~+bE?AKf0KXa+ODn_rLpHMiYYz;{k?N)zh{2@wh
z!V5)BJ)J2xW=UnorP||_1gD6)m}DW!>V6K<;;Gg)XPIXt`w;t*jY@s(MUMe4PH#BM
zsNMqKew~Ow`4o@NXD6Mo91H0-sF~8xp)UY5I_pqL-Z=x3Eswc0#t&oxaYkc|NvmpQV*hUmXA;UDH~OKok5oMwo-MHDci7l&s)8js
zACLq`1?!uE-lBRYMV?LwQlptMaEwdG36gb{%@w8q)6JE_^B8Q({qrPwI*$c~a)zSl
z3x<6DcO0&~+PZI5KWv5KJh7^L0gcriopqyd#oPKzD#DDq_oTPdzc)BkxM|Rp756&M
zjszgOaaN>yO25~g9y3NCM_~2{}O1U29-F+y&5TX$I9SX
z{R#5P)zhlf<&ey%);zR%gGsLd5=EsylJneCaOxZ-$6o9IokwK9rcjI}n#}!0N^4zP
zg0(i`8(ykKCOy;mm}~_(wr5xw0TR8ydEiY5fn3~(!5{Zf{EXx~;TP6!f)i9Auot@>og=1%*it{NeoWX4R;
z%}b}%OPo_b11!Pj+l@lLY69`HBEQ+lVgQaH-(Tus@fVHkh-|1tS)Eb0x)tAyNwzoi
z5OJFHYcE+7T{-xsUP
z-D;u>w*#!tC~Y=wM_2~pEK$4!f<*^kR1nsTz%QgUFjF$K#9>}il3=>rWQM7s@T#HP
z6Wgx>r1v)fI*<$bv%WscvwaPRc8#2VVEFy}H%$cVVWb3p%`}mHA%a5H#VXJHXF;ME
zx;n{mjy*Sl$k@j7s*rDCF}ebUom!W2_@4j|{5W2=dx}ywvGZfAs-Y}CssTh=pR1L9
z+`OE0Nd|?o0-To%Jr_F%g2s(iwrEZYQh4!)xeo;{51q9mma6*Onmf&ygaLY}Rb~C2
z2e?~T)he;G3okN<^Yv_RPPqDt$TfBraP;5H(rt=$k_Ondxc}e4{WE+_0iEzC#68Bq
z_*{Wd=Mpk^Xigz5}$5ktxD*YduCo2AzHypy--0h%>_-+;HCFk8VUE<8j;8%3Nmc;L4{Z
z&W{1GtM_m2@5)U88+o(zV*L{kD|oF{)Q1H%iXH?=%tXj%bAGeN(4ZR)B11bAaC5i
zWp}$So6!pC`Hqj%dK&K7!OIB`V;cqo950vI&%CI2%YfK_5PSt+&TL_=!Z1MdVN1FR
zCkw$u>=MnG+1|xH^W}8p2ddgx_mlY8OZ2zr4kRLc>H19yOj3!@W;2G)s`arU^1kX#
zu>bN;B(TF)wa}vBmuFg4%qX8vb4z5`6p<(tx21i~cX=tc9x6NR@`$3B5EnefOl{(!
zud<4_ziY@QdU{i0+c^6c;$t0Y+0n=m&%cAwV
zn+6-Bee$483D9*|*~L8|Q=V-y`C2x9LfAHm6VpSam35#yXv1nQ;O2UnG0|Wu*``W<
zlEu=A!}k)??;ZW8R)n|l7}F;onijwiT$HJnncQc!ai
zq>tmsd>T%VFcNShGjS`JlL`4yAS{w@<;c*=ai?(WW-@osQ
zvuHkmGQdweRp#2>6l3rALD#*$Vg`Y{lsQ{&nQllJU9ye28Q7y5&U1+y}Y|pc)OrpL7}m*Fl>=
z*rRtyQh`#EubHnvaW3NBx)Uqh0?^3hUy%*#mkuIXQyU@Mo|%N%r#els!%DBJn;1l)
zGc!-#x+`~hiX@x=^iVVO>5pQMjBOsQkt&~Qce@`3jl#>}p}DJ+PGPDyJVkFPrUzKa
zEsrMG`%Sd)$4*r7dz_uB0G!DV&XX!U5U)`*e?y-?x2j^tAkLh7Km}gne;H<`@Sd8x
z%H8r=_&z3o;~B2R3CZI)SxKr=RLO_6!gmmOSpY(M}ao=0$)T-lVHe8cloD|VNikKe)FtC|8SkZNH3c=_K
z+6&Z<4Sz5_=uv4|>qr@iNx|CG(SDhb*}tSRz*v3{hY!eO-7`y|)Te}EASIM$U3i!F
z4U|P(@eA_N>H2&Ny4Ju85wikB+&!9Q2L=_<*a*4mi3}8c41r#jM%xG-6HiNApP0aP
zYu~J5n)hvz)4v}X6|F&ZKU3%8hKD_1sY0SvRr?FKK#dY^<`P|e8+uwHXzF{$qh-3g
zX9=-Bj-wqF3nqUeq|T<&90DZbimg9IEZU%Gasr53thcMXOWNnho`9Jfs-?}@v?9v#
z?^ES)?=`o@QO6U8L?%Dfq$hn7gTabD^#_R@Jjp?rmbdX9^fJ))+q51NsqQ
zTEmz$QuiMpV+i@fiMkbqQ_C~1r_lEeI{S$7k?z_BGxx@Vs%jVSTT8PbEyEx%J46RL!6P}Oz~yx
z>;4UeA=d5|0u7K3U(Ucq>*Xas7_4
z(kMYBe96OjyJsWcz6%)sM))1_CJe=g?)5*Ol|$=VVhq#+6Et1%b@Yqu;C#5LT1b+K
zX(&b{;fJ^+L%a?E!ZB1>N3SUGJjfOiv#3*p7p`?(>#$JxM@1~ScC8?<^Fn-$*57tw
z=-`=Tb~#yggtV%qNncMi?o7md)Wgk_xKi`+`_?|LtxTfE;X1|d?6Hu)D6KvGd?7kC
zk0>V(6+x!~$4!8ON3^Pn{z0WpX>7!eb4!~J9G!cQwo9x
zE1T+YSHJcci*%hLTebmX<0qqDk;DcCi+{(TPSY#1btRr$JM?A#q*6+|h>B
z@E=SD4UF-o|IOl2_^?YqFLG(_CG^AL1BHkosglIpO}0Wu^%$ze6HV2uu+j>D1j_C{u`(eKd`Y6+!ATk
zpGB%Q7CUpAW4ErJ<+CfxFRI%$Vp3IZUN@WXWO&}^2#!zo=qjH7**y7cEMn=O`-g#w
zocjYb-YmIvt=(8jwD~sVBX$+25|)Gmc{DH?^>DCO&}pvF@BA*jl3D5=U)4rH$Xzi6
zeSGaNw!V#L@bwuyCYGz`X;kYU0-H%E`OH5Ezc`0^A*gScS9jeUYeti8d8G5hBK}xO
zrPQ~htZ0X0d(!{rex#Yu_$1t6fg9F#+{ofCPr@ap)76)fC_Z$Hoe!3j|M2WIAk!c+
z?zR!B;K7=D5X*IABx{z>`)b|qrom1a_PH8UG#$1{a5ruQztB96;Ke}v>Zf?Wi?|Co
zDyFF%Am~>YH!%!;fnA{*`J*36*>4nX?RvRXtk1Yop_jKZxJoIJW4@YXcT&W-?k~!*
zzSv4_^2-YlP|8_t=d2V}5v@sepM>tRE$+%4gzoF!3Rgm3Ee;ES+3^;`0IpFCg2YRK
z45x?5tKUtF=NB)<6snN%bZh1`q_R2kE^VX9`nn%fxjkd(DqTkSI!!qKG`U!CDiRbo
zUX>{F?ws+HeA+DGO@vmJSVMR>w$F|B;FciSrCIUTmbrxclRgU;dAsq
zd5Qc35H(^TUG&hxczR7OA_>}%b18F}S~Vfz1kBmqE2MHCS6w-N9iMT|Eo|r@5b@l3
z*X7Y7w7a?(p;^Kg=clP5O)&K$6}=$8Uz=d=lN6|`1vr;Rj{{sEO!ZxCQ`pbS&}^>*
zHh7LVJ0GAAZcLk~~8z)41%wTedJ~Z^qC%U}rqC9?nBvWwm@Nj4Ok1S5@5G;67
znrJeK=&_)|^76=@?TGR45_&P+87xYyjz14O(FFkXz)Ip~vfN!KRnNGXc&}(I=KGrY
z%!3`dR-3$X8dw$ar*x%GFd8}1R={Sr^?En}xDm$fU?CmTxN{VD6h_&w4lvN8FXCyC
z!bxX|2|PHCzYdZdn*`okaCt-0odPd*Ir{0-%}3nExvt_pF|oDcf;Cflbh2jHZqh7?
zP${Lm$fHUI1sER7I`X`|!c$QYmECIjeEm5E_F{ZzxIH+B71@Jyza
zOcb+jBPKJMR`hlfK6Uf+#5gp?OP*Z#P5=GullT`MNhqU3Yeq)iUS@XLYVnRL{TI5L^himWs{URkfph?)GsK8V1&QZ}672u58b
zL$g7)>La$yK!;&OP)c;Lx^BnobA&NLpzHr(FHL{KILyWmtZ$P7&B?EDa~V+a2_2l9
zQyZ$97dtI`QIYz{ytIphCK;43i-CPpiEZa;oMKCn?N-V76FddxjBTb;e<_&2NuAi5
z9p4s>VrN`cNUejPs$_;(vXJ#PSM&s+xvffYsY*neaizORNdZ=xnM`9bC)FMQPcUWjL%=Ri%m_MJ8=a`L~{QQJ`h
z>d!&%;&~Vhs)Eotsycoew|#kQ83|c_#t2%^Q`8NfB)0h`AW74?zXsxDjh<9IW}Zm8nN^2kd%V*kM2Ncp>z
z{aDfQ_&G-NK@hdzMQ?HG*qXgu&qY3n`r!cVL0IN0NSC-wY?5iR@d77yp_Do=wfohg
zitkT?C9I$tov3QyiSfd8g~)K@H8b(X)s&N=1)Q+fBynRQMid#naO^PwLJEV;7eUj&
zhsRKdhkHzxFcZKE8Tr$0x@&qf3ohLHWgFq
zX#V&BreXIOStcF%OEdmVF4wG4Qt!QM&-$Sx|H&?VR-1jHxE!
zR{)8;%2gCIq2^Ip7KE#tlJB2Jgrm#R!tgC$uz?JsMTWLN*PEK$sSKD(aOafML*a=2
z-?aS2{=76arIVss3pgvAXyEfkPI0XOE|8aGfTIy_tU~Wdvb{07^1`=O67v9r^e+9q
zOlejZ_VRAmozzqLNb*-X67G1+9zq7Db&dLaWOH`!pU-FLCaAd>OYQF73T<$LS|S>u
zd?=K`4B?L?(eOY6UzoeI)o=}c_vMV)d6puhtcd+~lbynrtI_i5CL0|nLkJ~W7=o4>
zBtVjw=oQFY=Xy%e@iMtez{$+B$-5#2rn@xNU%|B3<@3HQ>1G5uifs&>xqrA6c!O1Z
z)aP?Wti3mI8sjQb!=(75i6ps19qJ578JvK^C(~}UX+0zj@jPL?{GV_k2o=2iQZ57
zVJB*08O@pbU33ukzkKu+Vto&e3|U^0d~8`jUM%fY4Cz?%PWrD~YEF
z+S{v4QbnW&A)IaA<&)K%6%ElhHY8IllIV?24^a1;_a{0!IJG|usefl%di?XxDLuHYX-}UV`gBk>WW0ns4TO%Li1KHdY-EJs&>3EdD3PVnof_*AU(MXJ!ZT{0
z21VH{UQe&+oSBWubGI;)22xy0<4M|k1pd3uwlu}RZtkui)F>GqNC^x^9Bdz<IKvLQg#V=g#n}UsC1_FV!F|n4oE(4sS9y<4S~NLcZdO;UMxNQX
zkf&ZV(oIezLQm#PdSg9{HzuR^Af|hZpE7);Y}VcIJEd0{LDHYk?8i#$?S?(v(z$Io
z7Yv$xh}A2#17j(q@>GVRsBLdbW)5fSi&KNfCRjW4S&HNy`_VmAb2fDI-L2n1V~O%D
zZMMF{>(-`eRt~GAxxCj;Armj?web3)a<3-jU`yXEiQzHMJnelKwZPO>HTWAfrBkH@
zXR0tvnh~tkT+#WFbV>SB6B3?I)@mPvj#8fdU3+OEAmvK!lzzWZ{+i=GUuPUr#(@$)G`n`{Mx*Ssq^_7vyk+ld!#t0X(5t*Nx
zioELU$#csckn3*?pg2SJac4mJ=zlmvlsJLv70kw;h`_u$bb^K6#{WYzJP7@@O%yv+
z6E%*c#U?UsNBF_LCNu5FeAOQVr)4F_YMKeRmP;m1$0Mg6=*EpKSn2
zkr>Z%>qFvW^
z`2MuZSAT#`(|%3S;;jc+2I&*b)CwK_&QHvtD}fZ!(78d?o5&9@mulZ)Zy6e^3+0
zo%lbFYiNW