From 49870c1d31b605808eb16f5b234cbea356f3978c Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Thu, 10 Nov 2022 22:58:24 +0100 Subject: [PATCH] update documentation --- README.md | 15 +-- doc/README.md | 5 +- doc/dev/README.md | 252 +++++++++++++++++------------------ doc/dev/config.md | 4 +- doc/dictionary/convention.md | 12 +- doc/service/README.md | 8 +- doc/service/file.md | 8 +- doc/service/override.md | 8 +- doc/template/README.md | 103 ++++++++++++++ doc/template/patch.md | 39 ++++++ logo.png | Bin 9206 -> 9357 bytes logo.svg | 12 +- 12 files changed, 307 insertions(+), 159 deletions(-) create mode 100644 doc/template/README.md create mode 100644 doc/template/patch.md diff --git a/README.md b/README.md index c5d2c0a46..b810dd48b 100644 --- a/README.md +++ b/README.md @@ -32,23 +32,23 @@ version: '0.10' # describe a first service with a single file services: - service: - - name: my_service - file: - - engine: jinja2 - text: /etc/filename + - name: my_service + file: + - engine: jinja + text: /etc/filename # describe a variable my_first_variable # and a family with a variable my_second_variable variables: - variable: - name: my_first_variable + - name: my_first_variable value: - text: my_value - family: - name: my_family + - name: my_family variables: - variable: - name: my_second_variable + - name: my_second_variable type: number mandatory: true value: @@ -82,7 +82,6 @@ async def main(): rougail = Rougail() await rougail.template() - run(main()) ``` diff --git a/doc/README.md b/doc/README.md index 1796b8000..5d9c36176 100644 --- a/doc/README.md +++ b/doc/README.md @@ -34,6 +34,5 @@ Rougail est un bibliothèque python3 qui permet de charger des dictionnaires (fi ## Les templates - - Type creole - - Type jinja2 -FIXME ^^ + - [Les moteurs de templates](template/README.md) + - [Les patches](template/patch.md) diff --git a/doc/dev/README.md b/doc/dev/README.md index 184d6b5ea..50d130fe5 100644 --- a/doc/dev/README.md +++ b/doc/dev/README.md @@ -1,79 +1,130 @@ -# La bibliothèque rougail +# La bibliothèque Rougail -Rougail est une bibliothèque simple a utiliser. +Rougail est une bibliothèque qui permet de charger simplement des dictionnaires et de générer des templates. -Dans les exemples suivant, nous utilisons la configuration par défaut de Rougail. Vous pouvez [personnaliser les répertoires utilisés](config.md). +Dans les exemples suivant, nous utiliserons une configuration particulière de Rougail. +Vous retrouverez toutes les options pour [personnaliser les répertoires utilisés](config.md). -## Convertisons un dictionnaire en objet tiramisu - -Commençons par créer un dictionnaire simple. - -Voici un premier dictionnaire /srv/rougail/dictionaries/00-base.xml : - -```xml - - - - - my_value - - - -``` - -Construisons les objets tiramisu : +Le script contiendra donc les éléments de configuration suivant : ```python -from rougail import RougailConvert +from rougail import RougailConfig -rougail = RougailConvert() -rougail.save('example.py') +RougailConfig['dictionaries_dir'] = ['dict'] +RougailConfig['templates_dir'] = ['tmpl'] +RougailConfig['tmp_dir'] = 'tmp' +RougailConfig['destinations_dir'] = 'dest' +RougailConfig['functions_file'] = 'funcs/functions.py' ``` -Un nouveau fichier 'example.py' va être créé dans le répertoire local +Penser a créer les répertoires : -## Convertisons un dictionnaire extra en objet tiramisu +```bash +mkdir dest dict tmp tmpl extras +``` -En plus du dictionnaire précédent, créons un dictionnaire extra /srv/rougail/extra_dictionaries/00-base.xml +## Convertisons un dictionnaire + +Un dictionnaire est un ensemble d'instruction qui vont permettre de créer des variables. + +Commençons par créer un [dictionnaire](../dictionary/rougail.md) simple. + +Voici un premier dictionnaire dict/00-base.yml : ```xml - - - - - my_value_extra - - - +version: '0.10' +variables: +- variable: + - name: my_variable + value: + - text: my_value ``` -Construisons les objets tiramisu : +Puis, créons les objets [Tiramisu](https://framagit.org/tiramisu/tiramisu) : ```python -from rougail import RougailConvert, RougailConfig +from rougail import Rougail, RougailConfig +from asyncio import run -RougailConfig['extra_dictionaries']['example'] = ['/srv/rougail/extra_dictionaries/'] +async def main(): + RougailConfig['dictionaries_dir'] = ['dict'] + rougail = Rougail() + config = await rougail.get_config() + print(await config.value.dict()) -rougail = RougailConvert() -rougail.save('example.py') +run(main()) ``` -## Templatisons un template +Exécution le script : -Nous créons un dictionnaire complémentaire pour ajouter notre template /srv/rougail/dictionaries/00-template.xml : +```python +$ python3 script.py +{'rougail.my_variable': 'my_value'} +``` + +## Convertisons un dictionnaire extra + +L'espace de nommage par défaut des variables et familles est "rougail". Il est possible de définir d'autres espaces de nom. +Ces espaces de nom additionnels s'appelle des "[extras](../dictionary/extra.md)". + +Les espaces de nom additionnels se définissent lors de la configuration. + +Par exemple, voici comment ajouter une espace de nom "example" : + +```python +RougailConfig['extra_dictionaries']['example'] = ['extras/'] +``` + +Ensuite créons un dictionnaire extra extras/00-base.yml : ```xml - - - - - - - - +version: '0.10' +variables: +- variable: + - name: my_variable_extra + value: + - text: my_value_extra ``` -Et un template /srv/rougail/templates/example.conf : +Construisons les objets Tiramisu : + +```python +from rougail import Rougail, RougailConfig +from asyncio import run + +async def main(): + RougailConfig['dictionaries_dir'] = ['dict'] + RougailConfig['extra_dictionaries']['example'] = ['extras/'] + rougail = Rougail() + config = await rougail.get_config() + print(await config.value.dict()) + +run(main()) +``` + +Exécution le script : + +```python +$ python3 script.py +{'rougail.my_variable': 'my_value', 'example.my_variable_extra': 'my_value_extra'} +``` + +## Templatisons un fichier + +Un template est un fichier dans laquelle on va remplacer les valeurs attendus par le nom des variables. + +Premièrement déclarons dans un dictionnaire complémentaire notre template dict/00-template.yml : + +```xml +version: '0.10' +services: +- service: + - name: test + file: + - text: /etc/example.conf +``` + +Et un template tmpl/example.conf (par défaut il est généré via une configuration particulière de [CheetahTemplate](https://cheetahtemplate.org/) : ``` The value: %%my_variable @@ -81,42 +132,27 @@ The value: %%my_variable The extra value: %%example.my_variable_extra ``` -Générons le fichier tiramisu : - -```python -from rougail import RougailConvert, RougailConfig - -RougailConfig['extra_dictionaries']['example'] = ['/srv/rougail/extra_dictionaries/'] - -rougail = RougailConvert() -rougail.save('example.py') -``` - -Créer les répertoires utils pour la templatisation : - -```bash -mkdir /srv/rougail/destinations /srv/rougail/tmp -``` - Générons le template : ```python -import asyncio -from example import option_0 -from tiramisu import Config -from rougail import RougailSystemdTemplate +from rougail import Rougail, RougailConfig +from asyncio import run -async def template(): - config = await Config(option_0) - engine = RougailSystemdTemplate(config) - await engine.instance_files() +async def main(): + RougailConfig['dictionaries_dir'] = ['dict'] + RougailConfig['templates_dir'] = ['tmpl'] + RougailConfig['tmp_dir'] = 'tmp' + RougailConfig['destinations_dir'] = 'dest' + RougailConfig['extra_dictionaries']['example'] = ['extras/'] + RougailConfig['functions_file'] = 'funcs/functions.py' + rougail = Rougail() + config = await rougail.get_config() + await rougail.template() -loop = asyncio.get_event_loop() -loop.run_until_complete(template()) -loop.close() +run(main()) ``` -Le fichier /srv/rougail/destinations/etc/example.conf est maintenant créé avec le contenu attendu suivant : +Le fichier dest/etc/example.conf est maintenant créé avec le contenu attendu suivant : ``` The value: my_value @@ -124,68 +160,32 @@ The value: my_value The extra value: my_value_extra ``` -## Appliquons un patch au template - -Il peut être intéressant de réaliser un patch à un template pour corriger un problème spécifique à notre environnement, sans attendre que le mainteneur du template n'est fait la correction. - -Testons en créant le patch /srv/rougail/patches/example.conf.patch : - -```patch ---- /srv/rougail/templates/example.conf 2021-02-13 19:41:38.677491087 +0100 -+++ tmp/example.conf 2021-02-13 20:12:55.525089820 +0100 -@@ -1,3 +1,5 @@ - The value: %%my_variable - - The extra value: %%example.my_variable_extra -+ -+Add by a patch -``` - -Le patch est bien appliquer sur notre fichier /srv/rougail/destinations/etc/example.conf : - -``` -The value: my_value - -The extra value: my_value_extra - -Add by a patch -``` - -Deux choses importantes à savoir sur les patchs : - -- le nom du patch est obligatoire le nom du template source + ".patch" -- la deuxième ligne doit toujours commencer par "+++ tmp/" + le nom du template source - ## Créons une fonction personnalisé -Nous créons un dictionnaire complémentaire pour ajouter un calcul à la variable "my_variable" dans /srv/rougail/dictionaries/00-fill.xml : +Nous créons un dictionnaire complémentaire pour ajouter un calcul à la variable "my_variable" dans dict/00-fill.yml : -```xml - - - - - my_variable - - - +```yml +version: '0.10' +constraints: +- fill: + - name: return_no + target: + - text: my_variable ``` -Puis créons la fonction "return_no" dans /srv/rougail/functions.py : +Puis créons la fonction "return_no" dans functions.py : ```python def return_no(): return 'no' ``` -Après avoir reconverti les dictionnaires et regénérer le template nous avons donc le contenu du fichier /srv/rougail/destinations/etc/example.conf : +Après avoir reconverti les dictionnaires et regénérer le template nous avons donc le contenu du fichier dest/etc/example.conf : ``` The value: no The extra value: my_value_extra - -Add by a patch ``` La valeur de la variable "my_variable" est bien calculé à partir de la fonction "return_no". diff --git a/doc/dev/config.md b/doc/dev/config.md index 75426100f..7bde28492 100644 --- a/doc/dev/config.md +++ b/doc/dev/config.md @@ -111,7 +111,7 @@ Le répertoire où se trouve les fichiers tmpfile.d sont par défaut dans "/usr/ ### Le moteur de templates par défaut -Le moteur de template est géré dans la clef "default_files_engine" et a comme valeur par défaut : "creole". Les valeurs possible sont "none", "creole" ou "jinja2". +Le moteur de template est géré dans la clef "default_files_engine" et a comme valeur par défaut : "cheetah". Les valeurs possible sont "none", "cheetah" ou "jinja". ### Les droits par défaut des fichiers @@ -129,4 +129,4 @@ La méthode d'inclusion des fichiers générés est géré dans la clef "default ## La configuration du moteur de templates -Le moteur de template est géré dans la clef "default_overrides_engine" et a comme valeur par défaut : "creole". Les valeurs possible sont "none", "creole" ou "jinja2". +Le moteur de template est géré dans la clef "default_overrides_engine" et a comme valeur par défaut : "cheetah". Les valeurs possible sont "none", "cheetah" ou "jinja". diff --git a/doc/dictionary/convention.md b/doc/dictionary/convention.md index efeecd687..617b7bf3e 100644 --- a/doc/dictionary/convention.md +++ b/doc/dictionary/convention.md @@ -8,6 +8,14 @@ L'ordre des informations mise dans le dictionnaire est idéalement : - variables - constraintes -## Le nom d'espace +## Nom des fichiers de dictionnaire -Le nom d'espace dans un dictionnaire est de deux espaces. +L'ordre des dictionnaires est important pour l'ordre de création des variables et des familles. + +Les fichiers devront donc démarrés par deux numéros suivit d'un tiret. + +Par exemple : 00-base.xml + +## Le nombre d'espace XML + +Le nombre d'espace dans un dictionnaire au format XML est de deux espaces. diff --git a/doc/service/README.md b/doc/service/README.md index 02bab8fe6..cc219766d 100644 --- a/doc/service/README.md +++ b/doc/service/README.md @@ -70,11 +70,11 @@ Dans ce cas, il est possible de créé un template, dont le nom est obligatoirem Deux types de template sont aujourd'hui disponible : -- creole -- jinja2 +- cheetah +- jinja ```xml - + ``` En YAML : @@ -83,7 +83,7 @@ En YAML : - service: - name: dev-disk-by\x2dpartlabel-swap type: swap - engine: creole + engine: cheetah ``` Dans ce cas, rougail utilisera le template "dev-disk-by\x2dpartlabel-swap.swap" pour générer le fichier systemd de gestion de ce service. diff --git a/doc/service/file.md b/doc/service/file.md index 927f0faea..02a99794c 100644 --- a/doc/service/file.md +++ b/doc/service/file.md @@ -275,7 +275,7 @@ file: ## Choix du moteur de templating -Par défaut, le moteur de templating est le moteur de templating compatible avec "creole". +Par défaut, le moteur de templating est le moteur de templating compatible avec "cheetah". Il est possible de désactiver la templatisation du fichier (il sera alors uniquement copié) : @@ -291,17 +291,17 @@ file: text: /etc/squid/squid.conf ``` -Ou d'utiliser le moteur "jinja2" : +Ou d'utiliser le moteur "jinja" : ```xml -/etc/squid/squid.conf +/etc/squid/squid.conf ``` En YAML : ```yml file: -- engine: jinja2 +- engine: jinja text: /etc/squid/squid.conf ``` diff --git a/doc/service/override.md b/doc/service/override.md index 3a1486dd4..cfe11e2b5 100644 --- a/doc/service/override.md +++ b/doc/service/override.md @@ -44,7 +44,7 @@ Dans ce cas le fichier de destination aura le même nom. ## Choix du moteur de templating -Par défaut, le moteur de templating est le moteur de templating compatible avec "creole". +Par défaut, le moteur de templating est le moteur de templating compatible avec "cheetah". Il est possible de désactiver la templatisation du fichier (il sera alors uniquement copié) : @@ -59,17 +59,17 @@ override: - engine: 'none' ``` -Ou d'utiliser le moteur "jinja2" : +Ou d'utiliser le moteur "jinja" : ```xml - + ``` En YAML : ```yml override: -- engine: 'jinja2' +- engine: 'jinja' ``` Il est possible de personnaliser le moteur par défaut dans la [configuration de rougail](../dev/config.md) diff --git a/doc/template/README.md b/doc/template/README.md new file mode 100644 index 000000000..f7e2a99ce --- /dev/null +++ b/doc/template/README.md @@ -0,0 +1,103 @@ +# Les templates + +## Le moteur "cheetah" + +Le moteur de templating par défaut est le moteur [CheetahTemplate](https://cheetahtemplate.org/). + +Par contre, la configuration par défaut de CheetahTemplate a été modifié. + +Dans un template de configuration, il est très fréquent que le caractère "#" est le caractère des commentaires. +C'est pourquoi la configuration par défaut a été modifié. + +Les choix sont maintenant les suivants : + +- le caractère des directives : "%" ; +- les variables : "%%" ; +- le caractère des commentaires : "#". + +Voici quelques exemples d'utilisateurs de ce moteur : + +### utiliser une variable + +``` +%%variable_name +``` + +### condition + +``` +%if %%variable_name == 'oui' +text +%end if +``` + +### vérifier si une variable existe + +``` +%if %%varExists('variable_name') +text +%end if +``` + +### boucle + +``` +%for %%var in %%variable_name +%%var +%end for +``` + +### boucle avec variables meneuse et suiveuse + +``` +%for %%var in %%variable_leader +%%var.variable_follower +%end for +``` + +Pour plus d'informations, voir la documentation de CheetahTemplate. + +## Le moteur "jinja" + +Il est possible d'utiliser le moteur de templating [Jinja](https://jinja.palletsprojects.com/). + +Il n'y a pas d'adaptation particulière pour ce moteur. + +Voici quelques exemples d'utilisateurs de ce moteur : + +### utiliser une variable + +``` +{{ variable_name }} +``` + +### condition + +``` +{% if variable_name == 'oui' %} +text +{% endif -%} +``` + +### boucle + +``` +{% for var in variable_name %} +{{ var }} +{% endfor -%} +``` + +### boucle avec variables meneuse et suiveuse + +``` +{% for var in variable_leader %} +{{ var.variable_follower }} +{% endfor -%} +``` + +Pour plus d'informations, voir la documentation de Jinja. + +## Le moteur "none" + +Ce moteur permet de copie le fichier sans y apporter la moindre modification. +C'est utile pour les templates ne contenant aucune variable ni condition. diff --git a/doc/template/patch.md b/doc/template/patch.md new file mode 100644 index 000000000..f14a323a0 --- /dev/null +++ b/doc/template/patch.md @@ -0,0 +1,39 @@ +# Patcher un template + +Il peut être intéressant de réaliser un patch à un template pour corriger un problème spécifique à notre environnement, sans attendre que le mainteneur du template n'est fait la correction. + +Par exemple le template : + +``` +The value: %%my_value + +The extra value: %%example.my_variable_extra +``` + +Peut être modifié via le patch : + +```patch +--- tmpl/example.conf 2021-02-13 19:41:38.677491087 +0100 ++++ tmp/example.conf 2021-02-13 20:12:55.525089820 +0100 +@@ -1,3 +1,5 @@ + The value: %%my_variable + + The extra value: %%example.my_variable_extra ++ ++Add by a patch +``` + +Le fichier généré ressemblera alors à cela : + +``` +The value: my_value + +The extra value: my_value_extra + +Add by a patch +``` + +Deux choses importantes à savoir sur les patchs : + +- le nom du patch est obligatoire le nom du template source + ".patch" +- la deuxième ligne doit toujours commencer par "+++ tmp/" (tmp étant le nom du répertoire mis dans la configuration) + le nom du template source diff --git a/logo.png b/logo.png index 412ce26fed611d625a65f816ab907c7a04591f71..3c1833f053962431baae2e17f7ee45483de4e689 100644 GIT binary patch delta 9346 zcmW++cR1W#6a6h4R*M?F_ufTkb%G#BbcfT&As7GvIQowC#xtlO(oL*W4-q5&!$qZEcBB{7{In9k zqr;it48bqu(Xa|5LSp*2>a+hA(yO5w-YrQ+GK1u(Gjz%aGIqBh0nJSB=@aq@UBREk zDzTVb;7tDB5(}maruv&w7qMpJYJNpK5}u3hKb8(R6SaOcF1inwCtrAHdi$G&bo`e3 zdBMpBbVl!AP*R8Q$Z7E+1tKN7hU|QpiAI^3JBnzbQ+nd8%IBFC1>7A_2Gpk z!OGCIF&dUu)sXmT)%b(u@3%w*OQ+o>PnHlym1|Qeil&iZZH#5Xv@}Xj-jUYNVGZeW zUkI&aASVDAZm*s|4sizgqz01-AK|buw(u?JEs-bjXtC+<_w8X6;=A zfDsx!v+E!*XhE+0_nQWamT|H2?&W&+PU&TqIV3)+njHMtw;I0iz~guf*)$`D{! z?-UCbPN-~WZU*k&gyM)h-eh!OrIIGgXOI}`@EjrCwnTJDAGL_pVT9{};^580gc7G9 z+JjC6p3&sdSp#n^H*@^4mGqXnQ2wBj9w>e@qpJomBD6v{ex@>=yyR+7o2{WpfsB^& z^iWAAT%k%ms)Lz)tm<@#oTva0K~EKBiQ;>|;hjY<5Yy$Vf~|q)75+6y`RW%V;!d+6Qt01W9%jd^a_1REG7w)jVa% zT;JFGgM)~fA_X+zHs9AjgZ>^jSSGTnYKO#a8*|IT!ot6^WT?EKbd?418N>_-{XV$6 zFz+Nq#GrO_WJK#aaIf(q=uC`jt~e&8QpnE~XfbW_7fLToG5?k$e;U-%D!pn(Tc(@V za}Ls@XrEz6Cl6bR9GQo7FwXjsaQx#0NoJPD+~&no^2}P!hYKPJarJI#4narOz=`#) z&J5Pw6SN0+$H|QcHeR5k+Fw7Z@qZmt@RY?yFgzN_nt#Mq@br*q5 zr`9_8xO07^Eac2r;~6>Xo2#6$sGg%!5|1*g?m6bt#5I)G{Zt+I8h1i?q38u21poTx zDwAu&VLyRK8AEp*@T%FXr(He-QaFsGS;%#iIW%kLGPC@=0Y4dow!v$orZ$(>FI^b#Qw%Hu+klhX8+m+Z}PqM>75O zH_SMofr!C}MZ|35o%>+=PtpEQ0ahcm(%Pg#-(Yv!Wh)zZ&Y3D}W;DAg zP-PqYhnOppz%krj2TszH^6#f-jWO*Pp01aI-9YBdP25uXg*4Dz@ZT`E#xkZI;&3WF zyu02(z$=arW3<|PPDA&b3dDfbILh+Hk)#5-sI5FA5p{x5QRQfiZg?sL{C;%R;E1VO zz9=pJ^M~13mD9(I1eyBw%|Hx-KFUj8KPc?vbDWaa{=3=xi^{OP5H=d%55;&e+kqH-qDvLPW7eoS zhBqK3wTawXoQ$dP0|+4fDpm=ba!Iu_B+uC0SUJtVszB5A>~S*|`1tRmNR4q2yK%2U z{S@FO;`~4Yc>u=>>&|PqPAR3B`iKM=ZKbzmIRgq^IF&AYzu)Bet9{oc5~9FBjM3N^ zi^@K_+SNb8RMfdG18XU+v=a|9u1!#)?E0FTSVgy&(i18)c_M)ped~`5UePR#HkV2eCs9s?zkKZrE7B> zhEea{bEVB8qJmELhG&yj26T)o{03LMMUZkahyW3Z=NSu(?P6omf9W1*XAyQF!&T>c zVlKSZt`EE_)BXR-1(aa?PR7Pf>si(~6d#K@XJKC-9$=9l?kFiz5O10Ze;M{UN>Eq% z{rmH;XKZmUycwmz&FxQTmtH>eS1g9Rkm@461ZS`9Liu!rQ~8{3PWv47GD20D!_>B{ z8KUBB58PDe#SB2nvyG>x9PV2k7!>Ne0k2voe=-5-5RS!_g7{!{^`-aCs5K%|A!DEQ zOFo^9HZ<|pe_vFY5taZjDp^26Gi@GOd6R`L3FVp@;_n2BV=24~prnUNSKY5?+aL zY(l1ds;LR5`y>a3afN+T$2qe0O4{Hbx9r%H`6gE&X1yy!FzB1=Wje>}AfVU(SRa13 zuHC=c2jH>>ySSwH9Vb~|RJAE=sG%r7Dc|Ecu z?5xENRwo|+GdI%mlczw|<{q1(SrR`uZk10#u7b$0m64ngVnZDGPe_bdI#M^DRB?zF zfX>L$%(fyd`yzj9Ee}~8)n&*d^ceuC?Bx3r*?pDlEAXep1?YTeDwSe&C9r_QIcjbU zj^i@=v7N0->~lQZa=~qGdhv@`5UhFy|N2>B% zE{v6AJTxOY!v3^Bj*}$|3HVFdV|dfhU3OLi1rh0&qkQ5e z^^=%c8xHEK$)J=g!_nbWG@HLn*wRs)E~oDHg!q`h3pHppE>|AmPUm^u7;^#IdpCQY zs(~oIm1Dw>DtOR*l|)CLvcKuEPAA`;OlG8_^=JSp%_NY=O+lbl#fz>mX^6nRlkLFy zTzYHSxBo899yjEH_i@_G94tEC)N>~=2H77U5C(L3@m9CPJC9hX^_(k0X2g2&1q6-O zr_r-V|E1Y)0rZ*K-8qM-s#{%us-(=PUs$}7?`zzg> z13vGakQj1Qru32sI3PBJzw_g+xMpoR`FHUXHr_1>a^6&&WD?)lHr!Ra0tbriTt%`C zCjaw*>G-pmN4M<|A#;r4C&e#K z*!MAxJa%J>A-7>3<|?ee82HM)PV!yXn@2f~<&7*lHWr2?pMSrRcq@Xmy;#)MaJUm* zn2uK)?M<9|?~G|iVHlTJtxYEOn+3{IoD#wqvvW(hBOGt<2iCqN4 zBF=+~CH2T4Lp$N;u9BHpss;gsAB5pIkvSiO+i|0t zoBUE&T6B={5nCvi>?x|Swlfm6p`M&NTNAyC`^YKnKVHo*2c{nxz!_&$%@@#G-sP=1{0!#hYZt=y7Z_%xDa7GiZad;q+GP@dZ zC$qAcy%B6Y)_QhZT7c00c}DhM=Fh%*6%t&Gv71~vLkW_qIlOl>H7G|HMS>SWPp&@uljMG>d+vWL;A8J_Wj}6dde7FE?c+YtvWC{rLEWB3y@JF`3g3U6( z{A#_HpM!2v)!3eUJ_)7TOQ(lNf&Ob1WQC;RJq>UH9)H>pL@Rj(%YBxhpw zHs|&TnXpK2hw`Voku;l?)&z5Weuo(B4b11f-?-|6*p+AD;t!3r3a#@HM&)z(iC$+3CkIq7CxFg0DJ*bi8g9$rYXfirb_dV(UjE5TUk_P07Nf90b4Br4niY5~ajrl*|E!Ww41g`7ZY^7Tbn zDEhr(toBNa#h|ZQV?@+TXoDex5!aAr3-6O!wdu~jr52uI*YTdlPpTy}r2b91y}Rk$ z!lP6bd@1vZ*6oy?>LtjS8DXt*T}jL+#Fp7cU+Hf81Y2vB?~Nyr{BpxURF3|##^JJ> z+e0OGAejksC5Ci9{#9G)=I%K1?tbhWveoc+Hr-)((2u#f#1ISyn40cDj6IwCUfu?X zU}Ydtd>HStnxNl}S5Bvpw4rsJWA+BYd;Ap?7!8^%CfH2U z(Wxf2w{etfh~%ida?kCBs_R=a_05lcc+*6@+m3IDT1p=!nzDF;Tis?$_-Cnxpv3>M z8#=iASdABw1_k=s)H_Vo=$I%FZOPF})`tq7i`e>CBkxT{!4cQQ<#~Oh>U}KI#DM}N zcWX}uZ;$zMGPc#D@~h=fWfP>Ci<}YDt^RM2zDkv3@gH-Z{H)lsS-TdJ5LsDsZP$kB zX~kl&W_uIellt93`rD4l6`9|)6$*Et^qVdm%~J;j)B>fryOP(K`wChSKE(3M!44D$ zzn);wkEg`5r;4C4{j1AVoKKwjmqR#r%6I33l8Ft8IrFA{^ z6$Y$p+zOyXZzXw|aTkE&c3=EUMlJ>=Dm7Wlv_coyfdP{Xc%FJ($w2T}c?XhLf=mcN z;G6N^SgCYcchq6Bh%tn{nyzr?nii{(SPu5Wsgc$5U|BI=&EZ5cZk68NFFXqIz{*P@ zo*`tU-OdHq!@U>yJflJ`+MR!8Rf}dJepIg~RE9z5^BD+e;3#rS>B#;t?JxNe=amhP z&6?*Qx+i*b6Y*JRY;&)U#FbjdzRobVgyJG+8bw5;hZFa?5_k}D@nE5)gRl&&a{Ftn ztB>3`8o)!aZf$yx8h3XOF^6alNVvwy7-O_!f<-*)%f+rc3E3$KfL2V)|5Ni1U%+MM z-mW|h+}>}g%^2W-7#w??w2*1(Imx5LqGTMR7{kQ|M)HD8jni|7TH+04ntBUg8?{-NuB;-(Bm_CxeSra)sV*tWY4?8*Acp&i>s$ z`B>$|PsWdZ)@XfkNw)~FQQ{38!Qc34o#r`UWuowOgH=Drz>!xNMDqOmQ*TN%i`l_g z%?6W)J~#Lznt`nZ8!vl&A%lxV3DXYoRt08c4faCKUNXnwRi_J~7L1RQq;NHQ6OB#$ad;F+cY{0)`8}Lhrx9Qg6h1@;tgv@?$D7 z@)>{jnX&~&%MBG{{sjydo&3z$xAAJRg5H%Hxw+`s+pD6#==K>t^xFP`c)3?U%EGgn z&2#XdCEe3O+)UknAM6&F1ndA?2H=daW1Kg{Wvs#~*C2?-l*@Ky;)YkDq${xj%=C`{ zk>tR>5YRq4Qz#M&oo;`h)F$XW3mcC;Wlrf;P55;D^fRUl+{o?fh8$JQ(EXOiz~2v+ z8}o(W&NbA#EqH$O{BPHXTvZJ$#G*=j=)jWi8*6X5ozCxQ~Nr@wz*cGKtuT5_$UtUvPF;q`q__Csj4|E9St#yS;YvxYGUFP+r)ycRzJS4YrAATnKcY%!5g*XDT ziG3VgB$O&WK2bs`$B=W$JkkZtarQi<%WGRRJQ?ZDIc#uwQO9(8Y%wcH6wYnJ&#^&` zZs%7jKm~o#6fL2qHsvr&)I5R!W1zt4!#@#XHR|XuZBguw!-p6B$#G(#&ooP;H}?YE zVn8nJ6-2aY*Hlk6zVNi)XjF*29;8os`(iH8=p=}QAYe7c0jqD>R;b!%jc!;3$k!j< zNtFr_2A@_qP*7+MsxDQ}W#aM!OLGO*>Z;hR>AF25H(qaR5-nfJG2I~MzUwAnr2(%g z3l`?msuW1`pG5lF+P-CNwOl({Dfb@9JfsA8-A%@r1;iW9{zeLVTar<1#spwn;0GYFtla|CfNoQ>PHDek1|?>(Bc&lOevv z7f&{xN>e-sEbWV^r4tdG9$5vfmi0uL^k}0R^u;~lG|z_>Y_q%GbAd++yvr`m)2oFY zeKzJ*(G8^hTrb>mH+g1>1d$(|53dULMUkm@p}1Sth%GYTGe9L`iHG(_ zdXrZii3+Fv(sjHhT1zVjzCqtk_@cwmEYWI9--`Y7=4$6v|B(j4<)$_w&qGHV#_KBZ z>zePd1Y1cvXJ;2;56M+E#Geb03nvdA_pGXA-^W7h9%cAz=>y zQWTP3;6uuR|2*lB%~U=ar`XY=>>xPolH;*|iFF>+)^0?I01K-tIyjQJ8aXefP4TSo zfN4!kc=d4q)k7ZF1A#LJ4@no+S^Pf)Lf6k9|38irGv5F*9r&T!n2!rF!NjEm-WMkv zV#KSLwc(ybiWc=}adONjor!&0QzT(w%Y9$K$jtzv=nL|DPx*AHx`6H`%t2X6mQ|QH z(wP0G+nM0zx@qi!7@S=TGk0XE_}q`c2QUk6 zFufU7X`+x{Dv6^$vA@ebZO=e%H<+D9O8d9kL+G2Zo&GRMfNVB+6}5Su)MCb3*U>}= zwLw){TZ$Dfo{$G(HKsnmFpo3ui%X}y0awoQCOrcO{odCJ+(K@oy~%Ona3m=G>0Fy| zI*3{$S1JCXi>uaNRaAyYMghV9v*5K5{N}|(cvhslSYr5RYv8ChzKdWx*y}Q;-am2j z#3ITD(#{^w!%Wc;6#KNPp5V}F%#~Ni+|Q_@&xRYjdA;ZqhRmku2szTb_-=l&w&-xc zjNX9&A__QcSHMicWZ7Aio|sP49i;iYXzcNKLYJM3V&^pK4qmBRw+J$i{qH*FOhBG8 zMmWQ0JrfI<-tR2Ub)-GKqSRa3)FVsk30LOKVL{s`m;7SUoXUG7zOzY?8P04$G=*p? z1T~*Jqg+fjgbUlI?n|8R4?y@$v(jx>Z*sx;Uop z??Lq3K=NX7J|pl;uao7XxdMpeF%FaLUN@~PIACyX zhHRv4(A5wS_Ev0Z1n66?IncE=L_D_ZOabJ|Q}m;$VNL|LQa`zq9U87OFmAk@CONO2 zq!-`~p*(yi${c!m}#YqygqW=3jjQJ`<@xoF^R;~ltdN2FdD zBbL0}6#@fA-s|sYR2#R4T1Mu{3q0w?hSYrusKHr5L#Jm9RVcfJl0;S~eqjncSRmLB zN&QX*0Bg2I1W*ByUM<%s&n8&508aUCkHSqG+o0!o6Ix<9;k8v#lz>Zf8d7P1*$K@l)zyk`YeGI7v z&i`#GHYdvYiN8WUwe8aQiUv2gbM+{Yme^1*NmCvc!RS?-f&SIiH-NG77aS8JE;os* z4S)X2Vu2+QS?I67zCaTaK@N>_5C^n%)?yZQ!Wd2Uk{hkpsp!BMRUm;;1oxXkV6q<| zp?InEQ5_fgkCopJ0PiIh+aMzuC-Jj;9XJabx&ZJZ`6WI8b?%=KRQxUoD21<5qN5@p z$R}n=#n#Av#+=trI0ciDvD&Y64`UGionWG!1JLt8iZ8bp$+wlIh^t^_HN zP0d1=1FYzZX{Gu)`JxOL2RX`MYxTlf1nFrgJcC`I)cZu%K<@J9Kuz zMDg_l)xck?_Qb$ETH63?acRg@+FEo^XV#wnIh+r#LAy!2ZxDBBe-%Q9-DrDEY z10n}=ox<_uzA(432wvby)4nE|J|kNRiGczJdZoC~cth?K#Ipn*3-W;qUSXtt|DheG zPdT;PW@W_-5prp4m)n%;^zb|Dt}4BEXU!PPk4)5HE$l48~d9^ z46kMT>%n(Z9CE8GLdaht{UDOXjbmTKQPX$;T;XC7`lu!o_!J1av2I{L;=m`JYom$n z7W3c1$%98QXv^kS4M=7RVTHLy=hWir`XuL8#2~IYrw1SEG<2nW@9FsXk&~Y0QlRD7 z%?DGAMu2k1v?|CbM>Vqe%UZq78C^u?62JY)zmo^4oq0vHJI=dEBCF0{GSj#@>?9v^ zv0y_X)U$%&78^Rdr-c|O%hL|Q6jD|bld@|xlEuH3vkYsSjkYhEkV*BRlA`%r+j?eM z00B5O>pcd0(eiG*!U2m(d{n#TY<+lymQ6B$0^+D}ykY14y<#uF{87Ac)@v}r|9xN^Nyu;gn!4ic+>!$}r) z2fa4}z^d(Pi&U9jZ8cpxi<&$DTSY_nePOWP=qrWlR$*q+I;KIZby42u{$`GDVu1|*6V*NX zkiAL`0DzyWDaz?#k)s~pD?JmUHoyS1)5O$~`G*T$mCfbP=0&CAdjOakc|H|*KB)Me z=!X*bWzNKt*$)JvT4i{MkO@Xm7(4%{G`;H<;n`bE1z5xcbX&oPn71O)_e&$l-) zE0}_?uZ>sG_lQsh;kKhP!~c}}v+|~9gK#s?=MtZN=9Q`ZgWuLqTN0-@%64>L<6CKM z0vWseNUAvlTn{aG0x_B|wA0uJ34Nw5MU)H}K75^CW039f)Y(FSN=rA#6mi%bfd54P z5oGZ-8nC>e9{4UNuEX`mi@^E~H}9biL@GZ9=meDT_5ciCnv-8H$vcNZwpFBQU2v_7Cm$X7F`GG z=h=DogV&Lz&O+=({GC|07%NjEpy}uyPC-n@<==AjkbsAZt zZP;X*__UT5Nip_(o~Gp`j0*KDk^CF48##ZE5J=~TKcMkw8?{-61%0ys!v4zd z(Xq6oy_d$*I{ZytQK^F%F>E_N34eU#@1dANPn4F)(EDOn?;FOYAQFbzU>ykJ%x`ed zdVz7^h)482E~)>1{zOICKxxZRz0f0kI)b>fgUCcYAY zSlQ4dsfj7pul|YiKeyHO!O#Timh?W&$JtAMMwpxER{3^>(hA`(FOSCaGG0OkOyn450hRBdIy`!8-*%F2hiB7@8>vZqH%lO+U*0k$BTA=hq zp!1LoL)W}bWWG1rm_Q)$1A=OdeRq%>3dYI458_&#dwpn@;cfR)38f#kG~8b8L}y5xXbw1{*_N`o{=i||~!yE_FGknXy4cOwFq5D+93>G*iR z-`{iAnRRBJnZ3{66Qgvl7*B!SjfoBb07H#aZvvwt_{mtOh+HmNSmWJ2tqDNjgpl8K#G#n2{7 z#A$mG3^cEc;EzH}3H*ZE*KbOSqs|``1@Q)&A*ia^1^`Ur^q3vqoy7AUX8;qk1NewJ z*XwXb96^WPn(i$X>@9eN^gG}X#??O`j1%D#02xE~ z77pNG9X)`&mkPQdJmDaD2bnE@fh<^D;B^2aUM-Zof(rmyr+eSXy&|Nl$ABu*Xg6F_ zMhFhyIjR>iKkys1-IDK4n(txl!1d17V_Yi43P-CwNB|hF@93;#`8LQ)jNo`$Lp){! zJsDX@VJ*bHl?S?P2Hf~d7ChX9X%o2Zo)+OE%vV+njEs_+k{i4Q)4!oqW5eSsl|iN_ zxDITlZEQVV;^2J_v=(igB^jcJ5NtcZ z%8mI(id3*vZ|e)c&-~*aR8SEVJq%b{<**qg!z~rM)P&1je#>c{^ALG*6g!kJp>ZM% zdn^2h9O9HQhm4Re=hYS?}TWg%9_hlE^PSfO`3(H9H34_6g%2ja@s#i)2Xg zkd`mKo`S-y1!_Bei-hs+b0&b!LYhEm(a~GFk&>+dmjR1zN3mgZqT~1}I8{pdsng*_ zq^(aZjDWs8?=I9dti0MIsQW!HCsBh z6_8Zzw#)nxoIcH>`a}TxYk8ny+4qiVwJO^5Loy^=&d@MwH2wDj1Kbyw8`de}%fROY zKerX!`+l`Q!5;xst2_KadqE;8z%;^vJF?;rhoG>qh|?#dMnVa`Ej-h~BNd!w)<(E% zivu_I0fVW8>8h)1uQ8ZVDgRV(0m%L2=9UsZeTTXln2{4Lm=qy+lG7}mm-j_KLT~~w zXqGo>UVJdKcIemBp$#dF!{Y9$q`6<`o--dJw_p_<0X*Fu4D3MIryzJrZ3DZ*up6m} zQB?Uo>v~T27L#ThZhRf-$-NONVXLD{cW?tQ6g8QM4V4lHVK|yAltcX$pi_c zNM8I(mX~d$hc2zPSTXYpcS8(v;L6QJXA?4=ZMfn-F1G(?a-P51 z8o$-qAmF`zC)bx2wAr5xF*HYs+!h=Tw!qjM3GpU>G6b8IeGQ2miW4^g!6UMubY)Jw zq$RYb$PH`lnJ09&)7+MWQilDYj{Wh0?&CKDZ1v5maPn9fEj{D_f?CWq2-6OdiuX#C2HlJr`B79&bbFQewo+lua0 zz}9|T?-qedp877L7P0M{`Nj&^qBW7AclIm9;!?fKjPE{qxKbgNyhFd`rH7aE-k#eZ zdYTm%payZ$Oo7u>;bhmE;9Zg%F-qs-lZH(46oh=Ig4y3Js4#SDHR3O0&ZwI-qYHKK zIENk1PD`zXh_vR(JnTvMT2Aolhkd>MQl8Bw004U(AD_j3+RMq{Ubhd^xE~Tcarb1K zv-I{jGx8;GbvD9(&%ps~mD|&Z_!~4vC)K1t9FCW6SyBAnJ?;T|*GqC$Hq-eW%~?xk z;I&WJK{0L~qH7UUdfJ}<>IZ3Pdy#cNRY46V+U5%ZT<$8_X$#(hZ7C2#K(jncOrVMu zj&&yx8G1k?=0+3i~`V@*qFtWf%(?pK=Gm?dzm9;e~>e!{yrr-)$ zB+EW;F2)65#b7HTlwv~ml;9!0v1B@v>9FhApzrT|=*XK(8MnIu-r)tvQXgO-(fElN z(Oc^=6bch9|MN7sT_|;xS0Bn3Rj^a%y0JEzM6EaGk$$rO^E$>PrBe3epo8yCDknse z#W3ti*_esB{uTxh+OVY&Aax|$?R=s4QLRlT8l%a}0Ze_@uJ9F7-{AaCI`|=wV+9MP zpwlJAfl9yh5(5O5bfL&vLe%Sft>0M_Y0qR(2cq%>{Dn}SkS5H<#DpNgAaAq-7jFm$1n0o%OlM`RNNUoawtg`X>bwd|cl^~KJrTmun*_~BdfcLYD} zwg`OeYbrkYjl|HycVa-=R6=OU$|VGL{7Z4XBd+_x;O%D66D;GUw{s6wy6f|r&?RuK z^U4o+2uiuA$Ig2fF2Az~V>WI~E_Pi}&!&vcx0~ff{-R6dX5}Qj+|n&2GPDLH#D%$8 z3!M!-q{=hiuHqVRADX5(y8H{#xUaOa8XaP~ZTS7fkf-{WQ|jZh1-&2>?3)BGE1UD? zNw2JnmUjC(6sd&uaZ-tWx(sj`4)>N}XKM(Co_c+8B$6cAsf+89lxxDn_4^E{Ag zV8_w7$*O}+LHB>yg0+-6?mIM4MbXW=T5DB|6-3+0v+f~@dyxQH765Cp1)XhwwCx-^ ztTEf8pWNPK_#F~I;4zfC!8#0%s@Cc_Tf}Kxi0LSAdriC?$5-r@E4VAM70oY#s`(5T zn}|^uH+bY>yn#<80ZQf?2(Ch`sCZore`mHwaJn@ z^zy2JybJ7mAO;SI$5ldMW!#b!|3b=>I0kpL%?H?9Q+WZ9szoB*+S`NH_qb)R!!BZ$ zIk1CCvc1{XY&1WELg)_bH~pz|U=U3g1I1%k#tck_i2b-6ba4-Qh0RYazYI!-jew3G z4#jSP;=L5j>xWU9cEI-wCu6h?66<%fc0bc9WNl4z9jH=aFjc8LwUP}H=lsp}yi{&x z*~=~KMFNm-9C##SLX@}1|HWIAWyeIe3tEk;TSk~3*kd+!au_N+#boRg@jUv}S079= zOKq<-xTZ$5vBc`y`cu(jsFro<9I@=TSA);Nw9UXF4uvNl3mthV}9{QCf zVwv!58PukyfaK2ydG?eDK1@-yHJ|%j7NaajJVT<&c|-L9?YC-@6Mc?}{Oq;S@}C*txFsuB@&N0w9`~qwA5;kMM{k z;}DS3rKGemX-b06X0gbF=;q*Ep}7rjPFh?%vbwDojXh#9HxQt_M(*1ai9=8ttup!3 z6Cm{-4sBG3%wUWa+O(6Q)O^wIHPC<;U;Fcg4=&CIg}f{6B5@r4RQ2c27q$H@l{tpr zCbv;+X<(1DQd-3E==M*~Zc{~GLM8gFaTHo^&#lVZu`y8@#Cd$c`$83Oj~n}eX@y!nSVDdXy3Gy2WG^4Sk7NsY*2-MDr(u#3L)CPNw; zqhuF~-&?M3#4q&ka`Img8@<#aG?~8)6*R?ocQ9czJ--=th3?^C8>&sJQS7Im(Ms z8Q)>v9Zr_)*Pt6LtknGOv5Zr_pJlUg{IyR^7k0d4K_t9~vW;hDLteNVJl|Ph(vHjj ztAZVP7Cp;q1yr^*Jr{7Xy^gFX?OQLqzQbqaBb|IrsxFb}<6eXp&2X}N_q42r@Ta|h zhnKx(7O3;|AAXHO6Ps^^G5eXgU4d>$NAnV6<}PbswP{I_efnF^v3_jfQ+ zjL)pd-~6JN4h7`1P$DNuPq@0XH4Wkc0Bz5hOmWI)%kT~UXJsz*heEqD$Tbg|89CP&j(>i#atMh!GgUgiyk;eQ_gGo>%-Ly zxRowWKWNaMGLQZ}TO4vaUTQ@(9b6az>0-|dB~~NMO*Cf<1Sztp0U#cd{3Is-@I7iM zL-a>f1+*zjBFsLlm&`Zw?=jvkFzaULx5vjYn#vy>amU#2IyvMW{(FW8<1@+A@6fn9 z-1niD*Qs+9no3db6UrAUD-zjOSW*se7OFo!MnkZN$ITyB(No!%Wia7}^3o21dc)-Q zo#}_fqUW6{sjHk>)i{gLC4psoEouNNVyU8$>iWo{p?@{D%b~r1m_1%nLopGA52C2N zDysfl-d*OYN%p|kzxeN?gPaC%t`Hf$!8<`HPGP@gM|kj9r7mBDrp@O+-1_jfdASP6ZV*h|43HvK*6?3AAZ88ZN&|6!x2 zaav!DLMmyx+@V*0dz&vhkLs62c+oQL*8Ab?T^;FRyRCFAmYvbtrUJK3oTPhJhrX)O z&Zlmt`yqN7|6V@w)Uts*>}PU-MozW8^jdNZC?1M-;++ssq@=rFLt_An2F@IJ!B^TI zFs^H)mp^ERxDV(gb?~)72#phrU;Nx$lof6JW4+xnYN_l>r$h~qRJSq0iPWyuy4WFV z%VX1^_z~6A=Fb33nB;jQ%XUghxV&y7S&3n6H2CC&D{+STDt#8VvGvB&()#(j_ z;P1E$LoJl7Ls@<@x$9&$`K@HpDWuIRpt5Z^N=0tw-6}OkYoA;*`y6Lpj?TXH%VpB8 zW`3L;>#$RYQ;{yjB7MxPPJJq>H2%xS4p0C-Wx*?bAi@?f3=-pR)i?UJ-jQT-6Ir0_ z_~2-Fbm5vYyNa$Erk^jkX?>U)e^qCc=SYZT|C8r66RGu1s(zmO^Whko#oSLr7Oh4*xSgzsx z)nqyyE?a8qgTU5(hEY}xaA$GNkh0efJt*wIoz6UQY^LR4*F?hC) zqLjdXA`YnUtUl`?)7nlJ_WuguqqP9+e5!=Pxh9rcvU43!fU*2$H(Yp$0K9RrDFu)m z{HU}~B&eW0PcQh253|hXi?tMh`e9=$YS;HkBltW$RkG#=*~FRMUb%X*K`RzGV5d8?dHZO5n|14O|et3J*^-$((#gnz5>Ki4aE$Qs{ryY;Q@-fH04NDr~%40ZWEuvxwe@ zrN>#8WAJoH&1`^70H4m!w6uz?x0b>qODY%>y;&v%XPPLx?vvt_7V-Ar4~W%2MOAj^OmG z!NS^djYH>n?*0~*1U%7%#9Vgl8w*kG{q7p`3)>LsLD$nIE%1u401;>aFQN-r+(j#y zOA42U+%l04di5(@Ib@O**RVFC1k+Q;?hYAn^ow?8ni z=7cvg;@>|(Xg8ZjuiP=0ElWjqf5Pj18K7Z|5Ry5e3=X7JCo8CsIvq4a@f5k9b-LXO zMw>FA98Bq;CXR{P>6nWBI?hjfy=rBOtguzFj`o10XTV%m7uaG7aCEjrf^ccr0}`YN zWv>z*!7uS_cTCQ=ZZP$@V9Fr?TN4;Z|v)a>TjLxwh_8!-S|;X!7aeyP(D|vyp*T59}ECmjOI~7 zHMk95aWn^0u=)?OaC30w^QPz2x;U4pJ25?6d4_9*v5NF<&7;7J&R_DJ>6W8OJ?+lG z2bO}Xc_r4va!G~xiI_FK*S$G8#cR=sba2pV8?qD-#vF!$J=Suy+70aUcyCs3Xj5}1 zw11lue+F5ul=!HvSlR|<9-)AzlCv#vCOBW35u(81-6)KjEsB zDt|a>&%OB*x6KFqn?jF9Zi^f66tIGj+vqw!cmgG&b`}zYMvX0lFgL!d#TEWbd6lRr z<+mv%U($@)UFN0zWNFw8820Sas#xdWPi@sYB?jSXiRBuu{UZ!cZ58Z7{3Ws>C>!yX zWG>}A9p<6P+J3LxAQadie$`YL+ge%1kRF58^D^f51W=bBu} zMSbk~D%DS}^jCN3Ve!Neo~&%%@SrA|$Ylt*$Ece+y}$_RX(ZjT_w?D2M}=EbAZ=1c zWcFVWh4c_}L^&q$33C9&CVM~RIHHn42)i}OZFzzQ2VTZ74FR`J7W1@sw zl>_jvGKOanq>&XC<(Tm9Ms^#6%2ptfD$sENz`R3w)5r(cXDs-DLMo<~t0rqZ_4J3a zLL6X<10@VpH~Cr!$U6zzq<-hof-~eR!j_m(0C)>oqu!Ix>XtDr^K{F^YhWnWi$JPD zOB^a2r;td1v}K%Df(j^8!~EG>8xmc_1jv6AEFF1?4hXk~Fb)Z$tLp;6e-5XmG}*^W zYV{QPCZ9s#0BWDV^ndObRakg+y{d>f2n(4%WbF zx+sHr=!FWEKwrGuA4%wE}PJOR#meVBNW!R<0d79y#aR++9JKis#8ve zuz!g15qfvo(U`d-UZ1-#I7mu#{)*fU+h%du@=LLd8S&`PCC*#6d?+O^#=t6%&N!;> zq|O!)xoSQyrV*6;J+ODqt^X1d|A@f#EFsiY%_ zRld7?fTzViWA%^eX1;^%r5Fm|Wz~nB?1@LSCz94|Cu2rrT^uhcW)V(;KK1-!0$Q!4 zyCLfF8Ko}ru+Hvv!K*Ma9Xf6DWyd#B=vg#Js|4AtY>3gsxi?CGnaI%Cv&UC1tyUc(}{>2gA+;?EYjU zUw`$+U?s+lkW&cEv}Xb_<~{LIDWb(C0OvEB@S*ZE(j;}A!mV~RVcJ_LqE9XF_V1U< z*Xmg*=865Rm~XkYf&#E@Tz+RV9A-|d68^XR3_afizXQ`0@mhNL!@fB|;LEJea_oMr zNNl5K(B;dW?tP4O5ZVtkQ2gpYW~HU29Bn%31UJO^CTSRh#(p?1R37AFE9|FUb9xv_ z)}*L*KhN^Se$6Z;SG(nxgGi*#w0eljGfsEpjN5Oqe;9zAXk`@G3hBGTQl2Xg_%7dk zDoK-~qsy+k`ST~Cd)v!92xaDZR797=IKTtu`Y!UIh*u^gi;qXSH}JsBBz|$Mih>Eo zH}?P}XT0wC@_XO9nt0Pd{%m#+52kdpPeUXM>G>w~AksnN4*`IFxtnz7{{hO-SotW? z_{30?FO+dHhP)89>7`&SMw+;R7hA;3x! zr<*qOWdUM-!ibyPjKdHmy!f>Ja`6aSsdg$IBPtjC>=r zh)M7Crz|I!G*uS$)7dZc=HTC5z8&BT=3X_`f1AnZ)&6G6!LY_7bO51WXWZ-_F)qs| zKjHc>li}y$l3jV#m&@Vn5blI8@3LR^$Hp9I@vz~ndIk{8Gp2BtRfnz!h^)<$CUP^2 z;bsclVh~dz1o4oY~>ZK$ntsP|LVW$gAc%qw)9NgjjopmS(ffnE8$ziZQhyQ275u1L;?M`Au zdFhrxZzU~6m(Q0rV*VuW6X^BD!aAGscC-P{>rmO<=mU4i-nxLUC6Uj&o}9N=8=eaE zDo8-msVDRznQ_BoB1j%sfAgogkG4GPP81&OWKQu*S?E*6GLhDEY>blx&e!UOKeJC+ zQO;*OT{La)l&BCN4d^jW7X_27xGA`&T(9);sVX#~slBP!i)*@6)3t;MI`wub5QX37+dOljc7GB|A; zo0xMk1y(v_riRb^Q+4u~QHgo`9!UCzY#u#dQHV3bz}C+6ck+y-Ei zl8Js;9WpIZ`I4Lb!T!C|(#cyOX@R0nA|)i4cYROsl{`u$7D!6be9}*#yVBJ>sLdz! zvCy$Z&LB=UD8?5Vztc_fg^Tp^51v0Mnl?*5Wl=M%mqJQA;15%nus?&-`%6u6wvu^l z9^3W#__DE;Mg6eCTXu=8ux|vzM{kXCdw<)=!BrW!X zAnG#|JWC{BftMrKl5=TapY>#nWOEQ4-MEl(`XY?r}7Bi%5>$07rgn#NK=Ks z>gNHJ{}jJ|mj5cii+jBHMN?|;uIsJn6rfelnuKF{2I3nT`0g@3br{~J_C)+fIcn|+ zGn~8-ciKr~@(E^GoiPel>uj6rl(;Mb0=iaLT_z1PjF>HO&f1I&A?+Fa9+t9l%}2B% zFTE=1{p0?2(MD>W`k)GTmf|kHBTVM*C&k>OjkwV?_$SiuAyDdZyl^nI5trp!=}I{z z9iJFFuj9{hqUV%J^kz)(A$q@|lB* su`h60=l=VPURR^pR-8b`&;y3i@n@gCSC(0ie|i8Vc~!Y@GNyt52b~LD_y7O^ diff --git a/logo.svg b/logo.svg index 14da07da2..04513d2cd 100644 --- a/logo.svg +++ b/logo.svg @@ -81,14 +81,14 @@ + sodipodi:nodetypes="ccccc" />