From 2f921b62097b8edb3cdecb8bc971cb484e2833e1 Mon Sep 17 00:00:00 2001 From: Duoduo Date: Fri, 19 Sep 2025 15:59:08 +0800 Subject: [PATCH] Fork project --- .gitignore | 3 + .idea/ctfd-whale.iml | 16 ++ CHANGELOG.md | 91 +++++++ LICENSE | 21 ++ README.md | 40 +++ README.zh-cn.md | 39 +++ __init__.py | 124 +++++++++ api.py | 138 ++++++++++ assets/config.js | 27 ++ assets/containers.js | 120 +++++++++ assets/create.html | 100 +++++++ assets/create.js | 30 +++ assets/update.html | 94 +++++++ assets/update.js | 52 ++++ assets/view.html | 36 +++ assets/view.js | 239 +++++++++++++++++ challenge_type.py | 108 ++++++++ decorators.py | 53 ++++ docker-compose.example.yml | 105 ++++++++ docs/advanced.md | 156 +++++++++++ docs/advanced.zh-cn.md | 268 ++++++++++++++++++ docs/imgs/arch.png | Bin 0 -> 80104 bytes docs/imgs/whale-config1.png | Bin 0 -> 111881 bytes docs/imgs/whale-config2.png | Bin 0 -> 47065 bytes docs/imgs/whale-config3.png | Bin 0 -> 68153 bytes docs/install.md | 304 +++++++++++++++++++++ docs/install.zh-cn.md | 313 ++++++++++++++++++++++ models.py | 105 ++++++++ requirements.txt | 4 + templates/config/base.router.config.html | 24 ++ templates/config/challenges.config.html | 25 ++ templates/config/docker.config.html | 122 +++++++++ templates/config/frp.router.config.html | 50 ++++ templates/config/limits.config.html | 26 ++ templates/config/trp.router.config.html | 17 ++ templates/containers/card.containers.html | 57 ++++ templates/containers/list.containers.html | 78 ++++++ templates/whale_base.html | 25 ++ templates/whale_config.html | 38 +++ templates/whale_containers.html | 69 +++++ utils/__init__.py | 0 utils/cache.py | 150 +++++++++++ utils/checks.py | 50 ++++ utils/control.py | 61 +++++ utils/db.py | 104 +++++++ utils/docker.py | 202 ++++++++++++++ utils/exceptions.py | 8 + utils/routers/__init__.py | 34 +++ utils/routers/base.py | 25 ++ utils/routers/frp.py | 132 +++++++++ utils/routers/trp.py | 69 +++++ utils/setup.py | 60 +++++ 52 files changed, 4012 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/ctfd-whale.iml create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 README.zh-cn.md create mode 100644 __init__.py create mode 100644 api.py create mode 100644 assets/config.js create mode 100644 assets/containers.js create mode 100644 assets/create.html create mode 100644 assets/create.js create mode 100644 assets/update.html create mode 100644 assets/update.js create mode 100644 assets/view.html create mode 100644 assets/view.js create mode 100644 challenge_type.py create mode 100644 decorators.py create mode 100644 docker-compose.example.yml create mode 100644 docs/advanced.md create mode 100644 docs/advanced.zh-cn.md create mode 100644 docs/imgs/arch.png create mode 100644 docs/imgs/whale-config1.png create mode 100644 docs/imgs/whale-config2.png create mode 100644 docs/imgs/whale-config3.png create mode 100644 docs/install.md create mode 100644 docs/install.zh-cn.md create mode 100644 models.py create mode 100644 requirements.txt create mode 100644 templates/config/base.router.config.html create mode 100644 templates/config/challenges.config.html create mode 100644 templates/config/docker.config.html create mode 100644 templates/config/frp.router.config.html create mode 100644 templates/config/limits.config.html create mode 100644 templates/config/trp.router.config.html create mode 100644 templates/containers/card.containers.html create mode 100644 templates/containers/list.containers.html create mode 100644 templates/whale_base.html create mode 100644 templates/whale_config.html create mode 100644 templates/whale_containers.html create mode 100644 utils/__init__.py create mode 100644 utils/cache.py create mode 100644 utils/checks.py create mode 100644 utils/control.py create mode 100644 utils/db.py create mode 100644 utils/docker.py create mode 100644 utils/exceptions.py create mode 100644 utils/routers/__init__.py create mode 100644 utils/routers/base.py create mode 100644 utils/routers/frp.py create mode 100644 utils/routers/trp.py create mode 100644 utils/setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a5bb25 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +__pycache__/ +*.py[cod] +.DS_Store diff --git a/.idea/ctfd-whale.iml b/.idea/ctfd-whale.iml new file mode 100644 index 0000000..6c86ab2 --- /dev/null +++ b/.idea/ctfd-whale.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c2360a8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,91 @@ +# Changelog + +## 2020-03-18 + +- Allow non-dynamic flag. + +## 2020-02-18 + +- Refine front for ctfd newer version.(@frankli0324) + +## 2019-11-21 + +- Add network prefix & timeout setting. +- Refine port and network range search +- Refine frp request +- Refine lock timeout + +## 2019-11-08 + +- Add Lan Domain + +## 2019-11-04 + +- Change backend to Docker Swarm. +- Support depoly different os image to different os node. + +You should init docker swarm, and add your node to it. And name them with following command: + +``` +docker node update --label-add name=windows-1 **** +docker node update --label-add name=linux-1 **** +``` + +Name of them should begin with windows- or linux-. + +And put them in the setting panel. + +Then if you want to deploy a instance to windows node, You should tag your name with prefix "windows", like "glzjin/super_sql:windows". + +And please modify the container network driver to 'Overlay'! + +## 2019-10-30 + +- Optimize for multi worker. +- Try to fix concurrency request problem. + +Now You should set the redis with REDIS_HOST environment varible. + +## 2019-09-26 + +- Add frp http port setting. + +You should config it at the settings for http redirect. + +## 2019-09-15 + +- Add Container Network Setting and DNS Setting. + +Now You can setup a DNS Server in your Container Network. +- For single-instance network, Just connect your dns server to it and input the ip address in the seeting panel. +- For multi-instance network, You should rename the dns server to a name include "dns", than add it to auto connect instance. It will be used as a dns server. + +## 2019-09-14 + +- Refine plugin path. + +## 2019-09-13 + +- Refine removal. + +## 2019-08-29 + +- Add CPU usage limit. +- Allow the multi-image challenge. + +Upgrade: +1. Execute this SQL in ctfd database. + +``` +alter table dynamic_docker_challenge add column cpu_limit float default 0.5 after memory_limit; +``` + +2. Setting the containers you want to plugin to a single multi-image network. (In settings panel) + +3. When you create a challenge you can set the docker image like this + +``` +{"socks": "serjs/go-socks5-proxy", "web": "blog_revenge_blog", "mysql": "blog_revenge_mysql", "oauth": "blog_revenge_oauth"} +``` + +The first one will be redirected the traffic. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..97f7a6d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 glzjin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..799b089 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# CTFd-Whale + +## [中文README](README.zh-cn.md) + +A plugin that empowers CTFd to bring up separate environments for each user + +## Features + +- Deploys containers with `frp` and `docker swarm` +- Supports subdomain access by utilizing `frp` +- Contestants can start/renew/destroy their environments with a single click +- flags and subdomains are generated automatically with configurable rules +- Administrators can get a full list of running containers, with full control over them. + +## Installation & Usage + +refer to [installation guide](docs/install.md) + +## Demo + +[BUUCTF](https://buuoj.cn) + +## Third-party Introductions (zh-CN) + +- [CTFd-Whale 推荐部署实践](https://www.zhaoj.in/read-6333.html) +- [手把手教你如何建立一个支持ctf动态独立靶机的靶场(ctfd+ctfd-whale)](https://blog.csdn.net/fjh1997/article/details/100850756) + +## Screenshots + +![](https://user-images.githubusercontent.com/20221896/105939593-7cca6f80-6094-11eb-92de-8a04554dc019.png) + +![image](https://user-images.githubusercontent.com/20221896/105940182-a637cb00-6095-11eb-9525-8291986520c1.png) + +![](https://user-images.githubusercontent.com/20221896/105939965-2e69a080-6095-11eb-9b31-7777a0cc41b9.png) + +![](https://user-images.githubusercontent.com/20221896/105940026-50632300-6095-11eb-8512-6f19dd12c776.png) + +## Twin Project + +- [CTFd-Owl](https://github.com/D0g3-Lab/H1ve/tree/master/CTFd/plugins/ctfd-owl) (支持部署compose) diff --git a/README.zh-cn.md b/README.zh-cn.md new file mode 100644 index 0000000..d59c3e8 --- /dev/null +++ b/README.zh-cn.md @@ -0,0 +1,39 @@ +# CTFd-Whale + +能够支持题目容器化部署的CTFd插件 + +## 功能 + +- 利用`frp`与`docker swarm`做到多容器部署 +- web题目支持利用frp的subdomain实现每个用户单独的域名访问 +- 参赛选手一键启动题目环境,支持容器续期 +- 自动生成随机flag,并通过环境变量传入容器 +- 管理员可以在后台查看启动的容器 +- 支持自定义flag生成方式与web题目子域名生成方式 + +## 使用方式 + +请参考[安装指南](docs/install.zh-cn.md) + +## Demo + +[BUUCTF](https://buuoj.cn) + +## 第三方使用说明 + +- [CTFd-Whale 推荐部署实践](https://www.zhaoj.in/read-6333.html) +- [手把手教你如何建立一个支持ctf动态独立靶机的靶场(ctfd+ctfd-whale)](https://blog.csdn.net/fjh1997/article/details/100850756) + +## 使用案例 + +![](https://user-images.githubusercontent.com/20221896/105939593-7cca6f80-6094-11eb-92de-8a04554dc019.png) + +![image](https://user-images.githubusercontent.com/20221896/105940182-a637cb00-6095-11eb-9525-8291986520c1.png) + +![](https://user-images.githubusercontent.com/20221896/105939965-2e69a080-6095-11eb-9b31-7777a0cc41b9.png) + +![](https://user-images.githubusercontent.com/20221896/105940026-50632300-6095-11eb-8512-6f19dd12c776.png) + +## 友情链接 + +- [CTFd-Owl](https://github.com/D0g3-Lab/H1ve/tree/master/CTFd/plugins/ctfd-owl) (支持部署compose) diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..5f94f95 --- /dev/null +++ b/__init__.py @@ -0,0 +1,124 @@ +import fcntl +import warnings + +import requests +from flask import Blueprint, render_template, session, current_app, request +from flask_apscheduler import APScheduler + +from CTFd.api import CTFd_API_v1 +from CTFd.plugins import ( + register_plugin_assets_directory, + register_admin_plugin_menu_bar, +) +from CTFd.plugins.challenges import CHALLENGE_CLASSES +from CTFd.utils import get_config, set_config +from CTFd.utils.decorators import admins_only + +from .api import user_namespace, admin_namespace, AdminContainers +from .challenge_type import DynamicValueDockerChallenge +from .utils.checks import WhaleChecks +from .utils.control import ControlUtil +from .utils.db import DBContainer +from .utils.docker import DockerUtils +from .utils.exceptions import WhaleWarning +from .utils.setup import setup_default_configs +from .utils.routers import Router + + +def load(app): + app.config['RESTX_ERROR_404_HELP'] = False + # upgrade() + plugin_name = __name__.split('.')[-1] + set_config('whale:plugin_name', plugin_name) + app.db.create_all() + if not get_config("whale:setup"): + setup_default_configs() + + register_plugin_assets_directory( + app, base_path=f"/plugins/{plugin_name}/assets", + endpoint='plugins.ctfd-whale.assets' + ) + register_admin_plugin_menu_bar( + title='Whale', + route='/plugins/ctfd-whale/admin/settings' + ) + + DynamicValueDockerChallenge.templates = { + "create": f"/plugins/{plugin_name}/assets/create.html", + "update": f"/plugins/{plugin_name}/assets/update.html", + "view": f"/plugins/{plugin_name}/assets/view.html", + } + DynamicValueDockerChallenge.scripts = { + "create": "/plugins/ctfd-whale/assets/create.js", + "update": "/plugins/ctfd-whale/assets/update.js", + "view": "/plugins/ctfd-whale/assets/view.js", + } + CHALLENGE_CLASSES["dynamic_docker"] = DynamicValueDockerChallenge + + page_blueprint = Blueprint( + "ctfd-whale", + __name__, + template_folder="templates", + static_folder="assets", + url_prefix="/plugins/ctfd-whale" + ) + CTFd_API_v1.add_namespace(admin_namespace, path="/plugins/ctfd-whale/admin") + CTFd_API_v1.add_namespace(user_namespace, path="/plugins/ctfd-whale") + + worker_config_commit = None + + @page_blueprint.route('/admin/settings') + @admins_only + def admin_list_configs(): + nonlocal worker_config_commit + errors = WhaleChecks.perform() + if not errors and get_config("whale:refresh") != worker_config_commit: + worker_config_commit = get_config("whale:refresh") + DockerUtils.init() + Router.reset() + set_config("whale:refresh", "false") + return render_template('whale_config.html', errors=errors) + + @page_blueprint.route("/admin/containers") + @admins_only + def admin_list_containers(): + result = AdminContainers.get() + view_mode = request.args.get('mode', session.get('view_mode', 'list')) + session['view_mode'] = view_mode + return render_template("whale_containers.html", + plugin_name=plugin_name, + containers=result['data']['containers'], + pages=result['data']['pages'], + curr_page=abs(request.args.get("page", 1, type=int)), + curr_page_start=result['data']['page_start']) + + def auto_clean_container(): + with app.app_context(): + results = DBContainer.get_all_expired_container() + for r in results: + ControlUtil.try_remove_container(r.user_id) + + app.register_blueprint(page_blueprint) + + try: + Router.check_availability() + DockerUtils.init() + except Exception: + warnings.warn("Initialization Failed. Please check your configs.", WhaleWarning) + + try: + lock_file = open("/tmp/ctfd_whale.lock", "w") + lock_fd = lock_file.fileno() + fcntl.lockf(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + + scheduler = APScheduler() + scheduler.init_app(app) + scheduler.start() + scheduler.add_job( + id='whale-auto-clean', func=auto_clean_container, + trigger="interval", seconds=10 + ) + + print("[CTFd Whale] Started successfully") + except IOError: + pass diff --git a/api.py b/api.py new file mode 100644 index 0000000..3944939 --- /dev/null +++ b/api.py @@ -0,0 +1,138 @@ +from datetime import datetime + +from flask import request +from flask_restx import Namespace, Resource, abort + +from CTFd.utils import get_config +from CTFd.utils import user as current_user +from CTFd.utils.decorators import admins_only, authed_only + +from .decorators import challenge_visible, frequency_limited +from .utils.control import ControlUtil +from .utils.db import DBContainer +from .utils.routers import Router + +admin_namespace = Namespace("ctfd-whale-admin") +user_namespace = Namespace("ctfd-whale-user") + + +@admin_namespace.errorhandler +@user_namespace.errorhandler +def handle_default(err): + return { + 'success': False, + 'message': 'Unexpected things happened' + }, 500 + + +@admin_namespace.route('/container') +class AdminContainers(Resource): + @staticmethod + @admins_only + def get(): + page = abs(request.args.get("page", 1, type=int)) + results_per_page = abs(request.args.get("per_page", 20, type=int)) + page_start = results_per_page * (page - 1) + page_end = results_per_page * (page - 1) + results_per_page + + count = DBContainer.get_all_alive_container_count() + containers = DBContainer.get_all_alive_container_page( + page_start, page_end) + + return {'success': True, 'data': { + 'containers': containers, + 'total': count, + 'pages': int(count / results_per_page) + (count % results_per_page > 0), + 'page_start': page_start, + }} + + @staticmethod + @admins_only + def patch(): + user_id = request.args.get('user_id', -1) + result, message = ControlUtil.try_renew_container(user_id=int(user_id)) + if not result: + abort(403, message, success=False) + return {'success': True, 'message': message} + + @staticmethod + @admins_only + def delete(): + user_id = request.args.get('user_id') + result, message = ControlUtil.try_remove_container(user_id) + return {'success': result, 'message': message} + + +@user_namespace.route("/container") +class UserContainers(Resource): + @staticmethod + @authed_only + @challenge_visible + def get(): + user_id = current_user.get_current_user().id + challenge_id = request.args.get('challenge_id') + container = DBContainer.get_current_containers(user_id=user_id) + if not container: + return {'success': True, 'data': {}} + timeout = int(get_config("whale:docker_timeout", "3600")) + c = container.challenge # build a url for quick jump. todo: escape dash in categories and names. + link = f'{c.name}' + if int(container.challenge_id) != int(challenge_id): + return abort(403, f'Container already started but not from this challenge ({link})', success=False) + return { + 'success': True, + 'data': { + 'lan_domain': str(user_id) + "-" + container.uuid, + 'user_access': Router.access(container), + 'remaining_time': timeout - (datetime.now() - container.start_time).seconds, + } + } + + @staticmethod + @authed_only + @challenge_visible + @frequency_limited + def post(): + user_id = current_user.get_current_user().id + ControlUtil.try_remove_container(user_id) + + current_count = DBContainer.get_all_alive_container_count() + if int(get_config("whale:docker_max_container_count")) <= int(current_count): + abort(403, 'Max container count exceed.', success=False) + + challenge_id = request.args.get('challenge_id') + result, message = ControlUtil.try_add_container( + user_id=user_id, + challenge_id=challenge_id + ) + if not result: + abort(403, message, success=False) + return {'success': True, 'message': message} + + @staticmethod + @authed_only + @challenge_visible + @frequency_limited + def patch(): + user_id = current_user.get_current_user().id + challenge_id = request.args.get('challenge_id') + docker_max_renew_count = int(get_config("whale:docker_max_renew_count", 5)) + container = DBContainer.get_current_containers(user_id) + if container is None: + abort(403, 'Instance not found.', success=False) + if int(container.challenge_id) != int(challenge_id): + abort(403, f'Container started but not from this challenge({container.challenge.name})', success=False) + if container.renew_count >= docker_max_renew_count: + abort(403, 'Max renewal count exceed.', success=False) + result, message = ControlUtil.try_renew_container(user_id=user_id) + return {'success': result, 'message': message} + + @staticmethod + @authed_only + @frequency_limited + def delete(): + user_id = current_user.get_current_user().id + result, message = ControlUtil.try_remove_container(user_id) + if not result: + abort(403, message, success=False) + return {'success': True, 'message': message} diff --git a/assets/config.js b/assets/config.js new file mode 100644 index 0000000..34839c2 --- /dev/null +++ b/assets/config.js @@ -0,0 +1,27 @@ +const $ = CTFd.lib.$; + +$(".config-section > form:not(.form-upload)").submit(async function (event) { + event.preventDefault(); + const obj = $(this).serializeJSON(); + const params = {}; + for (let x in obj) { + if (obj[x] === "true") { + params[x] = true; + } else if (obj[x] === "false") { + params[x] = false; + } else { + params[x] = obj[x]; + } + } + params['whale:refresh'] = btoa(+new Date).slice(-7, -2); + + await CTFd.api.patch_config_list({}, params); + location.reload(); +}); +$(".config-section > form:not(.form-upload) > div > div > div > #router-type").change(async function () { + await CTFd.api.patch_config_list({}, { + 'whale:router_type': $(this).val(), + 'whale:refresh': btoa(+new Date).slice(-7, -2), + }); + location.reload(); +}); diff --git a/assets/containers.js b/assets/containers.js new file mode 100644 index 0000000..d7ae0d9 --- /dev/null +++ b/assets/containers.js @@ -0,0 +1,120 @@ +const $ = CTFd.lib.$; + +function htmlentities(str) { + return String(str).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); +} + +function copyToClipboard(event, str) { + // Select element + const el = document.createElement('textarea'); + el.value = str; + el.setAttribute('readonly', ''); + el.style.position = 'absolute'; + el.style.left = '-9999px'; + document.body.appendChild(el); + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); + + $(event.target).tooltip({ + title: "Copied!", + trigger: "manual" + }); + $(event.target).tooltip("show"); + + setTimeout(function () { + $(event.target).tooltip("hide"); + }, 1500); +} + +$(".click-copy").click(function (e) { + copyToClipboard(e, $(this).data("copy")); +}) + +async function delete_container(user_id) { + let response = await CTFd.fetch("/api/v1/plugins/ctfd-whale/admin/container?user_id=" + user_id, { + method: "DELETE", + credentials: "same-origin", + headers: { + Accept: "application/json", + "Content-Type": "application/json" + } + }); + response = await response.json(); + return response.success; +} +async function renew_container(user_id) { + let response = await CTFd.fetch( + "/api/v1/plugins/ctfd-whale/admin/container?user_id=" + user_id, { + method: "PATCH", + credentials: "same-origin", + headers: { + Accept: "application/json", + "Content-Type": "application/json" + } + }); + response = await response.json(); + return response.success; +} + +$('#containers-renew-button').click(function (e) { + let users = $("input[data-user-id]:checked").map(function () { + return $(this).data("user-id"); + }); + CTFd.ui.ezq.ezQuery({ + title: "Renew Containers", + body: `Are you sure you want to renew the selected ${users.length} container(s)?`, + success: async function () { + await Promise.all(users.toArray().map((user) => renew_container(user))); + location.reload(); + } + }); +}); + +$('#containers-delete-button').click(function (e) { + let users = $("input[data-user-id]:checked").map(function () { + return $(this).data("user-id"); + }); + CTFd.ui.ezq.ezQuery({ + title: "Delete Containers", + body: `Are you sure you want to delete the selected ${users.length} container(s)?`, + success: async function () { + await Promise.all(users.toArray().map((user) => delete_container(user))); + location.reload(); + } + }); +}); + +$(".delete-container").click(function (e) { + e.preventDefault(); + let container_id = $(this).attr("container-id"); + let user_id = $(this).attr("user-id"); + + CTFd.ui.ezq.ezQuery({ + title: "Destroy Container", + body: "Are you sure you want to delete Container #{0}?".format( + htmlentities(container_id) + ), + success: async function () { + await delete_container(user_id); + location.reload(); + } + }); +}); + +$(".renew-container").click(function (e) { + e.preventDefault(); + let container_id = $(this).attr("container-id"); + let user_id = $(this).attr("user-id"); + + CTFd.ui.ezq.ezQuery({ + title: "Renew Container", + body: "Are you sure you want to renew Container #{0}?".format( + htmlentities(container_id) + ), + success: async function () { + await renew_container(user_id); + location.reload(); + }, + }); +}); \ No newline at end of file diff --git a/assets/create.html b/assets/create.html new file mode 100644 index 0000000..459d667 --- /dev/null +++ b/assets/create.html @@ -0,0 +1,100 @@ +{% extends "admin/challenges/create.html" %} + +{% block header %} + +{% endblock %} + + +{% block value %} +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + + +
+{% endblock %} + +{% block type %} + +{% endblock %} \ No newline at end of file diff --git a/assets/create.js b/assets/create.js new file mode 100644 index 0000000..78ad73e --- /dev/null +++ b/assets/create.js @@ -0,0 +1,30 @@ +// Markdown Preview +if ($ === undefined) $ = CTFd.lib.$ +$('#desc-edit').on('shown.bs.tab', function(event) { + if (event.target.hash == '#desc-preview') { + var editor_value = $('#desc-editor').val(); + $(event.target.hash).html( + CTFd._internal.challenge.render(editor_value) + ); + } +}); +$('#new-desc-edit').on('shown.bs.tab', function(event) { + if (event.target.hash == '#new-desc-preview') { + var editor_value = $('#new-desc-editor').val(); + $(event.target.hash).html( + CTFd._internal.challenge.render(editor_value) + ); + } +}); +$("#solve-attempts-checkbox").change(function() { + if (this.checked) { + $('#solve-attempts-input').show(); + } else { + $('#solve-attempts-input').hide(); + $('#max_attempts').val(''); + } +}); + +$(document).ready(function() { + $('[data-toggle="tooltip"]').tooltip(); +}); \ No newline at end of file diff --git a/assets/update.html b/assets/update.html new file mode 100644 index 0000000..a3415d8 --- /dev/null +++ b/assets/update.html @@ -0,0 +1,94 @@ +{% extends "admin/challenges/update.html" %} + +{% block value %} +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+{% endblock %} \ No newline at end of file diff --git a/assets/update.js b/assets/update.js new file mode 100644 index 0000000..a45103a --- /dev/null +++ b/assets/update.js @@ -0,0 +1,52 @@ +if ($ === undefined) $ = CTFd.lib.$ +$('#submit-key').click(function(e) { + submitkey($('#chalid').val(), $('#answer').val()) +}); + +$('#submit-keys').click(function(e) { + e.preventDefault(); + $('#update-keys').modal('hide'); +}); + +$('#limit_max_attempts').change(function() { + if (this.checked) { + $('#chal-attempts-group').show(); + } else { + $('#chal-attempts-group').hide(); + $('#chal-attempts-input').val(''); + } +}); + +// Markdown Preview +$('#desc-edit').on('shown.bs.tab', function(event) { + if (event.target.hash == '#desc-preview') { + var editor_value = $('#desc-editor').val(); + $(event.target.hash).html( + window.challenge.render(editor_value) + ); + } +}); +$('#new-desc-edit').on('shown.bs.tab', function(event) { + if (event.target.hash == '#new-desc-preview') { + var editor_value = $('#new-desc-editor').val(); + $(event.target.hash).html( + window.challenge.render(editor_value) + ); + } +}); + +function loadchal(id, update) { + $.get(script_root + '/admin/chal/' + id, function(obj) { + $('#desc-write-link').click(); // Switch to Write tab + if (typeof update === 'undefined') + $('#update-challenge').modal(); + }); +} + +function openchal(id) { + loadchal(id); +} + +$(document).ready(function() { + $('[data-toggle="tooltip"]').tooltip(); +}); \ No newline at end of file diff --git a/assets/view.html b/assets/view.html new file mode 100644 index 0000000..5803732 --- /dev/null +++ b/assets/view.html @@ -0,0 +1,36 @@ +{% extends "challenge.html" %} + +{% block description %} +{{ challenge.html }} +
+
+
+
+
Instance Info
+ +
+
+
+
+
Instance Info
+
+ Remaining Time: s +
+
+ Lan Domain: +
+

