From 4cbf153b5064d3243de3fbe570680e2831bacd96 Mon Sep 17 00:00:00 2001 From: JP <37535226+RabbITCybErSeC@users.noreply.github.com> Date: Tue, 18 Jun 2024 16:29:56 +0200 Subject: [PATCH] initial work on gui (#2) * initial work on gui * removed wrong readme * update on readme * fix on div * update on the readme description * description update * give back title * added dashboard example * removal of redundant * added _templ.go to gitignore * removal of _temp.go files * added comment maarten on gitignore * update on the makefile * updated gitignore according to feedback * add temp ignore --- .gitignore | 3 +- Makefile | 55 + README.md | 47 +- go.mod | 37 + go.sum | 89 ++ handlers/auth.handler.go | 53 + handlers/dashboard.handler.go | 39 + img/dashboard1.PNG | Bin 0 -> 76043 bytes img/soarca-logo.svg | 36 + package-lock.json | 1487 +++++++++++++++++++++ package.json | 12 + public/public.go | 20 + public/public/styles.css | 1 + public/public/vendor/htmx@1.9.6.js | 1 + routes/routes.go | 35 + server/main.go | 19 + tailwind.config.js | 13 + utils/render.go | 46 + views/assets/app.css | 51 + views/auth/login.templ | 106 ++ views/components/cards.templ | 402 ++++++ views/components/headbar.templ | 20 + views/components/navbar.templ | 44 + views/components/notications.templ | 21 + views/components/overlays.templ | 8 + views/components/reporting_card.templ | 80 ++ views/dashboard/reporting/reporting.templ | 323 +++++ views/home.templ | 15 + views/layouts/base_layout.templ | 33 + views/layouts/dashboard_layout.templ | 17 + 30 files changed, 3097 insertions(+), 16 deletions(-) create mode 100644 Makefile create mode 100644 go.mod create mode 100644 go.sum create mode 100644 handlers/auth.handler.go create mode 100644 handlers/dashboard.handler.go create mode 100644 img/dashboard1.PNG create mode 100644 img/soarca-logo.svg create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/public.go create mode 100644 public/public/styles.css create mode 100644 public/public/vendor/htmx@1.9.6.js create mode 100644 routes/routes.go create mode 100644 server/main.go create mode 100644 tailwind.config.js create mode 100644 utils/render.go create mode 100644 views/assets/app.css create mode 100644 views/auth/login.templ create mode 100644 views/components/cards.templ create mode 100644 views/components/headbar.templ create mode 100644 views/components/navbar.templ create mode 100644 views/components/notications.templ create mode 100644 views/components/overlays.templ create mode 100644 views/components/reporting_card.templ create mode 100644 views/dashboard/reporting/reporting.templ create mode 100644 views/home.templ create mode 100644 views/layouts/base_layout.templ create mode 100644 views/layouts/dashboard_layout.templ diff --git a/.gitignore b/.gitignore index 85c0365..6548a91 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ docs/node_modules/ docs/package-lock.json docs/.hugo_build.lock **.hugo_build.lock - +**_templ.go +tmp/* \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b33660d --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +.PHONY: dev-server dev-tailwind dev-templ dev build-server build-tailwind build-templ build launch deploy + +#----------------------------------------------------- +# DEV +#----------------------------------------------------- + +dev: + @make -j dev-templ dev-tailwind dev-server + +dev-server: + # run air to detect any go file changes to re-build and re-run the server. + + @go run github.com/air-verse/air@latest \ + --build.cmd "templ generate && go build --tags dev -o tmp/bin/main ./server/" --build.bin "tmp/bin/main" --build.delay "100" \ + --build.exclude_dir "node_modules" \ + --build.exclude_regex ".*_templ.go" \ + --build.include_ext "go,templ" \ + --build.stop_on_error "false" \ + --build.exclude_regex ".*_templ.go" \ + --build.poll "true" \ + --misc.clean_on_exit true + + +# watch for any js or css change in the assets/ folder, then reload the browser via templ proxy. +sync_assets: + go run github.com/air-verse/air@latest \ + --build.cmd "go run github.com/a-h/templ/cmd/templ@latest generate --notify-proxy" \ + --build.bin "true" \ + --build.delay "100" \ + --build.exclude_dir "" \ + --build.include_dir "public" \ + --build.include_ext "js,css" + + +dev-templ: + @go run github.com/a-h/templ/cmd/templ@latest generate --watch --proxy="http://localhost:8081" --open-browser=false -v + +dev-tailwind: + @make ARGS="--watch" build-tailwind +#----------------------------------------------------- +# BUILD +#----------------------------------------------------- + +build: build-tailwind build-server build-templ + +build-server: + @go build -o bin/server ./server/main.go + +build-templ: + @templ generate + +build-tailwind: + @npx tailwindcss -m -i ./views/assets/app.css -o ./public/public/styles.css $(ARGS) + +.DEFAULT_GOAL := dev \ No newline at end of file diff --git a/README.md b/README.md index e0b6f76..09ebef0 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,50 @@
+# SOARCA-GUI -[![https://cossas-project.org/portfolio/SOARCA/](https://img.shields.io/badge/website-cossas--project.org-orange)](https://cossas-project.org/portfolio/SOARCA/) -[![Pipeline status](https://github.com/cossas/soarca/actions/workflows/ci.yml/badge.svg?development)](https://github.com/COSSAS/SOARCA/actions) -[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - +A [Go](https://go.dev), [Templ](https://templ.guide/), [Tailwind CSS](https://tailwindcss.com/) and [HTMX](https://htmx.org/) based GUI for [SOARCA](https://github.com/COSSAS/SOARCA). -Automate threat and incident response workflows with CACAO security playbooks +## Quick Use -## Context and backgound +Usage of this SOARCA-GUI is described [here](https://cossas.github.io/SOARCA/docs/). -Organisations are increasingly automating threat and incident response through playbook driven security workflow orchestration. The essence of this concept is that specific security events trigger a predefined series of response actions that are executed with no or only limited human intervention. These automated workflows are captured in machine-readable security playbooks, which are typically executed by a so called Security Orchestration, Automation and Response (SOAR) tool. The market for SOAR solutions has matured significantly over the past years and present day products support sophisticated automation workflows and a wide array of integrations with external security tools and data resources. Typically, however, the technology employed is proprietary and not easily adaptable for research and experimentation purposes. SOARCA aims to offer an open-source alternative for such solutions that is free of vendor dependencies and supports standardized formats and technologies where applicable. +## Documentation -SOARCA was developed for research and innovation purposes and allows SOC, CERT and CTI professionals to experiment with the concept of playbook driven security automation. It is open and extensible and its interfaces are well-defined and elaborately documented. Importantly, it offers native support for the emerging technology standards CACAOv2 and OpenC2, both developed and maintained by OASIS Open. CACAO (Collaborative Automated Course of Action Operations) provides a standardized scheme for machine-readable security playbooks while OpenC2 offers a standardized language for the command and control of cyber defense technologies (e.g. firewalls or IAM solutions). +All the documentation to off the SOARCA-GUI is currently being worked on. +## Contributing -## Software -SOARCA is a security orchestrator that can ingest, validate and execute CACAOv2 security playbooks. These playbooks and the triggers for their execution are consumed via a JSON API. SOARCA comes with native http(s), SSH and OpenC2 capabilities to interface with external tools and data resources. These native capabilities can be extended via a dedicated MQTT interface, allowing developers to compile additional integrations according their needs. +Want to contribute to this project? Please keep in mind the following [rules](https://cossas.github.io/SOARCA/docs/contribution-guidelines/): +- This repository uses git **rebase** strategy +- For each PR, there should be at least one issue +- Make sure all tests pass (including lint errors) -Development is ongoing. The current version solely supports machine and command line interfaces, but a graphical user interface will be added in the foreseeable future. Furthermore, its current capability to run CACAOv2 playbooks sequentially will evolve towards the ability to run multiple playbooks in parallel. Such further developments will be announced and published on the SOARCA repository on Github. +### Running this repository +#### Requirements -## Documentation + - Make + - Go + - Npm + - [Templ](https://templ.guide/quick-start/installation) + + +#### Development environment -For the latest documentation we refer to our [Github pages](https://cossas.github.io/SOARCA/). +The Makefile contains all the required setup for live reloading, meaning that whenever a change is detected in any of the files, the Templ proxy will reload the browser. For file change detection, we use Air. Note that Air does not need to be installed manually, as this is all handled through the Makefile. Although this setup works quite well, it is not perfect. +To start the development environment, run: -## Source Project +```bash +make dev +``` +In some cases, the TailwindCSS changes are not picked up correctly. If this happens, you need to rerun: -More information on the source of the project can be found [here](https://cossas.github.io/SOARCA/docs/about/). \ No newline at end of file +```bash +make build-tailwind +make dev +``` +This will rebuild the required CSS files, and rerun the development environment. \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c1a0fac --- /dev/null +++ b/go.mod @@ -0,0 +1,37 @@ +module soarca-gui + +go 1.22.2 + +require ( + github.com/a-h/templ v0.2.707 + github.com/gin-gonic/gin v1.10.0 +) + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ee7865f --- /dev/null +++ b/go.sum @@ -0,0 +1,89 @@ +github.com/a-h/templ v0.2.707 h1:T1Gkd2ugbRglZ9rYw/VBchWOSZVKmetDbBkm4YubM7U= +github.com/a-h/templ v0.2.707/go.mod h1:5cqsugkq9IerRNucNsI4DEamdHPsoGMQy99DzydLhM8= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/handlers/auth.handler.go b/handlers/auth.handler.go new file mode 100644 index 0000000..9f51418 --- /dev/null +++ b/handlers/auth.handler.go @@ -0,0 +1,53 @@ +package handlers + +import ( + "errors" + "net/http" + "strings" + + "soarca-gui/utils" + authviews "soarca-gui/views/auth" + + "github.com/gin-gonic/gin" +) + +type AuthHandler struct{} + +func (a *AuthHandler) AuthPage(context *gin.Context) { + render := utils.NewTempl(context, http.StatusOK, authviews.LoginIndex()) + context.Render(http.StatusOK, render) +} + +func (a *AuthHandler) Login(context *gin.Context) { + errors := a.inputValidation(context) + + // email := context.PostForm("email") + // password := context.PostForm("password") + if len(errors) > 0 { + template := utils.NewTempl(context, http.StatusOK, authviews.AuthErrorCmp(errors)) + context.Render(http.StatusOK, template) + return + } + context.Header("HX-Redirect", "/dashboard") + context.String(http.StatusFound, "") +} + +func (a *AuthHandler) inputValidation(context *gin.Context) []error { + email := context.PostForm("email") + password := context.PostForm("password") + var validationErrors []error + if email == "" { + validationErrors = append(validationErrors, errors.New("email is empty")) + } + if !strings.Contains(email, "@") { + validationErrors = append(validationErrors, errors.New("valid e-mail is required")) + } + if len(password) < 8 { + validationErrors = append(validationErrors, errors.New("password must be at least 8 characters long")) + } + if password == "" { + validationErrors = append(validationErrors, errors.New("password is empty")) + } + + return validationErrors +} diff --git a/handlers/dashboard.handler.go b/handlers/dashboard.handler.go new file mode 100644 index 0000000..2c62317 --- /dev/null +++ b/handlers/dashboard.handler.go @@ -0,0 +1,39 @@ +package handlers + +import ( + "fmt" + "net/http" + + "soarca-gui/utils" + "soarca-gui/views" + "soarca-gui/views/components" + "soarca-gui/views/dashboard/reporting" + + "github.com/gin-gonic/gin" +) + +func HomeDashboard(context *gin.Context) { + render := utils.NewTempl(context, http.StatusOK, views.Home(nil)) + context.Render(http.StatusOK, render) +} + +func ReportingDashboard(context *gin.Context) { + + render := utils.NewTempl(context, http.StatusOK, + reporting.ReportingIndex()) + + context.Render(http.StatusOK, render) +} + +func ReportingCard(context *gin.Context) { + + id := context.Param("id") + fmt.Println(id) + updatedCard := components.ReportingCardData{Loaded: true, + ID: fmt.Sprint(id), + Value: 10, + Name: "Executed Playbooks"} + render := utils.NewTempl(context, http.StatusOK, components.ReportingCard(updatedCard)) + + context.Render(http.StatusOK, render) +} diff --git a/img/dashboard1.PNG b/img/dashboard1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..033ad2d4070e7105ed62a20fc3c16822c872cef4 GIT binary patch literal 76043 zcmdq}XH-+!`vwd%;|x}0)KP{$iZp48^ePsbQWX#gpwerk6IygoQ4x?XEkP-f7Nkok zQIQ%TkO+|)rG*e65)uLglIO(H(f{vxKEEH{y%vkbS!eHa?`z-Xy7#^}k1WlN`1T3y zUHA!k<6}xrDPD`E zOawO2+-3i;kL99PGb};Rh(NEu$b~U14yPh}Syd*ZT-H0d)!@7S3}$ztbtQ)eqdpA{ z4S4$&JMftnQ^cTpTOv;Qk;7a#6&$OT>kaJ5R_RD}z$5?LwD7JHE>~3O&hQOn@EG~5 zXOCP}i$i7)^>x-~>wey1WYqTNLU4$g<7KY%ItI2ZTjxS*_TACl8F+PTIOpP7i+XwI z#XRTSB&;5*;!3u%WX2R{A{g6qZ|@QJUY7XAZl0!0_i~RoYr-TWkKTkTsXEHlRy=Pp zY+kj}z}`Cz$B^QBe{MVH`AjX?`9+HQ_R8)&{3(CSwyni->r;`O_m7UacRmqR_UQX7 z`%G|V#fDo(FvL(*IK4MC$1Vnm^!B~~)#>q>ny-DA(Cg%k2;xHPT!VH#zAQ*MJ@Vw- zSiP_NK%OS8?<{u1tk>Ge+P2wX^WC$(k4VMXVPIjtxrR*C!JlkSS9s^0?<2!0Rf01q z&(_`BvZ0}&7Zpm`mMRuADMdtuDqOW`Hqa!udjCAkC~gk^r%-x{NhzOc(u?mwL*+5x zy%mSLn>VH}f0Ihobf?rgdi4^7)+4Z| zQWC#U?@m$}b(e*t5Cj2_MFl(9n8(rD`SsHSXF4xE5mGI?Ae^3%g*4Vt`hiZJK`8>F z%4g~>l)kL{7{@UD4|bzwAeJ0XY&l|~)uUO7lPVNDG>XHWD7UN1 Chw?C04ZLtov+oGyZMYN+=ikzX= zRToN)oWk7VtearDz9@(1TwB8z)LE>V#{K88j6r5C)_kUu`fb~388u$3htVdRY!(#* zXw2L&!FdfB5$ta`@J#bE3^Ff>HUUNi;?Es5dHaSFLj`qJ7e;N
Ho3RbRf0>OD*6MT?*irXs9b>o&5Mip#(#wr*52X zY&r==8aWKWw5#0GYR33_fv|ZPdl_EtJN7SV{+5fOGQMBghWz(gYH`WLWfdB-X (|fy#s4KRhHF$=3@+oy$LK6HX{SEDaZ6iONYw zmK60f9{kWILG{(iixSk#@s$ws^6k!<@~W@)@}NjfilLRhUqJE7gc^kAhSt;!UAzWi zZ<4g@{$FNjugTZjkn|!%Rni}+{*%yk*=vBJeh%0FlxLgG>+b7YUg6YidrZk${&JQg zBR6ez+_vKSaRmj1nn;F^pmvyFyqb)7L`cZbD6g;L=2Cczd&dg=%1y|T?cZ0fps?b4 zz0^?mRfU8sEd)VorWUIwceUh7&qWgXCEya9DVp4+a`|_ugwip#6@dT$2B_Ed 2k~Ds=jvrGOhN&fzm9 zkewKssFF%auA`J2E~v{*2Xy1x>kL1D$US-hi-c~8km&W6m4IBelqRmLcKPb6Z3E(P z0oH(yf9vp}Fa?`rros@5S^S+;_iu;bZOB4!u$iMTSLY0W7?XTSe_oc?Qt4Ov(l!P} ztq-B0y1QcnkYwLPu7j;JXmT5Ue1*@{4ltT$Dj@LnZ(rdFdC+Cp_RMQ#XYH*Ot!J@* zfLvbM%4h0i oKcz3w>rP@mz%}K`VoD|ICp*%9Op4 z#VIZTg+CBhD|CtIA6>|$PpOdTkOIoQgXa&@@DrlB9hdF8otU}+yD)>R5;ZM6aiKw# z<$Ak;w;@_zJ?c+y7xr8&Y0i!1L|^g1`Uei+1w)+vr7-`I9zcwL+Z_+a^v6d7op80^ z)^49HMqY3T2I3mPjQ}D4u5I92L@KZ3x0efsbXNN?1H1)`eZJNuPQlh>t>$_10WRbX z5j{0I>fCU;|NF=T4Y!7cARDWsyu@=1AS8Xo5aMefepwt}uV_lJA&jbmJqx%l@F#H^ zLpFO;&3d7F8m3dM8zsS0KDe&IuAs^|F0BdeAGhc7p$Z4UlmIJLSNQfZ9@=?;bB3bq z7z QQkpxml*oZ^OIL4dh@YpHdm8e8`Xd5P^w1<93^PY#VbUqiuvIPetZ zss+Pz)M%GHk5nI{SJTfpQBsY#f@BsOc&p3)(6yXLYJ5g|+9RXaDtMj3bXBGJ{;!Ii z+oac(&k$kO8HJ}p1yL1|8X3MhQr?z|siFf8e``C0X$0T&6XKZzxbQdO&bixGILwGM zGy FnLCBRFVtxz4^SLDTD@QM&Ly?oubHtAc6-w# z-fd1Yqqo@7ca00z;G5Fi-e}goE17%op2l;sSXE|OO7aH?pKz9Zy}yw9GMr++BrQe0 zy*SE G4}Y?V(OzR6S%9(Q|CBX`tm{O#Yk~g>qv1{UO0 q^&L`JK#6T*YzfMh7;PwF@O9@@8BP=AAYS(}+Pv zjUC>Cf-}`Q&!&UMrghC-LU9pf<}!Z~hso%+W7c4**P0UCu;L2ot%}ZnM{(R>OKbQ| zTF2#i3`{`b>Er--mCZXwte9H<=NK5We}CAfK|(Mp@-Wzv>l?nc0+G N53Ee0oHWITG!dTfMlpS62*qZTZOV>H `qfj#-B?!<8d({J!fB3BvIq4{+l+#*<>xbfGa @&*7dFSo~AM19`YLVkajlN%s&8!1Ij(Kn; z)d>rq)Ad-FAa6mTZGJItPNRQeZU)46&rk9zVo1%ROW4|u75%g+qvSBf@dfDCucIrk zb{9ETU2TP6qMwMxZ}ztW%J8A7FNi)telZ)=sA0X8PeTT8sf_bQ%XsN@W@X%0hbI3b zuxS*65^FCpTiz9`X_v&ohiC>qQ F;f?f=fn$UJo|)S+ApSArGwQ!Y{>v;ZiOw zbvudF0U)vYK96f xTmN))WwDWyt^&pbJX4%~$3>iR{ueK|vyx#H9oWR7SForpw_r(%?DQg$Ao zvgXKB91)U^H;Atn%hWj^N!RT!WvzRfGTRWB36;s=ZEcgRXrl(s3jO`eQpEfT!Hs77 z0gvanLLrOS{y9*$VrYo_(#x*t5d7SJfsAl^p);8F8@LHMmv?(SWOT-8G`YKP|4)Wv z9XebvLC!liO3kA7-nBD32y)VOsojy94AA#uMc&)7fJ-|yYN-wBP*99&Trf%eGIfS6 zHx6a(B6D_rXES73BAiseTFx>qCO){Bq9zT&Kj?q2kd&$y*QF)y+T1R-zM_AkCYp1m z1roUuodVq&iA9*NTAVFMI8Ck$LN8^9V|A?p*P_u zFH_hl8LN HJn1J=)2FQv zk;}%qr<8FgTU>KQV%83f?!3$VP L`U8$ z* 30Zw9?Xk>&h1M68%i|oJr(1%av@zDX%aj-cJ;{pZ zIB#wZ&*b9|*6rv`-nBCiMHUXZzTrQD@SD7qESHBb87h=>YAkm)dSVPa+(0@MTZ>hV znNVX959JdIjhxq6^KK;i?+9!Lay(i>3(jm-Q(qp}BhH*A2TxpHaerUeXfVp5Z{mUx z`z6*Wr7kQHX7tS*B^N#Qz>`H{nx%*v^;sG7#;r+ie(XXpOi>%2g#+nOBs3QmHB-op zRsLjgD@fNhj teuJs<3n!z_WA|Q=?AhfCMMkV(;fJeRM@zv(qw~%HOe27 zP9Iwn5sa90yw6IM(2WN%%0xEsh`Cq3oh)?oLJfK&joz6mw(}SGnLn$(IUjHP4&7GV z8g0RhC1$aSxpR4XNTRwl;PwnNhk|eP6e`(J3*nE{jx>wP>xS=?()HHu(FQ(BU`o}* zG{_JX1?)atEQ6^LU@jIZ {@@0uKsCHgSSgf`(uLV>reLOqh*F$ei#3qJKW*DD!|tp168x*o!o9C?IIpRM>T(; z8bIaa)Tv@!lYdV(>KLN#M+T^057VNb8jVH6O{*rcDGHG>g|}TA6@Jx<0shQ%O4`sL zrT!B?`%;*gQV8CBqrNcDztdUj8xysn_8vSnYE~ <_LJQ<3&q@tT@ABn^fymsBkCtl z`!f%v6Z4NxHtNeMLvQ~!2i=c9fb#Yzl6`q_J9Ie-v`vH$WF4W(z^rYPVcWgfxGwDt zjz<*QLSaIEW1U<>O2%wMF)2+6dMTR;c0K @)jBFlL;Cx^XJ;v@k2CbQ5 zuJ-cny=+@w;(&7a9+S?+^~A(k=icd>+Pdjg1|~>A<&1XN%kQX?JF>SIs$5dV9QoGs zEUTxQ;nGG#4f~|E% 2S+nR+o_TTSjmNxvp6I1MwkmNnpw4 gOp9H<7DQK8?LH ;N>my||UH*E!BmYM$CK zsqW4KL$5!Zf2MCJoIdvV1XG#GaZ=6uf|z!dZDkj0iZ0!$73lf&k$j6E9qVyR5MuOG zfIY?J>jmt~!u++XgBJ?ioR7`O=Wi?f66Kh*H5oDL{)uCP^*0|_+RxfP$JW{2+q62* z>9#}1KB7 qL&r<@Qg-ouvjoxCyF(bPVr1|rs zFld+?{H<#-K)9I6ej!RqJ_)+9hnxZ$
Vy>`qO8p;mJbH$hk>TKR)! Q@S()yjHyoL#LPVZq&>3MkS@0F|o=-m$sdVcqh_M{yjw6 )306O))aQzWCJQE3D=q TT;E!I`v@!p{n;hP} z{9fOJ8(}UbwR)$D1kPb bliZpF_jfq|__ks$h?FH`32pNP4?RHMcM;L)y=QH;H8vLg$&ok{1!ZXJqsT#AK+ z*iR`p$PR%*$W1Kl3(OZTDb2(Ctkp$P!A2#+jOB3J`|c3kEx2%gN!K|JDq~$G5Xn17 z0?4TvRkOQvJd8*aeh#O?bk5s^QiC0)&rBPsz`h{JwEGD@_&;JO4GkeLToLWU58k1!YBVDAyi4GZw5@Q?eRrjXz6M?sce>4 zZeU-^CEu~cNa@wTR(a<>jhFPmR5fk|B7%=?_FJ&3=?ne8cp4$b=XUQuf)|a#92h;L z<^=nh0rrN*1rgQ+dP b_E-Nz($9Vhf1OyW_) zPw6?eh1mO>Ydh`-a^!Em?yC`O_s%KMCRy_l^SzB!m@E;s7NfbD6h0^1Xr3y{+$r`O zChhjusB(&2zI|6mGw2`r>kYPIQJ(j=w|njfO~tLv) KKE<4t|_~Hs6X${zX5vjrif}bcs51+Q?GOCGKj=%2r(F`+7x2U^x18 zWO`{ei(jDkQ8m6rEc`Of3)Au=QRg|8LE)WyLsWW-=jdXYJJ0Yd`I1p$kTkzZ=DR`u zBMs#6=h2&QTrjaNXwwD?M}nl{9Z8KY1?l+ZfzJ4( -OREVBDw78@fs7@$+qLeJ z1#k-ez>{)4?JBS^w;J6fg2$_-1hWT9jGlA~=S()}+Bb04cMp*BjVuE~pV0N#bN3XO zO^RN&4*0O~mE71hLcQP2YsbRGH%EX(D$2!rvhXOHUJFT)I5B((`Ye0ww#e;)6PmOK z*(qcTlxx}2TG|*$xOVJk0yu{<*i6(WVY2xZzvLH-nQqZ!p=tgNXpNhQR;X-MVy>c8 z75a=**hl||!DA0&?<&Pms)E+r_m9zcpi1ewvFX6cP49@yPWc8xp+4t!Zn(HijKwLK zRH&T)hf6E^*Bd5g1XAYeijB~ ^aBJpUBN_b%{w718mT2PFplaEc0e z?KvEW 53c zsZUD*;!VP=ubo0_Of1UyU{hF19^=yqP0pjDG_aVGi^jAC4qD|~#56}gT@Kr5T57|B z-THGZc6jGJDeB#K<0t=)3EM1QdWBV`Wq>CoiLGm*&?!8d-R6fT4A-;^KqZJfYi>=S zdM>$Z5*+oz<7#Myrx-HtH%hNGZqdZ|Gr>SUEWs>YiLu}kWkGxMoHl8+WG?uO4C)DN zS1~ii;#kQjyBXi=os?vbKN#8Cz09j8V$YvZZ%`WP2Q_z#JgU!!TplD2n5z8Bc-SS1 zH8rQa;A^jP(lk1V@(Fu;7Y&op&TsB^=}bXesGS?1xuN^GrZ1Et|3AJ=Cv3rphQ9C^ zO^syV(wsvk&&FFQWbQZ8dg8D&*=RhlML3|zumJa_=!?o4<*$L8!s#jy*SA^_?*Spf zAZl~$F4_dAZylj--u5|ElU8FD)TytRE}pp6UHf{09757>yS~017}9D(bv48^>?TTU z=cO!rY3S~&0V3~X6(VX~qfb9*@Cu&N-L>-ouG>Ga%b&G;kY(X!@7*xUX;^510UHI9 zJ8cZ}n?kxd*2!g0ED*_#NfB{2{?)9xM})#uUUzPIo7a?APDWCI%xWc%EvFBcljci+ znKSO`n`P-j>jpJrCaly?3P0^)pV7btGQ}0?S? ;dSuE0FPaq%fAE zw*TUcCBms;59t#O1djBP `#49r|`g@iS#+(B(yD!FTX1U3&$q?jeC;e8n*^w?I z#A?X+e9@ E6rW}0$T|4M3rBu&!miqIv2vwmM(J4A*42Z z{KT%RT*)|a 26t$ObFfy(&SUCj1YeV%NjiZ;fd8#g#J8id{dU54q|6sbihxox_pJXLTPQ z9dhWJGSXLoQv>e}YiPd*zagvs6}3Wh9bNwvRZKORaRaFOC-svoVE>c8*%>j)-R}S# zU(dYmGGy0eWd5|e YrWkeK=lI) zf;EAc>%zxw5#W*~!}wQ=-dC5U3W$4JBs5ZKuZRPwO3pQJSh+qazmTF&0$X&J2e%m@ z%`Fcw>iU|M_l3YWqX|0VJ*yWAnfVbcl}()c+F^=iFQLjD_Rso4u7?Jq|9^Lqp5W(a zNBI@fFwV%-Gne$`@XrY`BK8QRBmAjX&e3}a{o&3WaJlQY;SGX9awaxh|AVeYa=Tk@ z6 u_>cm4(``e7dHzd*dZ6 zBZoyaL#5Ii?|t@aRudXZcMCzyJn#U^e oKo7J0a zRQ1#a(ummX*)KOMr=RQ`h5Nc2y#5Jln#?9?ShSA;%f&*4Os=0qryvN4A-WHqCl6Cz z#TP}vsU_l)f`#}{VCQPhxZQspEpaBMQIEKmo4D#dUStGWiSfS$0eGy_vl3lC)B4Hh z%&4{ZaOUwEMpi(GdDS{+4urN6M2ESZ0;7Q4ZCRI%z|}EW)VA0218oXg`C^RMb`c@& zwoxux`hhAXu-GuBI4|E&%g+ZLHUvJ?&|W9ZoTsZTkm0(>>O(^_4s23QH|L3&Jurcz zx$%*F?=HkPUyI#dGTj`#4n`4L$XyV97kk+Y&JJ_xQcTWVYIhK@msTwjIeED0(<6&n zPo=7KIcIxGyOza%>JE#=ah7UkznRQ?f~TkjRFkTTqloxo%1Bo{0iknEjT-neWEc;R z)b9^H)f@n+(4WkVav`}C;_6#e#=0jwI5%TwhV;uUb7N6{(9Nx@S 0;&?tSNk^YlE-8A?cZ4!T^yfJkvVY zD&LwUB-@%4aV=7Grw%w|k|ambE<$xdYnuaJDSFavi&$S@sun{x5EPV6%q0^EoH~0P z>E4+X)>f?R`CEd;-2K>;&BSH2cE4t;KX)ToOhEDLF%t`<<+8rnqccju{XRwPIX?;< zE>XelF^`8QmHbk4l^kx^1LtFeHhlHs3^{1YeI+t>^<_Wz%<(%Ur)-#j#fc{W1k#_t zgY2Ij$JcVXpX1B_Js9P=_LzI1{xc~DdjEXvX( hkH!> 6RHmxKw`)Nvw*@w#(i1bUiJh|l)pG(; zUHcp8YM|VwndrG10->YQikO{YX*F;VJ;&AI+HCRVt)njE5@SC9l|Y;W7WVhW5(7aW z2;||?jeLiYv?JovGQFpM=v?<#by=)5C^gI*D*R|n39Z&4J>wnyp>l3t)r0Y|0HhUd zS)F3LqT|J_R{gh~`&xqxlzQ;~&m-GpzFtA~*!qvga-=`25~O?bv+`tI7A9@jh}%0~ z=l}82!PZ%4NZ?y7X7uyAPAAMidxP+ryL<2StEVW=vlG?R#I(g_1$O-Z=>uhgY-QJo zF}6re(rvJAR4->-0|Y~0q?}sa#bi94nH4QfA9btxTieRrmMRfF0u5>uRP|EqoVN1P z!|9ni_fKCIW bKp-sg$PH&^@bH`%hyDvYQ`_EPlxK_g;6y%-CqWY8&jT zbitDHn9$<2sG3&psOvOzY}tvV&I`DwG`g48-vu&m+LAC!6NKD7d?J zDIZo_k?Wd-wINS6wJ9hsJqzfN@-Y^EAUah5QoDrIKiQ;sD0f*79oe)@sGRG6PGcZD zN{Z4p(Z&Bc57mF=87=@xW1W->K29vsY?@*-eYK9}j^N$X{Ac&aAIx-3S`$Gv(x0d( z>Pzp6Z`8<4^V^6y9sShr7<)y$)Kei?jv}K+^q2|;3T&_yQErwMJ;&@Vu(8_UW4_K| zDWZykc3~Gn-`PZI3jZ^9S_ERY8ras*Uedv8oIu=e4xFnU>gt&)h#q6@1iz&^sijn| zYw3X2?<(J@P27*)RMWO$+f48IkeL u^ut}A3L=6F@lvB{-V5e{Lisj zs&dWHR-CUlRC#ULXqFb&STE#H=DXysekgRT6}ozhmR^pT@80EEH~Hm>%J$a5JwmPk zL;||XT|*~7TrCw-a&+vkRb=sJ@E^uQG85Ah!s>F;P<>E~tj#2EMo10eVv>%0?eoZm zo}hOnQ&`3E-U3IL4E`NFBC?7k*FK9IpE7}0-S+tyVlSLN**MYb!s$QQ@-|S2U_+xT zt=F@$YN<}KXH?b9yhitEde=^eL>4Wof-8cqkajrEhn-4(xbbUzTrWOXZcs|Nza*=B zYl(7Z3s`W(#Ej3u2lG*w4<&i}F=WFM=+@QXYw)hn-jBvJ=KgBN4|05kOCG8jH>TFY zE}I{*4{$Vc*m^<92}{4}*5rgT&Qjbp`$E|~+kpZk`m=+dS3D}gkJMX3|0E^Zb(bfR z4fC6A0&~<{8bfIVmAl-JoNfKFZ)J0VtG}B*mYEH!9?jj)vnD7STZ%sKl){wy(jw_E z{Ao5d2@nyZwNqmSOD9~Ks;{- SED+{?GflXQQ*h=K>9ei(9HAGmx2h9jf#11P2?XX8u%Ki&D1wLQh zW~@-U(=2ogE(P_U>Fy{lC#GBuS6TBrC9S)VBeeq2Y;Df=RN5S74Y4E=o6RgTp!UoR z9IYxX!Dyu;nK$~&hv^tc=f4Y=SYxNBpNQROn5gLK4)M;}&24QCvG5;S44OEW*`J?D z^|GTDqy<`!HKX4V{5umt|D9y`e67 z^#eLoIU%Hp}f8#p#l@z7O3P_O%0 zhmEd2rt{)`FBDnagk%V6=%D&45}RMpNgnDeZ9%Tth;Y><(#H{5@3R$PJ)lsmR%5h4 zB=*WG^+s~J$E6jyNB@QK55IAhaQIT3wOO0(`ogUe%84kD>aebpsG7`7GC_)^sb#J? z-p$wh*hT$^86Np+hU$E#*n8#cr(k1s7`wShLaDPvf3xVEZx>&tt1^l 0_zrwBC}}R-7FsF}m~&+Vf;XWi7tfu8$^S zBw+huns+V^(JSTAcKxc~dqLfOn2D8lfkT^Pw_M_au)glrOKigc%P~ZR0vK}qe dCNZ9FqD^v9L6ixZXm*8FMxhf-J$0piy| z^GLg%-zaSjAN%`PJayo&(J8{|RnBS!uUZn<#dG{D5wBc+)Wuoqegy-}*IQifIJ>oz zU^Em8EYI~?@BE42>5}`bMj!-)y11W6Y!1qWVZ>68sHt)lcw277I3HjPmaj|ZNwY<} zF*^OeZcUCo_E<@T_bl%mE`?;wybW>Zxb!jEo%^b?0WJ6zX8!dY!!B_+SC_cJLPc7J zu;U44;}adDhSSV&!M_Ds^HznD&kXSvt6hrk4#rI2c^%w79)ima)Xx2`eCkZU)+Rx{ z(pzl})=bICIW#mEHoE3OO34B;c?qM?%)lZqgo=z^a!PFle%phMw)|hC1Zrni=ch`h zqSuyLj&2LjI|^mg7i%gHphExYyW;Dn;CKqG1BnwMaQ+lrd99E8Lcw*Q*)yHZpuhQ} z7rdesVJ8V9xXOsc?nFK5xE1HrJoA1UjOF2>h4o zMAoVVANqn)W X7W0lII#OzW_Y*rcsJ)drN}6J<#x~Og~*P&mgxISE!DbME@9+` z(wtBcdDgODRUrbyqZxCN{?f`3sH_;4nESK&=9v4DQTCnNx(7cRn73$a#dxa9>=d3z zuFidPY72T3?ZLLnY~(*>e)&JgQ}*>{)nbDI`H{*rsK27ab-&TzQN(5ZB~ @Bzym{xh2EuY-hd`itFrTKHCY3EdA+frjNVcIGUi1z(aRD~|* zpsJSFe^Wx02tC?`oTcknF1uo;D2YV2f!2yx^s2yRZ_Bbx@PV|e>x&W`tjK67)|VtP z_uzW%t6<^uyPH(K6Ior(wTihR8O~ApGFjsY%>S~Sd}2W#dR=XMa1$`%ZqD&<#`1xO z>*0n9{Dk>>x74{ofYT0GH8qcWQ;^%9ivD;ZQr&Q1OnI9#{xac!2#i5*{`VE0J1Sfw zH;k+CSCOHNKlvQzc4Uo1nESgaur2EQMYeNcKfPmziEnrR m6i@NH0E;N6|Dl~Wvi$AtJ;gnAR*9jW_0g&YQ` zI5(FYH;hyET+udBYsgKO3{ByXp*h=(3pr`uM6=|c(0!Za8p8eUZ%x!J66SamBSkD1 ze8Op|WVSQcBzY A>B@l`?wvl5a zd#15x*;=oi qCQ4usB156jyJ=ySqJQN`wBNA$FZefbS|v>-dqW84J&@l2J`UrWBxye^{}1c zEuOsi+`z=RK4{d%?tOz2Vckw!MP~BE??zDmqmQq4i&=W#bZj$pV<1kzkplL_Q@F+B z_x?EVBUq{G5L~zJ#fNja_LtxN&@#)$^I`sHnX-0feMh34mPwWo&c_$e9>4cg=bn(i zZq*;EIe(lt_C#ba1{;;#1TJ2{e%o_=_>prOu0FA;v175&AlpqKJBZf?)50P|bolMs zC3}9)am_~~Co9by3b%zuM*fy-acc5$75hjrj*+_ehjrC+!>fgRkKdbBO1uu&c1RRT zM|SSzGd*9HJ!_Tzz&E!-Q7HXV*v&w`vZY@#V#^Il_AL7ixbYsKhl)daokvsKA%~a2 zHz#X-pF2rtr?r}Y@C3e?_@|EwFu_#xhp3npc~vh FO9)8nFrLoD! zOCh_fSntUBJ>DgjTwtGW7mFn48`|R-khKMc!Q-%)XR*_ydj=w@2JX-`tVcI()!LmS0B- z{ytLIR-SadujR3vG@rXmUv@S>L-!spasXzHFSr6+hiw>L_wM8^mi=SyV1=H&FkAW% zu)2K5Dgz;cH?rrha>x4P-=*%FE!88L0hcY49vHW1n#83(%{d9&LPh%HnwD*mqrla~ z)9-iNn(jA=zEQ02=-AFV35-&`?Sb!b=$N93O{@c69pVjv_HJFeZ9Ggn~EEg@31+RPmG6c;v$dFZ5 zfIqDGT&Ds|T}a1)Qa7LdOQxWkx4%kU#Rd=H{Kvm4(Y=%3l}P6UNyo=C4mY%?T3GUP zy)+97)dOt6=Z{HbUlz}aahUITNI-jrcL{H?{;PcnalSX)dF`eyPYVd{r~?4t4y=aD zN7h^T76^ih55A%!x@>&qZe|*B4eWgCb3;HGj&EM}93iy;Hfx=m#uzWyW(+pY&5EOE zbGJX&e6c-GJ35IBVVwe48E8B(%#2V#k8RL=<#4>_MpL&>+olNsmB|ZL3t#xio1op- zkq(Y~xnALqRIzV%7UB^zP!6yU(SH7BgTrbvJM%@vf;?fi`Uj&(QTpw-9cWSUDO2ON z!~T|G6ZJB=#Rg>lig*9q;75XXmEXrWy1!LU;RC710lJcQ(HAzNS9y2fmrQBB*Vf3K z-23(ixhAqFF#el~ c`o~U)bGCT5&Lx})> q6te;x=&e4)%kPk16j7>YTr!>H*~E_Mie6O_+1BSFH2qoWO!L&s3^q0 ze868T*Tcv1*yHop|2`2{el+rW?3c={CRjcEKIaVA?f@*|Bj+mbI~=K3>)dTOyv6(S z|5F%MUrXM8lj8m(Lh0mcp>$ZAr+I4jXWf)p0N 7nfo5aQrt(n zDr;gdY=~a~pinWXTlePs;P6s)2xQc*`sUOD OC#7A|YS z1YeMMIZj!12q+SW6H7@G`@$ZZ?g@=kMwyo*S|z0U_rbB*X+>>pQu{MfSnoY8;6EM+ zr4QfYwTnIU#miuD8c;Qdcl)<|k7w5w*?2_WFV4Vt0y^bg N`@0{Npako_GzX&IgCbQKi`*k@fmvy^*j7W{_DojZKb?*@ z8Vkk4%?qWV3p>Bp%XRS11quK+NEt+<78$0}UaDGYA#d?~r6X+LiuSBKM82gGX^r6P zy_JR=lbRVX$JRS#RRL+f$Bm 2V$U(T? zFelQR_j;I_YN#59C*iApx$%E wHSy#c%=vBx=^{N>A z?)z!8#?b8K?$N^baTRzZCFJ3ho vO&60br=GlX@r7M`T^8Du9W~=6Sb!zC5T;`S z5y=NUu~s3?w8pB7aX26A&PF@9Z?mGySrwW6m;RRDxBkf#JzR6UsXJQXBrH3@Q4j=# z1n)7gui9kgTR76~1KpMW{{{p&y ~% knY9E < zIU4b65xiUb#91hjS^apU+3x17`;Aeuo=!V|x}?oKXgS#&i4nZrccg}3bu$eI*NgP; z?wCR?2~8o)`W6_cjk>FuF@KtuR%e2f9BkNY`Nst)43&OY@3gZmZSx)2_*#;TyQ+*$ zbZ%$>Vb1r%*8o8LvOi8PS@)IoR^>4Tk+l|ms;2Xy?9WHjOBD_vxz^>$^+6wUUe;Ur zy4e$X_@Lp#Zn@b>|AMmro0j-E!6_zYKwPvstRhnnNyP&HqF_3dU?A~M$~G(>zUgNJ z+zL+`jPm^WvcOwy!5!jv>2_|j;B}p8+8tlgpUJPc>n c2zd7zA--zvxKg+7 ze0^OOba0R6PRiW0|Nfz8q)g`37DJ(QR4b5}r9 +WiLaMms{5Bn$L$Z5&R5c^ z3BOYxF_{X%R58)**!h#$6pJ&L6?LX>lC@{en%1>Z6Qnss@Gcp(vxP>ET34?lp4}~+ zRX_4>{<+D6(0Z4&TX #ioRPJhjrn?KbvOl$~lZ6j^x{&jzXi!D#*!D zLcui^89Dc U5>&TQy?lI-AKW@kB--_@wkWvc&Kz?lu+ zm$2T-;Y~ivtFFs$GhT41@$q54??zw)r^Y*BepTej%<#)WkQlGOID*j1g~}qN`E5 zm*qhbS!tIuh6903-VPD(XMf%7c%;Q~4f>3kf7w11L^)4Ie#uE=hsv~fx)YCIoisW& z_DEf3ry{jk@ixd#8IQ^#xD|nX2ef_Xs^Pma$?7r^gdzE&A>s7exMcvx=0B%CGKin4 zTg&MipUNU`LaQR=y)*2^bX_)B`yJ=y&k8%l_UxC|RoYRGT5#kDZf{ch2g6DE zCdL(T8=jb&9T~6bL(>NLy2j4X4uPF+A-qC6Mhob-oQ}`{pZ0sBy8~g`mzIC%|KaV; z 3CBUH)~l0AD;M79VSjAR{yQI_ngDJ`;PAA9yNQ_R?xBxGL(6S8Dy z$U1iBdkwnpbALYPKHq 7$HDc!uGjV2uGjK>&6BSLbiEu+G~?VTI2o8B)>7M? z?li(vOGhZtobUP0pq8Z?{oTQ&*L4k2q?n0ZUq^a6rrxaN1d>>?ZXdDcVGF@JHf|Q` zrHK|&-x(vqD1NF%+o}vV;Ky6_q-VTl!fc`uoo2g!S>JE#t4}Thl}hTb2VxJqKvC@t z>449?vt3?G?DuafHt}5wR2SZoY@+H2$-t19X|AJHTo*m#R$|YLZwYYRvB8ig`h4QI z1+YJ(dlJLQBFpPMs13&X2>cCXLoTM8m_p>k)-4LAsjg+dt+*)rVp_4~Ta(k5n5Ibt zlgAClV#}v)zC=amqOq_%6*tm7H%(SZ*b8!tHPzj8*A1e_$U+Y^N-8vE!k1zM79-v? zF2AXzXE*llxTJduSDzvk8}IkOZn6U%J$h1n*UKpWEoeDYPIB)RqmNfeF&D2E3|AQ; zLh{j;`gtuZ_Ow3IKCxbP3eYwusui8r`Ub02xV(R}_d)tCaTT@o26w8dD(!3dQKIs) zz_U5_WV|gtAVq?=EPIZF^y 4V_=@IkBK-wZ-qKnoO~NB2uQ%V0$v+Wlr%kH?B1YX& zPs3S_y9YMkGGd+~a~n;jm;*1u_8I=TL@2$!5D#S1%8}}Mt0s$UBa*sq Ox${!#Vfp=N{~%A~f`sv{fk(;~7f pYjkX+h7I1f*{V;ZZ-={CKLN&|+=*#et1@ zxSIzf+qsvU7SCiw1bxJtL|{(#9{pRT)1Gdt9_-60#`Csr27x;60I?;1c0tS>)n4ve zV~jiz&Fr)2gogd_^~ov~kEvw-4|QuB&;jl45*O=%81KBQgO^|IJ!|kETF9?xFV>mW z!_OXPV5pz^NC(hdysL zHD22 m*nnGn$JQ~m`WiDf?$}9s%Fs4!-`dBEg@u%uywf}0 zRP(Mk)y8Q&S)fn`%@o%~r28@ie2lkZ{jYo8TRB9cP-I|}9us#gmd;q{o~#O;fxpq# z;&b1lj2Lc_9f?nA`?tRh1tM=dvqWd`3Hc=7dYotHoyRBiS7j!~tI7y;^N-fV>_A|? zpl6@y5>{DOR^Ghi@WZ~a$TiUBZnW4ThSXnJ%%5eA$<}7Z)n}Iyxc}557o_MJ>K}ns zr5j^Pe3Q&-2i1hsvj<@FLcfr-2J16g*e9hG!Mhh1$Z8A+UP6X=J3R*HYRjNuJTfp$ z{PB^t ?*cN zT +@h}8dWj7*q|O&9+&qzs*^LZd;`$6=Zx_S zVhb;L*CBm s^m^`% z-wzyM4tzF5<lQI-yW 2Z4^tp}++!epepw~9qe4_bGt%x7@^9~WJU}Zd`O?@LSU2mry2&v%S6gvAHCs{0~ z*PrNY4;t=bhVnkLB$&DGqW)8#^&J%eV5a_thEH= zor)$KYq_6`DP^?5&FJHD6uYJV=N|nS01}*l1n fZ~(pY60J+}^%bb+1$F{4|_%82_tgK7xtoX0+61@fLr zij%3a#b}WLQyG7fE|pkN+3`pJx>&-O)5RtXYC`P7e!m(Y3Ygnmza^-fwQd|FjRXD4 zxaco%*de&@GeSvoilX5~;3St%*3ubx{6dNrqFG@I!>BKVA3FI3yf#E{+s>OQ*biFp zxIldAa*N9TgHFG76r9#zn=JYO#qawhRgE4qRq?M4N@&cn*8YI~?FK qCCgsd|M7nLwa4CRqQ0#RPhRy7unOG;;Iv4*6D@ W zOzy>~5fvWW=Z-V!G)ouS8ed7si)VQUXcF5vgBdr2Rh=i1FVC;D1Z^JVFrqLGH9W#P zt&`4ZJ?b068qR+@!sk^ZOyK6kE+Iguu39^paJ;-At<;yL-`{+NZkE(mtfN13i@i4- z ALtb^Bt`!IYtu$b!Yccq{tUd1tHE2_Ho()_xSxeeu04%Ear!rWWz zUuUeYz057_rzs1o_c(U_mcWiwnM1-pCG*a5%#^)*9{lEguhznZDtKwP^;dQpIZ1pg zEKP{7Sr6vCAob*+yqyteMwR b2p^do*kA8+Ijx;QdPbCHgfp9&%J7#HYZA3s_P zq{tw vwaFS`*ndmVZIdZAh-rSe*Km(&^}?peu2bq_cYos*qU7pFp)7HE)3*Q zO7F5m7Qe$jjl{Ja-4;1Q3iaZUPS}barml_}pYF6CFIE|6h&NvnHJCfyMlAoa&LQhM zPu3I|m}f;!e;io^(M1DW>SF}}4(S0{s;$TAgp>;@&n8@xdxJKXFyL{dS2t+e^ZpD7 z8tr#ccRqUe49!;syAoO>h-W+w{suli_#xKiU}U%#z36>jxwEe>^WSnbdSsnM5}sZS zGH}zxxIZYUrnPXLR=jt`#5vLYcr@lK;uxnuH}>&^`>A~MQNUT(9|9~L5{F+DH6?f7 zE<7P{PG|p&$Fa>`%!{@apHQ2Chg!OCv$oe%r;TsRm#2a6MU1+=Jx<0(eb3!IP;gOR z0e6QqEG}5K9Mk(Q$ozN$(U<)UA$t6tTVFfO|Eo3Na>mGGCgm;)=bqm^YU>QGXH)7W z3*Fg2G`nSX9?xZoeqc=2(ybQ8DFh(0BVm;3uZSe>Lcz7QB t=_ho8wD(V4!}Zq zdk}3pOMNRdwteh7Ga^JmrS#|j?#(sZA~eEAeQ)P7>KL?}*C)g6`f zs4J=CbMg#XlrS;) U0c zv32m=S7ukAh+B5n2DV?&4-sDD)~nmGKR&^UUASUBb=v^->;%$$y&+v~VDI%Fn1ZNA zN{#dw- JQ8#FzAVCS(~uP5t$1czEG1w_5JU%NM22Z?O^fiD~b zG<-kXJ9%gzy-e7-bUP)mH@hbUT5$MKL_&5*9ob0^)=e5bV;ZpnInbhr2oc #f>+U#vw$5BHVCvI!_MDFi?Oz^7suatu?O?vawXH&29L4#C z3vF{kE5jolc}% !n6?VIo;!UOOIg!Fw7f)XehiryR29VsNTyFocQh52j zcx|PZ!ec4Hd%L`O**wfmFcy_HhgaXGMBShZ`o;bcq$bp_6dtyH51hB0>4~_6wX7DH zTDgJBi4OF=fWxGGccf;kbg0eei=j};aS}^M(6`)r! )GqR78!hAy zIlan>@%3eE>Hg~Dt+w+m4?yN~ZqtK!=S|9U;RL0-M%ZKLo_|kLPETF(bh+Roc&nV! zJKLnHIKwNIzZj}dc}E&21|6 !d?>c&x=aGDL_2hKJ@We$F9{D9ud+rQ2H@y-yvOicKb# zlX_nll$}I}j)6K;kaV5tECS)@Xtpq?h>pd 2Xd0E|FLEh`uVza4+_07d}v_J*XBr*)qGX@P^wh zt|vb5=yfrwF^pyhnj-;djyiTT{V$VC($#GqzcP4UhY1H%c&TjN&Q3rWj%F)8N`D~S zh91$BB77ye)sJ%;aJ6}C*GU@ U5=ne*EzkXZJjj$GiLa(c?_w z(t>>A7eYSDubEFwcsl3CUmz@tEuU`Je6(fUU^^fkwgOpQEYM3Ba*>^1JAbQ7*x88W zz=0hh-N)W;s%ia+0MN(R55C@27KtEm&X){0^-h>5X#E3dvbz2n^|LmiI&ddtc(QU# zc<6OAf{2}QaoM4f=cHMJIfebDZ|@kgY_$LzpqeE$Y0pz!HsLxf?;+Bkh|5 D4& zoC+#ep3Y$T^LgPbw^*;;Xde^fBOUw2Ylm>u>yrLTC;uX9pW@`x&@D(xdTgcM6^%`) zsPWMRTJG)5FT`^$eN80YA(vO%6{%&XU=JEzmG*CY+cSJrn>D`p{HV %LDjd@b+iS@sMLl!dGiaq) LF8hv8CnkJN9Qy>MFz3W6DClN3#Y^;if zyFPIFu@+@k79dBrSZZuOG5Co 6ed?KKDFKlN! NdvA>XVe*9;u}HI8r>9 zl)OeBHa;>Zji0#|R=`+S%iFKtrCF9u)fIVkT$QB3*9?iz;3%&9$5D}vQuE_89vXev zJdEeGxD!Lz84?Mo@htbU>2aHinu~M}fX8l6R)#x&Zq}N$7l;IW{F>d0yN%sC5E`DV zYd3ub0ns%-pYUht%EFh~$_ pIs1G;g!c zrq4q-x}FSqy1EY=tbE6C)wW{bIviCYU&oJIKU>$!82*W{B$5YR<}6Mt#Sm-Oy3gmI zSs`UF*1|-IK(DQ@FG6<~Hm7i|KisAqz5YsO$CKMnMek*m&~3aEmfph17AE?~K-^fH za;k)-?0`go8kbG~Qm2*WSD9;ZueN8DA@BZ76JC2-A-CFlvoK&4AksQ)&eWcfgG0iW z+d{>7^K7HQ3+`4BfvMx?%bC^BRbHPjGd|B&R8o9&R_FAE)6GwxCULe_k^N=M%bMGm z=EJj5jK`n#sxigZM{^4owm(OmRx%a!l{0TK8HSu*J46R#Y7~~?WLR0h02{}VB`6iA zHYj(8h4}L^FGhQPxgx$T@;nbdZZ>ZH`s>uo9PQi3#j8FI=VY%;x_Q6uM6HV8E|<8b zb(8Ffzut5yA|jJ9+&ax-7-^0TdW%k+o1j3p?*kRPx$o74Y)ByV7tfk>dd}k^QH>!d zl>79YfkO3Y43|7t!>w%KnWVe~G9gjZY9{!$qM~HVb*QXg*x~lunFr*v#q=gVcyJ?- zagVna@9@O%MA%Ij_R`y=Bg5ZU$1}rRG)tS|q?uLq6O B7IEQ_MI^O&;^{Ke&{2Qq&vXpQwW>Es}6fsO!VGq8)FPMov-No zHh^C
?O#dtuxEN3ibctRDF6X4^d3&!oxd5V1Y^cacf7yZOMH!GQCm=2xO zIGOV_mCis>ut~b`y?p40ngQ0jW+jkd1fi&@b8nLloom|NN;0h_G*ray!%1{lkK>`3 zu=FN+@SkaSCf5Qb_!$T|`sx_@Yp`mH>r4e=u>iK(yONJ`jNz5w3Ga)&dl4O4zq CFq|U|g~Uhzf>)Om7hr_0@S|NA2R16*JE?1-)aa|EM}C$*VVg z3p|L$RPOp9J#3(Nl0wXFoai#>K2?}(%ofiTaBR=;phLStLSN9PcBko3%^0DG-C70p zu9ErT%eaK+!B+G#3aY=VnzcYK90bD_IH(~DEA<_XWQGz!gtj}OB`#T~i}8i`wI13z zOwqOvm+wIJSW5S)!@bH~V=0g96PjnP0+1Mb%q_9)L^Z5T<>xm?+n<|_^VHdABh=es zFYJ`YT)>*qgJ{WE2MAv#PXV~oz6+`d?fmYP4z5e&^{}37F?B+_1bfB_Oob_FR%SB> zSt6Bb%%FxSak7t;C%VRhDo|PjkeYgRNQRok2=@AG_%0(3j2W bQ61LD$2_BhW6RJ0<1OP9F2VcO!K~Y1(UjtMhuA_9M(C1w9 zE;xmXbZ3Z7`)NMQ+IPU2n>YaH-7bi;Q~%)D`|XaCPFvzmSnYY#$3>8YI9O-BSF@wD z6CTJ=%xp)8SxQ_AaMMj^z| z`Y1DTpryfI2;VL^%|6yB6UNLw_rB!c1!OL&1 z$B~*f)JtwHD$8g3M`Gmz*l$U#>@>Acs)m}$?T+HkJwvwi`|yM78;IM}$RFDqL3S+F zGu8cp=X)a&8;eEx#N{N#x 0ri1;(*y9OvU0i*Q0&P(=$A|CPn!&2?!Z`1uENsob1sPu0F@XU98dn zHS-h>5Zya3%ztk>X<8JZR@M1!9|T;cT(QRY-rEn19@!)1iOYuU|46++g!TtF^Na1y z55+HqXSs*gbZ+jG4kgWsX)Metlm}eMKSy-cAMBCOLeXAC@q- h7g_A+ z929i~!0qevwEjZ<&s7on5X=~(wwAFkaUXGc@P~tOufbD93AJMGA5H^`_v$;v4i%vV z }a0zQ*hU?V-6vY43 7R8hw7#=r-&6?Tm=}nW*N*m&@k;+B3R8*HQ|p~EZemSjEy`!& zAuj71{Ufy*?X)2n+S`XPH4Lq ^ecoDzdbL8d+%@Y*TX9|g%(f_T-hIvo{)rck?H08Eg96zrCHH2;bTzr_T>frv z-ffet_(;pmC?eZPTJabAqm=1(C(&-V ~VCXc1Gn>i&EBQQsJfD&oH3v9h- zo*H+bW0W%~H)M%z!HW8~? 9? zjsS~u@ErcuZmw+yW7 cU!P^Z_HJSxXs;{a%3UJBu+W? z=XUQ`J9th5#0so5TBBs`gB;qcF-h?tw;$m-vg%OH#f?8!)P0$5o$NmM)3ZUMt1XNT zpc2v2vyRJ&04rj3SX|otv=T^rPd=fVCXiX9wpm9HS9X55DYDkhHnO?@aj=F?MULV2 zplx5Ff2yfjc}rcnK>+it &!|ulIK!T zJ3;0>CJ3Z6SfRf}|L8C(&ORveCncXw6$HD}>hYe@$wF$J?#I}l+h1gPduaA7xc515 z?^5o%eoLY*?W?iVG9&OJGwu0&F!6$<9D6B2w1Llk Xlo*dPa9%(q9DQEy}vDx`4%=9kl87fW6?4A><1jef}d zIRgY3BHu9~^5rzOaGEZCH;KK|eId()(R|nBDy8H1Lq;*8CpqRYtwBoyA^FO^p0e1o z=#~U7xkht4j}LDTB0(Kz`}f^rV^+UN buE+yH{osFMfLk !o`hbm2XjIn0xvR!Lo_^1+3U3D@T! zApblVlKPi(ai2EsR -9gj__#C$VM@uRBpXojmAUe9G0(fM zD-rkD!Zl>Lp?4$mrFK2+r+L`plR#evD<2duX5ZyC<-Z&~_Ymz4uf3Ci+}(C)lzh3w z-$+cIE=vP9H6=B@X=j=%&dV?59XrOsdQ!ednT;X%5mPD9H#!4J$^~3h*Z6q{?_Q>s zif16PJy_3i!QR7mEpp0KWGU;#S}uJ(*gywz=eP*%o`9ONksiaJP4;8%Qt2 IWu zYdYj!Liz%Cu0|*MFI?GejLK3^kItMkN~Z2elDeZyNbQJ+Vk+mtIozp*xbaE>4k|nR zoOy>D9r~B94Tn(O$98AHDI3?R>9kup*Z)8G)d-g=x>IB3)D&yeF;|~_A$CII86K7u ziN&_W3qZdd`g=mp(;3Vf3n#u;d?&|C@}4gQRmPw&{|t2jP>oG_H(U}mnI{IBsTsS* zT7J2dS_7~2Uud$5%K8SkqGgPHv|=vrs~Pmg%hN=Lzcd{D2^VnlXKv?%$nA%&ew}5X z#*0d$SwGF~aFdxL=XVx0|1XOkKxI8-xs4R{p7l>H-AcG^F=5bTZg(j?cLiJz`urX% z5bNfiR!`DJc=C=cj^7G$j1O2Y*8jdmRc0WzDzhus0Xr`7o-#W@k2#+n+ zy!3FEQrShSY4O`({+`6Q9lbf1gN1)KO@2anFiDNC%~=5|GjRU>) zSF$W@-AZIgBT1o>43VZ|_uo=40QiP8x5sEx--aB?7oqluDs qO6mB zSQ-jDihIuk_Im8|%f)`uB$cW!`TvVv0mXdL9y73N {OhtECWdPzq1Zkt@G
_wgD%TDn{$6CFX$@cx zRPGmgYc8`d;3Q9i29I_-sx<4sQ938&{;0}n$ggdf<2xfw<-gN^f61W?n9c0a)DwPn zYjnTPn@CO`znt!G*NzXG_U>U=n0B76rY;*sUA8@*HZ?(yFdCAj8CJGo$ITW4t(doJ zcZ%e){8o0tg0D=KT3V}}+ n?bu!*ls<-PA4D9iH;XMYjpho?sd2;3jgrl*qQM4 zPtNe3m+}uUvb}!4|NdeIr8HCpy;F4Z_ipsAHT;LS@}9@`-`_m{(!D@A{{2Jw|1VM) zI)OTYKSJaSp_~z?ferwz4&on|20!5asFfYy_HIG{`hNevZYwN?b~Jt*V8J;UUsm$N z23N?H^{i}AvX^`nmKH8HyVE!ag77Qti)TBL1|9XuN *Bbh{GYlkLB`ukor?v z8{6Zhy;o-t8{TWRoDCXG*oC5BbnRlEs7F>09Pv+g>VDFI=g|WSh !G>e89LAm$wTkX6 z2GtGMvb6E2$IrN@+bUp?A|~D!w3b=w6ke&qbvvbdaH_Y&{kp4s6;zE_SkG*x?3BnV z{^phjYB5NuBAoLOfUv~HL`c}{Ol=JmJ491Tq#m@#E02peI4}_sOI>cvJEwbejF>8) zBCe$S8Xk*IheeHpNqT>TzgJ{sH!hPa(5q>&3GYns3kRi;2jTB_J1?#v_ZSo{_4|oy z32Io`dlEZH%4n;EcG?kPgUjIq>Bd1iK@lBmO9yYueYg{}x{>5^AhmdAe#%&(tuyg% zPl{NOOG7f*JqJ{QXXIPiX!q>Tj$nQ#U5I|bfH~#+WsQ1JF$3IkG~ku5REE* ;Fc;(`LaU}b{jp0Q^6oGc)Hj3a9=sBI!$i0&a^exCBNJQ7@`Eyz z;_`^>&Cf-cSXcr;!|}@GZ5HCmG)}pPamF6j3mNM6Z>C&?W(bW_xs>%K+qE98Wa1ZG zBqfd%S(k^TU7RRJZwxs@;|$o!$0W824AY7<*wE` DYo!s5%tiy=tHEDOv$cwqE|< jTuX6CvQ}tDnrs;_v`ukx=llU`@!faD>-Kl6Qq-8>75NM3yOGa(maYRzDP*4 zlLZ}wu@&k%bOtA^@b&z wDTS4v7=(K^Lm&}|S(+a29e53>Vtst+a zW|IwA(6K$6VhpnOj%dpXF^?GeZMft~PF;Y<2>%|Mb)=xTfjG*(y!c?T{Ys0V&l@5* z#JU^LCb!M@)H-@pRxGWs+=Km&=vFv|_woSD6cQGY4%&IvXCKiTh@N7hGYB2`cwsr_ z;qHQ#PyaXsB;Xta$L^7A1*vxvGD?q8ZxZ}h6{Ny%ad6oc2eAMF`@2( 5<${o9fQ!2Se#13)liz bh#4LIpun4@7z=4M%?qK{FfQYCt@gkM{+dFKSAs20Xt1rcw$QTn^Q)7Oz1 zrl15$N4MV2{Xx Jw`BXOZ=spl+?&5sJAjpR&%JBT(2bsoqD{Z0um zUt;e}tw=)`p$;5@xMV}G(VMvR=BqLGRwHA@mX!UStA%Ld6mtZ_Ld}xC`x=TNw<89W zi5!HF*yIq<>ANk0VD~;7x`@;+^_)2Ifjxma{Cn>z9l)+7fpR^&&0a#*7OnZ_`a2AF zyoA6E+<38T3S_~K1-j-ni}AX|`^py7Ounh0BgD|YC)qU2ZY8ar83H|R(xJ-n0LCO) zkeQ*rrgM&=elB1@s&K)kGHUIiqtDz*+4Y5AoBHku%`Aia65qbVa~7sL7~1Py#Hf1A z23G_B_g;5Jd>zG)wMt{e$l5btGImUU{_hZWGSv{a(x!53*`Q4?V`wc)Ur)YgXjt_! zj8=~6OT4=*ey)iRiu9GWIov~hpl%L%)uMh&Vsc3gCn*ahdeW$;4uUpYJfGQGkP$hgsF|C2? z)=o?FxtZV1OVZRF3nQ5G7!sJa7Oor=jFaP#_}o50zGM; DTMQ69RJ}0ire=$Uq}FdV_wV}C9=9)Uz&Q}sq{h8_@4>Cn3)7GP^ !6ctzOC;U<4rrMuOFhv86@7WKMxaQX26eZ-F4((10(p5IpYw};^jT12TP@a|)| z6KC`c1Us*mWvL;wFO}5UK-|YBu94eEv_^{xy6TP~=^8$=J+gwuDYLouSaiTO7Bzi| zpq~jwv5!bz8d#nUD$UJzypUeDsiSdi107u~AUAafiB$#@YO7%i-tuW7wh4!cFvclU zaO!YSjcjAqio`Z9zIovjW7+j?aC1=C=-IRP;|vKI#MY>`OXl)F&bE{lz~a3SWnQ@w z*~(PGk5fUQyCiZRQhS}@f9 =adaGw~xy~%AUKEY>h z5_IP^7;tL;B|0qz{wp(U)@U-JSPyB?^SqQ&Exz3rXay;Gx{69_upD8lJeJgx=ruPg z9+G?^0K2thzD6Qs9SO=*)-oRF%z;bt=t+T {Oi(R-un!{WLv#9NY zhx@b!@(G?hTW#mq%82MLu^fBoFs=*UMCeK1ZE^5*9PPZ76Al%{gL3gsDCnOy{I%z1 z{JRHOnR>zfiFOjBVn^9J1%o7JosiA}KN35RFp${Fx8LqmPOr19t-N_r d;f=ec!98X!|Nc@ zx|+XMZ{ ^4FXB^5CnMqOW7{=kNXq9-!QkSp|x~m2pBXHSPzK!CN2hr zTD~#3+aFz^*pDVmabgsftH=vq!Wb5oM#u|aV@RV(4-@J(jzCkxg--#mQu=k5K#mEt z3Ks#_AoQe(Ya-&hWOKZ!jdwl7=GGnVw;t+Y)z1+W2YF~}XV$OZ8Y>SNhxdwx=1r}M z9ke563Z^=%CR$1xks;Lx=j|mS{_}+7ZE*{fh!<*QU_$N}czs;h^xqVkKm4jT_Pw%y z(5Wa@P=ET|FsD-T+JLE0i`JoXLD2_89&0UygX8a+-+lyQIU)nin(j%(tN$nW-n%Lu zU;tWdZF4%%lcq9N!i6IEF8b_~JIx7jnLXaEQvx?A#*4@XjX-I~*1q(TMu0#vV{T?{ z%X{FRI64Z_Y_$E5+t34>pkK|0fq`;Te4U{+=ozxCbex$*PMxBG{az|8x=K57dlngN zJwSfb-b)&7JCv|?bE@A!eo-h`wk5`Q%kSeGD(FGnnH*JU3{DxI(~eHX-`>6FZApbP zNIG7V+A&XwNuc&taj&PR&D&aR_ORB|XX9$t@%jji-pidA;483o>gytS^CEJmnJW7e zaFeH;I%-njYJu+Kx|AhMWPe>qXut>HxQuD^a~MY>pD1IJe)7e>ui@v_Wx>~<#D1QT z`pVP9P_a+COs~c(k>z^-*_P70et!LgI`b3HknNiUe(2+h&1ibcto6dCC!0mFBqg^q zXJK-E(3yrRHG;`_Wkg^XM~))YAIA;1Z-=Df)esR~mvhXZ4Y)M8{bI%1WT*6R*9fPj zLFmGZ4!IcYw95dv2WkfO7Kbj=&KV8_8&*m1R!Mqz4- w5W2!Fr|WJ z>t~(TJ{ktzZ674@j~oUl7Y_C#MWL)GN&E)lb=S!pL8v*d%ciNVCt3U!B4ig21*iY# z{wxL`1_CrqTmt}PT+MNTF5;G%H8qAi_xhx)q{IW>%kQU|GTD?Hz|c|ek0#OS>%i;` zwDs2S^CyD_;h#-?8;^emC 63c5@%nstP_=%2he>} z%t`w0_QjH)*IW5DXEBj&un>=_8M4SwQ_INDdD5r?)|Z>&K^83%+LV|WDE%Y-<}V>3 zFK*xE!~GvyXQU?%)4>V?wmT?mJhRr-^uaFI7#g5u4_0cK{!tN47wpF106y($wO((*?f?Ve2y1^) K*Y(cHM z&E;vVxDFzf6qC?NjbG5xjA%}m$-|Chv~}3fT;q9F)>2ElmJGruJHVI$-xKeSG02O2 zUbsPPz#;bo=C8cT2H>WajIMAB&}-@@SF14nOt_k*SJO22hS0&Vut3K)QUUbKcz-9t z)-E^%Nji%tGi~Kyt$=ZORq;O>e)b@J;Okntk7!3S3shpiP-^ b xCS-UW?3@SihTkTn4#ak!#cK4PHCLd269H3S>wYXBYR&EWr+vGJ`&15t z$QOP`E^dcl71?!-*q3ErR)WVBu?OW7VN9F7bB9w}%A1m3oS MUy=iH&f48dpGA!&cL6FY2se={aw{>a7#ieJmi zar8s= nF!ezQOjY>N0bC3k87Yd(*XT5 zYv2#^;dY}u$!`Z*u3~SM{bJ4n&PH&g{P(j$XvMA)HVd4=cV+iKFQ2x_iR9_uY|K;S zSUH^NBRWns6dZ&E*u%R)DXo7Trm-=`toT??p-lPJ`{rz4bsf*)`@c)zJfYoYCTk)l z!K}%p^8w40C`}@)u%Ej)pMMOvr*2J2S{dFe+f2Ar~lVV!h9NSn=NJ>3#b1Y>Dgk zEZ7V;T;XbZ=KKx1dpSQdZK0OeR|Q*%=`0n8Y&8v&$N7Al`5lshX^S(Mh+n2NV)OE- zf08b%RbJLV%&fAgOJ^p(^|)=g-=5}44YTinB>6Mu7*rJJYQrE*zJc)XI{j~eDvR>@ zOmQ_tc$WahC; D?s$wN6oTDDJNTqO0D@OQSt@RpB|tO+Xlb0wS2qA-k9$xN zr>&aW6UFum2p(J~aDX<+Z05>ATc4|i3tGC1pA78U%m0*qjPf-bc@6u7P9%2B9VQ}R z`v^yPg5ru5YusMUTx7S%T o}n z^U@?f{5mk+=aP8!N&BAu4`V4^e=lA`NlRBj1a+Owxd{#3M0$CE WJhPyyWfNkk|$3Dg_}SHzM-|e zN3(f-@FC;J(m#$%X#}v|cVF@v5-lA{W>LteyEog22v>!D^6< (dn6|Q z_-9TVcicoY@&)a)2dmFk7XS2Z#mgsB@@2>SXlZP`=2v`mS*Qwb?s1npMFN+$y8pvR zV8`a^^f)MN2_ENsu@dlrc4(@2gZRf>Z1hj2>}dih-ppG4T#rqK>gGsOQC*_eGJx_f z^(WE*;|-x{T^pLE1i%tV`>0hS;<_l2J$1GrCcaJ6AX>{WwoKFDbwsRi!uRUu!xe`< zyxc;ZBOrSwGHGhuUuaZ#4>RTC=Da7EKewJHD-K#>uTEti2s;J9ztv4zA!fS*EgjsB zeowA$MW2ZE GO<_tU_G~bbDf20k3Y+DS~LbIKe6ns=!a2@r9#Y?7x-_K0(ZrZg= zo=2@%v}mrG^OLucQ!jpf6y494!y_HFP%%2$8Fl{}a|htl%ES+=)SadIzy id@b%^am;B+CZ&|D+L6 zMAFfSm0K{h_S~O(-bJ6oURfZ6Vt4Z}p{E$d*HhB0wNbcJ-Ka}|9brui*zlj7AG@V9 z+Iz-c0|*e3 `{vv zy_2wy#{H*9g;vLbUCBr?o+ZEbXg% *qf-cMJC z$t8-AZy`dvcysiid5x1cxCp^HA6jybxbR026#w|=OWCPZ1T-q8`V0G4{CB+&Ysa#2 z7I7`_=AE=0qMkNY?`$JYgU}f>VPTYjuFa{OIa 830*J o_8kz`uG_i_CU`ugae?Z70u6S!Bv3n9iRzir z`4bP7_yPZ=dDjQ6p-mO}^E`p3;Y2Kkdv#3x>}iW=B&uhB&e!|=0zOu)mfx$}(+l>| zpbfGwe;2RnIF`dVUwPN!8gm!7XoiRjzmGH|JpF07`x&aLk9>fy#IU7BXzxn?sjMTe zO;=n}?vR|~cN9^c1aCOs$x-@`=TQP%+%{LgUGiZQyK1jtmYDjY>3y|B;0ocSg6Q0( z)&cXwf1adiJ!y>pjA3?VXhZ9qzGc|>q+Xsu
01|jN?LJU9_2S Eld#hxkuO+okc#y*;+ z^qd~;Qn?JFwEh%^jJrLFmuC0#=k3S|2TqUkO#z)a$V32_qXTAyPjd6rHiZ<)Kjz+D z+R) HUMZ9p321>=#t>H~Gft*1aS_L(~3s%FjeMR-ES~r#4>&W>PE2 zwD Dsl|sSuPPR7S-tcFyxxPnvT(T+JIM@h!LL4a~R{jPXb`7Uyc#^9(c1 zqyE9)VusQrb{V^XU-AtzEuj8V$#qw6DzK=@zkx-mZ`p{yU&(H7euqe$iJg~+QHFNx z^%sf}d{!I=N&MA%SHOMz9TMvQD}dEK@ZyFOLf2d$UOFk@Z}R>B8NlprO@c^?o7tO_ zf?6pw(ig_)XwL38u>Vv|((&>!utyx2A7}MtH^znw3M 4Gr#PR{su?Z*kWx >M($GOYN|DKn*SJknHISuHrOY`Hu|HuEcQAMLUife7T;<=9VV2IPg zr$(c>W52)oabnx4F9@?iFxlwdmA%na0H2hyp0+;U9-jLMR2*+iTIc>A=|gkl_wTz@ zcvwqb0<#Xk2{3_@;2?#NAbHs3EMoD1-M?ntzWZfB+#(ex^x-LGTs!u|8YGc5bSp-G zdYJ$Ddkgl2t?9VVloaYngl2$fYBs*!#7K Qty0@gnYjs56N z&-r?K;AdAThLaQ@kOYWbq?tGq2LK5R-HNh}^P1OafB!vAE@A6eF-5Lit2{!wOtEO- zBIicHH-mI9X!|fWhs+j*v80)}2mZ99s*xz&FZ-{ ye~NU-e0#~MZZ^c?>1F K(l+t09>J9x4>T{$&ZL0N2KhQHPx{PtJ ze>k(nzoksV{yGH7$rnY!E;9uf@>AR{_t3~~zPSi0Ye*K2G70tFz9Ypk-#CF3?)?)B z^h1Ig-RtONu9>t{jTqq27hsIWC=P*9xb!ynrd)n9%E(_upnqc%A~ii;O{k4uFR@&h zi^7LY=A9PziK{R+K(&kAq;yuQ*!(dArZnv>{G_I>l|ik{Aq9TmlKnLfr%|0X?|L#X z*+w-^E9hefn5){6u7C?nyjvjGzpb0N{j+jt*kA)4B*xqJ>aT=_6f3%SmZf6lSgjNK zJ6$T;`Vn_*7h45LwN=m3Y>b-Oihn4$koaf+Tr9f^k2CfjsQ JfH0hb7x1B%{wX|5X(nC85HR#b^!juRZ5-S}S z4f8EX-$$K#w)YRBq9pn6a)};Kw1NFJ9Car$wW-`p3lo9e65G0^R+5ydaov6>8gx-| zyFlbF=?1Oi*rL`qs?3S?E88C%DJ!=_Q5(2p85R80eKkB5=f&4$HgsB|$@(51P|=*+ zn3VN<#a>%0y2t|o8kT9DX{lwHo^Ktb`#l620F3${yXloa-fp!+k|y p-)=h_p&}| z28_Ix0cv438D%NEptkg??)I!51>s) P!^F-N__6h!G!jaB&B1yEsA&H+XBr#>B86K(bl~B;Zq{^@HBN)k2u= zC;UijX^CyugPZG`?kBnk?)wi3aL`6u4G+Y_W+YD!6C=flaX5HYdwh*J(i5u~Jyud7 zB=5%&l2H&{lOVxCKKb#o!DiX_yVKJk!OqH>&;`no#t!P(Yoa&E&L742j{SR(&aMo| zt+$Dl8-tnWZYKyg*&^oGK2*m(=sLrkNp$KM7*03TAQ&>JIce1Kz_c)+VnYB%6!l3+ zO2><*7jIRes&%{m0MpTaUwuGw5~$)xNrt~oZR5INA5@XwB^8%M%yO2~KP4$wT8})% zcvx%r!%~J~S)Xj61bJzh^9NLRT{}oZjF7dL5if5N<26wcL4*B&I<27ACaavfQ=qWy z;WNH&x$VN; #Pk`#Mcp4yY{a-4@rJwS~NZbGTphI63r@ z$G=4}NW|+`j>`*@q^(kWe3uw=xTfe3ekd2mXCtICE6Jej -@x>21P! z#J~``G4DK_GvE)VT&|LN^+nkeA(@IrA1yy^j#s9SbQw`DOZJJC+6Boj;BW%#-;30L zlVeJ?N|KkU% |kV`J0Np7`i4-Vr*$C!(d=szAUrfA@IuG9vW&^ z`B4u;n^iw3j++vyRbLrwXd4?cO@PfPL>ShnQdq={o0h g_z{}>W21h}*0P7#Cs*kobd?O^eH8p>% zERU>=_OLlb)~d)S6f*7YcmV^H`-GQ5MV8x08p$V7FrYng)2&X&eW8xUVs&oAa$#g8 z^+zdX+qsB@p{y=Wi5NF1n;YUia(+Cj?R!*t(V#wovWzq=v$7xAKBgtlGj6(xD02B; zmTNUr{LOpsE5VP&c<(r^$g-Vzz1G3jrc3-|)D{OyZ`kmY_Z&X-B%X1K99U8-R^1k_ z686^A@SfvF#?8K?NdL-;BaWP!#jlT|M2{5wNxHK|beeiAwf)FpW6^uN1ui &>hM75e0DDG#z+W>qkM2#cJX|fjN9 4Rio~ z)Okx@5e^b5ciQ?zB)^mrqM-XTql<193Gj~0X{)fUeDddnhsmGU(;*y$9DDw03$PDN z)a|3A+1^|@u+xTF@H*v^6ZA;-zbN9~NbZRte_=v)&H=g2m_md2`Tas6gY-AM9rktm zGg9tABX3W3Uo|D`6bxrjOAr@e88=$B41ElY{2>vv>+yZJb5FMNh3S!<8xyA-(Izc;<#P_rw4;El zRs!#FkmF$+GXGNwtJ(L(4`L$D3{-IQJ@VL3Vhi8L>*;6#>p(Bx?R+SjoxGfhiu>p; zNKbXn5~)2~j*HV76!r6}Ix+jS@EEW)EKS9pP)S4YFI|(@-0_RyG3#7PJ(hYB!~L{1 z6H&a4y`iTL8;?lM9kNW`>)~Wu?nZgsH7wyrEu(nclnR8U`4cl&w|)c`g9k%+oWvTi z!!EODEu50~+$)4ywWVhYFbFpvm~ 8q|5wFJf_yDSb}pQm)bBNZ | ~)`>4Lp&s$*L=?*6XYm~`0>k4JtKX*%A)5rTe>7(gd)+<%9UXEFn?Pma6r{;dO zbqhf6i=iHSC^O%ITHGCBOG!lW9 XU14zO;e-28x;{LLE0nBF(>-RTu4g5cSdK)T zZ9o51p2*|q)U7O032Z&8vWi3L>H_!Dt*&S4+whxt)Hj=xGNGLxhL(B22-|TN;p1w^ z+{i#HD&)R}rME;GC;tuSRSos*F8TeEsRK2W-kOr*(4Qk3sxu#ThxLug-7s42s?UQR z*nKa=(sTb2u<1K0-l|d2V(L6fje7;yIq4vOKkfivVLV{^&}1udMKk36>6yg3l-+NR z1w&z{gb68rn=vo?>eC&@J{cLDpIbg|HNW4Z^R%4$6YA!IO#qwen|ewva-Ld%NH*PO zCoDzBMFV3{C4!vrdP01p%CaG_>0hT%_)S=vf!$ XdpZSb@KHF6p-ItM^d(8tAUeDZ1E4qYKFM!!XF6lkFP!)nT=%8}UHy*&_>NnV)5a z3EhUjY1X=027w}8=ayYst|;-`q#1>bUGC2g()q5p;Jg#&jm+bk&)PmZO8bm{AiN3h zy1Kqh-8z=;3@>fea=-l *O4N`2UWgWSEALIgkb8LB&M>T&W2Rn98XfB=)oi6=VkvP}effWoz*78aaj5A16I zN_z_Am)Se{ThlE+TkEV%tdJZW0n$|}m0>(=zEdOI@)G!IWf%VH`VQ%`NR=Sc$Z<_dJT@t*`BI*%2zP1 z-)oj{<+D8=@qqO1jJD3D+9pcp9i78xvCv&F&tw`6q0k1uF|Z?o?!XcpYwJq9D(m5C z;axAyZk)TtqE0pv4@?zCLi8a^T8R #6``SkG?dzJWt(305ebV(V>vG*}!T8S- zTDKZifsQ$F$USf&FYXZ&W;1UaI{!d)s;a<$p>|miTXEvfP5iamk(rIUP@yBCOR;^x z%Kax=`>@A+Vy_!SFMZbb?27s1uR_rPb|U-7_WSprs=t5Ebe!Yyo_d0x>z;*g#L++B zPlq5s?8)A%Ou>c8#pxW5W{knn|DY0Ybl$<4{@&M~R>VYTYu@X9Q*)#yd9liz6@p)# zA3WhV7Zl_agcJK4rIIH;r4_5V3DaaZH@rZX64o03zRO(&7}7FbaICT78*T+H&}W0( z3yZSiO~=+<3mZ8NMmNxoKs$cL$G%6r03z+x!OAPLYs6&Dpc$9$BR4Z* l zwe`9kxo%SG!UD}E01SsKWl z>b{Q4@0qcNG0I)QvKjyL8Nj;t+WFx3!e3L6ovHxd2At*p^N{}1vj0rRK!15SaKV53 zN1%qjd=|bnNMck)$XUQ5HwT^p>yZL1J3iC>%YT>jzFO+r5&pS6|6jjYn7=g0AD03; zKt3%52$=u!8UMWaPYeD3Xgb=h^Yp^XlHdf@;l+olS8%`vrH~_m1L{6!Hbzzq<^oC6 zB}CNMuQzw-uOH6tDBVeKO}KuYo^B)+)^!ph5P57x=c_|JZscz<2@F;NJtOe(dn+4* z6RIx6=5KlNcZuOYFHGo5TLRR~z>#;$p7d}}M_kL$Q}ZWSi;b&%W+ZUknXG@|LLmch z-~&D6v=ZIO(iI&*?#RFDapUiQE$iHyk5ji>a(uLv0YtNx-&a{E+aaB#)I#`O*fC z29XT?QI#(j$cyslS%ASQe;t?Ke-tJ^_co0b{(5&_6`!63go!Us-04Ktm-2mY4LSRz zg5S@6_#=Ql*Med jcM`mhFOaSIJ9X4{7{K`6(H*umh&=!8!8@;}V;8-Y z6;Y|DDD30CQ@*xan*Yj8(ySM-IK)o wYeVBbo#{$V6mJa1<=*FM6#tu2EW48RO=MluhaVD@lDIfN2vhcRO zb)GGi(nm|XX!AJkv>>htL8%L9@#%|(v>5vj{jii@PAN-MY~lX0{>d-kH 8rJXrnD<)xcl`reEZ-3K14n=sNs3cZLoGR%VVOiE~Fr(T6Md+vY=?g z`oga-9Q!tks+#Thh(>C6ghfzXliW_bD4>xMtV0rv=is)9*qeHOShqr>g*XpHwB4-N z+3$;(J;3f~2~UY-WaC3sEt#*9H8IJHEF<@bSEt6VsBj@o!$odV_ap%Q{Ns_Y&glrC zRe=HiIV>?BdqLI$Qd=_Gb8lD6>t|P Y+3E}r*oya1{ytcHQ;{IT z0hpO}K8)!WM(F*Jc@KC6`>cQX5zYgSnnd~9S9t*}>h>EsjxW!*1=7+)HzB>r9u_gD zPqt@1fhTL!8zbs#GLjQ%`+hwWo8KB5^LHcd;lAhnAHsv3Co(^E$fPcy6y0J^;VfMT zDyQO;D_EC(-=NgwLml6Y?}G-GW}FKQpg<8S<&m152IoD?1ZmrTOawx{L6qAay8Zj+ z?o8Y@p7ZV%c`RA h?OB#LMcD^GUC}nZy?FkW@E5{B8#(G z9qKW2v_}RYN7Qs>ZW#6nrP$R-C`HXnD21BZ#uNs*h{Vy3*LL;2w1=K tU2qr29-{Tl(4RF82`a8Y}arFai!yX=1%a z@lsb*uNr!5<|z7*M@IMi3KACUQiHHswpL!ZO+?DN^G0ZWjgm^qKH*%jrmfY`t?a*5 zLbFFmW{$%5i>ZvKl~d;k0q?z=O#BOOUgiarb?v(9>f5*Ls*B>fk+Q<9s+Ek8im1o$ zh3YP|()T=E3XP@w!|J*~KXi7AZkD~@CzkMt^(?8Az{QPcKZ>%GSlJk_{#;vAio>!2 zCZD?L#Vsv3#kalVT0_*5lsdc~hEPGPEg%Ym*Q2!5Ch5GEIO lL6cYU^d1%W2#Psy~?Yj^CRCvqS`pv0M9UEclUQ^ktoTuJ}lSyj7qVOZ; z$jEd^U~xHdmF&08En0_5ZGazQ;S^@*3|Msz;nz-eXxNJTeji2OY)o19?#wNJCRvo8 zUhKNH(L518u6#|ZwD30>@gLD}<9g?pjo!R1r)^gkU4KeWPE_UQm0|MPNM{lr*g)t; zP`oKN0td&NDf>K$+WS5$Du4{N4M9xb)DQGuJ}!>_xz3|&aS%R7ragPYzF4b<@9DnS zTGm~uTHeq&a=^w!#j@dL=y6r)>@za+UM>aTw?B%AmxyTggLDUE&74fyF2UX&4t{;Z zo7J4q9ret*IQpo$u-rTEYSIJc^XfV!2|vLLZ;G?G#zNucT6PP*&xLBj9+BJJvFwwq zgaL}_cGGeF8u)4V8`<+N1qKlT{&mSBDN%XG#c)AWXXB@ms#nX4WzW8mt5Q|l$D3F4 zE3W(SmdIFOTw+c)FK$uH-AwlT!d#Zci+F2?+4b-6eG%u<>LWdiC-C*`$(5)J#;_(l zRgA>3=CFz2VIKG)4s1mA%h~Y4)yoNRa@MoFd<(JN!<116DG*`pL-PjBL%T$ c%lJEpsrV8OILSM HN=4k3d54Zz#l3sxnRN=EyH8NJ66r7Nf)SbO{ z?Mmg$!P66OPYks;t3@8ql~8d2U1%puT@XtJX$=Sg%Mn1*>q}kD(E^^aj0quvXyi1< z@G#96-*HgK*1p`y=$EwUn{-ve-RyWO_D!3QU$aDt9acE;Csf5@9or*w#@&{}@+|rs z{^&!z=qLxXan_;f1>QUwdHMyiFc6ZEY-mX%+i)Tduk$ol?uJnCD=c#Gl2>>u$2$np z$xI)E>~-EA &ag9mpWAgunA~JkCCq@Q zk>WNPL(Oq?Em&U@^eYB0_X6hW`eL5UsLF_2H-;CVrLg;IYVa+`h}qJT5}jHqnPhx4 zt#ZTDGom~_PlgN@A1DK7|0t5ElLq>`t}`^u_JsproY0;eu>N2KPnSeK-$*?#;JytP zq1rb9yGHc*oNe$D!$nt`*lmsC)=)CY 2>C6fB88d*l(K|S4uA&ClhWEm;t z*I^it
RNss8 z;(~s_sqhQ4PhOAqkb^l9ZxGy%6tQ3&HP$!ulba#kLL>#Hq5ewC%EBD7Uem@VAk;vu zw^u0o+DAYgq|Q-FycHZ)s`ZN$n;q+?B6(XuLCf~LAuZd5H6g-r)sSxIkrnQtOgo&D zW^jlbCxB))1dgaIl2z!`Izri&)wvsKIqcpf;7y8(TA*fF%XpuWPLa}oU-1fI`@(ba z;N)-yHv>ENsX6sC&l%x#p5{}=6VD$Frp;IcI7=0q*e!%S7qWxeTFkNh85ip<0CO;;yl?jpvo$dv#t-+qrK#$@&yTV{_SsYZxoK* zM#$v9!PO8t+aY*Le3Us=ag_P7pNyDhg>9~$=a_J#DouVVlbbaZaG#!kKS%APcpx9M zhMw*N5vrk<7IF~wO6kMGpwe 7N^L z<&}mPH8p-qBl`( FloU`QA9vTRyi7M7Jno(?4gU1e)T}mVYFB#(T_`b& zb)xN >f*t27xU!KUP=dIL>ygby9DBL z85#W$FF%Uk^YO>NvOrU^ar;BL!XQ})iR0Ecxv!|N0N-D {R5vlF-*Vh~tMNfBdBk z@hOJ`j`c+h^_+MDZ;F22l;ht(IqIiKj#kJB_M892vCS&$vSD2XyLe5^x{yUux?T@q z$CiQ>rIcEyFWF%)n>OU48`y5~Ta&RQ;@TK-bIPy@z096O+Z-#Sa)+?tBYoKJ#U2S^ zRW|orQyCXK$LZsWPvXtvI>nW%ec0sB_4sO3j>%Srlf9`c(t-fYJ-f<=Z#pCVg168) zh`K4RvcYc!*zyCVV;os2@z1XgRT^2_lgw{w+ohRb^8>twdcxn&_+$)c{rv=+MJp6Z ziF?JNHu USIV#E58b*vvm0US2>~AGgdfv?zrIXJ z4F${@J-1sU9(mRr2db1+mNJJL*&n9O1r%L>BcYt0zTBXwfVxo}{T*+6UG$i!keaA; zo`|lz$Soo1-)G3uD;_xHWg5>Z;<#_{;&Ele!9m{L32xJ 0NvZfSE22D MXa^{s&bru{;tjMi#`D^IMUP&Xu zT?n}8R=;SFn&Q`G7M9_&)oGg~Z&{eWGpe#n3S#{Ou{ C}$h$J$P;Q3b>Spu~o9Qt-<_ 8jc}u#XG5BbijNE=dX;&MOU@^-z>EDT`)}EgM9$;7YB~<`k @%hYgbzF(%=w&afYJbuI86vnPDSnbudEEivK(RXDazyq5MDd z)^Gk%y`2j@!T-14&ItSpGKQ#wk03IHQr>!W^S|Cd&GY}+HF|4gsC5_j>-inPGjR}U zNQ3=;W|M<-l>-gkJVE?r^H~Z)cbv%g_1^p4J0n?Tz%#35WG=UoNyQye@j}P8N?Op4 z>rh4DGt9R9*`lt2K(o8!0}pRX0Bz5*{>nG!?WZrk*2lt44DR}i9NSWDMHlg%J?=}I z1~hX^R15R?xdi9uUgN|!n^md6S#9o@ff8`?YRI&8z{m}7d W3w=%yqv$p0F;qPzMw4m$wRS4r}-28rciKh3c z97gMy7>~srCx~GeW7|?ym;;z!ER%wo4GpbCu6%&3Ri*RG!12qN(zXR}t*!Z2{uFZ_ zc+Q@ouFMYBqxC(ARepI>{7^aeT##_fyD^v^!pmUXE(44e^pg=bT*tuGKL7(>eljtq zZely)?aJX1_mknX>5n+*8CTy7rkLsWd-b0k zXhl+sAZaNC;CuQd3eW~aOl`4OVXKEZ`#B~Tn^t l}*3=CU>hP1<7N6^xvT zq75IE>z19r4L3lJdy5wXXZeJTL19J-NLbO`BJ2Zs)Kw__c!^;)%gba^^te6fh!ci2 zv&?p?2hb3ib3=1A1mb17rje=A(O@HNprVO$LJ$XJs+6b(vBn;21UH(nYgk!IW83+V zqh;;Zn!TtO^B}@Cmd-(CRFvJY?eZY|qRr3cr1IhOPH=QT6QNGEDg3wx^GMV*NNd&` z^!6tJ-tqq84_WPI>s=FA+NVJomEr?_OrZpld-!2@lcQy2Qof=7bz^57A&AkzD`Nwv z `Nt4s~XW7ZP2wB*DFF7m+I8hCvR|he!)&n#6H@D7h2P9E``$E z*C4y~S&?>TZL56iwqKr*dMr5>6Wdu$)g9;pz0#=ETe$y`XlCHJCiys}8^{66!{fP& z$}ks~&rwU+wJYJgfQu&I!Pjz}+WOeVl^tfv?q7UzX}=)hxS$%o<@ixw4WZTc_Z#u= z@5aNXawg0_GE&niK}YhU?0UgQ%hA`3B$dz+SdLyZ7j(3bNgq1hfJlZFQ|dQiEbmQ& z49W>HcQT91R6Jc=F}8hr`=y>;4ZdS>b SVfDs|3XSa?D?Wgi>zuR>z_iz}t5S5=26s}vfbt}(C3 jNh-GvB{BRp z!Bqh%sKjt6-B~Clu6(!UtWZjC##Ll=v6gb^x^}rB;b!I-7WtRT04RX@b!Mn>NQptT z2Dnw@8!lGQSoFwFc|)`VwGsp*$7jzv7=jL7B`XsxoLzn6qJM|#+qOfk)Kr+QG0{f_ zt!TElUuV2DvD39SwpL3yOg#<0IAYaUS}x1D$~lDfUB6Uuy}uaWG8I4uFY^W%+8em# z%D}oA-3d-L!_3je_fw>h>(s+h<2J8@F0Tn_>bU0s9Zl}UOME1*^qV<0l?9`GWW|Eu zS>-Y5Yc;*5%;HWztn+gJ;xQJp!SxS#tdp7B)8j^^kw@m}RXjFj8-5#0jltTyD5tJ+ zW$H!aHmI2_4ykPWmzH )n40TF{HGfdtE}m6JUp^hP19D{c5)7ER*+h{xXdJyIaW^9u(fjfGRhcXOQeia4J5h? zoKXz@OECM-FLa`BaEl bFQq RaTOYSC@j2jV*4QZk=gT zW3g6blk `sVe0lmNaA#*k*Zp$N8u!J<*erGnXiii`78yFtJ$4DfaNxLo0&7zP zyBPgs$A|{*?MX8Uw80gebV3X%dvL^h&bxIgeDr#S^mmzsk4t0m3+{9DYV<8#4cibZ z;np{m6MzeUE{Lk!LM791 zu@sMO5yDi>Bo#7L*2oi1f0F0&vz*Y`12Uh_Nb4(QY7UYx)&4>wwtgpFF3EnlqGc;0 zvv_vYzC4E*^`>*L8|e~*YB1!nZB6jB-qJ2$Nj&9Ms6U_*3phrLs~-18fHt5`HYBU4 z1D($_mFap!2WvepWaaWs5dUBU>bHD1&-5=K+PDI1Er+}Himo6BI*E)GltZ4Bvzf+9 zDh4MJ%FzoPizTl63~Rm}zal_Y>?ofVrdEB7JcfgWZ$n;hRdAo_gk-C#%b`AA8EA6W z5vfsg5Q)M79_)vVA_b?ZE4H^(u7TSH+}8s(+?4R`!Z`D)#&gRo;W7Kjsr)Frt6#!n zfSv#?K*`x{Exv8T(}`kEOM}|lGcl%j?4johvVN(#ybjiNwnz%Oz`b^*VdLJf`uYP` zWcLr=LD5b;^vMiws@!;cV`2lqLAJP3*wPSEb7~GHEre{10J+mct +z|KKO-$zwyO`Qt1= jEDyH0nTy?8^f_f-ns;+2pCHJfPe@qcrb^x|oon|&Fx}=t&la?| zF3^Ud7eihVU!2Qo8hX>^F7GME7I}RcBv_B|G7Nrw$luoY(?R^y21uo*xUT$RbaI@a zXqh~7dV_NNs9#_&UMYdO#^dw>F}qU(u#;jZAY-v>ClA>}^+&QL|JIP}V!YQ^$F@eW zWi23oW7Z|s8^BGOTJ;N7?5$YSEg4~cP@jFF6P8_qz!th 6 z0<>YR4_7&X47Xe$Xqt5E&uX2W`HsA0Xyu9UNlj0{C1NB5VzD;$)ZC)-?e59tHAdz_ z#HxUM#7Sq u!5TrB_l7o2le%3Ll6-6;DVbs{&uV!H$HzxAV06_sNvf*S+*TWYSq|Q7j%3; z`mGb<)+zdypTASwp35LFK>%he?CHv!{doKLDULPJy;?-%J>TRi=_TAx@YwV^2lSzo ztIJ@$rluOtY*i}uI!p%pfj{k|bI|3Du5e1%Wc&hgok5gz8ifa=7ABE7