+ + +
+
+
+
+{% endblock %} diff --git a/assets/view.js b/assets/view.js new file mode 100644 index 0000000..ee572f7 --- /dev/null +++ b/assets/view.js @@ -0,0 +1,239 @@ +CTFd._internal.challenge.data = undefined + +CTFd._internal.challenge.renderer = null; + +CTFd._internal.challenge.preRender = function () { +} + +CTFd._internal.challenge.render = null; + +CTFd._internal.challenge.postRender = function () { + loadInfo(); +} + +if (window.$ === undefined) window.$ = CTFd.lib.$; + +function loadInfo() { + var challenge_id = CTFd._internal.challenge.data.id; + var url = "/api/v1/plugins/ctfd-whale/container?challenge_id=" + challenge_id; + + CTFd.fetch(url, { + method: 'GET', + credentials: 'same-origin', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + } + }).then(function (response) { + if (response.status === 429) { + // User was ratelimited but process response + return response.json(); + } + if (response.status === 403) { + // User is not logged in or CTF is paused. + return response.json(); + } + return response.json(); + }).then(function (response) { + if (window.t !== undefined) { + clearInterval(window.t); + window.t = undefined; + } + if (response.success) response = response.data; + else CTFd._functions.events.eventAlert({ + title: "Fail", + html: response.message, + button: "OK" + }); + if (response.remaining_time != undefined) { + $('#whale-challenge-user-access').html(response.user_access); + $('#whale-challenge-lan-domain').html(response.lan_domain); + $('#whale-challenge-count-down').text(response.remaining_time); + $('#whale-panel-stopped').hide(); + $('#whale-panel-started').show(); + + window.t = setInterval(() => { + const c = $('#whale-challenge-count-down').text(); + if (!c) return; + let second = parseInt(c) - 1; + if (second <= 0) { + loadInfo(); + } + $('#whale-challenge-count-down').text(second); + }, 1000); + } else { + $('#whale-panel-started').hide(); + $('#whale-panel-stopped').show(); + } + }); +}; + +CTFd._internal.challenge.destroy = function () { + var challenge_id = CTFd._internal.challenge.data.id; + var url = "/api/v1/plugins/ctfd-whale/container?challenge_id=" + challenge_id; + + $('#whale-button-destroy').text("Waiting..."); + $('#whale-button-destroy').prop('disabled', true); + + var params = {}; + + CTFd.fetch(url, { + method: 'DELETE', + credentials: 'same-origin', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(params) + }).then(function (response) { + if (response.status === 429) { + // User was ratelimited but process response + return response.json(); + } + if (response.status === 403) { + // User is not logged in or CTF is paused. + return response.json(); + } + return response.json(); + }).then(function (response) { + if (response.success) { + loadInfo(); + CTFd._functions.events.eventAlert({ + title: "Success", + html: "Your instance has been destroyed!", + button: "OK" + }); + } else { + CTFd._functions.events.eventAlert({ + title: "Fail", + html: response.message, + button: "OK" + }); + } + }).finally(() => { + $('#whale-button-destroy').text("Destroy this instance"); + $('#whale-button-destroy').prop('disabled', false); + }); +}; + +CTFd._internal.challenge.renew = function () { + var challenge_id = CTFd._internal.challenge.data.id; + var url = "/api/v1/plugins/ctfd-whale/container?challenge_id=" + challenge_id; + + $('#whale-button-renew').text("Waiting..."); + $('#whale-button-renew').prop('disabled', true); + + var params = {}; + + CTFd.fetch(url, { + method: 'PATCH', + credentials: 'same-origin', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(params) + }).then(function (response) { + if (response.status === 429) { + // User was ratelimited but process response + return response.json(); + } + if (response.status === 403) { + // User is not logged in or CTF is paused. + return response.json(); + } + return response.json(); + }).then(function (response) { + if (response.success) { + loadInfo(); + CTFd._functions.events.eventAlert({ + title: "Success", + html: "Your instance has been renewed!", + button: "OK" + }); + } else { + CTFd._functions.events.eventAlert({ + title: "Fail", + html: response.message, + button: "OK" + }); + } + }).finally(() => { + $('#whale-button-renew').text("Renew this instance"); + $('#whale-button-renew').prop('disabled', false); + }); +}; + +CTFd._internal.challenge.boot = function () { + var challenge_id = CTFd._internal.challenge.data.id; + var url = "/api/v1/plugins/ctfd-whale/container?challenge_id=" + challenge_id; + + $('#whale-button-boot').text("Waiting..."); + $('#whale-button-boot').prop('disabled', true); + + var params = {}; + + CTFd.fetch(url, { + method: 'POST', + credentials: 'same-origin', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(params) + }).then(function (response) { + if (response.status === 429) { + // User was ratelimited but process response + return response.json(); + } + if (response.status === 403) { + // User is not logged in or CTF is paused. + return response.json(); + } + return response.json(); + }).then(function (response) { + if (response.success) { + loadInfo(); + CTFd._functions.events.eventAlert({ + title: "Success", + html: "Your instance has been deployed!", + button: "OK" + }); + } else { + CTFd._functions.events.eventAlert({ + title: "Fail", + html: response.message, + button: "OK" + }); + } + }).finally(() => { + $('#whale-button-boot').text("Launch an instance"); + $('#whale-button-boot').prop('disabled', false); + }); +}; + + +CTFd._internal.challenge.submit = function (preview) { + var challenge_id = CTFd._internal.challenge.data.id; + var submission = $('#challenge-input').val() + + var body = { + 'challenge_id': challenge_id, + 'submission': submission, + } + var params = {} + if (preview) + params['preview'] = true + + return CTFd.api.post_challenge_attempt(params, body).then(function (response) { + if (response.status === 429) { + // User was ratelimited but process response + return response + } + if (response.status === 403) { + // User is not logged in or CTF is paused. + return response + } + return response + }) +}; diff --git a/challenge_type.py b/challenge_type.py new file mode 100644 index 0000000..628e6df --- /dev/null +++ b/challenge_type.py @@ -0,0 +1,108 @@ +from flask import Blueprint + +from CTFd.models import ( + db, + Flags, +) +from CTFd.plugins.challenges import BaseChallenge +from CTFd.plugins.dynamic_challenges import DynamicValueChallenge +from CTFd.plugins.flags import get_flag_class +from CTFd.utils import user as current_user +from .models import WhaleContainer, DynamicDockerChallenge +from .utils.control import ControlUtil + + +class DynamicValueDockerChallenge(BaseChallenge): + id = "dynamic_docker" # Unique identifier used to register challenges + name = "dynamic_docker" # Name of a challenge type + # Blueprint used to access the static_folder directory. + blueprint = Blueprint( + "ctfd-whale-challenge", + __name__, + template_folder="templates", + static_folder="assets", + ) + challenge_model = DynamicDockerChallenge + + @classmethod + def read(cls, challenge): + challenge = DynamicDockerChallenge.query.filter_by(id=challenge.id).first() + data = { + "id": challenge.id, + "name": challenge.name, + "value": challenge.value, + "initial": challenge.initial, + "decay": challenge.decay, + "minimum": challenge.minimum, + "description": challenge.description, + "category": challenge.category, + "state": challenge.state, + "max_attempts": challenge.max_attempts, + "type": challenge.type, + "type_data": { + "id": cls.id, + "name": cls.name, + "templates": cls.templates, + "scripts": cls.scripts, + }, + } + return data + + @classmethod + def update(cls, challenge, request): + data = request.form or request.get_json() + + for attr, value in data.items(): + # We need to set these to floats so that the next operations don't operate on strings + if attr in ("initial", "minimum", "decay"): + value = float(value) + if attr == 'dynamic_score': + value = int(value) + setattr(challenge, attr, value) + + if challenge.dynamic_score == 1: + return DynamicValueChallenge.calculate_value(challenge) + + db.session.commit() + return challenge + + @classmethod + def attempt(cls, challenge, request): + data = request.form or request.get_json() + submission = data["submission"].strip() + + flags = Flags.query.filter_by(challenge_id=challenge.id).all() + + if len(flags) > 0: + for flag in flags: + if get_flag_class(flag.type).compare(flag, submission): + return True, "Correct" + return False, "Incorrect" + else: + user_id = current_user.get_current_user().id + q = db.session.query(WhaleContainer) + q = q.filter(WhaleContainer.user_id == user_id) + q = q.filter(WhaleContainer.challenge_id == challenge.id) + records = q.all() + if len(records) == 0: + return False, "Please solve it during the container is running" + + container = records[0] + if container.flag == submission: + return True, "Correct" + return False, "Incorrect" + + @classmethod + def solve(cls, user, team, challenge, request): + super().solve(user, team, challenge, request) + + if challenge.dynamic_score == 1: + DynamicValueChallenge.calculate_value(challenge) + + @classmethod + def delete(cls, challenge): + for container in WhaleContainer.query.filter_by( + challenge_id=challenge.id + ).all(): + ControlUtil.try_remove_container(container.user_id) + super().delete(challenge) diff --git a/decorators.py b/decorators.py new file mode 100644 index 0000000..aab3fae --- /dev/null +++ b/decorators.py @@ -0,0 +1,53 @@ +import functools +import time +from flask import request, current_app, session +from flask_restx import abort +from sqlalchemy.sql import and_ + +from CTFd.models import Challenges +from CTFd.utils.user import is_admin, get_current_user +from .utils.cache import CacheProvider + + +def challenge_visible(func): + @functools.wraps(func) + def _challenge_visible(*args, **kwargs): + challenge_id = request.args.get('challenge_id') + if is_admin(): + if not Challenges.query.filter( + Challenges.id == challenge_id + ).first(): + abort(404, 'no such challenge', success=False) + else: + if not Challenges.query.filter( + Challenges.id == challenge_id, + and_(Challenges.state != "hidden", Challenges.state != "locked"), + ).first(): + abort(403, 'challenge not visible', success=False) + return func(*args, **kwargs) + + return _challenge_visible + + +def frequency_limited(func): + @functools.wraps(func) + def _frequency_limited(*args, **kwargs): + if is_admin(): + return func(*args, **kwargs) + redis_util = CacheProvider(app=current_app, user_id=get_current_user().id) + if not redis_util.acquire_lock(): + abort(403, 'Request Too Fast!', success=False) + # last request was unsuccessful. this is for protection. + + if "limit" not in session: + session["limit"] = int(time.time()) + else: + if int(time.time()) - session["limit"] < 60: + abort(403, 'Frequency limit, You should wait at least 1 min.', success=False) + session["limit"] = int(time.time()) + + result = func(*args, **kwargs) + redis_util.release_lock() # if any exception is raised, lock will not be released + return result + + return _frequency_limited diff --git a/docker-compose.example.yml b/docker-compose.example.yml new file mode 100644 index 0000000..686f067 --- /dev/null +++ b/docker-compose.example.yml @@ -0,0 +1,105 @@ +version: '3.7' + +services: + ctfd: + build: . + user: root + restart: always + ports: + - "8000:8000" + environment: + - UPLOAD_FOLDER=/var/uploads + - DATABASE_URL=mysql+pymysql://ctfd:ctfd@db/ctfd + - REDIS_URL=redis://cache:6379 + - WORKERS=1 + - LOG_FOLDER=/var/log/CTFd + - ACCESS_LOG=- + - ERROR_LOG=- + - REVERSE_PROXY=true + volumes: + - .data/CTFd/logs:/var/log/CTFd + - .data/CTFd/uploads:/var/uploads + - .:/opt/CTFd:ro + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - db + networks: + default: + internal: + + nginx: + image: nginx:1.17 + restart: always + volumes: + - ./conf/nginx/http.conf:/etc/nginx/nginx.conf + ports: + - 80:80 + depends_on: + - ctfd + + db: + image: mariadb:10.4.12 + restart: always + environment: + - MYSQL_ROOT_PASSWORD=ctfd + - MYSQL_USER=ctfd + - MYSQL_PASSWORD=ctfd + - MYSQL_DATABASE=ctfd + volumes: + - .data/mysql:/var/lib/mysql + networks: + internal: + # This command is required to set important mariadb defaults + command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --wait_timeout=28800, --log-warnings=0] + + cache: + image: redis:4 + restart: always + volumes: + - .data/redis:/data + networks: + internal: + + frpc: + image: frankli0324/frp:frpc + restart: always + command: [ + "--server_addr=frps", + "--server_port=7000", + "--token=your_token", + "--admin_addr=0.0.0.0", + "--admin_port=7000", + "--admin_user=frank", + "--admin_pwd=qwer", + ] + networks: + frp: + internal: + containers: + + frps: + image: frankli0324/frp:frps + restart: always + command: [ + "--bind_addr=0.0.0.0", + "--bind_port=7000", + "--token=your_token", + "--subdomain_host=127.0.0.1.nip.io", + "--vhost_http_port=8080", + ] + ports: + - 8080:8080 + networks: + frp: + default: + +networks: + default: + internal: + internal: true + frp: + internal: true + containers: + internal: true + driver: overlay + attachable: true diff --git a/docs/advanced.md b/docs/advanced.md new file mode 100644 index 0000000..596cc83 --- /dev/null +++ b/docs/advanced.md @@ -0,0 +1,156 @@ +# Advanced deployment + +## Note + +Please make sure that you have experienced the installation process on single node. This deployment method is *NOT* recommended on first try. + +It would be easy for you to understand what we are going to do if you have some experience in using `docker` and `frp`. + +## Goal + +The goal of this advanced deployment is to deploy the CTFd and challenge containers on seperate machines for better experiences. + +Overall, `ctfd-whale` can be decomposed into three compnents: `CTFd`, challenge containers along with frpc, and frps itself. The three components can be deployed seperately or together to satisfy different needs. + +For example, if you're in a school or an organization that has a number of high-performance dedicated server *BUT* no public IP for public access, you can refer to this tutorial. + +Here are some options: + +* deploy frps on a server with public access +* deploy challenge containers on a seperate sever by joining the server into the swarm you created earlier +* deploy challenge containers on *rootless* docker +* deploy challenge containers on a remote server with public access, *securely* + +You could achieve the first option with little effort by deploying the frps on the server and configure frpc with a different `server_addr`. +In a swarm with multiple nodes, you can configure CTFd to start challenge containers on nodes you specifies randomly. Just make sure the node `whale` controlls is a `Leader`. This is not covered in this guide. You'll find it rather simple, even if you have zero experience on docker swarm. +The [Docker docs](https://docs.docker.com/engine/security/rootless/) have a detailed introduction on how to set up a rootless docker, so it's also not covered in this guide. + +In following paragraphs, the last option is introduced. + +## Architecture + +In this tutorial, we have 2 separate machines which we'll call them `web` and `target` server later. We will deploy CTFd on `web` and challenge containers (along with frp) on `target`. + +This picture shows a brief glance. + +![architecture](imgs/arch.png) + +--- + +### Operate on `target` server + +> root user is NOT recommended +> if you want to expose your docker deployment, you might also want to use [rootless docker](https://docs.docker.com/engine/security/rootless/) + +Please read the [Docker docs](https://docs.docker.com/engine/security/protect-access/#use-tls-https-to-protect-the-docker-daemon-socket) thoroughly before continuing. + +Setup docker swarm and clone this repo as described in [installation](./install.md), then follow the steps described in the Docker docs to sign your certificates. + +> protect your certificates carefully +> one can take over the user running `dockerd` effortlessly with them +> and in most cases, the user is, unfortunately, root. + +You can now create a network for your challenges by executing + +```bash +docker network create --driver overlay --attachable challenges +``` + +Then setup frp on this machine. You might want to setup frps first: + +```bash +# change to the version you prefer +wget https://github.com/fatedier/frp/releases/download/v0.37.0/frp_0.37.0_linux_amd64.tar.gz +tar xzvf frp_0.37.0_linux_amd64.tar.gz +cd frp_0.37.0_linux_amd64 +mkdir /etc/frp +configure_frps frps.ini # refer to [installation](./install.md) +cp systemd/frps.service /etc/systemd/system +systemctl daemon-reload +systemctl enable frps +systemctl start frps +``` + +Then frpc. Frpc should be running in the same network with the challenge containers, so make sure you connect frpc to the network you just created. + +```bash +docker run -it --restart=always -d --network challenges -p 7400:7400 frankli0324/frp:frpc \ + --server_addr=host_ip:host_port \ + --server_port=7000 \ + --admin_addr=7400 \ + --admin_port=7400 \ + --admin_user=username \ + --admin_pwd=password \ + --token=your_token +``` + +You could use `docker-compose` for better experience. + +Here are some pitfalls or problems you might run into: + +#### working with `systemd` + +Copy the systemd service file to `/etc/systemd` in order to prevent it from being overwritten by future updates. + +```bash +cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service +``` + +Locate `ExecStart` in the file and change it into something like this: + +```systemd +ExecStart=/usr/bin/dockerd \ + --tlsverify \ + --tlscacert=/etc/docker/certs/ca.pem \ + --tlscert=/etc/docker/certs/server-cert.pem \ + --tlskey=/etc/docker/certs/server-key.pem \ + -H tcp://0.0.0.0:2376 \ + -H unix:///var/run/docker.sock +``` + +Remember to reload `systemd` before restarting `docker.service` + +```bash +systemctl daemon-reload +systemctl restart docker +``` + +#### cloud service providers + +Most service providers provides you with a basic virus scanner in their system images, for example, AliCloud images comes with `YunDun`. You might want to disable it. The challenge containers often comes with backdoors, and is often accessed in a way cloud providers don't like (they are obviously attacks). + +#### certificate security + +Please follow the best practices when signing your certificates. If you gets used to signing both the client and server certicates on a single machine, you might run into troubles in the future. + +If you feel inconvenient, at least sign them on your personal computer, and transfer only the needed files to client/server. + +#### challenge networks and frpc + +You could create an internal network for challenges, but you have to connect frpc to a different network *with* internet in order to map the ports so that CTFd can access the admin interface. Also, make sure frps is accessible by frpc. + +### Operate on `web` server + +Map your client certificates into docker. You might want to use `docker secrets`. Remember where the files are *inside the container*. In the case which you use `docker secrets`, the directory is `/run/secrets`. + +You may also delete everything related to `frp` like `frp_network` since we are not going to run challenge containers on `web` server anymore. But if you just has one public IP for `web` server, you can leave `frps` service running. + +Then recreate your containers: + +```bash +docker-compose down # needed for removing unwanted networks +docker-compose up -d +``` + +Now you can configure CTFd accordingly. +Sample configurations: + +![whale-config1](imgs/whale-config1.png) +![whale-config2](imgs/whale-config2.png) +![whale-config3](imgs/whale-config3.png) + +refer to [installation](./install.md) for explanations. + +--- + +Now you can add a challenge to test it out. diff --git a/docs/advanced.zh-cn.md b/docs/advanced.zh-cn.md new file mode 100644 index 0000000..711fe7a --- /dev/null +++ b/docs/advanced.zh-cn.md @@ -0,0 +1,268 @@ +# 高级部署 + +## 前提 + +请确认你有过单机部署的经验,不建议第一次就搞这样分布架构 + +建议有一定Docker部署及操作经验者阅读此文档 + +在进行以下步骤之前,你需要先安装好ctfd-whale插件 + +## 目的 + +分离靶机与ctfd网站服务器,CTFd通过tls api远程调用docker + +## 架构 + +两台vps + +- 一台作为安装CTFd的网站服务器,称为 `web` ,需要公网IP +- 一台作为给选手下发容器的服务器,称为 `target` ,此文档用到的服务器是有公网IP的,但如果没有,可也在 `web` 服务器用 `frps` 做转发 + +本部署方式的架构如图所示 + +![架构](imgs/arch.png) + +--- + +## 配置Docker的安全API + +参考来源:[Docker官方文档](https://docs.docker.com/engine/security/protect-access/#use-tls-https-to-protect-the-docker-daemon-socket) + + +### target服务器配置 + +建议切换到 `root` 用户操作 + +### 克隆本仓库 + +```bash +$ git clone https://github.com/frankli0324/ctfd-whale +``` + +### 开启docker swarm + +```bash +$ docker swarm init +$ docker node update --label-add "name=linux-target-1" $(docker node ls -q) +``` + +把 `name` 记住了,后面会用到 + +创建文件夹 +```bash +$ mkdir /etc/docker/certs && cd /etc/docker/certs +``` + +设置口令,需要输入2次 +```bash +$ openssl genrsa -aes256 -out ca-key.pem 4096 +``` + +用OpenSSL创建CA, 服务器, 客户端的keys +```bash +$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem +``` + +生成server证书,如果你的靶机服务器没有公网IP,内网IP理论上也是可以的,只要web服务器能访问到 +```bash +$ openssl genrsa -out server-key.pem 4096 +$ openssl req -subj "/CN=" -sha256 -new -key server-key.pem -out server.csr +``` + +配置白名单 +```bash +$ echo subjectAltName = IP:0.0.0.0,IP:127.0.0.1 >> extfile.cnf +``` + +将Docker守护程序密钥的扩展使用属性设置为仅用于服务器身份验证 +```bash +$ echo extendedKeyUsage = serverAuth >> extfile.cnf +``` + +生成签名证书,此处需要输入你之前设置的口令 +```bash +$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \ +-CAcreateserial -out server-cert.pem -extfile extfile.cnf +``` + +生成客户端(web服务器)访问用的 `key.pem` +```bash +$ openssl genrsa -out key.pem 4096 +``` + +生成 `client.csr` ,此处IP与之前生成server证书的IP相同 +```bash +$ openssl req -subj "/CN=" -new -key key.pem -out client.csr +``` + +创建扩展配置文件,把密钥设置为客户端身份验证用 +```bash +$ echo extendedKeyUsage = clientAuth > extfile-client.cnf +``` + +生成 `cert.pem` +```bash +$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \ +-CAcreateserial -out cert.pem -extfile extfile-client.cnf +``` + +删掉配置文件和两个证书的签名请求,不再需要 +```bash +$ rm -v client.csr server.csr extfile.cnf extfile-client.cnf +``` + +为了防止私钥文件被更改以及被其他用户查看,修改其权限为所有者只读 +```bash +$ chmod -v 0400 ca-key.pem key.pem server-key.pem +``` + +为了防止公钥文件被更改,修改其权限为只读 +```bash +$ chmod -v 0444 ca.pem server-cert.pem cert.pem +``` + +打包公钥 +```bash +$ tar cf certs.tar *.pem +``` + +修改Docker配置,使Docker守护程序可以接受来自提供CA信任的证书的客户端的连接 + +拷贝安装包单元文件到 `/etc` ,这样就不会因为docker升级而被覆盖 +```bash +$ cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service +``` + +将第 `13` 行 +``` +ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock +``` +改为如下形式 +``` +ExecStart=/usr/bin/dockerd --tlsverify \ +--tlscacert=/etc/docker/certs/ca.pem \ +--tlscert=/etc/docker/certs/server-cert.pem \ +--tlskey=/etc/docker/certs/server-key.pem \ +-H tcp://0.0.0.0:2376 \ +-H unix:///var/run/docker.sock +``` + +重新加载daemon并重启docker +```bash +$ systemctl daemon-reload +$ systemctl restart docker +``` + +**注意保存好生成的密钥,任何持有密钥的用户都可以拥有target服务器的root权限** + +--- + +### Web服务器配置 + +在`root`用户下配置 + +```bash +$ cd CTFd +$ mkdir docker-certs +``` + +先把刚才打包好的公钥 `certs.tar` 复制到这台服务器上 + +然后解压 +```bash +$ tar xf certs.tar +``` + +打开 `CTFd` 项目的 `docker-compose.yml` ,在`CTFd` 服务的 `volumes` 下加一条 +``` +./docker-certs:/etc/docker/certs:ro +``` + +顺便把 `frp` 有关的**所有**配置项删掉,比如`frp_network`之类 + + +然后执行 `docker-compose up -d` + +打开`CTFd-whale`的配置网页,按照如下配置docker + +![whale-config1](imgs/whale-config1.png) + +注意事项 + +- `API URL` 一定要写成 `https://:` 的形式 +- `Swarm Nodes` 写初始化 `docker swarm` 时添加的 `lable name` +- `SSL CA Certificates` 等三个路径都是CTFd容器里的地址,不要和物理机的地址搞混了,如果你按照上一个步骤更改好了 `CTFd` 的 `docker-compose.yml` ,这里的地址照着填就好 + +对于单容器的题目,`Auto Connect Network` 中的网络地址为`_`,如果没有改动,则默认为 `whale-target_frp_containers` + +![whale-config2](imgs/whale-config2.png) + +*多容器题目配置 未测试* + +--- + +## FRP配置 + +### 添加泛解析域名,用于HTTP模式访问 + +可以是这样 +``` +*.example.com +*.sub.example.com (以此为例) +``` + +### 在target服务器上配置 + +进入 `whale-target` 文件夹 +```bash +$ cd ctfd-whale/whale-target +``` + +修改 `frp` 配置文件 +```bash +$ cp frp/frps.ini.example frp/frps.ini +$ cp frp/frpc.ini.example frp/frpc.ini +``` + +打开 `frp/frps.ini` + +- 修改 `token` 字段, 此token用于frpc与frps通信的验证 +- 此处因为frps和frpc在同一台服务器中,不改也行 +- 如果你的target服务器处于内网中,可以将 `frps` 放在 `web` 服务器中,这时token就可以长一些,比如[生成一个随机UUID](https://www.uuidgenerator.net/) +- 注意 `vhost_http_port` 与 [docker-compose.yml](/whale-target/docker-compose.yml) 里 `frps` 映射的端口相同 +- `subdomain_host` 是你做泛解析之后的域名,如果泛解析记录为`*.sub.example.com`, 则填入`sub.example.com` + + + +#### 打开 `frp/frpc.ini` + +- 修改 `token` 字段与 `frps.ini` 里的相同 + +- 修改 `admin_user` 与 `admin_pwd`字段, 用于 `frpc` 的 basic auth + +--- + +### 在WEB服务器上配置 + +打开whale的设置页面,按照如下配置参数 + +![frp配置页面](imgs/whale-config3.png) + +网页中, + +- `API URL` 需要按照 `http://user:password@ip:port` 的形式来设置 +- `Http Domain Suffix` 需要与 `frps.ini` 中的 `subdomain_host` 保持一致 +- `HTTP Port` 与 `frps.ini` 的 `vhost_http_port` 保持一致 +- `Direct Minimum Port` 与 `Direct Maximum Port` 与 `whale-target/docker-compose.yml` 中的段口范围保持一致 +- 当 API 设置成功后,whale 会自动获取`frpc.ini`的内容作为模板 + +--- + +至此,分离部署的whale应该就能用了,可以找个题目来测试一下,不过注意docker_dynamic类型的题目似乎不可以被删除,请注意不要让其他管理员把测试题公开 + +你可以用 +```bash +$ docker-compose logs +``` +来查看日志并调试,Ctrl-C退出 diff --git a/docs/imgs/arch.png b/docs/imgs/arch.png new file mode 100644 index 0000000000000000000000000000000000000000..f22d8278d94dd9eb10ab6edcef9e7742e37d1428 GIT binary patch literal 80104 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

1$c&d%FE)5rwJR=BJ*zq zgLw9=5w~f1w58uSL~|*Du#&vD`)8wKGu;QicoptSvd%B(q`Mjz!8CSX6Q%l;nf z)bvIO;(3K_DmvLQLbVzD`o^5Pew$Ee~oEd+yhOcri0$g8>1n#{;-H>vdyN6*bYr@51)15c2fA+XV|M{CpE@FiBEDrK~YfRRD!e+meVAswad+pmFze%ZqtJb9EhcMWV zYkBz+eZo+6-QGO)WGZs0WI~J-om>c5C`w4$*;gdI4ih5H2u5oKj*1oqC@hVf`crHQ z)VtzeA$@%DYi11;NkaQ^i-YjW>*51X@lk#ci{IrDGc@z`rAh-ee-k@UwTNGnD$Zd) zh1`9%q}P)dyajkr8tWC1%B;EnJ-)?2=b7IrQw*?V(q7%6-Pb3C0*EBOtX z-&^K8rwj9SEEh4J4D*RIhMQrQWurJ%6^F#ob5_MJ&S!p$&?&3suVIKMkYFNE#$Jaz z4Q^E3Eda2cg|>4in0yAEJAAM@`B%vgxQ&-NIn;R^^1+f%=KgBKPH7#&B}*{+s1SVW z%HqhA3-VXF@@QiR-Tztc)By_qw9}8~BJ>%3UsT|wm6LUXk*i6WEexN37iyvQ$Mm?F zWb#%LgAcOC z1(Q8P{lB2{i+R%WZc9oWMJbca2NOvvlZ`thqL{5q0Y0pc`L9+OfGKe>AirrI)0i#y zGW}QJTwVR|>f+)5ehu`0zRS+(yTcgiq}*Ylt({>w!z%rRap_ZKVuVXEgdB!8eXYK8 zenfp!xKULc(3o*Kn=^0u4e)1pne-ynv>;r*9w1FeL%DhuGxM7^v+VgRk1CZlfIs0d^mFNttbOk^~NO$n%7&V7!@ascq)mZV%ojykw$Ql)u@5t=_6t_ z_54a%L&DcPR&Hv$Z|3d)JoQDff5x)UXwr^b*C9T^<2SuADToh`VOBh!&ZAuQ3e6%md^-D|UE`jvU+KF5Y{)u2Ibf}c$6h!afmAiY59^oFLPE$73g>U31&uwK1>S{(Ob%N4#x)Cbo9Mi5rYB|5gP@maIis(JP8Zb3?w zYx5O8-Z|s2??(k1@&dJ0z6)Ni{o9zMLhkn7pA|(`FGJV$U9E~djOLwfQXvhQzv2jc zlqO1lX^p3I{F=-CqMOkfd4*t|*jTYSapUKbeiONtf*E@1{AeMZzUK1>1tpYmROtPI zY+HY_NiD$5>nvealUbx$#cxn96E}b*FIAoJKr{0DjfPD3 zyOX!+ib$(>ze@gw@-7G&s~HcC4V$N-3IyEaQ%NG$)4;v8ZB2NyQk$AQZboDrq!{?6 z?a=ZQbzI^1{yKWZl;&F=N_gsgpwja}xiDKk1!;$U%jo;`X*$g0wlnZ8yYWiqhXMOi zk4NHdoI?(0X8<=E()=ulreCriUKFY~hRs6_-4F9o&JI$&gm-)NcYp6W%_zq~gW^iu z$S>&PY>v#*U!kRps#)j#Znqh%SMY~XdJ`z? z8fRQL!gSLFYVbA~iao$gCVEUeZT zm*;$$OyXZyIpUkijWr~ffWb44VV8QrMRRBJh~+^}sg`RlyoXta+;N@Z@kCq|6o#-p_hyaV^Q8 znR0+$;`1NZ%^1x@;v@&w!zGO|vDm+1;Do(7cC=&2fy((S1%rU(r7D^vx0$8|92F1f zzY00;#QuI(tz?`0+d4V8vTIzMKJ^l~2*3RuP%P)v;uRVF%$QiRP3bUKEqrMEK3M?= z;!+QK*SxthByAHkqyc%lwATDF+4Z1*F<*!7h#{Gf-Jg-Yhi33iMYmKPq*feGA%udm zdDrcTR6&G0A}HOuQAk%YE$f|Xq3M{*AzxZkU>zYx$9TOi%xe`JS>$mAAZ?F}Ns_aR zctyG;mibg$UUY#y_Jp%Ma4>tI$*!vbQZKdpDT)@^uh@bkyv;GBO992N_XSAsv(eQ*iBSEC0u89e;L6y7Ya?SchhjK?pv1Nj=G1oqks-8@&qn_V$b;YA zV>|q8O;*95Mz&1dqJM4_QrWHrDv}V3W1(@Nn5=XU-MkXNT@U}Hl{Gq+88{3Zj8JB&SL zt35WGp8ZEkf5S!S13S%m8g(56xQTTS_ttt`R*P+B{>tN@$i$j(VRb6K@hl2yU>d>OD_#()i6r#1JuV-RtVzh(hQ0ew9$JVk} z&WJ8yzpG^DpS}qVGHsxyzW5%1*tmBWCSQOL{dx1lt06mDwt|RtoXN_Ua0N(S+wRI6 zSBBTv%tfcZr+@RdA&0ZD&R6hMQVD{i^i(W65F8z7BW6Sz^K^(!%!(Nw-ZF$fADrc>&{dlI!M|OwJwZa0eH0`8 za)yg8n2Gkw>&r>(A2_K>==lc}j)dXEv|NLgrhj3<0FE@mh< z$oXUBHO+D#w>je$@@V9Q6{V_ZhEFDh`ZGP`G&)PI!j{%OsGkrPZ!#6B zo@EwG(BG;xAcHFe!G`r6JR?4aGHV6oZ5g^Ng)dS3SBr- zJLhU~=3HD0r`Z*T?~Sg*y-wIWV%>X)#cw;)YFcg@yfNRJ9Q=YEMYf16eruIyT$auI zE3I$++)7H)FUAV?ZOwp)KpX5yoTP9bzh<^@ZPk?p%-d^o1iPsoc4_wqa*u*Bbf=Id zcHY4bOsueumjq77bbkHMGfkyaE(^`K#WNv(gMAV$ISv@KWC08pU;F_PIK_V3yeX9) zpccWAUVfCx;KPgPIxM%4lsPbsbexRqT7GsAcjU@_bNtgx=JI7#rTRuy? z&ABf&UjBu`=P&HKD<(c$fBppJLE)3qO1lnOfu}rg)B87S#o+@6Pw7;?1tL+)Q{sK9+L)9A+iYUd7&Cbi4T zMC_WC{P@8X*m=nS-j6c|aFcQOH{&0ODoltT5oSiK~kZ< zG?S31qyE>S4_A;rodwQ-1FSuAy_VY?J}Uj9fJ>-v&sUQ&C}dClfbDq;o{S8cAG zibEE}%fG8cKq`rE+9<=3qZnD|Nyz8Zm69n?gJ*JoLNA#a>L_AN2pgA+!^ewi2%gTt zGrirF_-W!x@0J-$aN5wvE1($y&S(8mFfGvii9xbCN{7UFq%X#Zbn z%#7rJ{_c?Pw`_dPwf<4zzxruyAN~LB;2k#j64!Jidk9))^{*dc&BS)Ruj|4@lH9*O znkfN9{v)i}@9F-(b!7j4Z3~E=o>Z#tc4bYrR>T*%>BJ?5Up2e=g5H zYLn-Xo?{if-e_Muo|WT}o7tQPz&w=Z*weoS;3(56PihauB;=EW=OlvD-t28fq6gEq zdt-eh53N5nrSYOybRtg~XR-s41=PK96qRgje0<39=r+=*0ECYU<(Mmc@!gN(A6~6J zqdo08diYL#`Rj1-T4`szl=Tr@hM!O_H1Cv>^B%OdoJ%otIF^)qqnj|Z9Z(qe=5I=W zZN8eO_tX#%eEUPI*w`8${G6mM7hMwBPFf^OCy3VU3)Ed}C{-uet+*Wx3Yqg!G`T7b zcaIH~rl}(8ERXS+5mA5@;D~bGTm~0$&`P3@v}3d(ZVbu`=P}k=5M3c-pXu2j22yq~eF+cgtKak*y@CkZf(GFl&Pa>@%zsj}$ZljJrS;C`NBxUECo z_YEEmo-2A$tUw{xd5#_!>X!_Kaj6yei*GM2@&JxQW>OAjXZmafBIb7n^E+zYvr_93 zdaV&%21Rr!`$a2QNbf6*TrjR8zHHnuy%kqo;2Y3o%i+)PhdyB^$P0>?9f^K5uc}Nx zOb;{(Qui~(On)6i#>6JxK2n^F6%Mmen`_!HnrdE+H=k9s{h)pkn7lu%a7x1L6>cLC zInyReuU{?dlM&Xj%{@r>mogGH+uYF;kZI=Lu)D}FfwOEZS5r{0HgG*C!C40BYeJ9U z=`g%t9$!~1u|WV%`5COzh47>b=^mxXS#H##XV8)C)eBio+4w$Moxz?Vf{MHV`H=!r# zHL5joyFA8eDKvwO@-{Pf_s~nOTeKs-?owvRPysbDr_hy8<+fyvTv|9E2BVm6)Pz#Z zKTCTWqV2zQL@RM?jGCw%_X~}H4>DVMOwJT6`^ZH}%O;GRqw&Xy&0QWd%ZvOJ*3n;$ zp$Et$-Rz zOej|4bD}{Qb>*2~MQhz^mg5;77@RM^`I}7Taa?n%$!XHMFBw`gC8cBP$u>j#@A=rlGhhR_rVEs8Cyf}?WloEGxVg$9QkjTs~vC# zAh!d5+)$4RQgtvKFQ}03QLz`?MA{>tJ0>W@r0oX}a%XrN>oxhCzgw;8;VZzuZl{lK zqrL95^2uL-)rN934p~as9H@pm4&NHYGBVZg3o6A_-?leHg@cI}*1Wm`E0G^f-U=H- zQ+Axq19ucXRJNVBn+(MgrHy;2+!bN@z}n|E^i;2@!l*jSrLB=;agyK{#VU7={)QwL z+~a1K(Wc%IP)=r!^^R&C9xzRzPrg#Nf~B;d5N}9YRSvUrVCs-MbyK~?PZJ#ER|?AZ zepQV!{z^=>X%~YNZYwK7%foEvdz6}f);fNnFE5S~{d%L!iu-LtFC}F6e2Xo}h={X8i+vfC9$1Nw3 zg>Fi-(#~^Bpm2dq=BVW_v z2lf1m#)XyK=Mq4r;>QD{;mNvETKNHm|WxDersP7~{IaIKqgI6etChS}HXDgz*9ibfdxQtl1W z?@HU2fy*b+y3i2FX{7e<7O_oERu36B6O;Whg! z2$=lA?*2gBSXwzFVC~55C7>roMZWmfsQ7o3Mq<02dvwOQL(z-gl3&R&1W}`+g)tT7 zwJK-m^X@qra(De@we1u|>Qcwy$a2lLj%ABb^;vL9mnf9C(NqU5wqsQ^3h9C11^1<7+$AXUjKIgmCvt7XgZswD zO9s43eV4Fuqc#1%v5 z%O<;r<~4qbeJF2J%(rQBD{q4bD`=D7&wFo=3C&mRRue-(p-Z;0#3q>qn?Q{g4R=fm z;8*`kK}DMN$TLkvr}md^@XpdP(&W6%yyc^9m3jBn#H@HTfw9y_Q8RWeF718E2_u%N zWoZp_YJtar*AQ`#if46d@4IQRA&>nPQpGK_GwfA1Fwcl}FmZP}h-|69hlPHXsgyOj zUGr9~HX_SzP!MdH1X$h!rztzGi4%;$s;78yrCiQS$v#8hrUFd9xxbp=;={VvN7b_I zj-6AA#EKc6rHE)(qj$&rUrHHr77d~f4I90`BO zf3Lgx;oKt;fT-Gn`+{%$&()l?vZEojn%d&h*!!akc&KbcvOr_ zM=##hzT}THqq>C~ipCmFmK*G;jwz)+4>r}gvRFcTU?9-nV&60Ved}C##1Udy_sXu1(u^92s|YQW$pu>BPx#qjtc&Ib(&i|J{9oh z5`6%`aaVQ3$K%KSed%vJsRL~pmPBnKi3-2qM*GDpe3!pGMAqCrMV#xj!Z zyOvtk^)zJZ4>a%^_@XA5h*t{stB!=9&QlXEwK3d+z0Kf-FGEFmt79fB@cA5a zL;W$ekv(+zAu=e~Ms)|b_7*ZJaE zO7_EaA@N0kdtdBP=AwaDlMYy?gpAL8@~D(ckCcpl6kAT%Rx~lwj+N#d}XKR5EW*5+L^Sqe20h$K623u0Ub}?z2onr(5^VtuN2=iMKE8| z9iQ|3lq>@88A!VcG3Vn#9E0>~#!c9>M7tDkv#PXGOz#M$VbY+^-#~{Xka9b%Qj_`vHYU)I07xSU=)w`iXlsR3m_b7wm-Sbb8 zXCQZjXOxxGj)s384;Dt=s&<^cpuN?*d{Xxe=TJ+Fj^oRgRNXN<>8nLqpeqHRbeg=#i;5Js@9^7>6!Ao((eG%?< zg%36);eM2huh@rb(yodX*JXW|pxemmy)gSuwwjd!CyrOSZ`L^%kB4UR=GW+Hnq`46 zS(8ILT~#LHeLNE?H*G^=ym#VfG&=Gr`Ep{NepUBNC90z7W(c?*p3)7xXF_!=M}^n5 zJduv?XJ2oNMgZPOnf8g*+K2cEu1Hz_39~X?`P(m+)Ghi#?`+>En_+?Mr0ES#Nuqu8u*w+23YdxJG zBtlIQ(_ymWJ5^|!FGD?2XxnOBkW$)=wWBF)cz!N-Dvnn@LCksx_WwZEDmH`P)54Mq z-#BRdFyDw-mQ)f=F1w552}Y2@xHK`Ms=dgUku*Qp>>YSVet~HLETWB*H{0BeH#=h` z%1ZW$@~w(!mg_k;+}=P^V;4^ZIez*K5C!Pd6lBtR1xC{z{^_V2Ihg}(yTL!fQ+>FP z1mc6fd_To7_Pth)W_R@5E_XT&ceSs#p`o%&0P1qL>%V=qFnMVgc8TN#o2v95@d6%o zM~$p&fzDJqWMFkQ!9{(&G2EX6*505|*<~C>y_fgsdgd7}Nkr)iQ$hS!Kc{KvCH_<8 zPPqe|rfD7?qzzm8+E_F&oT%r{xi5^iky5lTwFhu0yp!9kxl4}d?lZ}$E;^r5JwA^T zb6pm%cyH?}GCgpj5-|w}99KX`r?ex%_ob?<7Q0_dOV;$vsg)*n*~RB}e-rCjng|jE z(EhP%*8iIDy(SN@jW6l7Aj;EcJ$n)ZO*nOYpTv0vK2Lh3zThob zlhppgdjSgS=++Liz_V0EO(7FLJzm>G#!3^J!tZ*>6==WM+{rLpUPmx1(5Mi!B{-So zX0`t!A|`KO=$x)Nz_`)=nSe%eu1E$Gh@(B9tPIi}yBnz5o>-ex=seV2>y>K8=d|8% zf!&qxcv_2bk6cDH0Ab!bPfYzvpd4c+-zeta&f*>mAqW(5r8k1+Dx8984fn81BjAUh zfcwFMC0sm$?i^LE4$U_~Y4hKHT)x!ms8-^HxA=2J?}Kl<)%?re`qXlpS?(hL#f z_2&4ICuk7$AwG>}XzG;4cX{(Ml`wVvy^sB8M{JJ69qsECv4C&OBPA==RVxla@g~D= zJ5Pklm+=+}k$I{oIm*P*fj`(p-c0T;!)2(?R1BLnML7aCl5m zz`Xmo7yd8xojEb|w7+7QurU_0Ojyt#Lu#}+tTr53(rag&0&(l9_bC&F)`!%*@mU^c z-x!*k<L zw4UTNat5h|t~1d-To4iU15};}_kK}9nMn9`QmW)#^46>*$z#9SZK0(q_9TqHf+;a9 zxJ8O2y$(_|pRuJcvYcI!$eKS$O#n9zgm@bN-9#*74sosz7t!% z&-LMwHo?t`Nl#6yq!0>vkJ#)V**jeN z=hg9I%1@^WU$r=CNwJ|H^Jn-pFjgW+Q9eT)!7pbc{dPnB#F90i+?tueIuJR1ndjg; z0Ad=Z0qx*VGFnUWS(!u_Gh3U9n^}rmc``kyCFhw~!=bEIN{-Hcp-0cahW_35Xy5@d z0QFbDRy1xOInh+?9ePiyqEV(_*Zn=pw{c4ymdvr)E};j9zxo3Ccynq)rO6drHH_Ir z4ano2miM&@m?r@4egkTQa(*_7Sd@^ydv$-aZAqrOE{6ert+f zrh{-Cm&SsM&V@~6vN~p={M;E28RZ0tGOIiXY>QoWPQ3ZYt8#aqP(=w{sHEQA&0+_f z6u4+%IhX#8Vi(u^NjAi%zuyT;2Y;w^mq?*xjL>CMuAmbvEB?s2R?p}x5~~}D74%Ao zszm*?e1ASP;geb9-4yqMM$9uaY^x&xNE=$s4)J#Fbs8*ksDQ9>{YRd=CnI@&H55{#lpBunLwIWwWQO z`|B*}A4&Q7H>Y(riMp|jx~}y3*A32Y6U#Gh9m`|iY)|W&#i>;2o=Aea@pd~$r5B-) z-egacmL0RPwFQN!g{^12{)3e#N`|ZuAqWvY5b?!$w^Pcs`)yZyBslCs#J+zwkvEJ1 z=sNGXQ?Vo8n*5c!mr_Kgo{kj1OBsnzGP{qbC{3Lh73%tFfsnf)t6lPmOp>fMx&^Fv zu-C^*<6OAl>lQ4boz-4$4uFm4{Xr#^-Pcy!UXbP7j#Yqa=Lf!W)w8*he+tF>kMAM= zQAIpif_tZ1E@}HqEzQ6niPSO1Gp`||>A;xS1DXohurlw?k<|1`eM?fXE0#XrxlKol zY&LL5aLHg+x{<<+Y-zr=ixp&)=dbdlH$ckvq&c+BSIXRV!N!~AaF59`t9Y8>A+$}i z`F<3mU(S(kW2LX>EPuVtdWlFZ&pMSK>KRJ)_cKC<#PX(pxR zX?m7X-5pB2xkaNjUw2=NGR(f}T4W0EJrH!!?$5uZPs6U*@(^;*PIvd^z0^_`16IXr zj#tT7Mdug@qr(dTofLv7)eYirdCw<7G_$KlzuOu*T2lqSG`K#7xd|KT$?Qbw)6XH+^rEn3tLLJ+S50tu;Gtqi`)zajeU}d=yd{4cXpZ zofG?H?SukWTV2io*Yx=@>E_`}hP1?*Y@6_4+;+*}Ud3(C&T%RqW! zrdVL7sjpeHV9tL~GfPP#?qiBaCddqlw~@9=5fuJ#URd9^hZ z(a@6X4}0-ssX4n-9LmQ1cN5xKb4~~+(k4G%AW@5&HMSLgIvq+Id+!Su6S8?Z?Tp^y zXLo&Lc<;_taSZkhMyzjMM}G}VCvU&PORLUn)DLfNSa1!_ff5?hEB=w$?#3zf6D(Yr zg_>CiB0&#??c_&YNFHcTw?L7YgQ7 z<+`_%i0nO8btScJg2`9{uUwIXP8cUi?h{njHI;iTiQm_;;GdZDw^l7y{=<%r96CN( z^3Vf$}(Q!quD+?AoY+*0Ef6u46rT%u|PzVDQb( zLj>J(-JgcayHw%zDo%`~hX~`$PxZ5D94=BgB$Z%~I+JqDtNF5`g#Ga&QY$$gZWEek*Csh;db zMTc4LnVhZ8C~a@ph;JDA2CCvRQC+##Btj?fHTr^uiLS~I2Dh15J1-1XSW}=f>^FC& zbnBL<$E!r83;j1s>gJO4=~T))vB|ds$cxw>(L(xG7YNeycV|?+wH-GOF9DMngQV^ zm{d%MRa5bi|Bf|BpvU`sX4BKMiuT1UlMuMe5$~L|OYoMJ1pQ^I!VT6jK5Gnca_i;0 zW--&Idcj(a0l|Mzx2)|H{I=`T#7fdu;pw3A=b|B_l*Wu(ly#c?#b0i?rL23c_I|eA zhQ+B{A1HGbY|Mzfo6AJbutS|o2kZ)cIhs;{?lFWHe3$>x@2v4}lf8ClR#P3axB4Ss z@aI}}OOXgK@Z6Yoe&*HvR@_+9&bv_vj-?7%$YCm3|}$r7gJG3FtgioU~DL+KNRzbiU5JFJ{kAM!@_(GdyOYn{bWAI6zkr z){=Xb9|H&y1) zRLZ%T{71XkpuPIKJaeJIauu7a2ot@DhUd`Jjm1{LG=s>J!$>EF5%#^4Uy+Vg;~m8j zLFvW@e7l!Py>~akys@5AVn8)!qK=#B2*jn4@6s#w2@6?goQ_-eJNFRQlbLmSHX_tj zKH&JPV)Sm!Li*#l(olQ6uXBA9|9~NMPqUz`%}<^h7)`q}tSx^bM}E3kiy~ti&Pkq` zm(bFj7}5$9JTinu#|_9=C#OYJezu`LZM>V=D7YgU=>G2xi}>l=A>b7yU^--`ez$vf zE!W52)G{sOQ6y+cWfJt6?)9}QXrZCWKCyx(@1_jouVx!HjFN&i4a<-51`*ABhbtKO zTD~Lom8q8pIdJoK3)zRP19V5^q_SJYpB3|}uK+0Zt>*a(|ARo17b@(L3R^%`r?1*b zP|Ige+0ngEyA$My3oBVtG`wB)ilI?XT8s00WeACP`JmNi*C<9o=?Kw&Yyom%C@%%* zJfN`99@qm-^0kbZ{P6QG21eC@Rmp_P*X>_f5R6_*WVDuex22UI{pRnthlmbVC^*gk zqEL$S5q*d#u+<>wWYo#*8Z?tUn8$_F(S_}k0;slYjF%}^U+n9S-jt|RKt2UUl%_N`oh+JwI@Gd3J_q z_ROm6yZoB8=O2XrK$}O@B#r5%`MEy}^U?eAik4|a7F5XMBh0|2Lpqn|sb^+tl!)??{@OSxQI6CeIg63pTG zVZMqPuWk2xu6()J7h=f$*RT#WWv)7OZvOuKOviKvT%TWyv6fpw8WfpJ2R4_njHY}8 zRU$&y9~baY`WXnLonXEDd!42{c}E-08Z3pEjQlv@bx^lrN3zXSUhDUn{xn#G(V+wj zIRt$=@Wsm0ItEMr5VKo&B(1* zljjB9K5&CB>}+UT-xO4rkxXdz~m-bmAbO6wJ zdIIe*=^YX=Ge27#^U+h1jk+&_miPaq>PL(BX5WJ)TQ(IGBv=hg z?0bY^Eqbreyfn53mfO~=;>y)n!>^TRjC!k$6s2OvyY6*hEac^79z7fNx46~l62E$X z9wu_*sXr)<=3_4BJ=7oQ7KBXNOb}Heaf|i(7r#?C5!_)z>K@Ygb_V|J0X00mkg;+V zr(Lntyq2Wm6#Y9V^K}HZ{5^u%s!Dy+&i4n<$or9%)%l;q(Ls^a6z(>aLrWo7SG~Gjg$1& zU+);IO9Ez^Pqh6JMES^m#^*b1^H#bx=BCa{l?NxqWF5;=3AF(Y+?Tt}!t->!{ zV=0WLq#6QK93i@Y$&rO18~tLPu6n7Lz#ewdur`~0q~-T8-91>?>)vTAt?D3Ia86jI zF|)LQF9d`dfC8OL%liK9I19v~8zB(I z-2fJ5!vbR zc^940?QHhr|H*t~&6-)qQuImuOc5gOy8%evE!DCSSCAa5TvC|v$UN=#C#G+jp)Qt~ znV`{MRA|SiT$pwLV1;X5E9)kgQ>WX^R%aR*FmGIWGg=U-k24o@=#lc<>2bsQOtaOM zZ0zpk1hHVzyXzO|Q8Gbx3krvfmB*1*^Tq`QO~h2pDj=bBO`-+a(7SN|6sbwuDnRxz zwDU2Wf=l0V9T-QDZzf;Ju&`~;FOC*@I^CSxVCOwHQYXqBHC3f8@5EFZAI$jz04pK1 zoRxO2NTwe|(HsFFkFz*A2GOx+9B2q$4bn53k2J<__@4b2@I0mdPww(>OXJv-wiKk} zzuM9h!vFJ+Y5ZSen*J|7`SCxD@`#6nLG5zg?vB2@T#?5fkR)o?`tYus&(dlOu&7g%&eR!X~acLT{qpZPvOF~qSf zPgVkH`)b~V5N!#Mp93|$T0ZNy$`!@}Ac$G1_4MBSLD`pnw1oaBN2e|eh>fGNI@w0u z{JxKI;iFSgEpw{3v%S2nBsx?|J;OEj0vg(m_E;Yz5i9bJ>=geNGz2^Z;}mD+gHQ>~ zZM1jDUBj7hEyfGhCY}0~Jv+|w6scwJ7_~(Z9*Bt4haUfy2Y)aa$~745&`u6+Nl?PO z_9b!!6T)-m2u*I9<3Z+%M9G&p-@ntM(h9eOOpzDnl99njL400N@LcuerdL_kXDWi5bomEL!&hPwj zW`1Yp%$allk(taSPo8=5-1l?c*LA(#Z;_Gbr#^6hvDyC*ru<2R_Prh^ot^s2p3`m9 z^TThgc9SD3Pf5m4)YJ)?)usAM(0iWUHbgqM7&%DXDtx4twl5md>afl-FMMj@1YJUj5eX}-LP(`7Z0+xD<6shqr zuDp*(XjU@3dB86Nd5ErAMTzspS16dj4Y3eCYck5s?RYSy$^J%UuZkS+CGNzu^PIu0 z&0H5;`iX9TKX6!60;{dw3&*HG?DqF4?Vr_~Sp*NG36qeWT7Gpr)U5%2Fqr+dwoMXs z%VIDGTb7e7wbjsQFjLyJL&n5lGkcW+JjE!xBsre?n9iC5fK#MHQJ%p~Z-J(1GW#Eb z|EyK>Lxn&i;=))so=9}%-AmCBhQq!aY;pW?PfuXxLh^<;l9Y3rY`^P-rCiG2=Oi1u*Jch zbs@4QH&hsFq@slv-d1goPh{T?k7^{ek}+>r&yC;1Xl?q@X07+PakZ2{F>?!Kuy_!&prO~U$XS2kSfgB$9CH`* zcXcW&YsCpI?>Uhv^_mKGDWf~(Viyqx4Nup9-*1FA@lSQ#yB|aMcj{vGhOKP@yrwQ} zc~oU>B(>Z6d;%+|DqUOGoblBVpO*i=&2BT%qONDQ?|P)uS-)}s7#jx)+};zmt9SS# zTEC{J#w%H~7gS)3!gz#x_g1U=rc_W&1;727Ea8IX zwp)_uoXRdd*y#`sdEXTRY496)xwUw2V3e=_2hQf(k|U12!&Dz#=f{n;Mr-k@k{etr z8b^jIu!vm6D^1L-eO~-X4F1r=eo?DzDjkx0DC{yLwHX3btd2qpEcYtbH>_FL`A~R9 zjkl=9gs4rA)#ek~*ww;Xf#0k&tMZOfrthY`v>#OpX5pNBwr#sp79+O2a5wj~6$dCX ze66s@%wsa?`=D#w884sGJMu)Yr=1hRd`ZQ0nCpSqOI0dwl>zQd-Tj7*LJP5@XGpZL z%S%!TqR&D4a>KJ<&Fm@Ym*87fWp6s@%7F)Ap6nXbS&ziDg5fxCefP0XI2p5wm(|Q^ zYrcEEOWOoawlK&_>~c?!547T}{6zVO?EVoEHL4bici(#$;r}r&G`}nU)(A!mjP%&& z;hApHwJfi(eD<>3qqkAjwYs>eV5rg92>#wm!=7AJBy!8E>R6iY$bMn^ssEk09}zK8 zO%Ggo7T$ORqW5VE(FI5p6b658mUcj@u~ej++Z78owuV&54N2+f48+ACzhK92M#zU5 zJHR`c?$d3!gMPz2)VS_GR@rn)ocDAO(lh8GDzhw*9spv{ee~xN(XEwyc}fMk z+4zDMWGw3>CevN3q2HUXM}Nk-8h6d}_?h~{il(dH=4Od1SdwNERB-s@-0f`4#-55# zKBZXkP^=;?c7ANwj^C*@s&`1-!JeE|>9VKcWiEE9e76NbLa9q_awbFeBk73yV!?!+n^uzzXWBnh5(Pbk!Z zo8WHC(tq&QLdIrn+|8C>rZfUX8J}oYA=Z>+rx{ij;_1z|wz{q!La~JQ>U3?)UCT(@ z(m4XV7$WU-r6Wolze*o_emYVH%8(|ydqPe_5laZMI7qz($`kt{U5@b z_TGWIS7NB4;AIV0ZhsBlSxy;k`S9VcqhMfhu{xWH3}ANv@FvP>vhSFe@>7kJ*^??Xoat<6Ye*s4E-OZQ&%febu_Pgpp z-tD~Vkw;B%Z^Q$q-7y3hsF&E$HO0~?>D&E`$-GuRm?&6%IDIMCjUwx(l7VSqgFk4ng*;G%; zeZC&SjSyVG;DK&OB&Gbt$vk3{(>jk&s_w?G(6*#=Gd3ykv4tU5iNu$xAqMvbGE$&i|zG`qQIRj;bz zP>}n_5k3ptSrVV!NVLb!vmN;~ugHx2W%3=tUXeLq6_S9SL>b}g)|DdexwUa7w013V zI!-l6cq{0oE!OZz^I{8r9TRf!+yv=jQt{M<=m|D(D{+Huwtu6If5^;NtPXZ+TKM20 z=pBsDUlMjra7(b2aeC&~bAF~Jqsb98SC6BCdu@vxjg?_wi`EPgoda^7u~2mG;(p=+ zRwrU8?#L7De)kO2Zgp?-hWESv`K<_hdsPWr0V&y)=osZnPZyYd?}Vz?DkB7WUsh`^ z$Uzz5Xj&0lEAK~w&MklPP`wm!5inKzbNE_sD7D*Z0 zktTXiSmbFagD5=|5bEasDkvTLG0` z=uq~10+uENdgJ1iQ{TEE8xUIP!xDA{-J7nNI4vZNcq%E$&?$5j*Gl%XyP=2L1dS@I zp6e>^@Y9$s;wRcqHHP3^c}(pqCX9;xo2^9k(v_J6KW)-Tp6aF=sK`(b;|{jUS@arv zsL;_mO(OdTeY8#lrdkPuU2Za^5iAX7F;&X32{_)Z<0d34#~!HG0J z?W!_DuubK#GHq(a&H(gmQCpr|sxtPb!rRPg7b_w%G1OcwPfSRQ-NY<@N~SizAZz*| zUuSK{ilgcEvx%Z#y!S74dfi6f6cee`9lojVc7U6IguQc>y<`!-I|>x^8Z{!5d*s5D zI0y@882m=HcRy-MV+fXUm@RV7?!M%^M(ZwP_pTf`{8g~Y+1l#2)jt+%Vgh})5qI96 zQm>z|i{YUK*t+RucA1~_lNVy<_I=r9U2Ix*-J994j2**e3%1%M)vdbt#d18`(g`3- z=HV?&(narfxAPx6t*Rf@IVJ|5uOaC-iSCZ);)SQP+O!UpdgR-t^3Ooes~$mndgj%; zB*6x9%O+2b-%ZvUvcV)SgQ^7)7BLyn`RL0sBh3h;NY1AzW?822T*G?MJ&M*w2)Wkd zDeE;M3VrA={nT#pSktrcrjRCx0p{8IBgUUz6*0#H-)|NL=XnxmZsY%0<;Fc>x&+O+ zVxx!FWq{BG(V=7gXWkZ3R=&Pijy!YKJ7GBPzI20&Uz%Z)Gl$r4&q>f%+8V^jQ;xX!NJIBMfcOigP-x~1;DBaMA{I`U}6t|D6F%HtoN!P0VrW!q( zwEDh3dnKYe(h_r2m^-)O@f!tfSu+PQ(U@!VKaQdI;}iRZPDo#^@M|Sisa;H-^z&H9 zR{uvlC9)Y*DU|P}qqb*+)IBj*&e{+T-fR^*m#aPFpPX^N$+Q}`3^XK!gG3D8Is)C# zSYv?LV|~0retHj&e@nI=47OJ=eg2W7^s1)Js|0I3!gR7^;viP~e$H|N*>$3JH3vV%Q1+e%XLB85X%EI_L z6w*UKf>3KQJ|1|S)amXJ4Rx0Pm8Zu3AtKhc;Ykz9H9W5N&zz*QmM_H_0M*DBj;aOk zqkC^J00~!RBKQA@5+3dI(6Cw=0=t$?!eQjrW8-xiq&f}n^Mr`r8_VbC+uOOaGxLz6 zsnGI9Q+;oT@h2W8pewE>%Gv@9RG+FOm*_&L${Phk`s3@8B{~M8%qN)=$N{nXn$_%y zGH=+5ql0BlYJ9MXYZr?3@lD3^F#{FL(@taKWwP`6uYy-TSD9LwS-<*Zf7DKHCUVeO zlDQb^wa1&0;^uHMqB9ZpX3efD04{qjK-OII^KHT={ljyXTxQTN?)x7+!1s%4Vt-vw z`u51gM*=-l4SF3X1V2Z9(H}RHLVU|D=Kn1#M?p`Qy}^1HYzhzR#eIilJ03#(9wDC1 z_OT82d(+~PEW(Db2yA%4GpKLTg`7v;}v(p9NCfJ*%8qp?U9`=bN!4xWnR;)q+GB)OOGsAO( z0_5X5eWTcp#mLu-aQpoi>u29McV&g$N4ZASs5%5s(S{NS)8c z-5$9LR{zvLch)!8uv9NxU)LM~K8$P2pl!=NHD#K;kbNqU^t7f?uZ+PfWW!SG$UNFB zfO4O6g@!50-xeC~Y%hmM|6Cb!ss>`(9+77ykd4OivL3rKXth<5^mAfmg0UQ8aqxXC zGYY@13!ypfe=QD*3|utZ=r~EpKyN7I_uLF2Z+myrGBvn4NoR7IoYsKP#2Kq z(tgO%N}HxtB;+x^JR!)&v~4f8eH)&(nLkMW+2|W(zy4!DDAhYKM!dDL&cfvWatt+K z;+}n<#0bBEB3yj06cVn@noC;@ksT8!lht@$(H4pb#&b?b#_FG36tiZ<=(lsQ+L=sj zKmHUQ+Nig&@P2j&Iv_7tNrde09vUQTDc|wbn%X#wm-olzR;VuZl4nSfQZ-fwp9n@@L>+)okxV;Jpi@& z_;hP%FfsU{f|`}!H+<_zpFVXtYkE_cd959&g{`tl6|I%m;px30${T#T?O^VjvG zQT8aI`rFZcUE!W183(;1M;WNxeWJ(hmG`Aj3JmJ(YC!p-RU}EfIf&tNj$Kzw2fkPx zBVF_T9;(4PWt7JWm@i#^7OfNz^=zK=O_}X2*}-{sQAX9X)M8*C-0WVn2C4(Y=$E4?6+f?$n{CBLs{I9=^I*WpPnV!`P#8VDP`IL(yeV( z8IdinA={iMA)Jp9SR}YkrLUl>2@+|0TGe@l=VwC+=#!)XbI&ln&g-V>6oA*yqOonl zE!Tf9Xn`gzy(`eOw+tz6;OO*pS`}4s<~CmQPaTRDq=X&SwZe2n`iJg6X5?)pw%Z3D zL=MHD8|C%Q9z9_(`$pGBvre9!rutK5sijRSwG%1rMTO9hz4!0l&>2v$GMk{$eoB_@ z(C*Q!WNfB{&~->J`+T^uH@iy5|AIs2>iNym=;<+t+$9(S8vEDL0`K-Eh1MZt*LxFZ~{c|^%4q{ z-(uSYAwEd#kVQ1tCfVq@xgxUP2T<7C^&Pi1kR$52(AxAV;$!2azjcu(Cm=5+M9axu z2-Jr;6ebA0>xxblxt|Uk*_4|+hlkXL@*vD#2~!^aiunZSJz2q*^9>Wsx;xLy3wnk7 zC1SqE2B#ygk=`;M&6>X3DY{q{x$L-%Omab|`n2aP-mg2QFtYE|NT**b;~})Y+maw6 zt|wodYyM&eSFXo5*3|hbmd}Dn)sCS{&gpcQe2M1-)sJOr5oP-X%+#MLy{YOBVRb<) z5|R<9Z75Xof&cx-Ny2GPXyQ*}8UZem50H3Iv3D@Q*Glqc4cPjvdY~F$Xty zBjSujZRm5G8F)AO9!{hW_aTxR;-7YP;GxxS=%K0i#NBDz8cjs2ZSbpvU`Wj`g6Q)_ zFt5-D%s*T2&T>qk%XR0ROt~ezuZFGPXY(Q_pvaTg#UQPaRxM;yrdDBRm9fK`Y@x|3 zVtaqOWUv2FJx}a_J7+pgefe7X4&1&;2!2^qSk-tJ^Z4%0JAYSr%A5_5{iTM`G*gD^ z%`+cUb;6AC@9)9xS3>SeyRNqV$+~r=U|3io5_45@ftz9ro@;RT*nyj9iJ{bFO~2rS zGHJmLTMG+juMN+n4=|?lsu@?@*0nor05Muuq-49D#Lh=_S`|0nOZxj4)c5{QFo-EO z{QUQdJ)U$!@+Nm7xXtLh^tsJU2n&fh)n`_e+7mKetA08V1|u+NWo_r_6Av}>v~MdK zrS>U#0bkPet!J%iZ(nj{gfvQ@s=*4dl257V4Yfv}>(1^|==*Dqgtar3AHu5NT;U1> z^PPU$=6y`}SHjvipmtk&oO+Y{gemL{=z`UgG`j-$?@`j1#)>eCN@rR}5i|^}Eb7dG zq$uL8Pks1P<5b6+-|zf4RjfPmP-5kkdR#+h<_3UdQk^)gvda$cHtd_#>uP@4S9!wLqnW`&Bkps# zER`~akyRcBh-rNh{5(IHdL|SPF`3(0YDtga2JqA4-V3$)9(COHsCh*`+`FEC?s%bJ z%2`4+sIS~|T|m9$Ri3CaqZKikS5s(``@@LtGB^v;B^nW6v)=^4=Ub`P>J>>>R)*g> z5Ikt*qsXB(9g(3Sw!`*884@{uAP7E(F|1uP;Z%r|+w+FAZ!CoFpU)}QmqW?kzULjz zZ*Z6R)Qr0smM6aG=U0Y;0Y~@a5h1Y~EY0j^cSL~$V}TB)B#GnyNPq!*vTCJtn;4c< zvXR4nwMzx8@?PF0!ka!^KQ<$9=3S+Kuf|#q6~lR?2p8LsP?mY8*L~XHiJ*3?2`|}m zjF9J+MrAf^dfF5*@mXb*hzP?+*Ig9`h5HY`DTn{q1?Fw?jxBc_Z-|(=Z=9%Ah7=1y zrqn*~7d2&)h(y~Nemtv}DUE{sWq&h5-uihA$$c$4aWd?-+0l2&(A_xd2IrL+0h%`^ z-NjjU!+F-P3XV`(pO|k&utRVovSD5|T-BaRIgJ64uIDZG8SWcP!Ro^AOr=cDKD0f% zwRdytN9GgG`m=vF%6o(|aOh_TPD&CqxmMGu-M;uGp`QkC+OmSr`9&Ok(Gbb;MNc*B z8LSJ9O>``96oERcw@8cI-3{TsVawM0)CwhT#w?ic_FOhe)sjTB;{a)a0Kid3ZjlgG zq#{kc>s#r=c>fy?;cOZJB)M`*Hsa!4!`EO0ajgr`utubLvXL-ciG_5ia`=p^7~IN= zEDA`3 z{ci;ul)C$Z!w>VMm$g;iVZNhOZ-woh@2p^F2Se(F=%RMD?{ev9VIS+38W@e_@yJoB zWHK3F1-x_Lk9f_WTOlx+`mpP9&O*SQv)4a~JAD0HT<+MnH5Od`x~|~Mb%bGA->y^F zMT>iXHtASBd{`+dnUG$*IP~2s1zT(i6W_>mMg(cFuxHx@v zq~$k0;-bEjgtHH)7gAT;g)0ecKfLF2(Ri%6nBr3TF<1q7D5_$i(>GD{O->}_d`6?J zuW|o@`YE%UL)#`?Q8c)y|D|izu>@_1lHUtLwOaXav2LkUCyB-JsVX@-Y`IfIN@;yF z>`OQ{3$IG~t><^yC&N7G89zG?-5#xx9lR;Ny1$jsQFVa725#LF8_D`B5?!EZqmeKt z)zI8Q=ce3NLUQ_>^C!Z+UH96Ws74DIj@gC`+76>z?>ac_tz@4}J+v+aw7xt;DlGOf z2@STFJy&s}<`Cor3ff!EUawzZvMgD!Py_@KZ*3*co#;Z}M`8k_FA-^o@^6?3`vjm~ z4ViG{S7^i>1BcjFA!PR-XiqB=x1pTYRd@M)0yIOjsw_SO+T!Cx9BHnVaqp|Q z?|7%)5K(qkKAD8fWKTw1E6||Z8|GIUr|y{8KeivVZdN5-GM9y`M0)W(qFLEUZ2frqxT^87QWRJY*$oU6UNKTKr6 z_0j80NR4u>XhR6aRqRi%!l`4_!VoF)HJaH(!`gviklVT!ZiM%`gVDU{(-FfteGlV4 zS5Kqs=$WlQhm@lNmy_X1TnWb2at+jc@4w0T^6=w`o>iM2mjfB}jK5hD4`CB~7=U>I zOR0K88@pa9MkmQm-WGRMkuZC!kAoi?pH#;>wj_c4JyQzTl>y4vAhkvru%h59PmSVt za1D>4$Vo(-kJq*!x;UisG$w#}$|*GXe0(4qXg@gbcLw;?d~R=Yx#BFyq2fj|lJYBo z&R~(~)@5h0wZ<;H1S*$sj{9#ycXqoS>f*cqYTV^K8tBTtT=+`le(KmPgWllE2BT-* z8@u)TkLzPJyvP*G+cVYWZt=K7h?PQMopH)}4c8sGmKL%n$r? zh>cN-{BqLYj=uQR%IqIaM~FuEkI^DIBMj6*o9HnEoXwxr?eX!n6E8W!K_Wa`-#1*C z9G%CPyGDxn{GMuo10ThBPl3_a9xHQvJ{D|Lf>T@dW`EM~gvjF7T2xHnrsA`c1KkO2 zIugD)UYoOd9Es3@?J_V<;f`m>rX}T1<3~ZeT22SYjo5Xuamv*kdP3Lp4?WQFYmd@& z_u8}%m9XQpd4W_Tw+84ZGFW6tKad*!G9&Fnm`B)Ij(WybT@_9ChZ_^8x zKo9H35^8JJ^jYb`y9$H@3UM)jjoK0l<>f|yAM|E__JjXY{pLT~_RxqfBP_;iN7OP% z*2YL*0Hj+XHCEqKHWj^sig)6+eQc~=*P(2$>_hFx#b4va24Z>@=0Ak}EZPJ12aR@2 z@9%i#hlF6XgVv;uvc-|RV90cS$7GHX+v@2^*c2WHqcmQpC91_lp1a!Iu9Jx-(e9-LXbQFl=rE9KuyUhU{^x zm4=O2n?W6taoRSVTLSoztovVLf@_ig@9ld3*MH!raNr7vdjWoqHbEQJjrCW73kmxOo zu5VopglCb|c6`1F#wzA!s`F12CMtUtNuIa#R5{SDi+GohYr%b5;a8dN_4ne0lDIGH zrfQa_ZXK2wa5)fIZqimHV*E78-7q$Jq~e}8W^u~Qb60>k?sDATJEU9T!lNTIkv3dE zq!tB%;o~TU!u{6N(_p3fBYeU`mV8z46F>WRp-aat8@eH+s((0=GIXRLJLre!e!Ju% z$98ItRl${P>PK@j3tIodJA6p=aOeG7PSjF|>Z;9u)Ks}JOF#Fb_o#SQ?3gU~RV&h{ zK7Y^TG(utqCcRxPEX1lk+%yY@23e}j$ATY#wTzsSA0niAHw?}`8ETIjZMbG0w?fnf zB;xZb8tJ_k<%s2nej=^3glu-Z!4}_2QFiQb_7Bnp_PLvSG4>M1QXWhnhV^>>4m-pM zW*9JRFECwlT>LyT2{Y2vyR}Gq7=j7}Y5j02p4^nEgoz504s4jT#*b7eJ?WvyxXa(# zNiwCYN0`HMV!X0XI&a~EY(ZK&`^{QMnZH}DlpKcpR3I}MR0`*P`3k!|gFI#_s=Ppw;$Ph&|!XYE^n$aNgvfA+~stDYQQMfZ(=+ z0DrorMJlO*Wad0g&VU$BU+2R$;*PZ|>DlgmBKBG{LwB401C5}(_Mc$}Cg!p?A7LHP zA$-J4n>D0!e}{GT2OV~Ntv7Z?>F(~z+J7cWT5d)+X>Ci5{wi7xRiSk$kHHL|;80f3 z19RP*4;sJYQgROw!V6VXoYRZte=_AFN@D9n(DDNTVxRI7j~y;)Itv7gr? zgla@ir$hN38c%-Rqlz8LtueOC@X|&+oXVBhLc`>`{sBk`KgQe_--}ec{ONgnTrGmd z+0x8Q3{mye65nw}v8uGD8&>0O(Jm{#@Oy65!1U6bnotdEx~o9%fR~ex?M<4v=h@wr=hyF|+SvOV zQ02gpJDbR0GWt!s!3)uvKb zDK?A)r`-J3pG1Rrp*Ja4A$Gx`8eQ#0ulQ`A(h$_kIpyk_HnB|2v*^x$sa$&RSFr*e z2ifFFZxM@RxzSvzMJnC`q-W)4-NE&L^QUGGhm@N(>uRche)hZ7C~-eqv}ORhJn32e zT-c7)=ZC#`Yf=1Jd_x5AFc6mL@5v!zvB}w`1drXMKPbcaU@Qm7)ViZuF5;JHi#E2g z+U>Xb$EHgG{zu~^Ui7ABxO8LH73TKCL(xF+^C<7(p{_~P{b-ZBJr3;Vd~D0#?~;;7 zD+>Z!kEw6DuP-484KHtf%_@Qd2+HH=#|&G4s@(HUhs8X*n+X6-#Ll z4y#cYnVOH0?yZ_P(b}#6GT}XgHPJ|rKSM$F(Dw<{Ozq2myNZp$pzCd|`4VcT^b$As zkx*0Gq<-}U1V&<=Wp$hU#p6|7bArIow>P=|p!!)g!+TVmPUyZ?cfE9EO zp8;eGv{QYzL1z7Dh1w_j2e%{++P(S|&<9W7=wI(^*>5?5T974KzdA+6Sk65TeXM?$ z(75Wv-J)HXMC#`H-T<>mr7{=ZCr_&Msx(mi3Cvw5ah|S-s3ZvN5~G;@(UwpuwLe zivfvQOEPa=kR#=-M3b3pgwg1vmTjwly2Wq*cpd^OJ>1wm3jJAXrc&s@L1_01Gcguq zHQ4xs^d{lIAwQWL%T=;NeyGb|c=ir>@Gm^sE0r1mBDd!==KJ&krMf@9YVoV%#MXwW z)sUc0zTIYpAhK*_y0VksN&DkPneXhntL|IJKyS7eCFVBp$p)@#nT|(er43A*H|tAY z96MkdX^kP@J4T)_Uqy>dipBPg1|*+K`_Cg02)fe7vbw%^7Pr+yB+*Z|ep|Ut^eIor?xm90#!pD#% zJ0o7Z=?TO4R2$4FSM7NvCBZYRo z^+g;HlFKGd9E-?`s(fHW4v5^2f$#XScAiSW+-7osH%IXPN?JEv5u|~v$}LDUK#p~Y zIN?pH80gQYcRL)k@BRyaeRXX9Hk*fd&=Ni--}y43#@Od?S&6Gb7UUa=Qx&F}=s zP7uaqyh966O`Hsw!80F&5rl++d|v=aZmcc3M|3b^9*Kw@CC;sOThZkden(if@Q_f6 zkp!E;;FES2AK|>hfd$46<$^$uzSG%z8^^OVh=%`yReMH1oeW(LRXhhTzM2rJ?+fu7 zQnBbngXC9{^}L`e(z})v{|kk!>P_m@lP_9nD=RK247BrlUaysl%3Z&R{PHV!^^hkk z?pnhYQOFEF^9M7$MV!iaG>ttY3Z(xDCUWb`*2B#ote#s?H_wiH_&)OF^-+y_?AjH2 zTIlZXf00t9n0rghRY?-vnr)CAZQyoO(6=zg10TNDzqo#^l`tnAwSSyD{}Wq%by(sW z54yrhP2Nm|m;JG&_|D^uqD3*tepdeeWAtyjSbC$^vc~IYpggTxfu%DALG3+NIo$LA z*iH5L{*7V-%+ktPNgWNg=u)zhHJ%VE^S&yNIo#P@mmR`_z#3o~)Xi1z z2GrvtT5O^jW@9N)#djzN7~B4`J{s|IKPwOtW=+v(9JN=vbZg}RyP279C;2P0+AjhU z81$5dmD^e3Fw5OZb+=JGOvE^1XS*YiYi27)#FGEQ-Ew>d5eq?q*+C}pr(TXRCVqu( z2x)BnyJ~D}{H)=1;7hUEyCuN>1CyHR2>{^5+{RRsYs^WiN18+Pjut!CwNIkrIh-|B z@Sp~mGlOKL0&cD#U9-A;KzW#uEYE_LjEOkaKgnZcZ@~T8({Vc<4f_AVqPjB|wX{TR zi1!XpK+n-R^M%=)4$Bt9x4FVKzE)*5!dA zpgL{a_Xoci=jwE48iWdJwcT-u)U(i81iQ03Jl;F}tbcRI zkBi#FQ$OVxxa04>|F4-)avc=*cTPPZy)ai;#xXOl)q+K%1OvxA2D!dUWm}N*h-E1m zl#{hjXl2FAY?VE^a7{H67xi0a6W`@Tb_stZ+B`GFOpRG6I=wSlJeC+nyO$UbuQcyP z%D9Kgpq>cz1go$#akG$U34wHA#!eZd=!*sIp=Tz$L|a_zZc0Q!N!lW`(jI+jGpGHk z&9F{eg=)KfX(D_KTn# z-|Q0v-}ydnheQUa0=LP4UTEZeANEGDT9exGLkKV-{H}L+lLMf23?v;oK7Uqq%M!PN zcfiP&z7+}esgvwHC^Vpo*8D?!HEfYz;Mc|A(gPnUN;)H~%M}a3T3-X!+J!Xjm+6cs z#fT={ZoCE9zJ;}2AdjMVMI8Wfr~2p%ui<5^XOE=lA9|?D>nNX{h#rX@&xPOmlP9W9 z|2l6~Yxnv^v-A9y9IEa@;D`5v=`y$LT960!^2)#bQ1FX2nmJnOb6;+blR*0H<;U0a zcyRq1!!Rug9Xsqgr&cmHH-&jpaK>8B3iDf{LgDAjaXK#TZ!1fk$+t5m(=r$F{i`~J zrIf6k)EaK@_%Ob}%fo&mqDv@mxad_1S2I9Xk@Bn0fAMFF19)dydor^5-8Wa*r@GTz zJyL!Jjy*5G5dgbk5&voP&UR@j{51QATSq@7W3E;IdUk$cu#O0ZpLmA~i)Qi?;vPLBb zA5htMZeg1sH^~tBK3hn--})lSYR-T1{ z?LCU{l~U^hj_H zBXIg1CSue}?YyKQQ0cR{>)xHd3Su=`@ex^0a}biw$nwXZk0_ zi>sU1R*1ZK!TJsdjK(WO=6<`9OG?C{BG90x!K`2)AV=J$@pNioT0M#OtOyECnR~y{ zx0yDRvuIXduGiqYcP@OJa>h7I+rW<`4p@GFBMoyXdt<6Gwom3FZ^THYV#=)pvd+e? z1aAYh$x=`kg=}Wy^Q&EMgBu}Om8;zTe=CK^^>`IzWA@k|-KmAH)z8xn;IN55lx+Qj44XJIBc@a5kT_I23lhzuz9>3}OjO*wCL4NmX zsmsc=3Y}ZwGv)y1netPlGdKGN$B)Z4=9-L+E1Qou~+U0`fyqa~6Uhg|V#y6aM8K_rSKfA@6yyK@MS77Hs9ru;Sy z=ltejm0-o>lnZm}=jd3n4Y&wkKcy*o(NLmY)ljJ^M^EZ>!zb;eMb}#GhoTXrLmVp) zC`kt946zQSpZJzPC69xm=~MQd#M-+y^vP$wyN=EzgB;(BhGiy5*j4>)fItA#7Pam+@7u)$$J2PXabM zyiPj@xoJ7&y(<(^rm9_l7IPbQD4Awf5NbvfGGB5n)_^VnrbL5+j z75dz5_GfLm?7c+&2pv70sjkU`Fn|?)ox|iA^m|Vj4&K@5_1VP8vYM}YC#}s*6*mM; zNjqt&yG|_FLz1KFPl#@?wy1QJM1>9Y;lk#F>-Gk4!@NVjuLoYSf0~YrC2N!1QWELA zdvb-mtuzlQ0Ows%d>LU6s`?w2tl1?cTk$HKn-YK79+OlSQ|y3)A*YoO!~44Q_t) zJrp0Wk#LB#b&ww%FE0+&nzJejKa#fghp8RC#V{&Il>DNwEidpY%T7dR?G1Q_1UTxH zj2Jx~ex~7Baq*GMR;|t?=|okko9pu4bR=(X#%4IRx#$Jiw40NAt6eofe%H7lNrjN* zT2;Z;7;q?J%gTO+46=4>6L~zhAVNn-%Rfgm+NIu zx}QIiPrVqN!P$9B^ae1SqF|!QcIj(D-FrFyhkFVeeO)OS$@kUSp?e>Enx5>3hIwFa zwR?}C@t$2(5}0!5K)ye8iW6OSq0c^FG|p=`C0>@5X_a+>e!ALk?RQ5iPjXDA_-Xnm zJ9St2qjvsgDrk`wyThO>u$O~a+qQ)+J|=(~OMspx&tQn3ae(LI1VIH_SlX$xgfHoH za!zXe?p?S5c;S~99f-f!rYWWHqv;J@;{!rn4k{f%P~CA}8LS=@r3xKQfcd)2y?UU9 zwf5%UwX@vJJ52PQdAPr}2HSBTu+eKkAU5z`c74#1(_N)H)MTORBCt5#t*zzi9?@^z zar$%+OKg$IH2USs%ih0c9!9N8aG@UixGmW-lehB>-i?QHdFuD3;u}Z$Jz>bP79Hh4 zhROWa()cA8x}&jmi>aQdLm6yDUEvEYx@+pmG9xhywWMR}-n+w@1e8XFG{7of%RHYH z7ekk!Hc`HQbI04@WrI+#Tf?`UlU&P#8lJJ`Lb`@3uw&?^db>}%D?t!oFn2tkL3C-QkT#!zA}Xy$!O7*zEQt_j0sDWc-61OjL}V_A@XbGyAG$3_dY(MQMkb~Q2=B==ZbeO zQkrbLZD`9cL7H@-f0r0GCO0B0zMSQ=s>$R?(()bJ;$AgbCZj}TN47^2lkNY7Nh2%) z%5<=3pXkamtP!@DtvqQ{S)}X*IK+YL{L4% z`sIB7Ec9T?;G&)(!g=_NC)L;NBDm=GqaV0KriWnJHj+_1I3q5t1hfI{_0^KkW#`}DA++o+oKsNI| zpciDYY_@hb?mBa4p1$vso-yBl5O%(PFSF;?YSoOGh=@+ZyMNKjZMpNA{Q|)H=gj{B zfYutgVLYsjTuwE)FYNse@bsKMBO-)i(ZANbM_~~#RtVB^Cjr=>U8ZNygYu-jn)J+Q1YM8ip3JjVJP&4JCP zSwcta3ux*7*5vsAjv}Ay74i+jEesUY{51Fc)XtwP@aE<*g{&qNT-#fx$TKIM_Lv)a z4vYi&L{xz!qTTIJt#NTYiX*+R9_Q*1L@@O zye*jFofC7Kx%K8bVlE>L7TQnBS$44#S?Nz!G3}oS|yl>dD2Xu zEeZsz6^>5U1?9vwc_5?NB5tD7!H3}i>KWAEmRs=5In~eKeNC>yIs=*R-#?YeOjY8- z``5|QW%0`1IX)0&gnO7$0X12p>AnYJO$JMwOpm)30IoGR!WbdI`*Ww%MBt;!Xjl;(oU;VvhMv#$kH9-LT-iORXuzGjfO0bqeONDL6!k&>Wf`OybanJcFI)9h6E#X`)Aoz=>Y^TD|MNg* zS)9W31N%hk&RYOW){CMp=df9UsgV_wuK2r|1FoNa9|yjO-~TE9(6SS#sjprS z>u}9yGWk^pwn`nLp>S0)N4(k8$W=ar)?~#uw}ovYzru%@Uvh~EXklW=h|P7GQZHgOYaCTVAE_!%~gWKT+bm!C}! z20uI;oC*J+?6c|f%VE^TOU1>-&0I_Pzni7Fa46Sm9)@a!k73oT8ZiOxUA7n^KL*{p z3bx(Kul)PS`LV>x!s5b9zqM@T_a1%s*M++u+#?-y6f=6~34ViUox$6_FwA&$hZh#5vJAR~a=>tjmKR3=MwohE1zRjNN>8rA*Wl zD#GXs$R?0G?PJ}NYtIoIk?Mm`cPsl(!*UuY8D86kg>`;+W*s>``_KN8Uu5YGiu0KP z4(!)nICf)2t0I|KI#7e>+GKRhUI(XJc$3(@vQw+Z3Cz`!Do|D(z#I?p;pm&1bi8lC zA1q6}?`=3A{ZPw)6o>$v4w!AN)!I-AJD&LQZ*18-CnLteSV~eMpPYKvmQy}?el(^b zth)2-Y}oOb@B5ZFz8>9xUKtr1`M?#|fk~ce4gBM7SIylV1^y|1{o?zqgP?8)iRSiX zH1FAqwrWMqs5NDd?uxwn8?b%NWr?DX^Zb{huiv0w5Soj zsD5>HcpW}|`^F9SbK?R5i7x`db6xCr5>=fcsWGPZYLvkIPgyZh77`)X2i-_j-h{4_ zcS6`8L@y#bnjQCbx>~8Z;3FSw-G<}J`eHmr*Ekza3;KeWJ!*O;8aG9K3ijI z#(FJ(81MA7i}cuC&m&iN;F^4Lq`yfOOxXY2*s=C?x6u!ICU=7#xYf#D|4mx*&*T&T z8+C6P7kAHf3tz>Z0xj+?1&TWqx8m+r+>3j0hvM$81H}h-cP%!!yEB8lT<5g+^Socr zc{N|>_n#y?$g|hRMv5U8$OUp%b0^Vp$-$ zl4R}u)ZtwG7x0s<<;B^c9OI_oxj z=i)j+hY#;YssB4L0fz`x<~yh>W*!o^ql6~SW!E!Kn(AnF4hI7&4Z;BrjV2~cu!j{n zx{8*?4|CI%m}GjZy!>jjGZqlrke@1PSGl!IWo`Rdo|4og*@6AwwM_Bwg}ZvGL~k~# zXmZea&6>k1h_ed6tE5c|$1%G+AaRNm1~e86zJgBYM!JQ-W@mkN6ytlK^(f%?CP*Bp zf~I+ojrhP`5z%wRv)$atDbcwC?=r`~b7-J5AsSkP|AcMHR*~(uw+||iDWPuYc*-x7TvMd{6L_r6(#)&vuD|%r7v1Qv z;dAS~NPwNt=>7QGdY=xn`{7yHuC;r?jN=lKH})dC+EiOQ0sqx#jwrdq=z8-9NVwli zSKfil!KJbQTer^ICGk}k7PH^y4^_8=tr|pcm%0(u5`Sy@%Dc~)D0g=Lf_ya`=9q|w z$dZ#=?~Wges$j2kWRgi^aQnzF9yA?0ubaBu?M*dMQQyBzJrg<3Gt1 z*i4FyCbDKvdcR@f4Xrt~NRYI9U+RRjBOC5vl-Dhl*i>Pfo2IWcUU*bs&G*@S*l}s` zC>ZhCht)Q7QG3B&^b;CUWPsi~X7)?Amn@&MJ%q|?VPj2hd4hV7nH?T6@z%l<1}3IU zj*I11a53r((_Vm2nRY21h(N#DVl_LX=wuD*y~VHW0ACVzOABubV~t#F?FC2ik*ry6 z(;0uUVdaomELf$=(q9 zr~zG50ERaz?TH3S2Q^-)O(b3zjbUh3WQ-d5n52#BsE{!Hsw6ojk%JNGODV~8s zOuJDL$`>w@uSVpX9Xrd@rmbg43RJiYo<;Ky1+T4P5f4S zPFUFEH%;%a#pVWyZ8{;+^iF>+8k&0-vlX?j9W5rW{SWZ&8qDyv0p9IOUM*i+JkZR~ zf!zQnQtvBJ&#;q~Tk4EBAz#{$rv~p$(|V?binD#&#KjYtX3^C>A(^3a5^9>-IKEwGw8*F4RaXc{s_TB+C`+HL>6x2FN z5`psFy*EXyXtZJ`V3meAwo^KyKSw9fSgB6oy3~C9=!TtLtyeVmN@bJoP!_NiySyE>6r7Vwj zHq*4Gdn%Ycx{$X1auOIl&?lvMyH0|3xDtkS&l&Fwy;x1)ro65GHX=_EACo3!(*sI3 z(_9VmYMBG_Wf1dmIdXKIP#u5Nr9GwHu?lc$GL=jyc;-7rk!6iiuz0hnpMYX_{q%(6 zfbCNZDZJKnnq@@m&)>);?rosnq8oWF5->cxkF!{izo@h^+UFVu}`fPS%kREq9*Yf^-n}iXAIABh#;paJ=pU;!B8j zuO-{byKZ|!RVGRDN1k4O!X#SZBN(u0eer91Ds@H{c`(S>=ADsP+9G$ z1v0?I(3%{hqIOeFVGi4Zsc0o#ADn*wXjWXv{3gg}z$!JlS{5z-{^>_mC}z;5^+?@P z<2|b*okb3?I1x}(*Jqv$jbjIA!|N#xU7(RcBjz!DzHHTNCQA}8vGXlEE!`;|YZP8h z)Nf}pxIu2gTiZC`&Mj=kB?w$;axwXY6*wd%U3PbQ-Kz50Gk?>X({cAO-`MXtufpA4-%os5a#=gy}PlaN=tLe2%d9~AbsQaS@MiUxQqQn!W0Va*s48vAqlooh48*wucTLvq@}!a?sND?Ig-tYtItSo}{+E zds~sFpCJ1mxE_H@GQe0i4B$;TuOn2`TAN~pH;4Nu`c#TS2%Yfk4g&@^!?~dSxz&g> zr*M6@iv>l;;}KhwO4I#)LUQJyGt%%r{Pgv$+~aDAkhz#$nn}E`%4a*R)Td}~pBh1k zwwO$e_{GBRgYh!W5v#dLyroPY{4t$;!vm zj(>}0lR(9=)GqRasn51sb@OQkh}esShkoW90mUidm@ZPfWBuV0k_==||A z1-Y5a45I0yCauwl+p(wiu7p-E4j2aC)M)AR<3^KJaz`6Y2?~Ic|I^|1k3zYS13+)O zbr|>JI9uAl1&7%TYo>Z}J!*gYon#YIICrBj8~N4ZfNXmO0a0Ck760~aPOzSOCiGWJ zLZp1F-aB`b8_2`atkS{u?x+1jf(Nf_$K7<>aUL=XSK^{Xp=>-ool0(+$QbT1&-`oP zzsn1RY$~Ioi1QQ?t`w+2YyoNnKDA*71k%JOvbdq05AqB{kEf^6O_9#7M-5-NFOHUZ ztyabiS8CmT{W;IURPnY~=AR7JZDjc*S(TDA%RPxhX4bGq3^Ya_ya?1P9IkJZnA2ku zGlp6*_DSuaD?9|ULd$muPpBCE#_dx1OVJ{v;xrqMG?Tf|d8lZb$gC$Em~#C^r@^?_ zn_}KpdmJsH53P8n!}4y|`?{oD#45kc3}jAv=^nm)v#+mCjGFaY*c_cSGrYB2lUu%~ z5_2DGMe9|}yq$h$7 z&#OGEi$k;E9Ye}%L@9IylkOY52eUO6%8$rjQvBOlz^CC?qU8KdK+Qw3IBdweo6i`svoTFwiXn0DhnBwOKhy-D z&e-apyO+;`Z?g?u@t-R+ZtHItmGwH9rbl04i-1P%L4`1M z;u|7EN4$pT>$uxrXINVIdrI~(Vi+^R>FO4@H1i44oll~>0iFJ30#0Z8{crP=7UMZ0 z?fjOxm){n-FcDW5%a1e(przbH_2f0qjjP6a!I5w~*>W9?u*dGx!gVxanem-L9g$wk zNq*?(0(X5p*8UDnPH6P10Uys7KcEw8DWI^uRNy^xdeIUNEKLrzg`!l}29Nn~4yNlr zGi*@oIU4W~dDnevB%x;Z_FSZH)7zUX#dR9Hpq(*;hAJv5iLGTK51)vm2>z1&5LRO2 zc4J4$Dv<=dXi?w9(s@)s17mdG#qGm%M5nyDhS^H)w0mx*cW5>yj&-rjTRxD1u-Y?P zvw1mnVfVzb*u*8x)lvIuprmkf`Ue(2)-zfi^^-vNz9JBUn0~CX-ImOUNyt-z&WX(7 z3%U2XKG@h{W*b**)ML6MC`0KBKZH=Ru#H(CmmP_%HT z6kYv|@*7(REip`6x?4{(daVk9lsOq?^*P_n;Mz$smM)nfA0HRU97K$Z)d?XnUu z>qg`hzRNp?=J+8}>P2;>9XMpR6(e^cpv|`_$zg@hnin{p>7rbDcw|)VU9*dwfnv7r zBMYvV=u+7Wp|u|%`Bs)Zv09EtZFKvnZ@%{9;@fp_Fu>gRQbioNGWK`7mV3t~2k#%U~_(xz9v-gR!-v=P&v{rX8;%0v?(h4Y3~@T9}rs#U98)MWj3`*6ycsb~&GQi`QdpU7n#`B?#nqE*!HO$55wm-1%>bh)!+3b)fit;hCaZ~yTFk)3T4QV`{8 z*Lpj(EtBOr1=F*Oq*C>%VVmwK-aglJ0LQDD_ZE|SpPY1wtVT4T<9;Ut>AF_Lx~Ur# z_4uHi_FTwL*Ied_!}4AWQC@Iez3ClQxdfjy#!>^Hj{_^+=3CsY5d7htFy$QytA6&~ zrt}FvHaa96+$y8z@K5FpcgmN06KdWDpdieI|g^~+kwcVhYQu7OjH zndkZCyb!=u%4t|&Xf$zH-=*)jMV8gY=DcK2%=r)B6I9+eyAOZ9{n1x?++2jV&op}9 z;FBct{-bq|eCB5))vy`F!9;p*%j}&@<>glVh@nn_wmWWe!kb2?SyH<4B)`WwA@m)khftYI4J$hjKdFRz z3T#Nyfw>FYbu=}1eQF=dH_H;2K4k7*TXXOzz`lNrsYw4NaY`e9t;-9*7< zvAZo-Xp2}N6u{pju9tO47@x8DGjk`TN1Q{dgU%oj)m~uNYgvlz)QmDmCl(ZdshDT$ zS6^`uEvVYbFL_QHn!SH{JLF!3H$D^Y5GPXn5UJ?M9WZbs7)E>v2=Q-VJSzKiGj$yl<`>Q6j|lC9`l0L>cZSm+G8(dgRW< zR3|##z4s9fs?08_T%4XVe5$kH6a-gADD`Ts9`iAyGr&tVv4;jUR7~U;1 zV7x4$+QKzzyhNmE+@L}k{BFWq**Vqcw`M`>e@D0Ix=}!vV>B}+C*wu@TjRYgxKVgm zvZQvSBByrXn;*{IS+G9%nNdiS(?(Im*O2?iW2enb(fE4w!=BUh^*8EyNAdYHX2EWV z0dwy{FR-l%ykE3LK(oKby8vR>%AEYw+EJeWmTrp~R3BQI9%|48e>`Ivoyq*t5tzS+ zhOf4oM}^D0FW2h=F?$P>O)Nw8);7K^0lukagZWVcFp|YYy7yNWfe%qXMe;Wnh+SE7N z_Iak<{{Wd;FV#ZecDtlUf;{5aXC3|E?U=uKxZ%-Fyw>|t6}7T4J*(m4<@}v%fjIfT zJD}x(FF~m5n?{4x7P@XpE&na9X6WH;%4S5tBV5!OJoDgK5@fDEdDdZ1J9E}OS2m~k zNK{?8{@^$78qaoDquPTfnC8JyUShGFW)seSGGB(kKnO5Zwer&G+n;EUzUjLlZOanv zLv?dt>Fph6Y71({%^BHWvGfZv#a|tdLa_SywI$3Cz}*cbV?Ns^l%W9VJ*`$Ep2<8bj-u_{f@9zQoDtWv!F+(3;pIoK-B>c7HwZU0OOb=SBsVcMHF=r>-@sqvY%_f;A?IZf| z9v@nxhwV4W$Yp$U?5yHj7ub1f7}|07vj=l&7FE8^3eji|{Ib?vxKA18Zg#+@mV1T~ zA{oh@gU5&q=SN*X^!ko9kLU9|p0jtWrp}Hns474gJ%G%NcH7JNSO{L3QCo80M>9RT z?b(TA9D~D|-H}|wk=%@KRJ*viLHm^C*XrKuSU7hOa%o>be9@G@Si!`6$RvO5x196> z2xL`a-AOXa+En?34SCTG7WcF1?W`WZTo0O{wKt13H7DrvbjD}HhCXiDyqg{$Imdp* zLNm{C#l4*%eK4(9L*kKxlk0+ie#&jHk(5pVrPvMD!k-;Hj7Z%8l4f!AYTIgY*IIb% zUyqWT+)s`AJ_2INuq5(KnC_HqV)XLB2cQOCU1ISK1&>w=!bk=IVJlrE`g1xr&2MS(B z3s~CpsZkY%2lW=YAh|Kus5aURcOYIu;C6^QbIg}cn;UX-Il<8daCu*g=|!nvsRsQ! z8ZJQZx!+ST7G3nkMDt52Re%W|t!gKZM4RF}^cZ_C?IspL2@xOAHZ=^RYJ^li%Wisk zEv){2K(@d@TqkfQYn{lez)>1rm%oPCk1$4jdTT-p=6ytOK_MI(-qZYYgSyaHj{<0Z zB4*=RtH5WL4cjQTgK*6!wa)DeVGDJ%uq7({*DDtU`HP;K%RrazZhphZ4%Z)kofx>9 zB_FmDo%VSvQGKHB?4x@|JBlG-#0k3Z`ghk!0J7z$i);Be6g<(7P}xxOpMK)!eeu>M6!7S0y+&utZBpnlD(@u1-7l{6H1pZ#hn5A z@0((6m9Dm`QzLL$4^eNb;%;kgP#wL$CQOEQ#Aqa4CoMJl#q^Kv$G_l$G)|%vs?%jD>a38(WCuu>wNXG1|fWJCpva{xF;!-j-A7n zwF18ov{CVbQ|4~{mj4Cd-=phxUS?W;NOcC#T3v;{2^diplxe(AITW6`I?m;A65c%j z=pQwkk6+iIzQS%XkLK8a3Tg`Fs87p4_XLZ@M(6moqXxIib(K=LybdCfljpxS;y!UW zak?%y^|YRUdy=#p$xL*|7xHODQEJfd8*KkgMuefHKh)jHh#AKd&k2{I9zwPe42QBB z7njg_x2^8KY+7Hl)7B(?+lv%Rg031nnj!<`LY@m%o~v878A=FnMj&_HCu! zEwF}>@?8-=`xlPv@bIv(13c0q-M)b=r9o z?>GM!S5p-C?Z}}T0X0%F^luGeL&`6L*&bMJSjhir4*BSTiB;u)>-qm*`uD$L#!1}^ z`S_m8&a>y~mi^Er?1Gp?z26rYytfCjWv{EMgZvO>yO6Dv7Cyt8w8`k9T&mP2M)SM* zwP&X(z4d!!1(_q5d>yv@D^Gr(2Eomjmzw4&iZsXNsqM z?GBNE6R~)(@%lpw%N3-z8D4V7Nwt&o&;NN&@N;$ZIoYlkt*%Bi?K-xvuS6Xr!gIHt z(tO2dl}f920_EX8K7J2MWv5M1%JB5u>*&M*zK7oRa6RII>df}6B(U5V0hW!hwxVXl zUW6VEeI-oed#@)sCK<&4bTB4@lI*uqbnl(H;8QgzNZZgBLwR zUaUf;2;=(0>?eLl5}IUr@th9ep`=eOUJ9yAwH`7Unj~g=(&>H3(DjPr%e(j;+Yg;2 z57%@qGSJ|9IlUC&1EDRfu@y%QbX1w&hqGtVu;z)Al79FJm;7v`do1VU%r%>DsdQ2* zL#NqFj1_&GhxIkkXYr`wDLT(HEY)-tK}{4Qj&uN2Kua#pckoCf?;Y zBBBp>euyS~z;`oxl^G3CulO*P%K4mI8K4QMbn*ih&-ZP}r3T-6$_x?R6CM0%6^k96 zl@=CzMentw!j~i5^a(-%DJPU$^Yo|yb53lq6g+NDzi|uLGa0w9`}`WJ^g~i}E@ufB$y5DM1CBGb|h%aQcv@m=9aCUL(GO$JS za{JRK&1M8ykZnZI)k7-;#~2Laip!i-Ns&kH=ieVbyoCj8_=QDh1UR#O{*JTKkrslQ zLfkuF!rbxd6US=se6DZ35dy!@wY8mt#&B3M?QVRqs`XIn_HlQy0qmDsd0**2pEQ{~ zWzoj+REKe}p(8>h`p3iGJb@?cJr*tc_zv``suGh2I@mp<4-nlv9;S!unkxyiZ1K(Q z+c=BcF%kG$ZzP|5pt&z0C7Ql!A}{#NTWiGRrFT2Z`91HGb#W)ed5s*-WoQinzGO?S zq=sLF*ptO9du5x=ikIzQ@O`EW?1XOTlZ(ZgLRT!!Zp| zpH}A-EZLcuXvsTehk=s{BmEj0KI-x0pZ$(3ydU?8EUr9^`%;-4xKMrxyo1cxvYdu` zXf`;!FHcV^q3%Rxt&q~5s*A#`VNd+dfD&3QQ{!gkzi^8JIoq)?FewG3$RAEhR5cALaiYs~{=;mvUpjA@DX(^Vdm^KAV@1?|qD} zqrqQPlP$Bp5WBP%!b>s~2ZXK*;WWoo!i`YJ&BnivJ);{awg(BvR55!j7Q+#@R z2(yVN&*Bj2=;yj#pTseFPPpTAv*X&+v00|DMq^q;cX~MVSaBpr`}E(Q3Mk;VjT)iL ze;R1g*>WK%Y}Mqm#^}LvA#n;oSgp$9C(fxxk(e{VQLO-B>cOK9N}l@#sbB;NJ@ z=E{ADiTh-7sRjUlZcQ#q~MaLY-bkCCS~XCuX-(?=oj$63lDz>9;_7+ zmSG;pWV0ow$>G4g{DA-moo`SC3qP8VpWc#GI>q5u0!(h>SQ3Cyj7A{aGu>ZTyNkAQ zbd9NxS{by^3*SA95%y$_mYg|~c2xPAjjFb;cf|3dDNUaIjA%X7C#~MYJjO?wg#A;A zu*?>djnH=kq6`TbDz{TrSuFeuyD2E+k7qU@e~SG52xn(CBQG?(Xyzu6>fnFyPZ4gL z>>!a^`ECLzp~jf`x_$sfYFFOO!ccZWe}*}(X~IIB?1WZIc;2!aQim}s#S7uOGYGL|iQ z_Ay^3HP-v{*~B-F)kM-J>MD)e_1&CbH}vY=-1-8Mbyz$!m%%qgpP^J14aB~8U>-ca zNU_sbzKE%p>%tBVM>bc1=x1Yf-)Bbup!n0z>Fd~TJ~pxN7JJ{+0F88Y5hDn^44~}( zL}1!t?sHF$@RSu7)Be_q5suMff zI_{IB!rZ5=(wjZcXHQxtaoHM%gJ>m?uRqtyL$1^dcXuN z6e8XQl5`IJGWmkT1)@{s&l=-_>Sh0u1lu()Kp z6qEhtiF(pz$p?-Dj*=n{B>uV-rD~IlnA~aA9~$#s&BQJ+vKsK)`VrvZug?6A4&5o5 zK579f{bv@3mZlnwe+fdO?HdA*NGz?wy}$Doqa04_nTDl`Y#lNo*}l7Nl`+S3omj_x z9{*5(t4RIVQ|9Xy#+JPild^iplp4!i;KN6-}uU>LhNV8N~b7USeX&SNE4=&;QjS3{&)q z@xMcW@&7R@_P=d`|A&a>zlIJ!z$4e|tZqx(+%VkLn^LVpl54QK`T>`&Tr^kv7qNVL zqpd>&QjU&4U!FC%2r=IE4KgsBY9b&ityALQSU^GLUf!s#pB~LA4gA>$r>_IM`M{I! zg=-TJXN`o+P}qxPD@?AFozDmhA@}dtiuU@<$D;{GYIx#9Lz$#X(3iqzT>e(4`?jK9 zu|?CG{el%+VKcK$+V{3U0tm-DX8Tu!3s^eVo? z1hEKQ;ch;N`KKv~a;|UOP%^Q(F4@G_1{u%T zY<6WN6nuJr_Y7fk_$!Af?6jb+Yw4&pO538o;F-gN@Q)DE8m`^dbsxOwmtoNc#%{@^ zDrXP@?Hq)nZvg~Z*DIgz*KnrG`(aLiW%8dAl&g(;3z;myM<`E3p6KfWAsgdOA-O*N z?wRXX3C zFOvbot1&8WZyR*%7`vcfZx1QhN#DZ%vbHYXK5f|FT;Ibwi7U~%+l7fDV0%}Waz0S@ zhRsw>+}N#W-;2*5Ud!kwHewOU=9)+@$z`KJIIK6CZ3zg?#(q2>1L`C-|9IdLm)FOQ ztWtVNudJ)ghWrDKZclI|aC3k9H{+VH<6&wrnTzW#QpJMc=}xwpjbpVdJrz}=CRl8hy z&lPzCad}nCddgKz$Kj@HgOp)i$8eWk?{u_3YBs3;*F>J4y~{ycZ(mmmq)u{vSJo`q z)ml+66%V>jPyCMjmVPNHd)%5Ki(mEDzS7?CGpMdym&3_m$9eqh`!B=m)i5qO}Mf{z9@oHu$rprN2*=15)2s*4P+kg z*Y;|pPkhOLMG%79f4Nh6EvTbhX}NJ0i%1p4I#WH~=7gTnZe3AmhwO0L(fd+_G-Pb` z2SPLs5FIb3+qQ!IYzTn+yMeI-StgR&iX^kUi5V_`zZsU>eUhlkfG~zDq+a|nsQ1Ch z#@?B@lWg>d?l|@HPX*u3RwpFh+w>nGbX~bcl}fVcVmNKInIs#?@pJV7BQsg+CYDI2(LRq*+zj9iQha^N#{Z zICy>R6jMG^Noc2bWhG@ZMHbTvP45RZU-H)Rz1Thma?NR%k&X5pgMK-M{SR`Cl@4!2 zrvNJF7aKPDGyP~Dl|jQNFSZ(+Ya^S-LfCvR`JN~tlexojCtFT5Wc{jgl)+&8zQMqi z-qDJ8a9_bB3viO@h&w!aj}HbHzm!E-FvtixL|!=?l&UuW`I_2*G+1E6{FCNyAM#bR zOEDSB2O{oHP%K47=l@%0a%eqDrVpT8@>P&9y4X&0w_>vt09mbmleQY`qpEb!8od*w zCwiM&gUJ1Jj>9PnTcM`tN|m!Tsq3woc7^^U?ULKK%J?U`K-iQy$333B=~h2uP(b*> zL5ck=BeAfxU(dtK=~V9hH=7RQOk!6i-_)!7w{z1e*bXbm4?4FPlkrTtgWvgNVEJKS zA83}cypLYZM%>FaUv+&yhe6E-<71J$@E^bWEh8JUk!8_qx5TVn#D*jcb81r-h?D~q zNVKZdDN*P{Pg6B&$7_S9;rJplNBs1#=Jv3>b31-t;h_8SqVxc}>R$Omi&d14HgJ*@ z>R|P1@NinEF%68bU=?JtL6x{q4O??diY-gbwlH|bv_=ov=n_I^v9;h+{f-5q+*-Pl zKDa)^UezeBx0NYt!)8pRZ_FS6EBTS@+`XC79KQ=I+YJ6Aejui6KK^m~q-U=RZwz3b zzA{U4LP{g}_Gp)41k(F6`e747GTxSKY>)^e9U+?kkwYtMjiJEu{PMx_+UO(;f=NHJ z9lyr~`bQ&yYm5=n=(jMnmyLOpEIN6)Wx({Drj*zCcs+^DSS)5d1O}WXhlCQGyl<)zk z@N5_Abf}c4j$&)-{}DFx2`_UH*Ac=0tglo!6~DE_%^n79kt_E*k_{sbXH&Mt8($dl z%ASz78}JtYj8}G|r_^q#@HMjqCN%a?rhW|>f=I%MrqRKq)b{I&*!!&QDqBa!{U9JH zMt(#mnH{ZPDL-O~m}ZB~rtZJGzVxZSq# z28vMlY^C~Ms56df+WmXKjv?`ND7b*_JDhfP0do8qs7lyiIjgFL%xldU7(x) zivqFKuW!Vrp1wa~b+{>BmYm!8eGw-HDhv*a`nIQ5^KdU$K5{p^_6*u{sPdLhdA;wz zs9OjkU8l`W4l`MCV-U?Yby2f9jcgpSwpSNdUS*9UYJ$Nbp)XL84v$-6Gsnb+G1rCq zybG3yI-AC`^;8%DvpF6uvEy)hhu~Q!D0Mk;1Lr3JQLT->m_TQX$PN|tw`*v0yZ8%V zGyHGAGhLCaBfryv<@-yKhUoF7i_wJK)}K{+&J+=cv2Qx8q!OF4{9BoU+Svch333N| z*rN_C!i#mBQGgDZX|xXXZYm4K4`Q{?!BhPMo1Y z$&l1rmS*b&L{Rf=%%53-Ht=g6OKDV#s{tXo%D0t^+O`8;&VTE|b{S2MKg)sV8@ekA zcPzv~-4&A-d1`7>}R> z1q)uG7p>@CtJfB}Cr3xr0Yau&G5LDYOLMBYoV#qZGs1=O(9Lw4;Nf~VelcE6GF?>2 z`xgj?Me#3ox3;-HAK*XzGNf}QLDqnB1sg6Rx5Jq@z}q*QO;NAj`gCqx8>m;ju4Gd9-VW`gm}2Gd2wUNrqxg?8`60nc~1w~ctq zF@iTPFVUS4bn!97#TJeEma75E%jlvIcFB!JKTGNy8@p3mC2jAtf#s-~hJs3h++zMy z6!8r5?X$}$4gg5xX*4$|J60KpH^cEX^On2o1v+^H$jiH;jOloIfIpUcLC?zp$O6g( z>z_W1x@JqZwbXmd)T762M^?WpUAJK8l$1WwG;x!+Q*A7fgI;TVLvAtXT>E2!e|^)4 z?f+Qg35AK)5690K?p~)J7Dyi?+wb%go7f!=Hw>1r2?GbO*mr@?=+BG_9^V7h`#NA*RvjC`rAGq1gm-BX}hE1OBUe9_}L`~Td!j^`t{a9 zW58@N7*&PksyB%nqPYIz`?o425fJzZmiB%Z#K=E0dIs94;${Ufyu- zn^Rd_R<5rT&><_(iME_D&rnEZv%6KIpoLx?b84gG*mjlczfzi#MD}C6+v37k4JfxW zTfy#Z6R(<+QAAuWGbl4=P_#;`Uw`SqnZ-hJo^UQDMyPpb70j6xy3P+1$ZJn#naK|5 z>wrQA`t|`(VY;`1b(#HI1KN#88YU5(JKLNTHZ|9k0kZoN);4jBJ=XOvi|LUBZ35&% z9lwWao{KcQZDU-SJN8`L`~=y!`kO4q6~q4@g=7`Z;p~U2}dkm{ZOXfTn*wL#&go7xKU`Iayax6AkEX zni~;IFPFBF4ppDF=VQCC);ZXf(}GAnIi0%xf!qH?k*vM1rtWmSJ_`pd00uVje=~F^ zr@f^ZqkmVF7%+a(&=%#GRbHsmp_p5#c`nM`xMw>zMjAldXmXtoUsGov;-BDIP)j-K zcd2~RQ6X=bmv~HYxi{6q4VgmB5`tij(zpmyvDNZKt7x&4@Q{$vEEonE_`2Af&8$cC z6n%9K%!(u#sOAsCYBkIEvD`*fI5o(FVdaa>47=NP@-;9ErCjTouhYK$EAcBWWFKy1 z1##;NPze_}hN`?9g<@AeVHBfJ;LS6fz^NMjc|(ifB)D9px_NT{_|>_AG|CG;Eo-__UdQ>^5Z!i!vvSEydyE6oH)+!{(me9Id{30CdM&{2M=?PM`X=XP z&#cbmnOmQ7zx=cDjf+mkEL}vW-kF`xO>l|rlbD#cn*XB zy5XOp=jBDMw)s4AbXT}PX7REAc&+IlvFH4X^!1d#062+~sXS0TK00g7&AB=k&G!(T z!>{L5MK~*$>9U*`!WBk$%wO#SSV3GMMA+5D~g^FaNt`jyz$JFXtV89t)$Ei zXVm#LUV~34!@I>+zLMPRZqG3!7PNz+HyMOKP@a=jNAQoHEdcs=cqCMy8R1)Kd;Qu$ zAKM2RyW$waNA{zZyyhfxbJ~6@Q<}AZ2+L#R+8C=E^Sj=`#PEKwH!Zaw@Ka?|QCq;5 zE_oTSr>S@N#Qu+f_7Rjn>~Vwe{nMA8B#tE#JFUZNcrxK7N}Aw6QGy54)^rDQk-d(f zfi;?qCg^F}6=%|QZ)*f?b+fBIc(!`5a~BiMk#dC&t=nPzhMY*vjf zDws2IbahSPU8m`*FotTB;qix2z0&13{WjMcc~(3ua9vk6RRGMTm1f!g>x8Jz9z^EQHC!On+Fha#1{adEho)9*=4fh^Yf^NtJdGav#_%G0OPYE}TT zP*B;nbIkZrZWQ{{O>Sao%;?y>(7IwVI&PyfuqvibeRbkc8P$UrbzPHAPgY&BJf7)j z=C{L(wrweUQ3No@3O(V4J0;gQA=~$vRfg@kt$YEO`q@L2s7y-s{5+uHsF@x7$eDvz z88ba?AE^nrO^NnP`F>x2vu|Kjc33XQ%lLdTVrU6I`b;-r*xDeCQ+VzbZVHiQL&LS# z`96n#SX7Qz;x^MMTV!{2FUagoM-;6hS+0CWtbWzvcFbIqkbI*12X1*X@n6rIiI>2t zysSqDV*$IG!t8WMvbHtZ%#l1BEy6lfI7vrxkqR~x8)fqQy;fj-|Jl%bmvA_C2 z+a7UsUBHrsaXpSF{4BH%6HH?x`dGO7JElLPX#L7sF$_nKx1H z%C#!B?!)k%?dQ|F^+R41$I>M%`%d+D_pZ$SF_DL|p!SQGZ#S1?857LE3hg2-5-x7F zKtmmZ3hF48ecoK7S#aIEf{0k}@#E``k&FG`t^>2*6tCQW^(=s2cmuqs!$wYUDrY?r zeM`7KrlZXx<&B3M@)?6lF-CW4cETR{fhK}$Wp+4XnHuAE?P(;=B{;yr6quPiohTfx z&66;f@}eJ-h2O=o@zME$6YVpPs$ERBuPe5juF^uU0?|lzVyfbaV0AEMzu~n#X!H1d zrgI@PzH>3VyWe_1EkT^Q#Wvk^O;|$zZOj8r6xb_Xzr7Qu@zN_HZaUM_C(?sGVuw9 z_$PVosoS;X&p*J+U=~+I@JqZ1O}hF76d{uJe6^DR|MLFd6Rb8<6Op z{<26vr#brSn6Y#}Rg$+hO5B{f!s7{P9`<8y$#Ujwi34OCs z`d002M{{OGKa9C;VT*WA{Zr>YN9rlQ2xFlLecg0}jixz885- zvIOpt^|-Vr(PTWvy?^mn3NDa-5#`oaN6u$UJE>x-f9f!uKk?t*hquhHW)!0U(GM$cs9RmH zV4f^zB#cLH+aH{F_%lD8&J1HFP)W`B^p)k@Dp$iBUA`q@rn%m_580{&^9>sYK6%E9 zVVN5)(iE_m7=YUx_jmBUZydqv34i2~gU5gGVqUP(aC+lWqh*H>$sDq3sM_Pd1#+1F z#Ka2{Y6{u76U|l6dEE?ESk9~0hUK(^Xt>+1LS-g(&VHap0~Mc6_04{Co3!iAS((@t z%zV#ngt*s!Rt59j+0N*);*B~P?74`Fuh{GOokZs!nLCMv1KXWwjOHo>WjNFz`AO5X zpWk;BU6YYraibBVb*B-K=Wa)Eo=@~@0Ollw4^cX7*N{O5DN_)?&@7Nua6D7{m#7m zi&5f}Zd?qO`65PDTs-BCOIkE@rKKB?}D0X;F57)jYu2^dWV`K6|%_; z?xai}p||l0*TM>zs0;T?kEREUts%B3InQGsksIic(ZAmqZ(ug+U;YHpnVMY7PT?YN zzFW^VML9PPe=NSl1Qh8%Fcs7wezLUWJ4*Y6!xfM^Y|tEZy5!QwmG~Z) zcH2Ls7u#Wbn!_=@jjv9=^Fh)q_tfe~{NuiQKJ2U1haRf)SI)=txmzfK#x|dR^vXFh zzQFfB{!?-9C7;V7p5j7#95q%PK+RUzKoJFcSUx?a3O0l`UU-35%QMJRQo+&Ozl?Zx zm{<{~#E@noxwcDtrKlaNvXvzFf9+T4xS zP<)D1#fXCM+A_1B$9t=8Ndva6z!LH(ZldwzWFP`P#EnGR`%fDUeo5m}wSI{_SepF5 zoaylGmeW%be05Bj*)6AWp7c*FKiD`LkDd0008pxB(B}8yay{M9KJV_Rt(72PltX1# zf(9@DNI`91Pc9tgS{afn3Z7Rzysq?@L(rpq^g4Iw?1>ZrCdKU1)x(5JSzUw^8mlzL zshL4jrS08_HR|hk;bPP;t>aeQtE3aJXVM}!H@#u!@4rLt3&l=)&89w>?2i)W5k3|) z3;zmft=_ox*Q7i}^n9xUkIm;u?oH4#BT-Fi9UA@5vRW_IQ2dAA+D$=VuI)eC`~pM& zO}yCu@8m8Ss)6bCT{+a}6dn@3W1aOC7wt|xveeiL+jPHVo!p7F_{j5|NC`44oxI;j z3@Oz}?@}OyPe3!(Uo-aQH-ZXw29bCzV;iF;Sz>EeNz28p5YyQ&wkKV?26m!8=v3zl zrPv4a%Rg={kvQ$<1K0Wq-@iZX6@7}bX*vQeJ-h(8pTwCu5It$lx+U}`1aojTvDGxv&I;cIA%r~VZ0kc zA9Ed}u#K^vK9i4scq@&@x{y=4QbH!_+<~!4UC5j#=UTi`@apt7dtuZG3X#)s3GAb+LZw?{H ztcQ)F6^fbY3OB3tR*V>;B|8e41~n?Kf_6`Dh3h;Hq*8JGHnS(7PQr+}2M%#EF9TJ& z9H8mO{>iB%cl{PY*~6`1NiEsC!u`X&g=q~faPzbL_~DH5owYHA(N&!{C1i`XF6{9hhL9w`qG z>jT$!n_pkOdAR95tIs!Ll1>kq6G?^alpgEzVTT>|V|alTiZ*kFjpu=+5h@+ESYJFC zjOz{%Rh-f7ojF%6>CUmpE#BlvT(_bjZg~hweeM=Tj=(GJ;_KiInFOehQom?T>MggI zqNlF!rBOtTJ*s8?`AqF~>?Ye>D#TD$J=Vl?yPaaiOgs3RSUyNv*sRKXwDCtgRg*7K z8Aqcc#ucrS`av2#19~Qf7d1)s8{WLY8>lVnPH{JNHHd3m*=W74AmTszI=z#AGb&xC zn=xyv-tL>fwgjDO&aNO-Iq!vGI0J66|L~=OOhH`WTm(#RuBK%ZE#*#;=vQyDFuNHP zq8QMpQ07J7%3DMyGk`Inl`ndZy5#Tn)9bbj^sz3Tl?A+k_i8-f0P&7M-kq1grZ(Kb zgGAs1n%`V+xaM7AEBVEhaVoL%Vc;rIe1>jhz>SE@dAP?cH7CwU6ib&eRAoo&TV@V{5o=CbZ^Vz_JRc zgyUDJ1RaPAmC)?+t{0?*Q=JBl3mZHaQ27K4~|IFhIy zVCIxD*r=!Q<9JLw@G)FGHDcpe|C~%SyX1=?qf&3yIqTF9#pWwDfoA-lU=8c;Vv=S+ zeEAgGG0Ji8BiSD(?2him``y5@Sv8r)5S!BH?)s^@cz%nNT}GSB(HIlZuOIccUdQEU zl!B*gLGtu$?FE{tObI6q!}Z&8L+^d zorzYrm2f$xVq>}7qiCv$esShHpwh)umEq(SAOG(rIALzD7bb<*>D{>@;p5d7HgU}M zi0j!j_T0^wDG!G-iowpq&(9}(WuaAp8i(lSb6FoO<6M8P*(_BF)w8GE<8tYUv7Crt zqU*YP|9WOz*AXFTm2GNAWNW`iG5fMSQKrWSKYK2rrQ6-EhiJd0j?7-7MtSYSq7Up$ zZ9jW!yAw+>t#1xRN|$DT6@jm}j`%4#q)ls)7?vw*wgK{VS;xW*Vj8i`Rfn>*1RY^o zn7MNuR({zJvXa@Z&)2Ios#Ia8aF!qum<~kRJ5Ds*Ss1Xtap#iUopo9})gqjr!7$oA zsj;t6!@#?)j@$cWEeOP#C{#4O#iL=jnIT1MlU;Y%LMBDyMJbjLb;ak@@S6B#3f)3D z9P~|ZPaZoOkB|Jx1$452jCOabOpzO}r@jc3K9vLPi5}4PKU-VFqh|&Mni-O?SE`^h zH9Yr5N4;HUTEu+LcbXBXsp+8J=dUm04c5GE-dm{ul@gI4%iBg4imoRaERjAwF@<;2 zn{MyvMLVjC=#i=}{%xHvy09IhKB^*ZYd+iV$E3)k59%tH^wtiKTMO@(o!X%g(_M#g zJX%J&wv6}L+|He^;z1n+e%CIgCv`F=5Ml1y>|PKJa_VqZRk?zz+to+H6%pt9w~9b?whw$2O{T~P#4UIcUa&J+#6L+JVK3>CtGO}|1zn4#5X|>HVchh zcUTD6TgisCbWadlP8OJV8G;*Wb-J9*bRS*R=td!P+}GLYvUt261O6W9DBWi|6?1B? zG_&cZmVaG)vWy`ARGMQrEm$Ui3s)}D;B|f9s|oob?L3B&a~W#Tp%nl%$c=v~^GhM9 zKWXw0k#AKRR!|t@`Efo*EjhhEO;mmj06rk&7U?OX;U@Dn5Y=qWS3jneFBxDdM{}q3 za`dJ+R)6a-t!J#0!4rvQy~lEA#m1nY24yLP$MNgt<{*Y}CyzBWRUiKq7ve567S_`D zCVo}9OK*iDcXgrMn9rBf6Kl`~e;I^p&B9p4>q4<>3kNz4<f$(siktjlmRb#BXjkl0e4au)Jux}-6-Sc4 z=`O`F5Dp!rb{Zsy~jk2B%Eq|AqVR6{@3<&2;vlCFR{sEqkfT&aGn|9 zZaO}(;SzV0pCJ$4OH4&?VFA3jH#JX5?m-X9t$B>HYt;`iII8O-dS7t%F+ys-@eb;K!rx0p!+WVdwQ?J_F>+umqpa3sTfjr9Uwi4A+{#~#cn}veCohO_ z$c`>1%VA$QMgyv=V}Yy)7Ue1$ye!gUJ0a;rP#1w}*Lf^4Q#9n3FyhHcd!wZgOZ{9H zc!b_(uK0r^m&MxJO(qH>`nfFik#K$Z-fqvblr4C``Y*KyU@?jbs$P0nd9Eq+e{@Z} zt~MFrSxT`A+1@u^0S;N~u#ei(s<9H$Y_kWKPUA8UfijXL;7@*D-E+Fs|4YsMo>9jV zWESxUB`8xup-L?v#=VY(9mjNQ?69X9$FJwfUTXPhulI+@nGdB+IvSA0HpS_5A+;mm z-jre(#5&gu)|>ktT)5BE>DlEDm?^9kwR(*0$SaLHG7|!wrNDi0fvwMf>4;{PeLpnK zKVfs2PUK}Xon@K*C&;FSu#=Eou4SP!^|G=q&@1jtimO}9IUyQnaQZ5sMHpgn6q+l? za^H2G-5%JRwggUy!B#Z(l6plt_&TdXc%}W~`jwK%Xdp;2Lj{yqIHn?gz$HO8RX;y{ zJiSZ((uZcKIiO&&8^PNyety^eT2~E(OdL+54NrWUxSXJIua|h*I$rDJpe6C}rB11a z)_#2h&q+>U@QGh-enwuwFO(a|ziLfG1M&D$;((*dDg%BjI@Hk;T&-9OX?>HNo|~rk z%iwfk@zM`U>&zzr|DaKPyE=@pFtDT}wHlFXL}R~_M_iQ8z~fxTV|HljDK8zX)~wkA zW?jO!+P5gsK|rWT4V%)om? zz==+Zl;Uwht1JaH42cjAd%VAqKNnIeiZW{KZEevIt=b4&NV;mbZR=xvqtY=DK`15> z@-~Qmn6cTqc=CJ7Z%W8)EW3Xa!BBt3(TUxYsEdpoL)r1i_0jbw?$XyKv*&DYDi#t^ zKew@7JPY9e#0fxaB*JVf`4(4rWh)j;=lz!mDEXHN2<09uov`3OGRdj04 zto1l2Zjj5%WNM6A;Q7eBkZ2K+fhN25zc3aNK5!`1jhFwx+v;dX%p3xD2)VOx!i&Gt z7mQ#q9r&~T`M5M&!3^{GRszTWs-7r^o_76Qh_@tR%{m84sRSYRl!6?WZn+k#314I` zkw9C4*Z&)*O*|QCFao+X;RU4p^yX3D4@pO%1Nn|TNzo>p0_@$6tS+5+JPbsJOZ@bbDY3@+Zr;iGbi`;3)_l+d3SWNi$RZPhdkH@ zp1g0UcxQ!u_|`RFmR>#qM%$+il@|&s*QOL{jE6fvtI9QdmzVAs4VqawFr`wTTTj$9 zfd48edlq+Nh^JW&lF8V_@4=0sh!s#!>hRD)x3dQ{JSIYS|Fqh6A2QAqqXBfl^*n2A{wikQBYPOOg z$@Tmm&~So%b?jwuOyS8_-PKBaWEXDf>PDR1ug>mons&Sn&<1wpfy_veG568fB%$v2 zBl)7jjl8=eGFxjr@97oD<0lGs5AUv~l+Cv@!a^VX;y+G6X^n5Y{pM`JTrD2ah@{&d z-!zu>iYp+W2xQ)V3#47&o@vGD^ZfK0M?0~zrxaSqT51RDhKmZTo@4y3aw#x`z)*1a z`LA^rqlOfxR6$FKowRfkhE+R!>(IK4f8N&UZNk=Aio2($!2yiNu6a*>&zbr>_#cdN z$z}%pFtDauf!UkF+(sAHq)k>rql2e{9BuJq=o}u(b3~1ec0y2O+3V1jLKJ&*y8#TP z3-@5`fJnti`}4dTb)vogd*CO(<&f#V8f8W|uyE)$D zaed%oxIp78q2o~2rJMPuP#x%O(@y~A{WK_Hw7Nes;2Lh2KZ!tWedBtfQ_^oM^&Pim zfjpOI2DX}2Wb#%q=(`|R?osJoP63L&@tp1NBz1Z@;7`c}vvu8Ajr+Fd%7(O4$||b{ zhjyG8Z1Ut4GexErz#y7`Xo#m5o(9^c^5R2K7%Otodm5^Nw=3+h2jY@Y6qm0WJ?#^RYmXsLd!gOwzU*uc1<)2`HD5mRCbZl$j!#$D_K5N zq?h}?5b4P9sS&Mb{plO$sD=e>d@?@uw3;7&y$>V4Hr2CJtImJBiocfGmY2#DF0OIr zoo;w@PAt}lDMGgSPP!ZF_td5@GDy>h68vzTVcanSH^2`UJ?ptGLCqcrsdG<0;1^UM zKRY;8mMK*Y$m+Mt>@Tm~Nx>99JtbdyMfoK8TYuoJw`drjKbtqY-F6?6$Kgisjl8c=zsRmV@;12Nv+@GVj-LNxq7`gA2DpdPf-O{us;a(7@WDm9XW6 z;HSy5XJa7~SB;|-m@2o;UA%FHJ7fil&S%y3ZR13rV-7UF-jL_M?MFM-_e6&Eceb%`CTkC7%G(T?BkS8 zhh(lw#00G$<429b1NLd$4=^_hk#VNBx)6ejogcy;t-$1F4)z2GyPDYyiVbweZuiUj zyn>m!AV1C4bzJg9+pyJg`tJP;e2=SbR#G-@molvy3YL4zYsZ{f=o@v ze>>sbcl=y7vUy%+?0;qohK{40)2<(5bbRbx&#Qhk5`{M{;V23W2@=_xFqxlzV@G?Zt9=Mnxw>mN*Nx*9~Ka??7)m(>7ynB<2V4 z#Fqs(#~)zuMU_1$D2U}u9EaFq>)dQ0p5 zPwVc}>;~mFQLkEt-MrCv0`9kzjqY1Wqk1wDz3O#qwn@XR(S-*O1fZ24?=CJB-rjBT zh*`?Mt2&k4JI-BFk4{XPV~SW>2URKR6^1rkcCl5l1vp;#glhM3mae7u6{8OFNv_}R z|KJ8ZvXbLp#wF_E^==;nV%E~52<}&;sV?-W;Bmu6rJ_7M$oc#?X_zEEzbUY=c>P=ss3p4uc1*~GdJfR)m0482<#%%roz{W0F_!Cdw)s z#VKM{DASzjB1_6W8ZimSo2jU%R$r> zrunc6=<>gO z@t*Za-;2x{4xz~8G6QK)Mp@arl__MS7Zw9!-sz<5fdNOD)yiB~FB=(EH9-7KBP2{U zfX$?lU-mthWnSx&=b6t;$5SQt1LbxPM!eC3#Z=b$twz9~-i)=L{_lc6{kt49d_NZ+ zMLG^n&t}%g+DWyCA?86~Z@JC^AAj%X9RmfOx zuR5GXb3Sb^Mg4P)T4-(!lCNH5fd0miuYFXeCG&}rSM67D$EMH2>8<(Pzq<}w>1QbvpifBFM|E=o6Q! zbM74ZO!#6pJ7d9`8{YEMiEVDJ7Q#dG-k(YAmfY_X&0aO{2NTHg-lRJ)qQZ~*x0`cJ zqQKd%%0W`$Y5%guc>W6msl2M>e9&L6&~X7|e_&hnnc8i!7VL?5{L7Rmv2##d@yCK< z>eF(Q{e0ECIyVb_Odr1E`Rb?&eKo<*NsSxm43_*YRD&Gcw3YE}nQIMU4^Gd0KM!N_ z0`R`Jb8aA4(qt zkw)R%CkD|nThJ)ZzCKAycbbt0dvf)>jaad&+_o_M+qd1bFg_bCd;b$5ushq{^Db_x zX!DokV3&880&WCiZx7E~m{m?(Z#VorUF4p1*SBvw5hD(`b)u4T(6^G(hC0NwluO36 z7HSG6?6%gIqn0kYK;|vq8*g=3I;H_;(W8+4-}IGv6*`<#I;tIUqiM&+yD?9K;6)|)k1+jt-z39g5qEwGiypHHE0l12)Y_8oY?M0goUzxwPzyx3SuWz!jtMzId1 z8!63od#1#v4R(kXppvW;sNvUjJf{%bPfXR?ptP*_OvNW*W1LOqh>xFuGb>8ci#BK% z)!7)ND@$=`LTcR6-QTV(1C=H3V8H zzH7jif=`Edw8E_j-jj)15+&-&G!cb>y|f~13YpeVsCZy63499eP+A|gy{0*lkoMtN z1K5ej9DQ={h7hYP&oi|~6%~hXNBrsbcc>O;A0&aF^qZOGk`;kmc2|TPZ{TDoM%Z1= zjxYS=B~L z>h7^oqeX&kq`pGAL0dan^l4#cbx)psnvq*F6UxOb?rm8xx}JepgM_Jar+)IV)VKS& zlBe_w7=l~7t`HkOha)+5@{jpaWb4|KI3q1LVwpD_>$czScmCkJC~PKjZfS0fMz zUp!wsXNHK!@ONOh%YUNvtHuA7x=Pv6g232y)Rby}0G)ysPjcPMS6L@1t^sIo5IKh$ zf6i{ttuE?$a+Lg2_AVE7_OxoUc)3{PAus}tMJK`r1;t9jfW+UT9gsCU&Q4Rz_gG-7 z5)BPtEO8QcTj1b>7RA>pb}7TVsBq)nxWFH#nh7(!roU5Q#0T%rEns~%db6Vqd?$X% zzp_cdgiXUeCwbx@jEB>8yw_{?(2{oPxt7v1t49C67;=qiVKom-%@9nwT|dQ)4xDJxvGYRLNRcGZnc82bnd`+%j zi#wqLjl%D*Zq0oskaVNq*zrPAs;MX=Yd-;vrL~M*}{F{o~y2m&D8{#j?z< zi$JvQLY+yMEPH0hclsn8XhH)+AqxG4j|D$3O?3IHQ4As}e2QPbPV9>e!jV2gLA@(& zXVirGwz3D0dXqas4ij4Zs)ZcyEtrkEt}HZv=!>x2bBzX1RM8hHdfiJr>cdBfOVR3p zK(zK|$2VJhkfz4$Ab#CnQMQcfZ=h^+2Z9x|o+sib%?1MjnXR6-AWVj5H~zk1L5AJb zE7su-^(`(eLp`>8w6I6#*Ebnq{^_ZC@6HtYgSHpeoJr>94Ps(%fh9{0$8+VKO- zJ0A$@&fJTe#kl-RU!BxDO1ll1OfdX8EB~DCaYQZ9c`tx+e$yzoN8crecnQ= z+6o`Cr6{tzjX9jjO5Tw%*i4o5!i%Mgi7`q!|ABnAS2iwTQs^-x&;m>K6E(TpH5q15 zpaItSFK7h<$inY>qwFT7$ln^8DCqhQSW00=SUZUW%ZOEmjd2=q`2LmI;Ozx(GX22U zi2NaZj5|nY`n+>Be~)QlK_Gv4(^Y@i%>%UK@EU6xcPWo^t8&;Kgl@iAr&2hr{ED5z zBTEO7M=$;=-YXXj%y-m9A7pLYuB~Tp6CeMeCcnhY$iQnQg~m-{-63UHjUl%9HBgEf zD*YdgIi@@HXQE9>B0CrR@KJxZw*Rxu%W{#lgTI&&VGZHJwodbZ0MdJ@_XCt5yA&%` z!;>bW4O)aixnu(Zd*}${sCkR=-|y69k2Xy33{a1HMzFt zSt0c)S`k{WWb3m?w|K6j?9kH`!nqvd4^Rm|xqH49*F4W<@(QZef;bSwB@_l@=!AuT z7#bTK4flGNt!-eM5juVU#9dz;Gb`zp5t5H(ap|6OHA~*r#~Aagyt!2X!wN_i-iQ8O z`?qzM`{^*q@0$f^D5m%F99ZgmfpKa)RgVdn;wf7KB2{em}EI~~3yD6oVC15mPzgJCk>RYyQNYx2AFsF;}cWvV~!Mit1% z8|@!yZR?Ghd$qj)A?(=qYVgmtE0fn5RwAT<1)zp~{y$3k#VbFT4_E2LuCHAw87r<} z_%t5#KkVxIkucj{4Clr2fDkYeVcoaG_qjd9^ZYzjKD>lQ-I5JImbaxO6II-3 zD&%Rg4UQTj;hL~)k*~!zdQ;E1ETZoprHh_cOhV6)jsVviH-wXV6YZX89 z<FKB$VW}wy;-(mwW() z>P2H?My4*_fr??pSedVd7f3NMoIa1be-M!UIP=PE;Hfyf?{}xVSTTc{K_L zv5YQY&b=AA65hYqb~^p`70;CoRHd3%V5{duYZ8#J$}y5!D!P+@Qi|$ZOoZ?bC5i7+ zTY)YeGQ=#?5+##iJtLzLGa-k}6>6$lzBsc?@zM0)85@+LiTI;Zu9Sz5&&7GgatMt67z+cX=50x66r7vllNEg-58%;BS|zli{J3 zs1r}(ewWm`*VmksSld8Dj=}XKA)q#A$5S5d(fv$g;-J&f%h!>i_KI?`k#Ly}hiKx1 zZjW02-Ly&Bi)GjXJMg$1Fi&&ihwD>17se%1rm=v%Ge>`~i*!Q`cWs&f`bXJH#=C6QHX6+lhRShZk z6SFvI>Qw*A1uA{el+u^b2JN`QUzs0^aX9Ml^xiF>Y=iq}s*7$8*f+f~2u+xTo(lgY%pgTy)+MErqo zG63yv@#8QmdPS->y4`)*D?-jPW?$)?brP!ZSf1Z+?~;jn z5bom@=+VjLjy=}2_V84Y)%V@eJ!70PGI3_rsmBINc6o%6KX^S>W8>mHsMmTHZb>_| zhB}|ImK3Ch{sw@m*z=p_YV6CP>gt3Sfu9S)a2;Kt{b-@;QjLpcXyq&us83Gct2{Y? zbAfIp&Y%9BWK`CLvikc1<>T{6AmP2S$}|JzD?@4Sjt3e!$a)ph`bX%MWWnCFN7D81k^`yzg3w>U zDpzzD==$&^efMqDqfD<3>6B}1wYX=}15!Jg$`B{LPwPpd0$HWND^#Gfld&I=E5w_` zsr9*@-t&{!sQgCE&r*VJq1nyA1_5LWmbaRT(+Rwvy4s7bc#~KD+L<-SZb;5L)F@>k z?eRXIYbpW@HCdgY;iu86(xS?+FUQp3WuTzJHYYVqX~MUfRDK>$X%Q5^NuC@{mTktG zCvm7&a>ZbHHtOBPxef0gDTBF=DO>VeTSTP@X;~ak*rxB2ujA3?ij6ZH}_c1|B1IWFpgg3DQBbgVzh`m4_+2#1noRu@biK0f!Q=Wz`R>Ff2c-PUUCk zp~z5&jRY})^UYMNv>*>;86~P)DbAi9o!z2(~ z9SeL^V`AI$7Hcu`QXg}j!_1W(5>hYBW=u~AdhekL!8`uY&Vck9u7lTK z`Gx4H-yotdi*2kR((1Is*H#;G6TZu~Cd+h8S9Ikv&xUtkvRMxH8i})Pt~JwW&R{#1 zg=87=pw%wI%~y%SBTlt60;syTZ)>rw^4B#CP~RIp++;b<=*O>q#d!UWg^8Gao1RGZ zm_xn(DV1=oSa@(n@6KqTc=|pFTRj|(Ewuybw@vSo0K)oqLwjch$w5EEGB4Ioq;S4h zmMQhf<|{W_L;2T3QiJ7scUvP9grBUV7oHBZvtuTkeDw?N=LR1WzMnJvriw_{6W{@- zItx+?p{@$~>bcjMK?k0i-Dc@y&*Jsrl<#|lIL^H* z0g(0tTycyuWmJ3=3{*hhpOllfs+;i2jd4a0#u0|^td&hH$+S+DQf!$snDdNk&{1uf z2A=ybtmRK;q@>wpNFWQC3LW@`WqKyqK8XqT+afYJ!y$e=-HBip-aqTDdT$m4$)0Itw$NwXnguGyT-QbC^byn4SMOD5AfY44ScycX<)OV;+Mt+c?3aH_fkJ?H6t z)!P=ctN0zi?HArbPD5SIF}K0NF$^h`C{{nPMb+-wPtZ25`6fK^7LMB8 z2>QWjLzNjFc9POcnSO&@=Ea%uHGL_}?rkvpnXK35@!kqLoaL72#Y*_yBgrP`IOXkd zS0Md##(7wrL?BQ;?wJ4P(DBi{(PN?427CZ4r1NEBu9rh2oIMbHU$=O;TN*aCwo#vX zcG(WHr=7$XAZ{r(nVOnU{9M@p8L)a=2^RWs2BOmoBoP@I^;|C=^*Zo1{7pD)Ktd9c z*`fIp>HWJVN0sUNBC=aVZr~X%>6^Jg#ipy7kL4>FX$C?jyG#WF@QVbM0hZ`2L7@vl zL>IqKh!|wIqI<07XuFu^7H8sXhxuQ$6Tw&1Y;|;qRW@E_w!AaBMM}f>_MGVNOR37P z?j|XcAU%S)wNtw)SXJ)%UVhWpW5-toM>uGsp@{Yqxy4Atw3S#?UnmBT1JF4>nilMj z3v<2oW%WbYFG!?F=soT2@%n}~Zv_RDu8Lo)PSE*Hrj{gs7PsxUTyX9QEKC4m+d$~1 ziuT{tGjeo(D3p{Ca7&?@Wa5aTN?2)Wn4~X2`bH;kJ!oOBxhRtfqzr<_wX-u7RF!QP zRqs!<47m(pjwB)#P;^6%v6h%7)sBf&!G5;-2;Qi4!V*26R2MZ;R?%Eyi$nKsThf09 z9nYQ0Zr@qX$jl9d&Sx4wY#a5!*fj6=o|`u^O%>Ab(-sWu-z>B8amKY)Bv9fWMm3{Z zLiYTix8nta)7D&6`ooWtk{yB@nlpv5kAGOc(TpZ%3i(zlqaQC-(vBqF4taw}jUraJIk^W>$54&yXuP>aMOD2m)zqf|G)-}V zx`junr~(fX;?je`CL-w#zl3`0Lmd$E7vW9a9IS&+x3&u_Lest(KgFRNZ&`fTRtE(pZubkg1ILAqo){AHVut0 z`oCHv%`g%YVgt|=Z=%Ukv20`MRrf*AMg|8o^3=6w(2&O(o*h>Nmvr9iLD~+1$>BUk zi3NiC11w;x|JCxbeDr)wnfy_pl8s$7^NTs)+B$^Qe=Bu(%YK;n4B2-{zR#|b1YAoJ z^Cic@yth)b@&0{9FST%N2hxEfVL*faaAba)P?vLHeNwe0tz-FhUU2BV|293B(XI5# zO%V8g&Mr`&`C9B46UOS#u}PZjnXLRFM_ zC~tgj6UVyd^7oPuu?s$B0(f_mZ0}~^G}+nQaQ|j+dm54t@Wzqt=uIS1pc@*~C}0LA zO{wg&sCU>NMh*@&mzGARgUcyjEe-(k6k(R*O@p%*%tJ5i)bAP92I10Hn&43qj(X`# zo0@H`SLX59kyfQO^ATw3t3_g46_j zPR*D#B7(n45~!A~;ENg@W*Py92CneQ99pZ_!WQ`HO4cJtSSWUnM=0pw^QU9q`pRth zXsQy)*=&x^;H7kaHsxl6SUM&sR2IThQ##GGL&a{%QkZXDlcpqU77RMGMOW*wpLE-! zlwORiookdAa)s97m7?9+p!k;}bqDJIh88SQU;TYi;xNI1TP!4WLh%>;rfd zp!&<+{@}p8ssz+ykfUn`W%r{VOw{zU|1-+z${>-Tnod3SA5bnO<^ShdPGsu;?h-MD z<170&5-lYJ1B$8sBNhJn`M*5O>A&m>`GfY(=45B*_3;43(;L)Q&I9tclIt`wFbL8I@i*E?-b#MuG0Q6DL&#BnmO9dVz|*$?lQKW0x%*V1kQC&o_&F1vJ@Y@3Vf#(Ork^kB z^spEk>bSne_F_(EsuYD|C*sABv?~@G^nOnUf{bx(3Swhj^@tn|8bg-9+l-_Zov^_b zPLIt>wbx>8y0eQM`ox}ZLNJ#Z4_mDTFn^C=Dw?ubmJu_zTpO|DdMl>C>xA-ct&PRx(|Ydd z*<3*ncavzD%e&>4bEJEeVxbXliOoRUQz!B2R~6>GZb;g=8Xf&68q5^Rfn`5l_N*O` z1!1kmq>8w%WUcw|eV-2Tp`2>Rhb<6?*So7NdSy7y%ne8%TvPc;97F7m_n{l}^J zwI$F5d=#p)cj6Y9=N%)f@4r_5Z=YX8oc~)V~SeqW=4+9aa^t&(~f6b7kt$!V#LDO@&ri30CW-q+1#xhv8+fqfp-{wPIOuRC}h z?)qa-H_dbJ=V<0r@OEr-R!s7IT3<0kN@QAO6pq!WZsrbNPM4JyAmda_;*BYv(da5B zsjlFwy0n?-5|sxH+KyxX@05#)WA`3$WQ#h=jbBMhMgDmp1xEJ~D;Z z454yT)eV@%atA+s0fhT8Nn#RO77`aDX=lA|Pyt(1H6V*@q;lEBe{lTnML88J#Wgqk1St+JdSoObw03%q$ zK&1Zy0SdB+wV11v4uV~@y=5<9e+`7jv?BS1tE>$&153tVnJihOh7QHjdjFjMQJ+ zD?F1zX+RWL7;;Z5F5iLNk17=TJz-2!PUW|rb7M44?gyv_@r%w-c2Av5s%yaU<32C0 zMMUv~qmNtBET7&!qxr?|dp_!FE|%wvFJob0*hE7FU~1RmYQY znCBjR`b;h;uTT&1hYfDQKTJWfz;`(~iMd=e$p5^mw2A^#U3`Bj@ZXgKUfeq9-6D0o zsWhKbhaPdv1*y?Rtw5vp~DV8iu zTe6j)+XwW{GEBX3m0UVMOS05la1>J!^_YaoZXmf`aKs14N(nqxCc4|V?~zisR@TIpeNuJeTh{q>A zkVSiJ793umY4GY31;N;Gt9#ymT9y=qm}TDFe?{4N))Z@m!Myi8pnewP_@dQzNOxvwqxsWQz`VJ#gLh9OMWhxlREDz8Ot@SV3|gM zlw5DsB!8_FR4rpqb#-gz7~!__zOMY^n|^ydXD}C{?e>Y1ZLW|)Xw21YNxW*W`ntGh znfI!_?vIx~WDm{U_a>wF1V5)OXTF3G^oZb4om@**MX4c!=Vpb;YFpx}M^d&JDyvp` zG}r$ef>ErH)_lUv_ck_;b#rstqaFDa;PdcqOZ?C9yO*@mU{z%J)rPTDjql^64WgLw z6htbaBc9%^w=oW{l>hd{X3Z}_r7RzKMw-jGJ z`wMxwbn9Q_x_PztOe;SigD}y*`ksvd-C0F|AD!2yr)aa?JCL=C|iGd31HJ*i|SQxsP&*&ld_a2 zuV}LykW~`LkDhRF!RCM{qtaQ7!Jri{n|8_!F;VddJzcd9K*Gb5I|sg~+d@iQuL3*N zQa*evTsI4x-0u?7^!Qi01KM(&I&$Ct-Jq+|^z11|o3(+Y^6}__YJ)#CrE#cGZIADW zkIVd$VflyRqt~*m{Q1_%irmR;O#o}a`kJL-71w5Fz~{mEaT*F4ZcP8aS>B!8c;CsA zMqEmjHDa8eqij<)jAiVctJkbSr+`CK+fLif=c&OG+|m~gwn0;r625y;EnXrvDUY22 z12+r4kPV?y`x2$y6ya+~qSVON_n<{ENY;%s=v@fM3cxdo9d1SSG;TOwE~8rKs)sunBKugg&%u zKcIx7Qm+=Loz>(sH1^{O`S%4E5UG z&PiB;g_m8HoSuE_Kj`jc?Oa9~yWqFM-M+M;J9JkY*`hOSM}yA)qdj}n4h+ZK%_bGO zXm05@ZiUC&Xj>UzKXPIb=U#b@;X z+iS#O-0lzGa;@gj^0TUoiGNHJ0zHJ^r?!%s9ZONxQ^$};Bu?2JlNBB%mT_e^Eq!7$ zL29{h8pDz}%9VkICHy3^yA%8(=1ufZ?-^Qc9nSHsBpve299cbKM z6Vb(}6PTlNqDb`l7@unb@K22mjc?C4`llu&aS=m@&fxhaOAg>{n+w~KYk_t*B(Wpy zzsEUSv;}>0LtBvWT(?Jupq)yD6!2qTl`?0##9?nq;E_WI%X8M7EndYr?* z|2$vk4PI$%K+MuP?fIsxpzhU5{2x>wERvDy{35Pn1QTwr$fA!H@PyA}l!e*wyu7I- z-EAY5NJ5JV_8TXOYM#)n5eHwkY$R)82NTk(gAp z&oe&5P&lCH#kqhiGP42YbNN&!Y1fhq?M#n0<2|15F*pdpME>}gmJOc24H!?B@%P-z zgkIGrSX#XlE%w#kS|o4FpDpe!QFH5+2Tp_+iHSc7LLUhEOIdW?ftKIFyjyY3DlhI!bi4a0#}{)2pjcXyxZ*Yc#y zCXc8+-=?Kx{m1a`f1k@)D4%QqA2(uo=j_j)vHC+_F%TI~X3uBQh&Ox4q^8z2U=-nv zhy%%9moZWndC$auxDP((uzBzKC3W2XUZm{&A8l)#&ahs@-Bwes#bsTdxN}k41{oXcFtu&R;nB&Xch<_}-bnt(17V!3`zZ zu_sWB-+i~O1zzY97_qY#AU7+CJp~EUJO>PXY?nt?rw#Fq>vyCmr0`$o`xxVUJ1ii; zgJZCjU9(Q)CATbD6uPKCUb|K~@i= z_e+zcAzXK`jt^J5FSi@SFI`|h7{c4$<(|ud%IPFnkFPu5DSt74!%6j>#h8=@4)tW= zGT=a11Q{vH_ujuWIN=>+!C$baYD*XG_}n;p9%9RTmyuY1@cc0&j7Mvw{p;yN;)|hp z&vj!x6$hNl6BXjcT$O8?)k?hyx?~GR&|wYJqXu1G)QCYN4fUi>aL)K$U?DDen$O-yDqF?7eAHg@xxJJC{LGZA@<>o0)yW!Vg7KYB- ziZhl``8RJ|ba!vg%>vd2%)jr)FD%P_rG&}|+gy?_<;cuN+uX}{abi$tSaw83T%uq0 zHK-iZ2=t-&>Nd~0lXw|r@kZRZb&h(8yjq$vI_1=At?rW}P3)~mPD0c#V`;e$Nz5kw z4lY;YTPCziZhY=F89&_>U{gXw7~4~PV1*|y!Vutp@LNo6$Ch#-C>})_CxIq3%vhIf zwSyucdW9krD%HBIh{BAU7{?*F_9b zUb_GPzGlv!TCFvY4NIHX? z8l~asw}E{9;D(XY>`^#Z45#noWRLc}&ebnI{OE&elKl-{3mEgMt`>NJbXE++=8r0^ z-@Y%j_^Gx;h!Yz;p;5oJARRMfJpj*5|a*3#@CkE zbkXl?weL%r5hT#>!I`2>02BvtkHzE8L0s#P#+I)Kt6rxGU*fkA$M~)1X)5HqLqH_UaNO5c zWcw4q#7?#OOA&4FfdybR`Whpo;QbM4jb#0#?H zQUmxh_uRGJ>)=P$pE_kmQ!*Jx1{K^u-US04k;qu_VnqmLuyouWX4z;62smfGIQ<2@ zc{PS0tT#W;y;CGOq0}B->YRJ1NNaGv7OBIB=4$v-57V0o8;S3?pcaL?)hag0X^DW={$RH@ zz#nlc^!R2cp$=8o<2<~y#Q7LwMsQ$prbfE~jBhVV^OaJV5u9cd>EBJ1AOA9utjYUG zf1}9M3vbqrKd`e~yQmF-5ZezOO`qxs;GcIie{J?1#V|vnNi`iPe4BB)6;W^NLPuE| zJC2XT^QxQ&5bPc00|DSpfJuS;1LMBXj|E z4)u-NpfLT?1gO}&clGL{#;vU;>i7D5*M(N{15>@`i7xxorqfV#QSg4MdACA1cmg+f zA}*FPG{0Vk_;3f8k<3@uj!7%z`MJX9d5klhIDhMQHu!E$CIVXqXX6@-M=7Lc^E3#nv{d-qi z$fb761EIK^&*KP?(&+Hzp=zSmiVg@dHOgvbK5q&o(}@cSARExQUNbJ4TzgXBHk`P>6&{rsNb~z!uOw)HQ5fYdd9LVewbSrM6Evz?z|}9y#Lr#jTKHG zSfbpwjKb{s^TtQ)`m&!k8&xo(4cqP7Ihg#zxEDrQ9I2GFr#(ltrnZ-KiYu13upghM z!A#-TMomkdPVBMg;hn2grWG6=d=|~y=2eO7-V)`r?hnB~tQDe@vS>C|L+StqQH?VG zp7rK(9F?Tu|LFH#koY)l*9xC#-g67#OO0c&>xst55tP2?^?rnYkDwS7$CA%z!`xMIz0~;`<*`nLtOpu$JtBZhflR-))Xk z*)KEDF|Z4CsodY8mTT2~l_{gaS2)l0euuoCnzc|_niZ2rI$HsEf*p%kvqMe{4$D%-B;UNQIFG&FnsRT(Yh(HD)s7Yj|Z~M zcTFdHI4&PM9}K>J+lT*294DC}IXU~wTg7vuI~-Q(>$MSpuUu1GxQU_rj_Kt7)XI5- zdVesArFm|-W{v4=&G(;jeJwA?)+K6t(yhR~9bT0JLy#$4;RVgqS{R~N(6#egN4ZY> z`}JDVfy|h)Z5<6}A|Q_+5y0^aDn&(;Nh`aLxeb@iy`Z)wnOEd((~AwA!5ns|*ie zG_|Db(ZMnwReF-sR4t4YpHb5EB*z3(89<-iZ80QlM-j^7m0&Lg{IBk0RHrTt z+NnCYFupF10k6N#zFf^wZ_OVzQO$Owyb9gL@dh^&-EWJEkf?)_FxU%b_oYfsSn|s+ zm}B*O;@Hs)B{~s4ruc@ZrP0PA0?KC#8`yqjzH*r=uGeM7N~Jdo3qmeMl699p;Wzm& z+1j@4hMw517G@MMIS9sPi*hcC#P5&-5VtZFqJchau3uh-DnuRalD2T#1tGrMLdfb4 zv9U41nA)uGC<5#T2R*UQ*z~_Z*?=fNyG@SQZ;pOzO6e`H*j<$z!&M5Xb|(Ca9h#Eo zySZcfkw%PsKRw&0_*yINY;QU*aR;ITpYCnXUpdq6yZ1~F9rBFdE~_YkyV~77)9_J^Dms3rtAN-D&Q11~Bo_8^b(c*E0At`&2sg*wo!Tt4iHzr5) zqZnA5bY!1Yg^mOV4!|f*9QDx4*BdrQ?&FM6qbd{JiK59GKzaSf=7%+Wb9^GR@$nf` zTSghF5dI%5QHjC&5am*9yCz#*0{CRlA1KI(OOi>{(41X4@AcCl>~)YUawo=?WbO$l zINm}R7|-sR=J=iDyM0&akJL+J@vzAEn1^Vd@0zWjcAxxtmC8tqWP|a@pQs3e-jM=V z&Cc``RG38+EkuyOf$~xPK1zF;Ej*d((tpJIE^OLHj;HfrTfcsFTI@#VbE}TQ+c#5y z_3*AZoX310IckJK8QK#`I4I$TD>g_7x@*ZB_#@SxVqBJf&*FDiQ@2LRW`6ZV1DTyr zZv9wUq%+?^TXQ*Ju5~q~{LmWJ9j&xw7uf*vN^V+Wj2o6}HCe0i1qC<0hgn$*owtTP zKy};OI#TdmZ?9D4E>x^qw)u&hvVS@@+R_@03M9=?|4w3rtjUby@K2)7p&X zX8{?()p&DDeFQsTwc#)Zdzik@ZEhi-(wey;y&oU$$bh@NwThN>Y)$a&gvRo=PlMxy zn^6kNJx#Cpc$d57dT$a<-u1|`Q7sHxW*>vZvv?wtXoGM+`t4lgYE5gjx^Cm+^mFtd))A1Gx|+(}vU5pT>9+n->&-PV6Bv`?UepvK8I$}w$I<#! zmAFgoU0vKs_({k7-`aG_I#zEwMvU`bW1QulG zQtavf>Rp?F6{(K=GfxI=)dZkTB#S2{(Bx1s@*_G~D$^8HZ_SRH?Cl&;epuW`G;GF+ z{JOUrcA^2Ic%7rt*Lpy*YBd?gKPi==WMFur_j2lr_O)43nmzcECKSWW8w^$79ORLW zdU9+`Pa2=0#_qSLs0r~xyE7~|^h@U8cR*h#SCzFNUUr-W^4pbmB6iX8}7+_cAG?CUk+!#?BQ9W zgZ?Ho(1=%R@i>n=BjHkbpfs-v>G8 zXrPy+rhbz~Yix&~S~k*q1CFV)r(I6BQ$cBvn9YG;i{$Q*-I^O^aapvp_jjv(Ma3e2 zH*LF%uJ64}HUnLrVcc)AbT~BS;PeOuD~WUUP#-?qdB#R(%(@-90l##>Ki0bJoiUaI z^hJJab0bbRc+_zjKjJKy`!Z*;!nvmA%X-2F^}Sq#IeGxJJ$4VMy(tTqch!55x;3l$ z>QiglU;JPs<z4yEx~&V3G#-|qkD zIo$6Ls!Tn1D*fH#$s2+Xz5Hm-Krfb{YMd}JQ1HP@M!@dO zURU{>v&AjJ71xj(w%;SIV0HmOB44g(H0l7h#wcJnJ(jkJ^qGU_L2w73&1fUJe*S9w z-eyFn15bbE~UPK1f6{;(|Krr>NfwSHfZgp{jSgn zg+E*`lV7`kFzs@oXiZ6j_T8pbyFgu#LiQh?9~3%#%8MW0{}hfVV};z%-{=Eb$Y1f= z@XUQC4CZo_ZF#U`u$i{{wfYVF8PF=p+vF+s?;E%bI=f#mG08)}O6~=w$c1fmRKTIV z_)Uh%@li9>CMX_PJK(hgk~_NbDz>iSK#$M8Vvz&gh@_fzd29S(i%8%vl7=7XXvYln zje2N8P`hZ@qqNaljNgGty)Yw2)HU4%8_XFl+O$O8>Wf&5^(YrAG;ygwKK=8)F-TeZ z$hbl8)ixh53l^O*-GHe`J%u`pk{q?|${o6ts4vEhLYFF7_876omoivqV^nDl=$|Dd zcm2_AmZ#wz%y}BfKnyPZRG*eyW#-C;J_-$1=0iP4()n6YU^d8114f)0O&UnyjjH zPu|+;0P3 zN2NTtVG5PPdtS)%7}3+-nq4OH&^}hd_lqI-=Ryty6jUzz!jPY<|W!BWBx zDG3)8q_j?l(VaBxN`?y+hT8T@QokO;y$DMN!ooG(C3dF_keChqX}_^oYI(4rYSqBu zRXdH6gy-)Pt_%L685Be__+)A~f%i~6wiiW*AskEEH z!ZP4JQCs`;%eb9B(3!ve2MNF0y}Vp_%ol`#u~cSc8KH|uryFliPY@4t#hQ+2;*D7* zCEj$`2#tj_<)PH5is>h8`7zbKL_F|~Rr2&X$!*Sk_swm<^H~kI4``S65VG+vcpKYn zxVCQej%bZF8*bNY^D=_HJSuwh)B8{f7oj0>S9N3HBx7j4DAH4y|4pA_`iqGFqd+s> z+fU*_32?zCCo?j4UGCtJ#`x8#k<_+s374#1Mn4U3?B@loj((Jx&)53rZ3zKqr~V=z z4@d7qGVLZB;?2N1Q<18^vB)yQv=>?+QS8Pu2IcL5T|4z>@y+f)zW}Cz>3|&NTJYDM z&-$BQgfws6k&nc>;#=L}HBq=G!~Ob>K3ACj)C`|inZuH+Caoc|P)r%T($4aMrjN?f z4a4#DM5S8$mV0U#C^7C|N5K>K+I3%RXf>K(gRiODq^Xr^3!GOlXkT#URP9baR5bFd za_f8}zt>$j$B=8KXfPI3r^|1)Y1YBwpiMEVeeMReFLcCp_#j%K+YRj+X_?sk6eb)s zx7M~>%H?8QvHy#=8u@R3>1;5*fjz2)5`J!Xl*DgMv9nj>XEm%RNf@rg1#{c)^rWxP z7_5h;9Cj<0*#e+nPG5caXVpz03O8*YKT;4eao%&UPlz$SlbHV^f}If|?k(2jGNX|v zU>c1Vr^pe!jWA*051+Y?fmOuT9(sX}e#RGf+Df^Tc}Q{3ycQz$v6B3EKgnQJX;)cY z_6y=TE=zx9(G#d4)kW_i79dy*SgnTG4P-|t*$$araH{-@u$J^#^ch0PsGaEzoBc;A=*U;>r$_3hatkC6Kg;(eACEoKeAF zXnIddycTJM%QD<2?D0vSD115eRtyEv8`%>`bRqpLcodu&MlMj0peE zTO)nwXBUG#2I@kwC)kFcaxDXXsjo3_26yK?s5n0nIZW`^H`R3%8>5-Ry^iN{s-C z4S&``6zl!i-?=^F8?}8)tYjSL{P=YmxPGZ;G$;Or>xz|a2E$tcCu^gjVzacX)%=pK zHR-h!3HNC+`rO?Jd*`?%*GCgvejC-ip~awcw%zjsSrIzQ%ZT4;{6&WEwDdPS3CF*F zN|;`ruMSi9j^F?Yc;b7j-$-g7Nm9kgwHiqkAat`9b^=i4y4L0BlHSnm`s#Y>`eMVe zkNBVLT$vn%j&tNLbdO$Tc|8XWej7!#?gnMCfGQu-os|OC5t&eiDZX_BYEv(|&>zN} zz0hXTw7yFl5haZ8*KB&$(>j_A(^E}{nK2k|hYOV-7m#i$3hw} znN!kdP*4Cn&$SA9g9_r*GiL5WD+w4Px-95iJ>VoYpRsVnTVVVUg+m0iVNMDdPCVHS z-q}$3v!9tEi}OQk^El`vw>72VNdv(Bur(f4+Ko`42cIxSY&io#Yog1wtQLb@g0k>e zRucYEfx^V^ko!N=0PjW?mZ`@#rhjq!G}+$@=l`jLj6^t2{XbIfkY;z|U*q*Y3F`Pe zr~2=cd{?Q#SY&S=3nkLW&tU#f*{6Y;!BmZy>wmi?ivQnP;Q6;)l}j);TQpN+fMRv1 z=!P-d7<`@ujVDLo;(sY|m)iw+^(t*iNK|-uu15!*TE1R4VI~MzVDL+1LvHG8>o+7< zm&31WU5{!tWLR)XeSJTYXzuu(58z}|f~aZVXMU1MHW)G^Hh%KM`X(1eP5w`&_2NR$ z+|YfFP^hzu)fOo;nSc4k-|>bqd>yEk<=+ZgE&-}NPiry2k0M8~%C^%NgrvXPqS4YA zIcH-xh-^k!?R30F#_RyFvXzTvom4a3=os^{CPt&K_bZFDGHAP4E3^Nb?3hPahbuU( zRHMmwaP2{2H`sPrhF_~XsWyTcv^m|Vpk)|~pFfLGW(v$4CXi#a9#+1ONOex#uydf@ zV;97nu)1M5gh~SGJ=G zW+1mo9Wt3}MI0R^+A5y2d-p!OQTBh+f1b1?2oT1^Dp5q`=CGrWDZBYG?J9>-r|YwSQUE%AbQuud2f%S2O0POr%Pn^=fet%S`mppif5 zWg+<6@{(_8>tU8sc+G5b@3RYaVf(1ltk#1mxUgqVATN;Tk{=~eHCt+es>NjIE90i0 zEU!{*SKtwkC#&}dq41sHgB>F~6yN49Vfyl6A|7u)isLD|Y6AdvmDu#&R4|<7dY5wB zR|VIAZtl#~d(}AA!vmroEH6XS;6YgW3Ljv=Hg$;E&4N=pDK=8woZS`p=O(Qgb_B=1 zxdh=M-hlGNF$s-vl?{qKxP;;>wO>Tfl+aJP+)w3;cY>$^?ZvC(%rFd6XuS@rLXRdO zIo8R{ZZO+O`R(G_6Z?8Vc9b1%&Yt}EI7m0%WlygZTeo`-<@^+ZyiAjKLf-m(dG@KL zwHqar%gAiowJT!}L;l5y+kT+E*GLGUx6L{60?GC+&TW3~O|%00HFxprx4eXcdmzC{ zD$ecWR!H_MA0dV|k=UCjc#Or|kiC=P-MaS1D?Mp^($PWYi!$`fu8>VmY@b>NG9|^!;s%(d; zv~jKo@yY*;G+D)?lW~p5kdW7iwPv6fUuqmO{LFVo57>t@+i_7%T@6Nn{XCSs04)s~seZ@)!!x#l@oUocSx-WFLzGmX~8#9d$ z%rM(x+4VUxQIU6ACQSOap%SI;ZgMFkHJ=iW&7WL`ynl)%FuQr^TlGkOI+^J`>9${; zg5PM}BJ9c1%=&u-4+r2Ga9~k#B0v_11^dXV%Ou9gfw5ytwD|fe*K?s{R2Y(fI;MAo&fk^vPvn!f$g&d z7e@x-pOMsoVZ~Wl*S%R}yU$Ezj>4mI0lCE}+UzFpg>>AImeQKTd+YOr*$su442q}s zpJ08==1P-MXxD{1{&7Ih4JQNIgba5uY+XM@56A5BUrmOK;G$P^ zvy6_1mj3JWk6sb5D~SonNj#O=B1 z{@C`Qw{T0Xc2;D)`G(DYao@8?_wz1tXz!<~d-Okf5UVW4x6ONFlMHA@E8D#_-^ut8 zB9`Sp;N##QIoZ0nClB4z7%VkvV}2JG{3AP6b$M+g^N)}ltVe4LeDoJq7_yP$wjW*2 zuU*@OG;?eyWYKHk@9&7GbJkiDIQ#{QtF%(WjIXf+=|xw&2>8Ig%Zb<@lwtLEJ%OS| z{#Upd-MbWeyjwW;#VWY8m>36xQCVd&LOsnK=5WBwn}cIm7E=?1c~JaA#BX_T>OH)` zwqnuXTTx7~=$30eym>*$+pAjKf?6z|Ic<>9ClV&z^t4Mvvf|bGVGhSMAhW?-nSmXV zEGazi)|js)`mJqZEV0UF%8h`@HZ#NL7?P@eHi_p1Ixk_1S2EEvpyM-EAi$*m_Mtpw zPht&IbYcOQDS=c_b&4X$_WN>T#0@=I9+B;^kOIFPZfU?FOt;lE!28lJs|W9sHjhNeRn@Lx+UYzs*khi1fH(kkF7 z$yIm5B7PP8YQU*!%@VNGvgUd$lHH+}`k`6sNqckaZMpG;6ikTZ?EO4?nDEfUyGKSR zpaKzbx4LP4vI%$5DW-6KkOvalb)cvE|7rtV`#7)SW_wm&q|^l{0RY+4Y5ZN(G2p$# z4`$9aBf&Q*m*MQ%9%4oa*HQ-z%NN&sNI(Y}Z`zP4(&DpIfg_sZWUF`Ms{C(|o2=q% zSs|mO?-x;;57cS(JQkfojU|*A3m5|)3V;BI(=-qpqgP#oA+=62 zTQ(-)apz^K%>*um`PQ;~SpO8}^o8N1(w;RMhT`$ij>H^84*fq{rQLS zFC(qnrM;0juFR|^MiBXuiJeC2LP*2GrAK?Si)Yk|fYxZ}?w zx1FgyD5d8t1$KIF4(vW-+)gv(RS$717LWFk&zq82oJ~?Cb~iPc*%&5%gLIj#*DC*R;%I7t8vLq8cY;k;4%theK&Zt z34{(8)cb1C&gCWvzw2DChSos<85aHVpR}C9lmJ=rZ%kzu@T55c(M6785Nq>A zLFX}a+kqjUA3hPa_-~4^j~Tb$=>PcQOSU$1i;)KBuEoee5Po*%SZ(=t93nf^hpu;AiDVbuT5In9?wW zSc$N$Y(|VruRyXH_Or}{9Lg>8YtLs^SZ++AvbsJQiJH~Qn}dR8HJiyTRrd%kKa0+# zG6EECSCVyFU`2~1Wb!g`*?un4J7M_0)a$INtQrl+J_%oJDl7{)n7*%S)-X%)3*B^% zMHhCvdgwdzZ@m}fWeVLA+89e2>!g}(R0nUU`=EV47W~_O^#?uJ1J|BZxRTNOs*t@k zC71c01D!ZE->D*WDP{up9fHKk5;TptyyT6DdNSaWi70clY*oy-sdA&d`5m2$u^RLC z5v3^J&l>_k2Fp}!Z3|+Z zrAs$z4Q^850g6MUD1*nA^)xVuUk6ylxH)Vz$4^WNG@b+EN?g7h8u&b_G7_Ev@gORIH7=jSqO zozE!mGFTt7@C@yf8ge;S`z#j#1XX}8H$Cm0$EcV8C!(~U<+XOufnl$umwwZx*x-S zXU9r!l9+F+_wNt<9pV(8ub;XE!;+fZ{`;G$zo3nLFxwJLaiMSZqLtE+)aU1$DRK?hX; zH>3PUL*C>TI@o`%yx)1gKVb`H55jCTz4`#Bzzccf?%i#jCU4$S_>1!7pxU_+ef7a~ zhspCHTfgCF>m@yqx8g{HUN4J%(TF=?v0v;J`I4a}2PzrYot-xNp3XF;uwBw8zf_KP2!UEbDx^_x`^4e52bFOM3v2n;s>nk<9eH`vv(UQ*GC< zQJnHYw$I$HPcnVtr)`CbF9;gdblS=r@uvf(we0516$D@6Z|~Q}eu4^VR8n?GtouJqAF+*el~ZTPSz_c#M}!{c<|dG#@ivZwo&|6-^GI`gYW= z4@zclPDo%IEpZCBJaP%iN}O4m?adm;^_HhdS+*BuN~%|)NV|WNb9`JA%wy5S4y&jo zlG>9}N)AG@56VHhY@WnrTWN--R?9R{Ex6VWBJ$so8N&KcFmh{fmj(4Np{H&lIoF zBfeV{!6KO;P!u*vq+C#(Tnx^>x?7c!`Yhl(eyB<&oL+WL^QJXHU+;ZVu84^yW|a76 zzsCZ0VjZjL`g-Vpo1N#Vf;9y-GeQ3t!z5{8iEIVYUn}u*~GcWK%?!}m+AY0n< za=>e>TSeDWZFcxU#*E$JY65KdVzQ_s{5(a4y>sEMUW66=HSuQ|l{Oc>Xq;OyAu{Mp zADzp(A3vPf7Qs(z=R``6slFG;0YjFxv!|#4DAFXN|3HUDZ(eI_Y{|!@q?qjDM1|`; zi-2fZ%!HiLNfUf!!6nVsb{rMT^=WI~Znq(t@~G5L2b`juLA1tV9eoKiklvxFi?{wG^HKE|rx>)@=sZV11b}(a=v|T2s zF9aU2c3_!bo+l>F`iN>LgL*zOLh%9AHxjHNOxcA6xokf1&eppYNau z7>%^t01NuI8&mi{mseotN3LcFSY*}QpIZ8iAKm9-xz5q)x2RmS)}Hz-?9&%PS19^8 z;J~1x*uMB%y0DypEm6+Gv{Ly*g}M1GvIQz(@#svy+^xGDmGozrG=$85Y+RIeO?VzM zzKr=~qP|0I&d#$K;zf|apsSA$OPWi+HRQCTOr2W{o|(Nj!{=i1jw>0O0W`20e@{13 zn!vMgt8K5&^jJ_XwMzL*aH=4fTq&CSDe?-Y2?Um_Nx-tD{Rz!kI;4%{?fA!_<9_&u z35pY6%(W+TZeTfq?X$1yoWj|L4`N)ADW>uSS;vUliihY|k-JE`gI(n64Q-@deVtYk zyqa4;XM;@`druCXU0`InnmTNbJjFPoPuM0Gv< z@ci~w{PT_vp0v!CFPQqH&Wa+#puJp~<3_6E3v_u;i}&8B`j*Xx-BD>jt=cFT?@x{Y zT?C5a_h-oU4fLhi_c>XE{nJ#Jp2LGKbk7v2zRM z1@@!B?P9w~D2JQNgt}Q#Jxyn^9b8)1qE5Xd-06u8&2s zlxmfh*jI0UApTNY4B>RGGEbjpb(vS9i$Jty!$_gS`aGkM^*#Gx6xh6+?9q!a-{#FJ z!79qDWbGmW94Y7`&{UsPt_dfx9YdYR_mJNyDkF*jeFB znY7yc5=PWhPE#{xT3)9EtK9Q|__39Y3r;4*oMkLlcUIZjg#W zi5D$FdA;B;c!!q6`Z%0~N#e%A>#Iy&$6vf6y&f^=u`x=rfcHhn3(0>dR|!j-*ZTc| zLHzCTAw$qbUbJXb-;+qG zx7uwbwkw8`*})9bimTEKFw{2$)W;;LxEu_(fAtV1<;hdn%yhK~dX+ZpXGR$I&;99C z#iG{@;8EIW?HNi>g&!c3e28QI{cL0_-u6OeMo_*y*M=t*cb!+LpB9QW3N$lb&B=NaCU8N5xeTs-!UcR7 zVstK)zQlr$beL+gU&i1hk*!^$g_Y~=sMW(N=}hF*1zELscrt^RT6=Eh%-cB!ThuJI z=AJ+IDl29I^@?tOQVsFK#ylImC>Qv`Ol3!~mkPEMpO{Rfi79`{1AQ!tmJiUq^E7r> z@@D0Inbfj^!zaJ2}f3WYmd$LtHXxvp!u~r(^X`t(?bvvR+SVR3 zwIosLgoM3-oSK#?eepM@7QB2<6#2(e3A7<1yw30Mx#Y- zyob_?^6`^XtQN`-!Kz*&1Gq#0H#ZYE%m}p#_7$bpHOn1P)-N0%% zX8wVY!$gT+wx$+mtyvBoHF68#I%}ph#yML@NE`wWPiLnDmzdIV3u^GT)3fqU+(MxW zr-MlgWltQJ0-s~|zXJI_Y+*63$>^T{6&Ps9i;h_4ZsZkLex2P9isyiEsfY+!PSNO8DU}$R^wOWm1jDLxGG3a{!F{ z>JZ+LSUD4Kc5 zLRXAi*s_;cf+m6wayS+uz>Z=l1Qs zeV_Z|_H)(`{;{Z4tToq|bB^&2p}D)wvdla)lZ%)^4$K9Hg*yDwvAb!e$AR1bT zJ?r{9bVZrNAHiX+-Ap1~;cU3Tc=&p7gAp^~hJVz30F~Pw-tY2?p{8u~J$` zf)M)%eykaX9-C%f&3FK$sW?EiScVEPnjYa7>Uhr^#7ddkM7_gQm?k;$Ehq8(fL32h zl@-c3V*H}qFNFj5_W>T*PB=cu#fYWuH&b56M!KG_SNd69SnhDr5ac7gtHRpD?v)US z<4*xSLh`_#mWoG9g^(PNUmQCW#@ovLgYn?H$eVbtMePte4lDvpaYRWB4w@)a2{^(O z4m^vmY4zt`{LCX2-PL+uWd(PkL#$8qi{#NJo4a=QCe}6*DSifVJjoZ(`euz#MqTA5 z@+28^(n<@)LnY*zXkV%v#%}^k0aD&J_$*2_R_ZDr^`vy^ds!HRJ3i&(cHJoj63=qI zQV@|MeO34*m9=dybsN<%sxb2CpeN(vPjA66O}&)Tx;6l!{1YdcObAlC=v`kL6qgM( zAV%*;n`Li}FE7_1`t~_-`X=yVVq7X9F`DWgd669HqWgZ~>myIb1JU(>GqI zL-79L744k=Jau?=Uyxp*UkIDqt-CwxU$+<5R3qy$BB;2SSckKnl<4yQ)ltH#tjSQf z*B-Fj>#G#kxZNEgRXadx6e`%{`gG>U^2geA5f#jw-7aF~694q+q6sXcJ=}%1l?)7s z<2CviwXkbx^yYXv%h_79gT}}20d}4|T5Myz#p?nHU@Nymc`ZdS|9st+9kEot_KZl< zSs5^lATJOxm(06KK}L0X55Jf+c%Hd4IN~{t`n@FbG=T2y6?wS5I+^wTfN{oZTlpRG zzx(J8RSzVf=Udi?EY)u{k{xy1qe%oJZq$}f-8i(KPoH|P9?r}z1b&o}VF=0m7=y4M zIgx}Qj1LtE+p^oPsND*hpKT37c{grkQpOaC3;fDn!$+Ax?@y02?fE~?M4iMn$v{f_ zp;Rte+CQIPk)x5uB;_d&E%it`nSGJ-bXe&jjU;KCt6j>UdMACKU?l#Oy=u)?%t~}$ zLH?osNE@SEpHLPmF5q-r57eg9l+=`R{Mlvu{oGDu9+P$^vuuIZJS4U>$f#txW4`OT z_bBL>)4uIaA$d7702MRxYI^6Y5oJ)n!aBx+w$YBmYPD;{^1wvys)KFyE(CYu zBH_gbteeEQM19LCD$f2CRzY%*01~}h5e8^c6BE$pl|({>N$;|FCZ0iWSrm*T#)BrD`~w#!iX+8 zk3;~YxXPa~89FLk0XgeU!dVW;?QVza!%?wu04BE9gV%V9KLho(%`*M?CpH}mJTJHg zzYEYECwQiWlN0&-O99PUz?T9_er1i$rl|F7Lz7=^oyN_SQP~4mTk*FimdA#0Z$TNZ z&^;q*v5+&fi6kA5yY_z-W`vOV`oAq zcjS7yqd?idx(&mD7F__rFX$@WQ7t_l16FK2NoNt+8$~{LeAbb?_vH{=^yQ2nY6?QJ zHq4Bh;b7sqhlb)mnOVOt&ZiwZM5`3hC%oj5 zQo=UoRgHD0Y8cw+srfvf?E9&Y;wZJ+?`LI!UD_3;?7dEzPgxR*DME1W< zy%ztKPF$$J=26a+C$pu2OS*;|8@O-m9xJ%yu2u{Xz5CgNG=YC-(yJP(Hm>>jBS!IP zsKBB~B%}TA^$O!5{^LGgHf$MhKpa`MfN4vX3SflvTniSzf9;V_5kQSdt}MI)z!o)1 zO00EPZDPngmn{7|8*-ZJ3#9WxtPe|c!<}XkOdvb&7kBzIRINn?<5PA$$&iB{@`z1L z{>1a!{BG>mF_B;Ws}9dX(Nl#d#DDe!bI>3{k`Ai{pVBC zKIkP)eRU>vBke%oO}@NGGk_J?*fV5gZw{o|p7^>3*`F895Iwc$s(nxF_)|2*Iu;~^ zEZ-h{hC|3pn{Bvl%aYSf5WTdUaU(raP*y`Du<^(nyY)0auxQDyH2W8vhQ+EoHmY4= zPVSc4h~?^rud?#q)AEJ9Cu(2-FCxl(PDE6*v@w5(tEUF>^aDW$zJDwZ%S(c%E4ga+`b6&kTDN#;AWBHP5Z{;W8Ri))zI5|C zgwu?2)4IooSVeXqWB$I6t9TDMHGTo$L$n>kEj=>BHQQp;^rxK(Od2_BC%>Ppd=yrY zlGPJ6IpFWqh~LLH>VFQQ&BKas3Jx#=dh@^bm_CoE-at32s&=RN8SPjc*7+Q75cgy6 zZhA~dd@X0f4Zn*kyVSOTsyox{7FfaOZ{GHC+quz^h z7Q`a;5!M^O>Ps`O-m`~tW}BoK>Zu zj}W$X*^>#%<~2{~dS}Fl09Ud0xhK5{uN{@HrYUmZXq@i;)IqPX3TDMbM-?ts{v0~9 z{c~jh;3V$E;i~CAV`YvA^!WxH$2Bqp!5U867__iA&8Jo5 zAQt96q|RJutxs;TRXw?L8Z`Z!s#cz7rv4jl{ZI>i87syN4k)&0t4t1L_ih*pK)Jv$ zy`3x9R(W~Pb5M!3#d22vg{-rf$ZVyaj#rtECylr)Z%kg~ISLUbn?EXT^#&rJ*xU=|&MU0}SS&VaBt}L+iN*jS&yIR$1 zfIQHa+`b@v>Y1CBT1Y2kU?$yUhn+O0a~>ydcHlRI{@2$f|6kc;73k4^pArclCmY_o zqGorIKkK3n%>qRubhk>kvIk*L?mj$h!s8mDw$EU0nRg7a*=&>-Tg+OG0-1 zz6P=T`D@ST$Yyf%@1LlKy~~$wg=y*l=HD^>nguQR|3<>5>-NKSduGI5rvbDcp@ygd z%$dy4(t4EcKY{}nnO_24>5UJu*6UPSDWtLKl?#KTk20p<%YzKA2KYC%tOLge76054qcXx{UH?YNn1vAZy`2e4em>uaZ{S9TuMa0FzksC3S=VL zZ!W5cvpRW^;!yT|QA=fO@_TQbM-Sp1PYBWgv{!&@=c{Fs2hV9Wp z>96rfDkT#dcCa{_V2lCrL);r>3zQ#UtO$4FiTd**iaK`32O;>MU4aDa4=>W_>^M9P z{{um*GMVMy2wE6OV@n|mq4f2akdk;0`z`j_IgA;>k zlbB-%_;4WFY|q;N6w#6`Xb1Q>wR;!+T$H|%GT2(B$?kp~jBi8~j8#j`ig!+};F%c# z@2DL%Zw9|)z>Q%3GlC{#v4`eWKgmD^yz5!t=3}Cfb#Q@ZK;J5m^GtyqS81t$%`QD(^6YI@+IYpe_zYW7x^f%dH;c1l!f#ao9&VrP?LYj0%g4%5mQ;DY1NQ?^BKABVi+NUa0R*npcsP)n&P{(qq5DbtQ=J!4pDJ zTrAaZ=>q=&&=4)$43igdg?J4d4PVD2P4NL;xkzun7Y$sM|7~6IX5K9F^;g{gxFs>< zKrh12(|A_!cy^%1ezOK~t`hz;MEY?267eeQzzJR+U;4s?0)@8zEm5#P#%!?XrwoK=-dV2Z@VE-b*l5vS+_6$YyfFdAHW1WZ(@*il1IY1=dEki(ThBYUB1I| zUH#ebVXyg#NDVbIt$J`CB}p!Yy!>I5TMBd)2Q|yI*tSRgNi#7EddP7m&l^w#8oLr<9xIF_KG3lC@`)Y49=n)$F zHgnPk`V&8ud9f-v>_qfD*R4j(bmNa5>~-pgjLx-hjOOCbb-66i{D||mDq5xzvL<^ZF${^U7T~qedp4`#RtHSs z9W-}NXsih0+3o00E~tB>-ZdaHl;3|(s2cj-gRxm*Ej!}BfC=p2lCepiDKm`papsjc zKbr1w2DdyJyqsI!Dp`3pS>-W|@h~-EUQ=}uEq!mKaqMoV+l{9`z9L~~Hqv5WNyb#- zo`7`yAVXB6T?+DQa=WLU^Ie*9sRx`Cr=@pv1on>gK<$x-d(#mokm#>x(M3kxo~{q*^0G}GI@UDe~*nq(W3q@*{E+aqZrwLvr*>%AFxp*=q%Y0j5@`uo0oActsj=Tq4#lf}dA-Vg zztf-|KLgl6;qAlxtU&Cc*odYx4TvreN&SR^5p}6#=#4C`4C852Hboi^bTAu@zKFW6 z30@jdqTT6#Eqod8%m4lngL&yxU(m5#(@&8u{+TtZ^d ze1S23`u(&6{@g6T+ka6z@~$a>bIZ|S>a}cR%g?F&C6piTuDnkxU+l7P@Z&g7Jmg|L@~qW(PoFmsHnp_Sz>7-GjAv7#qXQGx(Ot7{j?UZ^kKPpX&j6L5Tz zeS@i=X5X7ba_8MCz&%;^)f)gg3*ZctA~lRDk-hRSDlSI3alNId-mQ(qkhv6#U3#xp zq{pTQA^TJ-3JPWzxhP`%=tdmPN=seVW7(&DUg}p9HX7-CmdiKT?ZTGoWJ#5l6D1v; z7RpwU{&2=Hu76L1O126gd<9{fY3nS?)CNmv} zN=&^KA9z=B=AU~>r(IzZrb#gU2iW3im$!kL%;BTs~Tr;eT-zV@pckGcie`U@ExE(Js1` zIEdYAIvHMb=-bQ-_#1}pp?=3q_TAgzU6o0QAqsnF=9a#9pKaS3I@i&B30$))X)>JJ zMT{qiJ*J!kFGvBf%{x~bJkW~-8pPqTAzvcQay*c?amgeB6cb2GieUvZp@7QJj>evIW z^m5pN)8fnZ^nH4U7Q{l2T>oEuURLDVJ!0>gkg8tO(cR7WQ)ubJv0>k108x$7SvvKX>?@OT}sXl{&$4>(kk(KCdcdu}6X3E-M2UEt%xQRk?Og1X@tJ;QO5l zgzsF6EKdPvscTziTbF`N#d}1A1#%@~H<>AUGDoqLw>y#RvJtp~&a6w{pyfwaZIh#A(?L7uU@6N08xoOMbqHXs3HuE25B<>i?H=q`%;Ff(%RS-FYzr zS+pP##IwhfW z(NZ_SOL&B$hF??S)dKu-l;AM>$OHH*Oc^2}hY?xM?utwVY zO`#qP&16aJtATh86^{4xuF$Zo}_TpWTQo znSjxnkk3U%*J-LBdysYI^@}M4=FVlu>TwA;En(h{8^u?bof5((6D5pTueETwtSp5O zgZIcM48phzc(JNAG3r8vAyHI4NtwN?Ey+ocj^3H^KOhvAg)!9gQ9jxZ1Z-B_7|X3W+o$QeXsCc1Sww>m$T{v{3n`u$3fv zV2C?=;7@Er9CdelHB_4Z){4-LoF7k9bU)NXyv=EEQEMy{3~zb-N?XJ;O`ypb{oTnW zS$8fML8wtpd^SYI{EGFtFGIH@uD37*8Se;<05leyE;QQ{5sL3&Y;HIB|?bqBG zThmTk;{5aF^T^4$W$bq^KOgR0yBWk%IN2GUwqPWf)j`n?&&@no$hu~iR?M6gXN+R6 z1m?yZ@w0H#XBPjZ6^{M%pG7A07P*b`$p}SXjVW0`{8gxt%>X|GzsHn~iUd1UtDhgC zjkdxg?AacY>j{31ktfuE27-@h48ip%l#~MHz68wYsV!^>tDSsMVoYyIpSf z!`+g4USN(W6>hCf@H#jh!Egh2^zkgcCHLZ$e^hogm+G zUqcApqNAFpG?ic-wFkAK+MpPYStQYrs8;lbldhsx;6_AZ)@98=sxoKZt5X@Aj@WLjZ5x{ z>4fm+562Idb%2u(+m8-sO&5QWdB4)HIWyaHm}yo8;z{=$Hg^4Qr-bh40@m=t8N^>Y z4N+yU5yvpH&`jk!Ape;7C4<2dZU&-3#yy;qLB55Z2r5ieIT;Y8kaa#Uc&H=75C5V) zVYXFaadTBm@4bmG1geC?ia+;8rx9TIjBpncPnf>Tx7iGDqPG8vjC%ve=XMqBPi}3IAt(_NK zDo?(+=lo4k-M(1*_{`tqBiq)m*C`%8Ehtx$oNi90CAX$CwvjXi&?G{x#gA9;V{kUG zo7xdu-LL4hnC^)8w!noJJqwuGvVlg1P|a0<%=EJ??4x(lD=mrG5&FnX0T;AljXz8g zGjyH~>VN~_e=Km2pW!SP^1M6LuU>vctY0W}2-ImuOM*WtP!Jv}5%k zYYR1NX6#!7u5uBz7S$~)+wtF$uf%Zo6aS3SZ>ym{@=mUrEiyIkWbZnqGveCu_t@DM z)oJk})FM@uZ~|)3FDJd_brBT_2bPU*9?uQ^*Z?B|SV;Oo&5LcCwl(W|F31577M6}etXy~8|l(^wm-|mwB$ra1`n2KI7UuJsF(Qg zrJ#td+y+aCuLZY<$tXTN@Kh>;2eTIKAQBJ#5_1OcW7Jepd%i<=on@dg4gpK-D zDlgmNRfQ#^rjPb%L;?bjZ1fF^PNPKkF38sT!I`l0`blgj%MAN=VXYi??Phe5GVtl% zcxdC-vG6DF%9pS7XS2$Ms+~3_+~-?t z@P$<^l-VDQA34>okWnFU0r)TLtQ$r4*XjtcSx(+BZIdGwsUKZYcvV`8Tp>{)61fG! z+Q-lmO;q#t5QMP)4I`hQ=Dly0rw0LP)$?hhzoKgROUrn{834U{|s|Hovt<@}4> zsbzClz1t@<=&kt5=q&RnNJULz7=%vhYp!M8**?T0DYE3An_gg37b#~&e7hvPm-`MP zDZlN_Zw4U=Gna}5j&fsEJVxW-7-S|$9kRWlYBig)R z>I@ZKCLaerzag~PwhR*+4GvK|>`VIup^%COFNe}#v++On{CwI8IvXYMeP8=}9<6J# zBC(d=XG?F+so8a)y+dLN%{~-qn3(eybkf#D=*4yU>YJ-Pz7i1K5aM=8=VrSgvDBss zOn#K-b)fUcX7%YNI5cc}`TNX1A~w{}Na2J;*!|@kLz?>Y2%lL^3(FRu;4#d23eey^ zQBo`@dw!(aV?H{}7!{L@!WM}!^3LYd!rF2C8_}ybnHlEC&^-9Lo=dJQ4zIv*DK1`q zmb*jfitwd&)*dJ3p1+m2M$AQ2+Z7L!LDWEpD*fJY5-%nxB8E)DcSLr-Nuh^I`{3F% zh%Ee-7p!b8D>aZmym?gH%zfW`#XIpu+!y>;+U3!wwGf$^X`@5+!xg{3O9I4b+-n~& zvtGyl)EqMPk)!TZ0QBzR_!NDTr=Cts$F<2e#*|Dh^UMyau3=`|NsmCvyrg*&xW{Di zj>*?rfUrI6eE!JVfmB7p4cB9HzaBZv+RJ5oy*u=#Xj;4RXw>Q1nWaV7EuNE^b<|dT zJkBvw!TL&pwW*dkC|hrbjT2hcTOd47z(=~JkFR!(+#ZR4wpE5xzpEhhYR(rUS=9Q4 zXtL|l@+uX;KYYQGOeP-eubEOCOo0Y3_-UwQPsF>=SRt+(>~e{tBOPLdT&GLKwY&_Og;nTdr_mEU2b134 zu{%!#QAK}dg`&|?rGj=?jBxxBA+m~XA|=Ii$HsS5cy>a;#4e;>KisvqQoFr+{Ant8 zR8{jFMqcl0)kc*1d0XQ%sX;6q6<+LJOr+W`_}`~Mj=!ssvz#pV?et;Hb?K_Yxt4t4 z4X)I_67=&A4uRj8ZmE89%q;3vj|1>>#SzgjQ(7~Hmk6uY99$hI=>TfLr{G~)^gxI= z%^~H%jB2X=Nq_X@yUJ3#-vhrz#8`}S=AW)GjXBF$5Vc9so;&S9{3^@ydu9Js#YcFga$zo#Tg$`kC z<%bf3alzpUp5pIpwJ>OeQYD?BE)438ADT*5_5}B-=t`@P7QeAy_#hI4i9oF(sze&g zH`8>>{pAvv&bcmmUS9JXLCyMeGdMEaPPIBQBQK%u;KwgK>mLev$qYL~5Lrs53T^A; z)o7r_EM$=sGrSB7=`MGDta;kttA(n;9lxuox+ZVd=6hNE^_+w~^K`#zSpn4@JtGZN z2g8mqfAH1#-q(b;7ME*NK#`a=&!<=t3!=@r!>17uER$cn5OXDh8V&Tu?S9Mf$LcK?vT$#6vjnx&52!Q~d5mAl(=TrTE9$qEA z1x$;$?95Vt@3={T0A%0O*V07-FMkvm4S&?hwE+DwR@ zhxLqa@=ORhZEg1>uUUx|A1+l^XOJG_gwfw){+{G(WW83)%CH9z$zDhte|V}{e0cOb z?!-gHxP2*Dt50$YYzy9ceuy)i+L=;vP%V|rlg4xzmn~v*y^szYdcptbpTr8ln*!8s zDeY@jiN22gh*m+_Go0=~W)MvJtndSb6-WLAK~a(VnA+~F{AuviZyMFriA`uGE z{_^m?P~H*lkR#&P@Wyusb4}OWAJ9_A5hEVd_PhxXqdQPDl8vXcsL<~u$ik*c(VixD zq`N=%r(hae94yWYjBq$Ls2s}dCSisJc6yI=l$uIfL%W`~(7PA1NIh;&QCS-p7T8RR zJ%&MFH*{MTT6QC^BY)~)#u6O^b6r&0!d!byFF#?fEZpSJogL_OY$J}{2O#V|H(u?9D8e7Ss3$TcAN?uyigM*aVSEsewm#WiGnP)Q3^8c{p>yH_S1)#VBu*M zy*VK`vs@U3&Ed*|y8V6&_x6r4Fw?a2smjxq3In?i6zP0(`vDx&(*C3C<}fx6N!3Zx zsdiY$(xrNBu(Q~2Z*qmT{;9NjJe!@5%@a;!jUXCYlC{n`O6IxwkXPM{J9@#Y6GdZu zC41tB%-8IKy$cE~51`5{2cQ5BO+P;*7HykPNqnlv(|&y28feWM{~e{d^6g(mEdu^U z#BfE=$AmXkt~NUvBS2AgkuOu4mkNsCL`U(4uMQ&)AA5LO61-h^O$U_PR#t+(2nO~q zHSSv2S3c@tLlb;RE+_(oi4#`D{h{?YB=#Vd+&Q(L`bd|@K=e|BDIR*J*TgJxXLM69 zl}Cz&G1j8dY@J!Oh5f)=5==SfbX%ti-F@?c(YhT<_`%WN(;Tn55W5&X20VKXdpJS& zVC^ld2JiE$@LX$fd(>Mdtv`(@fJk=D`>lNC6ONv*$(T zK*-gk0s|e7O=dX>1HW`AA^Pz&1^dOp9qXqV3?lE%o1P|lS^E=h6(tB3gvlp+4jaOd zMxe_mdK=Hylq{Ok)EytrAQUNsNUQOQ0M>=uG$OsEhLK;&s8oNxwPwguEfb8mSkTB# z;K*~hbK6g2Vn_JUFg?@h;XxBI(q5yRT+(%#!VeRP7V7rc4hA5-`IyeC9ijfEyC3rd z*1Okz#_;EWol(qfoV~gSrR+YU(Jdw84=kLg^z2GnPg)}JqJ4EG>9UAm{x=W z-s#S+ODB6byVaLDuh+rFDRMVCd?5S5MyCM~=||eT_f^>}3`kej*rX>}s@B~7W()iw z#8$Ky>ai6#@Euf^FL|(SGLyN5n15ycNg(*`y$Xq12<^_7IayQ2-u#%K%f%UiOb5GI z$L%b=10`fj+|9XppQ{BW#xQYwnO>Krq9bGRVN&|MYb(%g)YF2MgnBHsmnuX$Lw@DV zmU0^Kw@Cq;NfRQ!d9G@()BSc>*09JAyv7eR&z_%>kN4(AL&$pnw~^$1s~Ym zt!vj& zS+lXG#x&LO7eRDU(gnm*%Xk3lN=Z*wht|iS^zFU1o62S9ekM5&97K;W`jf8rhPEfd zCE0U=1>vcwE*G;7F>hT6X;)Btla}xN7vf3Od}eQX?L#WG7-Y5xqkPb$YQKF!;wLOQ zRom7avC>{y2}0%+%s8BI~`l}Pd> z)Xk{;Leo`&KT*F`|9Va)9f_b9x2}(~e3b?VoSTGzUiy{8(snLxPZy3zD zxp>3aidFEO%iR7)!(~cvSlkMe{U6KD8rawK|eTYV4aiuD4I8 zGLTjFkbP|awB`pvJjT0vWBBcgcsCRK;MEx*w+5O9S|^BAuFKyxR0sva#x8aD!tY3z zzOSLRc7b?51ps)Lt_i|Slkv^^dKtAwC$;Xm-8UEN6+p5SDh`MdMyaLK%d6Zq7HYLg z0Bq`I4>s@jQuPwxwFMe4E!&VRj~0l;j)D$a;zxr=wWeYyZ~T5G8q*>>$kz03H4@U| zXT@E;$?cn^Habk{3j$lfoh~AiUyiUnL*Ra3q?R)S$?X`4R1B zpOknB5z+?OdX_o0uEK*&@_6VM`)l)k34TDH?wyxoBOQ%A;bB2CD@^J$9)VJw_e4&rM^kTh8a+-ooPD zxx(QJp}hH!p8p#yvWzk%akCDO-L)jZfHxEQINAaSoMr#3(g^=eFZ~o-F8eI-1G-SL zppQM4m_kx5hUmNN=-V!i&p#r6;rN#ei%8 z92$uvXgnRZ4UB4$#@;VBRMQQOUYQ+<;H{}Ig+6FJK@0lVu6M3kx*1nfJ#OJ3jdGQI zk-CJ0r?l+b^C1>lN|`OPl@_cm%u5yYeV!?<1l?34I>iGDV&e@t#D`k94h##w6UjLS z)^m_;T}SAJfT=-Y^F{F8PZyq5iaX67J5pQ|Vevv{)+SY@s3D9Q=<@E#I3;TeN{mr^ zZ{%aX=PYCApZ~|ai$Z;Q=-WvAewY$7>zz99`O$gkMtVb6*WzWLq3{U82K-}+%)w{x z1I3&cG49L9ZQ_Ue4-^59*P5LRl`k1?qrPduJOOX1WCF>}Pz#}k+em-p=_JL z7KJw_E1QmSu_^?@;=Z1Y3vjh~a|Ds&M0k^!l1*RcTS!#w^*ezlx}u#r<>%LSl{Q@d z%w%fvfov9?|3o2^@nO%d-iv(Zany=n*ZYje@{VkAz(9M`i@hwPG{E1YyvQqGdmIwh zi*laGTvI@Av?8PozO62yr=nZnV*32Xc%n*Z+n;jrP5dxYptJSbn6X3-xyR z$E5{c(tPo17sbi1q6d3xMzeZ&8j$LwOlnYixv%6S(Kz#nc3puu#f?jHMmjUh5c*oMY#T!PM?8W{ z@q>oD9|Oa&^UvZ{|JJn``R&@gC$6+mQ0H}`*MqB!`L-roblE?uEw{>Q*z1lp+qk)r ztGj7~NQ>R&?9iqCZG;Y6Ro-2)J~+);l%&Hlcz zELIXRH@5o()%2n>Q$#v!fQdaHq?=A3$hx_7&$&KYfwNs(mTJGcT-nmQQnjZZ#h9}0 zrCzw=^aS+aVZH5bptS{st2a6axva+dI=(sY>>est-C8Qo8aV`{u^4xnHCyGS5Ck8M zIPG!J=}B$Rpuoo*f`S>fBKkGvr%Vc?DV!!bMOYSws?h?J`*mN;mZU3H2*0FzL z3uH;bk&GLY3d~YtRd;N3}?a#fott&qohJ447b~KEc zGR3S{93c5*&y^Bqz%mcRJQCoJg;ZZ?B_r3E+s}PcMcepBg=P<9K6Zd8FiuVeIgryI9Vg#w(8!kmjB|xHkLAgGHir03LMb zWA1@kX^fvLn)_v7S{%@n*^l3&)(Y2&z9Vecsnd~9F6i2YG4eqa9@n>{ zhV=>SqU4uI4^qGV;617D)|F?ONo2c@xZWul#sGXAc?hHKIP$(uzzUREYM}-KgONd~ z;t9bh)$^5}=bzbfe1w~?ZF7h#AYLfS+e`yFh7r07i8>(pW#8yK=G1kkMT#~c8E&k6 zYk|#{9?xwBLvO{+ms#s37Wx7%Qr@cRi#n~B$C+mAF!)oN$~6B# z9kt^NwDs<cuQlxxLQ0DZg@-Da+k^W+> zrJBRa*oW?=Zu4n1Fn!Z;rtJlqxQlviVRdn9g0$YY0Cvi?8C3?uss8Bu@KktlRB;~e zp7=>Pc=}+$(d*KtjWp&|d*9FwOR0|g8}r6ahP~rO_2)<=o~-QOJxsf4=}z9S2o@sd zrmlK!8Z|!{)(Ig(N3^7W?-NB3<{AniuT}MYl70I!b+HnPC6C2R<3re)stKy-e{+n0gFXrqbam)sO7%)^&`%tNR$7W^)I!@tdsC#xeg^ z=MvdHXj+?`{w2M4hgsC@^wg{Mu1Rdj$9t}e-lplv>k8=L@@o6iJ|ozpv#T)lE@iyaNwi{$eIPR}P7 z7gqdgN8J?nxNo6R?l%hE^Zv=U(LC7TJ%wAnAWt>^5++T@p82-ziU{7dk8jBH-T*>% z7tM|>ARkT)_4D6my`Oq>x{?R&IAq_3s=qn#&IeYn$hQ-J&95F?ds~Q5sI~4@p7I)V z**wb0UH6CV1?bHg1yXu+Ba6?t#7p^H=ybN{czy(rj9ec+H95%8dAZGnMzrXM$$g!# z;cG{@D6p!RPcN{uuE+fJl}iLpc|z0|Bo&X!a%UnKL#h@|9ON1|~mLkBkEwcznB%GYhkcP)HfWJS$$ z((CeTO6QMIf@^`pt@L$JT2Nn4W=gOh^LY;9>A;k`8!ucbyU=vA7h)$QCfkG`RB6e? zea$q3XB~Wgc&l1_`^w+8H;8c!=dW=mGGPo?!pnJv33=~ z5d$Cza(7gls&(HyQ1)c&Mf-zP;{kr`*%{z`_3N?;@OET$A;clRapC}m(%6K3P;mOg3Z|nW7K>mtn4d1)!%YVkkVo{f=4Lfw2bCk z%Td&I&>6K3Rp6$!kMvMlO0?4!H1XI_W1IY7FIEz6s(eD46Ev}RtaHVsaj-Az}FEzNFze*O$uW^nC$ zq+V-GgCuRF9^beCykGoScIafcC9>DxQEec( z2-3$z+~fd*D0XJeYmE`jYF6mHkRE}j)|v^{x!MKI*L0+cb*i${zqbeq4Qax}n+?p= z;^%2X4ktt%$E7-{^48WkjrgBW&b+qiFrz#|X}8jKAF-_WIK`&hlKJwTB|}Y?QTX_> z@;)i$1?xB0WK5P|`?>6EH*`7Qyy`bsA9pcimsHk&N$%ejb9CU6D%RytbT)%=$Mac; z*6i?PL4cggw-PX2boSKCpV7#u0nE$2&Sg>szAZ0n5@hA7wCZ@UKW75su8lol*1j7F zx4vqBdQW72vmk0>w)c62O;>Z1j6lfuZMPqQp5eA*tG=Dm>2sNA1%M<ldMet9N`0wqrO#yH3dvCN zU7-6p-Axl{l~5TNmuz%8seA|}*xfPsJHiCqq5BG1+=sa-{ZJ z$hodrp2%VD2eZ5l-}&Ne!_cO2Q^k+a{}n(H-#x*8lW#}pYswe;8SwPUA_WbXO<~Xc z*~TFjJ--i{ro8Lk;e_L7{621X+4yqbWAn-}j>=r@rT?{UzMuE>Z7}C;`_nPq_KofO zhjU(LX^VZIYT750uX}dc{q08s%&xss*;*v<(s0{X$L63dw$a!9bbY@~+5K?$BOA7F z*QPJM0=}sAd>inRoQ=XnV~(bN9g$&!@gK z-=99UNc58MnbfaWR@knXGB0oCncL}RYc6hCK4Y%Sd5g&@ab!AgoOX5Q= zRsE!l%@Xq@q*uR}e3_8HZq2i#8Oa~tL~h9o(heRzxS%x`nH z9G&=h>b+DawQpi3OL<;~R&Uube zY3|+`-+y!NsJP;M+bu@nQDtIwXhf<}&EX`DS56#F9~o~P69|reUYzE2zzhCDtby1PuW*~&k4#-ipau8db4Hom)^ ze_52_G*?@t(p1IiW@37VJfUSRmzMD~rgV$WTN~ImU#iV>dC?w;XX^xtx6j=2)hAV` zVw>5LaH|rJyQgZ}7XCqT^N~jRYOU^oJw_R9-|iGUe~`W#@cHC3jpaEmHW#9R7ln8} zTkdP@m-qhDt?W~~6F77_E8pojdXnWmR92IxIBs4m3*|jR>uJ;`#k;y;yMSO7L468_c<0LxM^-A;U z2F73ZNy(sVAxeUmMV#GlG=El%ng8PUc|rf%6dsGmFY%baLfSdHaLUH?WmA6#1ylvk z`o{3~MquUk(mfW}46ZNoK0PgrIrHVTTYqC#PTIB5zj>v)=KL=PU))5e{MsaRKseJ! z$~p{mVH9w_%%H;EMRHNX%dS(acIwS@y|CcBL{Hw?xbpMD7nQwjJk+;kFSq%lz2338 zhyVJb=`%9*jeS>#{o)mjd3iUwe$Sr^+WYk79tFRCxO8P)Y^Auf)#P1eq5INxA54%0 zo|AVvI$yHdu#@xK)Z{Cl1S*Z!^l6?teC^bnz6*Xc5_Gf+Z7(y-v)J$b``f8)E7+Ya zyB(%QXt;Rx|B<~Rv1rYb^Vh>qu1>gBeCg&+;6+Hl%YD8a6x-R`nXoG2Xv9kX($s*| z)W`hxXD%^J&{REu93O-R?i9 zZ!g<>D@aEFUGn8EHUD6CzLbX`*@@O)v@?)?Yd=bl;`A$U#h=&jne(odFR z{2uRe9d9Eaf1y30BuG6@Gb5Gn*?u}k{=8TJU$Z`a+m>~@av!#yp7yd?ujt;CI?t=%6>dyp9td~e)}ua zH*5HBo#U$D{nAurx%-o&5*}L*9aXV-bZOn(T~lp48m4@^o&WXg(r+_@UODqrPl@NM z+#kf|==f{@<{266r)raT@IR>%%=Mb|+HK21b#< zIaeLA)mt7b$@Ra*HVd>VdCkR+P;KaeVk>}$i2VW<4ymRWt33;TJ`sL;FpTG~@wvk1 zZ`bOqn;>?$zyf&4TR;Z?WIwPRD5K&QF6q`2_}p4oEM6};>Egd)#9P*=?nwShZ>rFYeG;roJSMD7?vmxs=1TS7b%&HBt6AUgja)-h8h6~yrr}Tih zrQmzvl&3ug-Pr~PRZ*}@@?;TP#H*$i-p~QM9tEAcfWXt$&t;ucLK6TwR)u>2 literal 0 HcmV?d00001 diff --git a/docs/imgs/whale-config2.png b/docs/imgs/whale-config2.png new file mode 100644 index 0000000000000000000000000000000000000000..fae48aace547b48b3bb1adbcfcb0c0b62a72758d GIT binary patch literal 47065 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 bc}Mfg>9xO7DNR=Y#6kTB#yX{1k3;_#=jkT( literal 0 HcmV?d00001 diff --git a/docs/imgs/whale-config3.png b/docs/imgs/whale-config3.png new file mode 100644 index 0000000000000000000000000000000000000000..1dfec8902a0080e12d04ec6fe5bfa8859bfeb221 GIT binary patch literal 68153 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

ytnJj;t;RGqc42z@Ft2Q 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 literal 0 HcmV?d00001 diff --git a/docs/install.md b/docs/install.md new file mode 100644 index 0000000..93af127 --- /dev/null +++ b/docs/install.md @@ -0,0 +1,304 @@ +# Installation & Usage Guide + +## TLDR + +If you never deployed a CTFd instance before: + +```sh +curl -fsSL https://get.docker.com -o get-docker.sh +sh get-docker.sh +docker swarm init +docker node update --label-add='name=linux-1' $(docker node ls -q) + +git clone https://github.com/CTFd/CTFd --depth=1 +git clone https://github.com/frankli0324/ctfd-whale CTFd/CTFd/plugins/ctfd-whale --depth=1 +curl -fsSL https://cdn.jsdelivr.net/gh/frankli0324/ctfd-whale/docker-compose.example.yml -o CTFd/docker-compose.yml + +# make sure you have pip3 installed on your rig +pip3 install docker-compose +docker-compose -f CTFd/docker-compose.yml up -d +# wait till the containers are ready +docker-compose -f CTFd/docker-compose.yml exec ctfd python manage.py set_config whale:auto_connect_network +``` + +The commands above tries to install `docker-ce`,`python3-pip` and `docker-compose`. Make sure the following requirements are satisfied before you execute them: + +* have `curl`, `git`, `python3` and `pip` installed +* GitHub is reachable +* Docker Registry is reachable + +## Installation + +### Start from scratch + +First of all, you should initialize a docker swarm and label the nodes + +names of nodes running linux/windows should begin with `linux/windows-*` + +```bash +docker swarm init +docker node update --label-add "name=linux-1" $(docker node ls -q) +``` + +Taken advantage of the orchestration ability of `docker swarm`, `ctfd-whale` is able to distribute challenge containers to different nodes(machines). Each time a user request for a challenge container, `ctfd-whale` will randomly pick a suitable node for running the container. + +After initializing a swarm, make sure that CTFd runs as expected on your PC/server + +Note that the included compose file in CTFd 2.5.0+ starts an nginx container by default, which takes the http/80 port. make sure there's no conflicts. + +```bash +git clone https://github.com/CTFd/CTFd --depth=1 +cd CTFd # the cwd will not change throughout this guide from this line on +``` + +Change the first line of `docker-compose.yml` to support `attachable` property + +`version '2'` -> `version '3'` + +```bash +docker-compose up -d +``` + +take a look at (or port 8000) and setup CTFd + +### Configure frps + +frps could be started by docker-compose along with CTFd + +define a network for communication between frpc and frps, and create a frps service block + +```yml +services: + ... + frps: + image: glzjin/frp + restart: always + volumes: + - ./conf/frp:/conf + entrypoint: + - /usr/local/bin/frps + - -c + - /conf/frps.ini + ports: + - 10000-10100:10000-10100 # for "direct" challenges + - 8001:8001 # for "http" challenges + networks: + default: # frps ports should be mapped to host + frp_connect: + +networks: + ... + frp_connect: + driver: overlay + internal: true + ipam: + config: + - subnet: 172.1.0.0/16 +``` + +Create a folder in `conf/` called `frp` + +```bash +mkdir ./conf/frp +``` + +then create a configuration file for frps `./conf/frp/frps.ini`, and fill it with: + +```ini +[common] +# following ports must not overlap with "direct" port range defined in the compose file +bind_port = 7987 # port for frpc to connect to +vhost_http_port = 8001 # port for mapping http challenges +token = your_token +subdomain_host = node3.buuoj.cn +# hostname that's mapped to frps by some reverse proxy (or IS frps itself) +``` + +### Configure frpc + +Likewise, create a network and a service for frpc + +the network allows challenges to be accessed by frpc + +```yml +services: + ... + frpc: + image: glzjin/frp:latest + restart: always + volumes: + - ./conf/frp:/conf/ + entrypoint: + - /usr/local/bin/frpc + - -c + - /conf/frpc.ini + depends_on: + - frps #need frps to run first + networks: + frp_containers: + frp_connect: + ipv4_address: 172.1.0.3 + +networks: + ... + frp_containers: # challenge containers are attached to this network + driver: overlay + internal: true + # if challenge containers are allowed to access the internet, remove this line + attachable: true + ipam: + config: + - subnet: 172.2.0.0/16 +``` + +Likewise, create an frpc config file `./conf/frp/frpc.ini` + +```ini +[common] +token = your_token +server_addr = frps +server_port = 7897 # == frps.bind_port +admin_addr = 172.1.0.3 # refer to "Security" +admin_port = 7400 +``` + +### Verify frp configurations + +update compose stack with `docker-compose up -d` + +by executing `docker-compose logs frpc`, you should see that frpc produced following logs: + +```log +[service.go:224] login to server success, get run id [******], server udp port [******] +[service.go:109] admin server listen on ****** +``` + +by seeing this, you can confirm that frpc/frps is set up correctly. + +Note: folder layout in this guide: + +``` +CTFd/ + conf/ + nginx/ # included in CTFd 2.5.0+ + frp/ + frpc.ini + frps.ini + serve.py <- this is just an anchor +``` + +### Configure CTFd + +After finishing everything above: + +* map docker socket into CTFd container +* Attach CTFd container to frp_connect + +```yml +services: + ctfd: + ... + volumes: + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - frpc #need frpc to run ahead + networks: + ... + frp_connect: +``` + +and then clone Whale into CTFd plugins directory (yes, finally) + +```bash +git clone https://github.com/frankli0324/CTFd-Whale CTFd/plugins/ctfd-whale --depth=1 +docker-compose build # for pip to find requirements.txt +docker-compose up -d +``` + +go to the Whale Configuration page (`/plugins/ctfd-whale/admin/settings`) + +#### Docker related configs + +`Auto Connect Network`, if you strictly followed the guide, should be `ctfd_frp_containers` + +If you're not sure about that, this command lists all networks in the current stack + +```bash +docker network ls -f "label=com.docker.compose.project=ctfd" --format "{{.Name}}" +``` + +#### frp related configs + +* `HTTP Domain Suffix` should be consistent with `subdomain_host` in frps +* `HTTP Port` with `vhost_http_port` in frps +* `Direct IP Address` should be a hostname/ip address that can be used to access frps +* `Direct Minimum Port` and `Direct Maximum Port`, you know what to do +* as long as `API URL` is filled in correctly, Whale will read the config of the connected frpc into `Frpc config template` +* setting `Frpc config template` will override contents in `frpc.ini` + +Whale should be kinda usable at this moment. + +### Configure nginx + +If you are using CTFd 2.5.0+, you can utilize the included nginx. + +remove the port mapping rule for frps vhost http port(8001) in the compose file + +If you wnat to go deeper: + +* add nginx to `default` and `internal` network +* remove CTFd from `default` and remove the mapped 8000 port + +add following server block to `./conf/nginx/nginx.conf`: + +```conf +server { + listen 80; + server_name *.node3.buuoj.cn; + location / { + proxy_pass http://frps:8001; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + } +} +``` + +## Challenge Deployment + +### Standalone Containers + +Take a look at + +In one word, a `FLAG` variable will be passed into the container when it's started. You should write your own startup script (usually with bash and sed) to: + +* replace your flag with the generated flag +* remove or override the `FLAG` variable + +PLEASE create challenge images with care. + +### Grouped Containers + +"name" the challenge image with a json object, for example: + +```json +{ + "hostname": "image", +} +``` + +Whale will keep the order of the keys in the json object, and take the first image as the "main container" of a challenge. The "main container" will be mapped to frp with same rules from standalone containers + +see how grouped containers are created in the [code](utils/docker.py#L58) + +## Security + +* Please do not allow untrusted people to access the admin account. Theoretically there's an SSTI vulnerability in the config page. +* Do not set bind_addr of the frpc to `0.0.0.0` if you are following this guide. This may enable contestants to override frpc configurations. +* If you are annoyed by the complicated configuration, and you just want to set bind_addr = 0.0.0.0, remember to enable Basic Auth included in frpc, and set API URL accordingly, for example, `http://username:password@frpc:7400` + +## Advanced Deployment + +To separate the target server (for lunching instance) and CTFd web server with TLS secured docker API, please refer to [this document](advanced.md) \ No newline at end of file diff --git a/docs/install.zh-cn.md b/docs/install.zh-cn.md new file mode 100644 index 0000000..5d82dfc --- /dev/null +++ b/docs/install.zh-cn.md @@ -0,0 +1,313 @@ +# 使用指南 + +## TLDR + +如果你从未部署过CTFd,你可以通过执行: + +```sh +curl -fsSL https://get.docker.com -o get-docker.sh +sh get-docker.sh --mirror Aliyun +docker swarm init +docker node update --label-add='name=linux-1' $(docker node ls -q) + +git clone https://github.com/CTFd/CTFd --depth=1 +git clone https://github.com/frankli0324/ctfd-whale CTFd/CTFd/plugins/ctfd-whale --depth=1 +curl -fsSL https://cdn.jsdelivr.net/gh/frankli0324/ctfd-whale/docker-compose.example.yml -o CTFd/docker-compose.yml + +# make sure you have pip3 installed on your rig +pip3 install docker-compose +docker-compose -f CTFd/docker-compose.yml up -d +docker-compose -f CTFd/docker-compose.yml exec ctfd python manage.py +``` + +脚本会在一台Linux机器上安装 ***docker.com版本的*** `docker-ce`,`python3-pip` 以及 `docker-compose`,请确保执行上述代码之前: + +* 安装好curl,git,python3以及pip +* 网络环境良好,能正常从GitHub克隆仓库 +* 网络环境良好,能正常从Docker Registry拖取镜像 + +## 手动安装 + +为了更好地理解ctfd-whale各个组件的作用,更充分地利用ctfd-whale,在真实使用ctfd-whale时建议用户手动、完整地从空白CTFd开始搭建一个实例。下面本文将引导你完成整个流程。 + +### 从零开始 + +首先需要初始化一个swarm集群并给节点标注名称 + +linux节点名称需要以 `linux-` 打头,windows节点则以 `windows-` 打头 + +```bash +docker swarm init +docker node update --label-add "name=linux-1" $(docker node ls -q) +``` + +`ctfd-whale`利用`docker swarm`的集群管理能力,能够将题目容器分发到不同的节点上运行。选手每次请求启动题目容器时,`ctfd-whale`都将随机选择一个合适的节点运行这个题目容器。 + +然后,我们需要确保CTFd可以正常运行。 + +注意,2.5.0+版本CTFd的 `docker-compose.yml` 中包含了一个 `nginx` 反代,占用了80端口 + +```bash +git clone https://github.com/CTFd/CTFd --depth=1 +cd CTFd # 注:以下全部内容的cwd均为此目录 +``` + +先将 `docker-compose.yml` 的第一行进行修改,以支持 `attachable` 参数 + +`version '2'` -> `version '3'` + +接着 + +```bash +docker-compose up -d +``` + +访问(或8000端口),对CTFd进行初始配置 + +### 配置frps + +frps可以直接通过docker-compose与CTFd同步启动。 + +首先在networks中添加一个网络,用于frpc与frps之间的通信,并添加frps service + +```yml +services: + ... + frps: + image: glzjin/frp + restart: always + volumes: + - ./conf/frp:/conf + entrypoint: + - /usr/local/bin/frps + - -c + - /conf/frps.ini + ports: + - 10000-10100:10000-10100 # 映射direct类型题目的端口 + - 8001:8001 # 映射http类型题目的端口 + networks: + default: # 需要将frps暴露到公网以正常访问题目容器 + frp_connect: + +networks: + ... + frp_connect: + driver: overlay + internal: true + ipam: + config: + - subnet: 172.1.0.0/16 +``` + +先创建目录 `./conf/frp` + +```bash +mkdir ./conf/frp +``` + +接着创建 `./conf/frp/frps.ini` 文件,填写: + +```ini +[common] +# 下面两个端口注意不要与direct类型题目端口范围重合 +bind_port = 7987 # frpc 连接到 frps 的端口 +vhost_http_port = 8001 # frps 映射http类型题目的端口 +token = your_token +subdomain_host = node3.buuoj.cn # 访问http题目容器的主机名 +``` + +### 配置frpc + +同样,在networks中再添加一个网络,用于frpc与题目容器之间的通信,并添加frpc service + +```yml +services: + ... + frpc: + image: glzjin/frp:latest + restart: always + volumes: + - ./conf/frp:/conf/ + entrypoint: + - /usr/local/bin/frpc + - -c + - /conf/frpc.ini + depends_on: + - frps #frps需要先成功运行 + networks: + frp_containers: # 供frpc访问题目容器 + frp_connect: # 供frpc访问frps, CTFd访问frpc + ipv4_address: 172.1.0.3 + +networks: + ... + frp_containers: + driver: overlay + internal: true # 如果允许题目容器访问外网,则可以去掉 + attachable: true + ipam: + config: + - subnet: 172.2.0.0/16 +``` + +同样,我们需要创建一个 `./conf/frp/frpc.ini` + +```ini +[common] +token = your_token +server_addr = frps +server_port = 7897 # 对应 frps 的 bind_port +admin_addr = 172.1.0.3 # 请参考“安全事项” +admin_port = 7400 +``` + +### 检查frp配置是否正确 + +此时可以执行 `docker-compose up -d` 更新compose配置 + +通过查看日志 `docker-compose logs frpc` ,应当能看到frpc产生了以下日志: + +```log +[service.go:224] login to server success, get run id [******], server udp port [******] +[service.go:109] admin server listen on ****** +``` + +说明frpc与frps皆配置正常 + +注:此例中目录结构为: + +``` +CTFd/ + conf/ + nginx # CTFd 2.5.0+中自带 + frp/ + frpc.ini + frps.ini + serve.py +``` + +### 配置CTFd + +前面的工作完成后,将本机docker的访问接口映射到CTFd所在容器内 + +并将CTFd添加到frpc所在network中(注意不是containers这个network) + +```yml +services: + ctfd: + ... + volumes: + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - frpc #frpc需要先运行 + networks: + ... + frp_connect: +``` + +将CTFd-Whale克隆至CTFd的插件目录 + +```bash +git clone https://github.com/frankli0324/CTFd-Whale CTFd/plugins/ctfd-whale --depth=1 +docker-compose build # 需要安装依赖 +docker-compose up -d +``` + +进入Whale的配置页面( `/plugins/ctfd-whale/admin/settings` ),首先配置docker配置项 + +需要注意的是 `Auto Connect Network` ,如果按照上面的配置流程进行配置的话,应当是 `ctfd_frp_containers` + +如果不确定的话,可以通过下面的命令列出CTFd目录compose生成的所有network + +```bash +docker network ls -f "label=com.docker.compose.project=ctfd" --format "{{.Name}}" +``` + +然后检查frp配置项是否正确 + +* `HTTP Domain Suffix` 与 frps 的 `subdomain_host` 保持一致 +* `HTTP Port` 与 frps 的 `vhost_http_port` 保持一致 +* `Direct IP Address` 为能访问到 frps 相应端口(例子中为10000-10100) 的IP +* `Direct Minimum Port` 与 `Direct Maximum Port` 显然可得 +* 只要正确填写了 `API URL` ,Whale 会自动获取 frpc 的配置文件作为 `Frpc config template` +* 通过设置 `Frpc config template` 可以覆盖原有 `frpc.ini` 文件 + +至此,CTFd-Whale 已经马马虎虎可以正常使用了。 + +### 配置nginx + +如果你在使用2.5.0+版本的CTFd,那么你可以直接利用自带的nginx进行http题目的反代 + +首先去除docker-compose.yml中对frps http端口的映射(8001) +如果想贯彻到底的话,可以 + +* 为nginx添加internal与default两个network +* 去除CTFd的default network,并去除ports项 + +在 `./conf/nginx/nginx.conf` 的http block中添加以下server block + +```conf +server { + listen 80; + server_name *.node3.buuoj.cn; + location / { + proxy_pass http://frps:8001; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + } +} +``` + +## 部署题目 + +### 单容器题目环境 + +请参考中的镜像进行题目镜像制作(Dockerfile编写)。总体而言,题目在启动时会向**容器**内传入名为 `FLAG` 的环境变量,你需要编写一个启动脚本(一般为bash+sed组合拳)将flag写入自己的题目中,并删除这一环境变量。 + +请出题人制作镜像时请理清思路,不要搞混容器与镜像的概念。这样既方便自己,也方便部署人员。 + +### 多容器题目环境 + +在题目镜像名处填写一个json object,即可创建一道多容器的题目 + +```json +{ + "hostname": "image", +} +``` + +Whale会保留json的key顺序,并将第一个容器作为"主容器"映射到外网,映射方式与单容器相同 +以buuoj上的swpu2019 web2为例,可以配置如下: + +```json +{ + "ss": "shadowsocks-chall", + "web": "swpu2019-web2", + ... +} +``` + +其中shadowsocks-chall的Dockerfile: + +```dockerfile +FROM shadowsocks/shadowsocks-libev +ENV PASSWORD=123456 +ENV METHOD=aes-256-cfb +``` + +> 注:由于写README的并不是buuoj管理员,故上述仅作说明用,与实际情况可能有较大出入 + +## 安全事项 + +* 后台配置中flag与domain模版理论上存在ssti(feature),请不要将管理员账号给不可信第三方 +* 由于例子中frpc并没有开启鉴权,请不要将frpc的bind_addr设置为`0.0.0.0`。这样会导致利用任何一道能发起http请求的题目都能修改frpc配置。 +* 如果出于配置复杂性考虑,题目容器能够访问frpc,请开启frpc的Basic Auth,并以 `http://username:password@frpc:7400` 的格式设置frpc API URL + +## 高级部署 + +用于下发靶机实例的服务器与运行 `CTFd` 网站的服务器分离,`CTFd-whale` 通过启用了 `TLS/SSL` 验证的 `Dockers API`进行下发容器控制 + +参见 [advanced.zh-cn.md](advanced.zh-cn.md) \ No newline at end of file diff --git a/models.py b/models.py new file mode 100644 index 0000000..f9263be --- /dev/null +++ b/models.py @@ -0,0 +1,105 @@ +import random +import uuid +from datetime import datetime + +from jinja2 import Template + +from CTFd.utils import get_config +from CTFd.models import db +from CTFd.plugins.dynamic_challenges import DynamicChallenge + + +class WhaleConfig(db.Model): + key = db.Column(db.String(length=128), primary_key=True) + value = db.Column(db.Text) + + def __init__(self, key, value): + self.key = key + self.value = value + + def __repr__(self): + return "".format(self.key, self.value) + + +class WhaleRedirectTemplate(db.Model): + key = db.Column(db.String(20), primary_key=True) + frp_template = db.Column(db.Text) + access_template = db.Column(db.Text) + + def __init__(self, key, access_template, frp_template): + self.key = key + self.access_template = access_template + self.frp_template = frp_template + + def __repr__(self): + return "".format(self.key) + + +class DynamicDockerChallenge(DynamicChallenge): + __mapper_args__ = {"polymorphic_identity": "dynamic_docker"} + id = db.Column( + db.Integer, db.ForeignKey("dynamic_challenge.id", ondelete="CASCADE"), primary_key=True + ) + + memory_limit = db.Column(db.Text, default="128m") + cpu_limit = db.Column(db.Float, default=0.5) + dynamic_score = db.Column(db.Integer, default=0) + + docker_image = db.Column(db.Text, default=0) + redirect_type = db.Column(db.Text, default=0) + redirect_port = db.Column(db.Integer, default=0) + + def __init__(self, *args, **kwargs): + kwargs["initial"] = kwargs["value"] + super(DynamicDockerChallenge, self).__init__(**kwargs) + + +class WhaleContainer(db.Model): + id = db.Column(db.Integer, primary_key=True, autoincrement=True) + user_id = db.Column(None, db.ForeignKey("users.id")) + challenge_id = db.Column(None, db.ForeignKey("challenges.id")) + start_time = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) + renew_count = db.Column(db.Integer, nullable=False, default=0) + status = db.Column(db.Integer, default=1) + uuid = db.Column(db.String(256)) + port = db.Column(db.Integer, nullable=True, default=0) + flag = db.Column(db.String(128), nullable=False) + + # Relationships + user = db.relationship( + "Users", foreign_keys="WhaleContainer.user_id", lazy="select") + challenge = db.relationship( + "DynamicDockerChallenge", foreign_keys="WhaleContainer.challenge_id", lazy="select" + ) + + @property + def http_subdomain(self): + return Template(get_config( + 'whale:template_http_subdomain', '{{ container.uuid }}' + )).render(container=self) + + def __init__(self, user_id, challenge_id): + self.user_id = user_id + self.challenge_id = challenge_id + self.start_time = datetime.now() + self.renew_count = 0 + self.uuid = str(uuid.uuid4()) + self.flag = Template(get_config( + 'whale:template_chall_flag', '{{ "flag{"+uuid.uuid4()|string+"}" }}' + )).render(container=self, uuid=uuid, random=random, get_config=get_config) + + @property + def user_access(self): + return Template(WhaleRedirectTemplate.query.filter_by( + key=self.challenge.redirect_type + ).first().access_template).render(container=self, get_config=get_config) + + @property + def frp_config(self): + return Template(WhaleRedirectTemplate.query.filter_by( + key=self.challenge.redirect_type + ).first().frp_template).render(container=self, get_config=get_config) + + def __repr__(self): + return "".format(self.id, self.user_id, self.challenge_id, + self.start_time, self.renew_count) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ccabdeb --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +docker==4.1.0 +Flask-APScheduler==1.11.0 +flask-redis==0.4.0 +redis==3.3.11 \ No newline at end of file diff --git a/templates/config/base.router.config.html b/templates/config/base.router.config.html new file mode 100644 index 0000000..f42df5f --- /dev/null +++ b/templates/config/base.router.config.html @@ -0,0 +1,24 @@ +

diff --git a/templates/config/challenges.config.html b/templates/config/challenges.config.html new file mode 100644 index 0000000..6b824e0 --- /dev/null +++ b/templates/config/challenges.config.html @@ -0,0 +1,25 @@ +
+ {% for config, val in { + "Subdomain Template": ("template_http_subdomain", "Controls how the subdomain of a container is generated"), + "Flag Template": ("template_chall_flag", "Controls how a flag is generated"), + }.items() %} + {% set value = get_config('whale:' + val[0]) %} +
+ + +
+ {% endfor %} + +
+ +
+
\ No newline at end of file diff --git a/templates/config/docker.config.html b/templates/config/docker.config.html new file mode 100644 index 0000000..a46bf1b --- /dev/null +++ b/templates/config/docker.config.html @@ -0,0 +1,122 @@ +
+
Common
+ + Common configurations for both standalone and grouped containers +
+ {% for config, val in { + "API URL": ("docker_api_url", "Docker API to connect to"), + "Credentials": ("docker_credentials", "docker.io username and password, separated by ':'. useful for private images"), + "Swarm Nodes": ("docker_swarm_nodes", "Will pick up one from it, You should set your node with label name=windows-* or name=linux-*. Separated by commas."), + }.items() %} + {% set value = get_config('whale:' + val[0]) %} +
+ + +
+ {% endfor %} + {% set use_ssl = get_config('whale:docker_use_ssl') %} +
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
Standalone Containers
+ + Typical challenges. Under most circumstances you only need to set these. +
+ {% for config, val in { + "Auto Connect Network": ("docker_auto_connect_network", "The network connected for single-containers. It's usually the same network as the frpc is in."), + "Dns Setting": ("docker_dns", "Decide which dns will be used in container network."), + }.items() %} + {% set value = get_config('whale:' + val[0]) %} +
+ + +
+ {% endfor %} +
+
Grouped Containers
+ + Designed for multi-container challenges +
+ {% for config, val in { + "Auto Connect Containers": ("docker_auto_connect_containers","Decide which container will be connected to multi-container-network automatically. Separated by commas."), + "Multi-Container Network Subnet": ("docker_subnet", "Subnet which will be used by auto created networks for multi-container challenges."), + "Multi-Container Network Subnet New Prefix": ("docker_subnet_new_prefix", "Prefix for auto created network.") + }.items() %} + {% set value = get_config('whale:' + val[0]) %} +
+ + +
+ {% endfor %} + +
+ +
+
diff --git a/templates/config/frp.router.config.html b/templates/config/frp.router.config.html new file mode 100644 index 0000000..2ae8adf --- /dev/null +++ b/templates/config/frp.router.config.html @@ -0,0 +1,50 @@ +{% for config, val in { + "API URL": ("frp_api_url", "Frp API to connect to"), + "Http Domain Suffix": ("frp_http_domain_suffix", "Will be appended to the hash of a container"), + "External Http Port": ("frp_http_port", "Keep in sync with frps:vhost_http_port"), + "Direct IP Address":("frp_direct_ip_address","For direct redirect"), + "Direct Minimum Port": ("frp_direct_port_minimum", "For direct redirect (pwn challenges)"), + "Direct Maximum Port": ("frp_direct_port_maximum", "For direct redirect (pwn challenges)"), +}.items() %} + {% set value = get_config('whale:' + val[0]) %} +
+ + +
+{% endfor %} +{% set frpc_template = get_config("whale:frp_config_template", "") %} +
+ + +
+{% if frpc_template %} +
+ + +
+{% endif %} diff --git a/templates/config/limits.config.html b/templates/config/limits.config.html new file mode 100644 index 0000000..f07c7f3 --- /dev/null +++ b/templates/config/limits.config.html @@ -0,0 +1,26 @@ +
+ {% for config, val in { + "Max Container Count": ("docker_max_container_count", "The maximum number of countainers allowed on the server"), + "Max Renewal Times": ("docker_max_renew_count", "The maximum times a user is allowed to renew a container"), + "Docker Container Timeout": ("docker_timeout", "A container times out after [timeout] seconds."), + }.items() %} + {% set value = get_config('whale:' + val[0]) %} +
+ + +
+ {% endfor %} + +
+ +
+
\ No newline at end of file diff --git a/templates/config/trp.router.config.html b/templates/config/trp.router.config.html new file mode 100644 index 0000000..671f8ba --- /dev/null +++ b/templates/config/trp.router.config.html @@ -0,0 +1,17 @@ +{% for config, val in { + "API URL": ("trp_api_url", "trp API to connect to"), + "Domain Suffix": ("trp_domain_suffix", "Will be used to generated the access link of a challenge"), + "Listening Port": ("trp_listening_port", "Will be used to generated the access link of a challenge"), +}.items() %} +{% set value = get_config('whale:' + val[0]) %} +
+ + +
+{% endfor %} diff --git a/templates/containers/card.containers.html b/templates/containers/card.containers.html new file mode 100644 index 0000000..7de8503 --- /dev/null +++ b/templates/containers/card.containers.html @@ -0,0 +1,57 @@ + + +
+ {% for container in containers %} +
+
+
+
+ {{ container.challenge.name | truncate(15) }} + +
+
+ {{ container.user.name | truncate(5) }} + +
+

{{ container.user_access }}

+

{{ container.flag }}

+ Time Started: {{ container.start_time }} + + + + + + +
+
+
+ {% endfor %} +
diff --git a/templates/containers/list.containers.html b/templates/containers/list.containers.html new file mode 100644 index 0000000..188cc2d --- /dev/null +++ b/templates/containers/list.containers.html @@ -0,0 +1,78 @@ +
+
+ + + + + + + + {% for container in containers %} + + + + + + + + + + + + {% endfor %} + +
+
  + +
+
ID + User + Challenge + Access Method + Flag + Startup Time + Renewal Times + Delete +
+
  + +
+
+ {{ container.id }} + + + {{ container.user.name | truncate(12) }} + + + + {{ container.challenge.name }} + + + {{ container.challenge.redirect_type }}  + + + + + + + {{ container.renew_count }}  + + + +
+
+
diff --git a/templates/whale_base.html b/templates/whale_base.html new file mode 100644 index 0000000..98b430e --- /dev/null +++ b/templates/whale_base.html @@ -0,0 +1,25 @@ +{% extends "admin/base.html" %} + +{% block content %} +
+
+

CTFd Whale

+
+
+
+
+
+ +
+
+
+ {% block panel %} + {% endblock %} +
+
+
+
+{% endblock %} diff --git a/templates/whale_config.html b/templates/whale_config.html new file mode 100644 index 0000000..5181e5b --- /dev/null +++ b/templates/whale_config.html @@ -0,0 +1,38 @@ +{% extends "whale_base.html" %} + +{% block menu %} + + + + + +{% endblock %} + +{% block panel %} + {% include "components/errors.html" %} +
+
+
+ {% include "config/docker.config.html" %} + {% include "config/base.router.config.html" %} + {% include "config/limits.config.html" %} + {% include "config/challenges.config.html" %} +
+
+
+{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/templates/whale_containers.html b/templates/whale_containers.html new file mode 100644 index 0000000..8e2bdeb --- /dev/null +++ b/templates/whale_containers.html @@ -0,0 +1,69 @@ +{% extends "whale_base.html" %} + +{% block menu %} + + + + + + + + +{% endblock %} + +{% block panel %} + {% include "containers/" + session["view_mode"] + ".containers.html" %} +{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/cache.py b/utils/cache.py new file mode 100644 index 0000000..cd24700 --- /dev/null +++ b/utils/cache.py @@ -0,0 +1,150 @@ +import ipaddress +import warnings +from CTFd.cache import cache +from CTFd.utils import get_config +from flask_redis import FlaskRedis +from redis.exceptions import LockError + +from .db import DBContainer + + +class CacheProvider: + def __init__(self, app, *args, **kwargs): + if app.config['CACHE_TYPE'] == 'redis': + self.provider = RedisCacheProvider(app, *args, **kwargs) + elif app.config['CACHE_TYPE'] in ['filesystem', 'simple']: + if not hasattr(CacheProvider, 'cache'): + CacheProvider.cache = {} + self.provider = FilesystemCacheProvider(app, *args, **kwargs) + self.init_port_sets() + + def init_port_sets(self): + self.clear() + + containers = DBContainer.get_all_container() + used_port_list = [] + for container in containers: + if container.port != 0: + used_port_list.append(container.port) + for port in range(int(get_config("whale:frp_direct_port_minimum", 29000)), + int(get_config("whale:frp_direct_port_maximum", 28000)) + 1): + if port not in used_port_list: + self.add_available_port(port) + + from .docker import get_docker_client + client = get_docker_client() + + docker_subnet = get_config("whale:docker_subnet", "174.1.0.0/16") + docker_subnet_new_prefix = int( + get_config("whale:docker_subnet_new_prefix", "24")) + + exist_networks = [] + available_networks = [] + + for network in client.networks.list(filters={'label': 'prefix'}): + exist_networks.append(str(network.attrs['Labels']['prefix'])) + + for network in list(ipaddress.ip_network(docker_subnet).subnets(new_prefix=docker_subnet_new_prefix)): + if str(network) not in exist_networks: + available_networks.append(str(network)) + + self.add_available_network_range(*set(available_networks)) + + def __getattr__(self, name): + return self.provider.__getattribute__(name) + + +class FilesystemCacheProvider: + def __init__(self, app, *args, **kwargs): + warnings.warn( + '\n[CTFd Whale] Warning: looks like you are using filesystem cache. ' + '\nThis is for TESTING purposes only, DO NOT USE on production sites.', + RuntimeWarning + ) + self.key = 'ctfd_whale_lock-' + str(kwargs.get('user_id', 0)) + self.global_port_key = "ctfd_whale-port-set" + self.global_network_key = "ctfd_whale-network-set" + + def clear(self): + cache.set(self.global_port_key, set()) + cache.set(self.global_network_key, set()) + + def add_available_network_range(self, *ranges): + s = cache.get(self.global_network_key) + s.update(ranges) + cache.set(self.global_network_key, s) + + def get_available_network_range(self): + try: + s = cache.get(self.global_network_key) + r = s.pop() + cache.set(self.global_network_key, s) + return r + except KeyError: + return None + + def add_available_port(self, port): + s = cache.get(self.global_port_key) + s.add(port) + cache.set(self.global_port_key, s) + + def get_available_port(self): + try: + s = cache.get(self.global_port_key) + r = s.pop() + cache.set(self.global_port_key, s) + return r + except KeyError: + return None + + def acquire_lock(self): + # for testing purposes only, so no need to set this limit + return True + + def release_lock(self): + return True + + +class RedisCacheProvider(FlaskRedis): + def __init__(self, app, *args, **kwargs): + super().__init__(app) + self.key = 'ctfd_whale_lock-' + str(kwargs.get('user_id', 0)) + self.current_lock = None + self.global_port_key = "ctfd_whale-port-set" + self.global_network_key = "ctfd_whale-network-set" + + def clear(self): + self.delete(self.global_port_key) + self.delete(self.global_network_key) + + def add_available_network_range(self, *ranges): + self.sadd(self.global_network_key, *ranges) + + def get_available_network_range(self): + return self.spop(self.global_network_key).decode() + + def add_available_port(self, port): + self.sadd(self.global_port_key, str(port)) + + def get_available_port(self): + return int(self.spop(self.global_port_key)) + + def acquire_lock(self): + lock = self.lock(name=self.key, timeout=10) + + if not lock.acquire(blocking=True, blocking_timeout=2.0): + return False + + self.current_lock = lock + return True + + def release_lock(self): + if self.current_lock is None: + return False + + try: + self.current_lock.release() + + return True + except LockError: + return False diff --git a/utils/checks.py b/utils/checks.py new file mode 100644 index 0000000..ef1baee --- /dev/null +++ b/utils/checks.py @@ -0,0 +1,50 @@ +from docker.errors import DockerException, TLSParameterError, APIError, requests + +from CTFd.utils import get_config + +from .docker import get_docker_client +from .routers import Router, _routers + + +class WhaleChecks: + @staticmethod + def check_docker_api(): + try: + client = get_docker_client() + except TLSParameterError as e: + return f'Docker TLS Parameters incorrect ({e})' + except DockerException as e: + return f'Docker API url incorrect ({e})' + try: + client.ping() + except (APIError, requests.RequestException): + return f'Unable to connect to Docker API, check your API connectivity' + + credentials = get_config("whale:docker_credentials") + if credentials and credentials.count(':') == 1: + try: + client.login(*credentials.split(':')) + except DockerException: + return f'Unable to log into docker registry, check your credentials' + swarm = client.info()['Swarm'] + if not swarm['ControlAvailable']: + return f'Docker swarm not available. You should initialize a swarm first. ($ docker swarm init)' + + @staticmethod + def check_frp_connection(): + router_conftype = get_config("whale:router_type", "frp") + if router_conftype not in _routers: + return "invalid router type: " + router_conftype + ok, msg = _routers[router_conftype]().check_availability() + if not ok: + return msg + + @staticmethod + def perform(): + errors = [] + for attr in dir(WhaleChecks): + if attr.startswith('check_'): + err = getattr(WhaleChecks, attr)() + if err: + errors.append(err) + return errors diff --git a/utils/control.py b/utils/control.py new file mode 100644 index 0000000..09c2d6b --- /dev/null +++ b/utils/control.py @@ -0,0 +1,61 @@ +import datetime +import traceback + +from CTFd.utils import get_config +from .db import DBContainer, db +from .docker import DockerUtils +from .routers import Router + + +class ControlUtil: + @staticmethod + def try_add_container(user_id, challenge_id): + container = DBContainer.create_container_record(user_id, challenge_id) + try: + DockerUtils.add_container(container) + except Exception as e: + DBContainer.remove_container_record(user_id) + print(traceback.format_exc()) + return False, 'Docker Creation Error' + ok, msg = Router.register(container) + if not ok: + DockerUtils.remove_container(container) + DBContainer.remove_container_record(user_id) + return False, msg + return True, 'Container created' + + @staticmethod + def try_remove_container(user_id): + container = DBContainer.get_current_containers(user_id=user_id) + if not container: + return False, 'No such container' + for _ in range(3): # configurable? as "onerror_retry_cnt" + try: + ok, msg = Router.unregister(container) + if not ok: + return False, msg + DockerUtils.remove_container(container) + DBContainer.remove_container_record(user_id) + return True, 'Container destroyed' + except Exception as e: + print(traceback.format_exc()) + return False, 'Failed when destroying instance, please contact admin!' + + @staticmethod + def try_renew_container(user_id): + container = DBContainer.get_current_containers(user_id) + if not container: + return False, 'No such container' + timeout = int(get_config("whale:docker_timeout", "3600")) + container.start_time = container.start_time + \ + datetime.timedelta(seconds=timeout) + if container.start_time > datetime.datetime.now(): + container.start_time = datetime.datetime.now() + # race condition? useless maybe? + # useful when docker_timeout < poll timeout (10 seconds) + # doesn't make any sense + else: + return False, 'Invalid container' + container.renew_count += 1 + db.session.commit() + return True, 'Container Renewed' diff --git a/utils/db.py b/utils/db.py new file mode 100644 index 0000000..81a13ea --- /dev/null +++ b/utils/db.py @@ -0,0 +1,104 @@ +import datetime + +from CTFd.models import db +from CTFd.utils import get_config +from ..models import WhaleContainer, WhaleRedirectTemplate + + +class DBContainer: + @staticmethod + def create_container_record(user_id, challenge_id): + container = WhaleContainer(user_id=user_id, challenge_id=challenge_id) + db.session.add(container) + db.session.commit() + + return container + + @staticmethod + def get_current_containers(user_id): + q = db.session.query(WhaleContainer) + q = q.filter(WhaleContainer.user_id == user_id) + return q.first() + + @staticmethod + def get_container_by_port(port): + q = db.session.query(WhaleContainer) + q = q.filter(WhaleContainer.port == port) + return q.first() + + @staticmethod + def remove_container_record(user_id): + q = db.session.query(WhaleContainer) + q = q.filter(WhaleContainer.user_id == user_id) + q.delete() + db.session.commit() + + @staticmethod + def get_all_expired_container(): + timeout = int(get_config("whale:docker_timeout", "3600")) + + q = db.session.query(WhaleContainer) + q = q.filter( + WhaleContainer.start_time < + datetime.datetime.now() - datetime.timedelta(seconds=timeout) + ) + return q.all() + + @staticmethod + def get_all_alive_container(): + timeout = int(get_config("whale:docker_timeout", "3600")) + + q = db.session.query(WhaleContainer) + q = q.filter( + WhaleContainer.start_time >= + datetime.datetime.now() - datetime.timedelta(seconds=timeout) + ) + return q.all() + + @staticmethod + def get_all_container(): + q = db.session.query(WhaleContainer) + return q.all() + + @staticmethod + def get_all_alive_container_page(page_start, page_end): + timeout = int(get_config("whale:docker_timeout", "3600")) + + q = db.session.query(WhaleContainer) + q = q.filter( + WhaleContainer.start_time >= + datetime.datetime.now() - datetime.timedelta(seconds=timeout) + ) + q = q.slice(page_start, page_end) + return q.all() + + @staticmethod + def get_all_alive_container_count(): + timeout = int(get_config("whale:docker_timeout", "3600")) + + q = db.session.query(WhaleContainer) + q = q.filter( + WhaleContainer.start_time >= + datetime.datetime.now() - datetime.timedelta(seconds=timeout) + ) + return q.count() + + +class DBRedirectTemplate: + @staticmethod + def get_all_templates(): + return WhaleRedirectTemplate.query.all() + + @staticmethod + def create_template(name, access_template, frp_template): + if WhaleRedirectTemplate.query.filter_by(key=name).first(): + return # already existed + db.session.add(WhaleRedirectTemplate( + name, access_template, frp_template + )) + db.session.commit() + + @staticmethod + def delete_template(name): + WhaleRedirectTemplate.query.filter_by(key=name).delete() + db.session.commit() diff --git a/utils/docker.py b/utils/docker.py new file mode 100644 index 0000000..2fe1b42 --- /dev/null +++ b/utils/docker.py @@ -0,0 +1,202 @@ +import json +import random +import uuid +from collections import OrderedDict + +import docker +from flask import current_app + +from CTFd.utils import get_config + +from .cache import CacheProvider +from .exceptions import WhaleError + + +def get_docker_client(): + if get_config("whale:docker_use_ssl", False): + tls_config = docker.tls.TLSConfig( + verify=True, + ca_cert=get_config("whale:docker_ssl_ca_cert") or None, + client_cert=( + get_config("whale:docker_ssl_client_cert"), + get_config("whale:docker_ssl_client_key") + ), + ) + return docker.DockerClient( + base_url=get_config("whale:docker_api_url"), + tls=tls_config, + ) + else: + return docker.DockerClient(base_url=get_config("whale:docker_api_url")) + + +class DockerUtils: + @staticmethod + def init(): + try: + DockerUtils.client = get_docker_client() + # docker-py is thread safe: https://github.com/docker/docker-py/issues/619 + except Exception: + raise WhaleError( + 'Docker Connection Error\n' + 'Please ensure the docker api url (first config item) is correct\n' + 'if you are using unix:///var/run/docker.sock, check if the socket is correctly mapped' + ) + credentials = get_config("whale:docker_credentials") + if credentials and credentials.count(':') == 1: + try: + DockerUtils.client.login(*credentials.split(':')) + except Exception: + raise WhaleError('docker.io failed to login, check your credentials') + + @staticmethod + def add_container(container): + if container.challenge.docker_image.startswith("{"): + DockerUtils._create_grouped_container(DockerUtils.client, container) + else: + DockerUtils._create_standalone_container(DockerUtils.client, container) + + @staticmethod + def _create_standalone_container(client, container): + dns = get_config("whale:docker_dns", "").split(",") + node = DockerUtils.choose_node( + container.challenge.docker_image, + get_config("whale:docker_swarm_nodes", "").split(",") + ) + + client.services.create( + image=container.challenge.docker_image, + name=f'{container.user_id}-{container.uuid}', + env={'FLAG': container.flag}, dns_config=docker.types.DNSConfig(nameservers=dns), + networks=[get_config("whale:docker_auto_connect_network", "ctfd_frp-containers")], + resources=docker.types.Resources( + mem_limit=DockerUtils.convert_readable_text( + container.challenge.memory_limit), + cpu_limit=int(container.challenge.cpu_limit * 1e9) + ), + labels={ + 'whale_id': f'{container.user_id}-{container.uuid}' + }, # for container deletion + constraints=['node.labels.name==' + node], + endpoint_spec=docker.types.EndpointSpec(mode='dnsrr', ports={}) + ) + + @staticmethod + def _create_grouped_container(client, container): + range_prefix = CacheProvider(app=current_app).get_available_network_range() + + ipam_pool = docker.types.IPAMPool(subnet=range_prefix) + ipam_config = docker.types.IPAMConfig( + driver='default', pool_configs=[ipam_pool]) + network_name = f'{container.user_id}-{container.uuid}' + network = client.networks.create( + network_name, internal=True, + ipam=ipam_config, attachable=True, + labels={'prefix': range_prefix}, + driver="overlay", scope="swarm" + ) + + dns = [] + containers = get_config("whale:docker_auto_connect_containers", "").split(",") + for c in containers: + if not c: + continue + network.connect(c) + if "dns" in c: + network.reload() + for name in network.attrs['Containers']: + if network.attrs['Containers'][name]['Name'] == c: + dns.append(network.attrs['Containers'][name]['IPv4Address'].split('/')[0]) + + has_processed_main = False + try: + images = json.loads( + container.challenge.docker_image, + object_pairs_hook=OrderedDict + ) + except json.JSONDecodeError: + raise WhaleError( + "Challenge Image Parse Error\n" + "plase check the challenge image string" + ) + for name, image in images.items(): + if has_processed_main: + container_name = f'{container.user_id}-{uuid.uuid4()}' + else: + container_name = f'{container.user_id}-{container.uuid}' + node = DockerUtils.choose_node(image, get_config("whale:docker_swarm_nodes", "").split(",")) + has_processed_main = True + client.services.create( + image=image, name=container_name, networks=[ + docker.types.NetworkAttachmentConfig(network_name, aliases=[name]) + ], + env={'FLAG': container.flag}, + dns_config=docker.types.DNSConfig(nameservers=dns), + resources=docker.types.Resources( + mem_limit=DockerUtils.convert_readable_text( + container.challenge.memory_limit + ), + cpu_limit=int(container.challenge.cpu_limit * 1e9)), + labels={ + 'whale_id': f'{container.user_id}-{container.uuid}' + }, # for container deletion + hostname=name, constraints=['node.labels.name==' + node], + endpoint_spec=docker.types.EndpointSpec(mode='dnsrr', ports={}) + ) + + @staticmethod + def remove_container(container): + whale_id = f'{container.user_id}-{container.uuid}' + + for s in DockerUtils.client.services.list(filters={'label': f'whale_id={whale_id}'}): + s.remove() + + networks = DockerUtils.client.networks.list(names=[whale_id]) + if len(networks) > 0: # is grouped containers + auto_containers = get_config("whale:docker_auto_connect_containers", "").split(",") + redis_util = CacheProvider(app=current_app) + for network in networks: + for container in auto_containers: + try: + network.disconnect(container, force=True) + except Exception: + pass + redis_util.add_available_network_range(network.attrs['Labels']['prefix']) + network.remove() + + @staticmethod + def convert_readable_text(text): + lower_text = text.lower() + + if lower_text.endswith("k"): + return int(text[:-1]) * 1024 + + if lower_text.endswith("m"): + return int(text[:-1]) * 1024 * 1024 + + if lower_text.endswith("g"): + return int(text[:-1]) * 1024 * 1024 * 1024 + + return 0 + + @staticmethod + def choose_node(image, nodes): + win_nodes = [] + linux_nodes = [] + for node in nodes: + if node.startswith("windows"): + win_nodes.append(node) + else: + linux_nodes.append(node) + try: + tag = image.split(":")[1:] + if len(tag) and tag[0].startswith("windows"): + return random.choice(win_nodes) + return random.choice(linux_nodes) + except IndexError: + raise WhaleError( + 'No Suitable Nodes.\n' + 'If you are using Whale for the first time, \n' + 'Please Setup Swarm Nodes Correctly and Lable Them with\n' + 'docker node update --label-add "name=linux-1" $(docker node ls -q)' + ) diff --git a/utils/exceptions.py b/utils/exceptions.py new file mode 100644 index 0000000..08886f7 --- /dev/null +++ b/utils/exceptions.py @@ -0,0 +1,8 @@ +class WhaleError(Exception): + def __init__(self, msg): + super().__init__(msg) + self.message = msg + + +class WhaleWarning(Warning): + pass diff --git a/utils/routers/__init__.py b/utils/routers/__init__.py new file mode 100644 index 0000000..96f0174 --- /dev/null +++ b/utils/routers/__init__.py @@ -0,0 +1,34 @@ +from CTFd.utils import get_config + +from .frp import FrpRouter +from .trp import TrpRouter + +_routers = { + 'frp': FrpRouter, + 'trp': TrpRouter, +} + + +def instanciate(cls): + return cls() + + +@instanciate +class Router: + _name = '' + _router = None + + def __getattr__(self, name: str): + router_conftype = get_config("whale:router_type", "frp") + if Router._name != router_conftype: + Router._router = _routers[router_conftype]() + Router._name = router_conftype + return getattr(Router._router, name) + + @staticmethod + def reset(): + Router._name = '' + Router._router = None + + +__all__ = ["Router"] diff --git a/utils/routers/base.py b/utils/routers/base.py new file mode 100644 index 0000000..eba7118 --- /dev/null +++ b/utils/routers/base.py @@ -0,0 +1,25 @@ +import typing + +from ...models import WhaleContainer + + +class BaseRouter: + name = None + + def __init__(self): + pass + + def access(self, container: WhaleContainer): + pass + + def register(self, container: WhaleContainer): + pass + + def unregister(self, container: WhaleContainer): + pass + + def reload(self): + pass + + def check_availability(self) -> typing.Tuple[bool, str]: + pass diff --git a/utils/routers/frp.py b/utils/routers/frp.py new file mode 100644 index 0000000..08ba694 --- /dev/null +++ b/utils/routers/frp.py @@ -0,0 +1,132 @@ +import warnings + +from flask import current_app +from requests import session, RequestException + +from CTFd.models import db +from CTFd.utils import get_config, set_config, logging + +from .base import BaseRouter +from ..cache import CacheProvider +from ..db import DBContainer +from ..exceptions import WhaleError, WhaleWarning +from ...models import WhaleContainer + + +class FrpRouter(BaseRouter): + name = "frp" + types = { + 'direct': 'tcp', + 'http': 'http', + } + + class FrpRule: + def __init__(self, name, config): + self.name = name + self.config = config + + def __str__(self) -> str: + return f'[{self.name}]\n' + '\n'.join(f'{k} = {v}' for k, v in self.config.items()) + + def __init__(self): + super().__init__() + self.ses = session() + self.url = get_config("whale:frp_api_url").rstrip("/") + self.common = '' + try: + CacheProvider(app=current_app).init_port_sets() + except Exception: + warnings.warn( + "cache initialization failed", + WhaleWarning + ) + + def reload(self, exclude=None): + rules = [] + for container in DBContainer.get_all_alive_container(): + if container.uuid == exclude: + continue + name = f'{container.challenge.redirect_type}_{container.user_id}_{container.uuid}' + config = { + 'type': self.types[container.challenge.redirect_type], + 'local_ip': f'{container.user_id}-{container.uuid}', + 'local_port': container.challenge.redirect_port, + 'use_compression': 'true', + } + if config['type'] == 'http': + config['subdomain'] = container.http_subdomain + elif config['type'] == 'tcp': + config['remote_port'] = container.port + rules.append(self.FrpRule(name, config)) + + try: + if not self.common: + common = get_config("whale:frp_config_template", '') + if '[common]' in common: + self.common = common + else: + remote = self.ses.get(f'{self.url}/api/config') + assert remote.status_code == 200 + set_config("whale:frp_config_template", remote.text) + self.common = remote.text + config = self.common + '\n' + '\n'.join(str(r) for r in rules) + assert self.ses.put( + f'{self.url}/api/config', config, timeout=5 + ).status_code == 200 + assert self.ses.get( + f'{self.url}/api/reload', timeout=5 + ).status_code == 200 + except (RequestException, AssertionError) as e: + raise WhaleError( + '\nfrpc request failed\n' + + (f'{e}\n' if str(e) else '') + + 'please check the frp related configs' + ) from None + + def access(self, container: WhaleContainer): + if container.challenge.redirect_type == 'direct': + return f'nc {get_config("whale:frp_direct_ip_address", "127.0.0.1")} {container.port}' + elif container.challenge.redirect_type == 'http': + host = get_config("whale:frp_http_domain_suffix", "") + port = get_config("whale:frp_http_port", "80") + host += f':{port}' if port != 80 else '' + return f'Link to the Challenge' + return '' + + def register(self, container: WhaleContainer): + if container.challenge.redirect_type == 'direct': + if not container.port: + port = CacheProvider(app=current_app).get_available_port() + if not port: + return False, 'No available ports. Please wait for a few minutes.' + container.port = port + db.session.commit() + elif container.challenge.redirect_type == 'http': + # config['subdomain'] = container.http_subdomain + pass + self.reload() + return True, 'success' + + def unregister(self, container: WhaleContainer): + if container.challenge.redirect_type == 'direct': + try: + redis_util = CacheProvider(app=current_app) + redis_util.add_available_port(container.port) + except Exception as e: + logging.log( + 'whale', 'Error deleting port from cache', + name=container.user.name, + challenge_id=container.challenge_id, + ) + return False, 'Error deleting port from cache' + self.reload(exclude=container.uuid) + return True, 'success' + + def check_availability(self): + try: + resp = self.ses.get(f'{self.url}/api/status', timeout=2.0) + except RequestException as e: + return False, 'Unable to access frpc admin api' + if resp.status_code == 401: + return False, 'frpc admin api unauthorized' + return True, 'Available' diff --git a/utils/routers/trp.py b/utils/routers/trp.py new file mode 100644 index 0000000..9567b07 --- /dev/null +++ b/utils/routers/trp.py @@ -0,0 +1,69 @@ +import traceback +from requests import session, RequestException, HTTPError + +from CTFd.utils import get_config +from .base import BaseRouter +from ..db import DBContainer, WhaleContainer + + +class TrpRouter(BaseRouter): + name = "trp" + + def __init__(self): + super().__init__() + self.ses = session() + self.url = get_config('whale:trp_api_url', '').rstrip("/") + self.common = '' + for container in DBContainer.get_all_alive_container(): + self.register(container) + + @staticmethod + def get_domain(container: WhaleContainer): + domain = get_config('whale:trp_domain_suffix', '127.0.0.1.nip.io').lstrip('.') + domain = f'{container.uuid}.{domain}' + return domain + + def access(self, container: WhaleContainer): + ch_type = container.challenge.redirect_type + domain = self.get_domain(container) + port = get_config('whale:trp_listening_port', 1443) + if ch_type == 'direct': + return f'from pwn import *
remote("{domain}", {port}, ssl=True).interactive()' + elif ch_type == 'http': + return f'https://{domain}' + (f':{port}' if port != 443 else '') + else: + return f'[ssl] {domain} {port}' + + def register(self, container: WhaleContainer): + try: + resp = self.ses.post(f'{self.url}/rule/{self.get_domain(container)}', json={ + 'target': f'{container.user_id}-{container.uuid}:{container.challenge.redirect_port}', + 'source': None, + }) + resp.raise_for_status() + return True, 'success' + except HTTPError as e: + return False, e.response.text + except RequestException as e: + print(traceback.format_exc()) + return False, 'unable to access trp Api' + + def unregister(self, container: WhaleContainer): + try: + resp = self.ses.delete(f'{self.url}/rule/{self.get_domain(container)}') + resp.raise_for_status() + return True, 'success' + except HTTPError as e: + return False, e.response.text + except RequestException as e: + print(traceback.format_exc()) + return False, 'unable to access trp Api' + + def check_availability(self): + try: + resp = self.ses.get(f'{self.url}/rules').json() + except RequestException as e: + return False, 'Unable to access trp admin api' + except Exception as e: + return False, 'Unknown trp error' + return True, 'Available' diff --git a/utils/setup.py b/utils/setup.py new file mode 100644 index 0000000..ca85e62 --- /dev/null +++ b/utils/setup.py @@ -0,0 +1,60 @@ +from CTFd.utils import set_config + +from ..models import WhaleRedirectTemplate, db + + +def setup_default_configs(): + for key, val in { + 'setup': 'true', + 'docker_api_url': 'unix:///var/run/docker.sock', + 'docker_credentials': '', + 'docker_dns': '127.0.0.1', + 'docker_max_container_count': '100', + 'docker_max_renew_count': '5', + 'docker_subnet': '174.1.0.0/16', + 'docker_subnet_new_prefix': '24', + 'docker_swarm_nodes': 'linux-1', + 'docker_timeout': '3600', + 'frp_api_url': 'http://frpc:7400', + 'frp_http_port': '8080', + 'frp_http_domain_suffix': '127.0.0.1.nip.io', + 'frp_direct_port_maximum': '10100', + 'frp_direct_port_minimum': '10000', + 'template_http_subdomain': '{{ container.uuid }}', + 'template_chall_flag': '{{ "flag{"+uuid.uuid4()|string+"}" }}', + }.items(): + set_config('whale:' + key, val) + db.session.add(WhaleRedirectTemplate( + 'http', + 'http://{{ container.http_subdomain }}.' + '{{ get_config("whale:frp_http_domain_suffix", "") }}' + '{% if get_config("whale:frp_http_port", "80") != 80 %}:{{ get_config("whale:frp_http_port") }}{% endif %}/', + ''' +[http_{{ container.user_id|string }}-{{ container.uuid }}] +type = http +local_ip = {{ container.user_id|string }}-{{ container.uuid }} +local_port = {{ container.challenge.redirect_port }} +subdomain = {{ container.http_subdomain }} +use_compression = true +''' + )) + db.session.add(WhaleRedirectTemplate( + 'direct', + 'nc {{ get_config("whale:frp_direct_ip_address", "127.0.0.1") }} {{ container.port }}', + ''' +[direct_{{ container.user_id|string }}-{{ container.uuid }}] +type = tcp +local_ip = {{ container.user_id|string }}-{{ container.uuid }} +local_port = {{ container.challenge.redirect_port }} +remote_port = {{ container.port }} +use_compression = true + +[direct_{{ container.user_id|string }}-{{ container.uuid }}_udp] +type = udp +local_ip = {{ container.user_id|string }}-{{ container.uuid }} +local_port = {{ container.challenge.redirect_port }} +remote_port = {{ container.port }} +use_compression = true +''' + )) + db.session.commit()