├── 1st_Place ├── LICENSE ├── README.md ├── catboost_model.ipynb ├── compare_df.csv ├── compare_methods.ipynb ├── load_external_data.ipynb ├── main.py ├── reports │ └── DrivenData-Competition-Winner-Documentation.pdf ├── requirements.txt └── unet_model.ipynb ├── 2nd_Place ├── LICENSE ├── README.md ├── environment.yml ├── notebooks │ ├── EDA.ipynb │ └── check_prediction.ipynb ├── reports │ └── DrivenData-Competition-Winner-Documentation.pdf ├── requirements.txt └── src │ ├── data │ ├── load_pc_test_data.ipynb │ └── load_pc_train_data.ipynb │ └── models │ ├── main.py │ ├── predict.py │ └── train_model.ipynb ├── 3rd_Place ├── 01-ewl-stac.ipynb ├── LICENSE ├── README.md ├── flood_model.py ├── main.py ├── reports │ └── DrivenData-Competition-Winner-Documentation.pdf └── requirements.txt ├── LICENSE └── README.md /1st_Place/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Daniil Stepanov and Anna Belyaeva (Team Moscow Hares - 4 | sweetlhare, Belass) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /1st_Place/README.md: -------------------------------------------------------------------------------- 1 | # STAC Overflow 2 | 1st place solution for STAC Overflow: Map Floodwater from Radar Imagery hosted by Microsoft AI for Earth 3 | https://www.drivendata.org/competitions/81/detect-flood-water/ 4 | 5 | If this solution seemed useful to you, be sure to share ⭐️ 6 | 7 | 8 | ## About the solution 9 | 10 | Initially, I understood that I would not be able to build a super complex neural network, because either there was not enough knowledge or there was not enough computing power. 11 | 12 | Therefore, the only chance to win was to come up with a simpler method for determining flooding. To do this, I studied articles about how waterlogging is determined now. There were neural network methods, but there were also mathematical methods. From which I concluded that in addition to segmentation by a neural network, you can try to determine the flooding pixel by pixel by some formula. 13 | 14 | But since I am a "cool" data scientist 🦧, I did not output the formula manually, but trained ML models – Catboostclassifier, which solved the binary classification problem on pixel-by-pixel data. 15 | 16 | Before that, I also trained the Unet models. 17 | 18 | Further, I noticed that the models often do not fill the necessary zones, rather than overfill. Therefore, I combined the predictions of these two approaches, taking their maxima, not the average. 19 | 20 | And as you can see, this approach worked and brought me such an important victory! 🥳 21 | 22 | You can see other notes about the solution in the jupyter-notebooks. 23 | 24 | 25 | ## Solution 26 | 27 | This solution assumes that training features are saved in the directory `../training_data/train_features`, training labels are saved in the directory `../training_data/train_labels`, and the metadata is saved to `../training_data/flood-training-metadata.csv`. 28 | 29 | 1. __load_external_data.ipynb__ 30 | 31 | This notebook is downloading additional data from Planetary Computer. Spoiler: Nasadem band is an incredibly important 32 | 33 | 34 | 2. __catboost_model.ipynb__ 35 | 36 | This shows the preparation of pixel-by-pixel data and the training of CatBoostClassifier models on them. 37 | 38 | 39 | 3. __unet_model.ipynb__ 40 | 41 | Here is a classic segmentation approach using neural networks with the Unet architecture with EfficientNet backbone. 42 | 43 | 44 | 4. __compare_methods.ipynb__ 45 | 46 | This notebook shows a comparison of the results of the two approaches and their combination. 47 | 48 | 5. __main.py__ 49 | 50 | This script performs inference on the test set using the saved model weights. 51 | -------------------------------------------------------------------------------- /1st_Place/compare_df.csv: -------------------------------------------------------------------------------- 1 | files,unet_path,cat_path 2 | jja03,result_for_compare/unet_jja03,result_for_compare/cat_jja03 3 | qxb32,result_for_compare/unet_qxb32,result_for_compare/cat_qxb32 4 | kuo20,result_for_compare/unet_kuo20,result_for_compare/cat_kuo20 5 | pxs60,result_for_compare/unet_pxs60,result_for_compare/cat_pxs60 6 | tnp33,result_for_compare/unet_tnp33,result_for_compare/cat_tnp33 7 | wvy09,result_for_compare/unet_wvy09,result_for_compare/cat_wvy09 8 | jja37,result_for_compare/unet_jja37,result_for_compare/cat_jja37 9 | tnp50,result_for_compare/unet_tnp50,result_for_compare/cat_tnp50 10 | pxs18,result_for_compare/unet_pxs18,result_for_compare/cat_pxs18 11 | jja46,result_for_compare/unet_jja46,result_for_compare/cat_jja46 12 | tht24,result_for_compare/unet_tht24,result_for_compare/cat_tht24 13 | awc01,result_for_compare/unet_awc01,result_for_compare/cat_awc01 14 | awc00,result_for_compare/unet_awc00,result_for_compare/cat_awc00 15 | wvy01,result_for_compare/unet_wvy01,result_for_compare/cat_wvy01 16 | jja65,result_for_compare/unet_jja65,result_for_compare/cat_jja65 17 | kuo06,result_for_compare/unet_kuo06,result_for_compare/cat_kuo06 18 | tht28,result_for_compare/unet_tht28,result_for_compare/cat_tht28 19 | pxs12,result_for_compare/unet_pxs12,result_for_compare/cat_pxs12 20 | jja17,result_for_compare/unet_jja17,result_for_compare/cat_jja17 21 | jja20,result_for_compare/unet_jja20,result_for_compare/cat_jja20 -------------------------------------------------------------------------------- /1st_Place/compare_methods.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 4, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "from pathlib import Path\n", 10 | "import warnings\n", 11 | "\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import numpy as np\n", 14 | "import pandas as pd\n", 15 | "import rasterio\n", 16 | "from sklearn.metrics import jaccard_score\n", 17 | "\n", 18 | "warnings.filterwarnings('ignore')" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "train_features = Path.cwd().parent / \"training_data\" / \"train_features\"\n", 28 | "train_labels = Path.cwd().parent / \"training_data\" / \"train_labels\"" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "compare_df = pd.read_csv('compare_df.csv')" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 2, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "def process_mask(mask):\n", 47 | " mask_temp = mask.copy()\n", 48 | " mask_temp[mask == 255] = 0\n", 49 | " return mask_temp\n", 50 | "\n", 51 | "\n", 52 | "def score(pred_thresh, mask):\n", 53 | " return round(jaccard_score(mask.flatten(), pred_thresh.flatten()), 3)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "for i, val in compare_df.iterrows():\n", 63 | " \n", 64 | " unet_pred = np.load(val[1]+'.npy')\n", 65 | " cat_pred = np.load(val[2]+'.npy')\n", 66 | " \n", 67 | " with rasterio.open(train_labels / '{}.tif'.format(val[0])) as fmask:\n", 68 | " gt = process_mask(fmask.read(1))\n", 69 | " \n", 70 | " with rasterio.open(train_features / '{}_vh.tif'.format(val[0])) as fvh:\n", 71 | " vh = fvh.read(1)\n", 72 | " \n", 73 | " _, ax = plt.subplots(1, 5, figsize=(20, 5))\n", 74 | " \n", 75 | " ax[0].imshow(vh)\n", 76 | " ax[0].set_title('vh')\n", 77 | " \n", 78 | " ax[1].imshow(gt)\n", 79 | " ax[1].set_title('gt')\n", 80 | " \n", 81 | " ax[2].imshow(np.round(unet_pred))\n", 82 | " ax[2].set_title('unet\\n'+str(score(np.round(unet_pred), gt)))\n", 83 | " \n", 84 | " ax[3].imshow(np.round(cat_pred))\n", 85 | " ax[3].set_title('cat\\n'+str(score(np.round(cat_pred), gt)))\n", 86 | " \n", 87 | " all_pred = np.round(np.max([unet_pred, cat_pred], axis=0))\n", 88 | " \n", 89 | " ax[4].imshow(all_pred)\n", 90 | " ax[4].set_title('unet+cat\\n'+str(score(all_pred, gt)))\n", 91 | " \n", 92 | " plt.show()" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [] 101 | } 102 | ], 103 | "metadata": { 104 | "kernelspec": { 105 | "display_name": "Python 3 (ipykernel)", 106 | "language": "python", 107 | "name": "python3" 108 | }, 109 | "language_info": { 110 | "codemirror_mode": { 111 | "name": "ipython", 112 | "version": 3 113 | }, 114 | "file_extension": ".py", 115 | "mimetype": "text/x-python", 116 | "name": "python", 117 | "nbconvert_exporter": "python", 118 | "pygments_lexer": "ipython3", 119 | "version": "3.8.12" 120 | } 121 | }, 122 | "nbformat": 4, 123 | "nbformat_minor": 4 124 | } 125 | -------------------------------------------------------------------------------- /1st_Place/load_external_data.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "500dcee8", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "from dataclasses import dataclass\n", 11 | "import os\n", 12 | "from pathlib import Path\n", 13 | "from tempfile import TemporaryDirectory\n", 14 | "from typing import List, Any, Dict\n", 15 | "\n", 16 | "from matplotlib import pyplot as plt\n", 17 | "import rasterio\n", 18 | "from rasterio.warp import reproject, Resampling\n", 19 | "from osgeo import gdal\n", 20 | "import planetary_computer as pc\n", 21 | "import pyproj\n", 22 | "from pystac_client import Client\n", 23 | "from shapely.geometry import box, mapping" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 2, 29 | "id": "bdc03535", 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "STAC_API = \"https://planetarycomputer.microsoft.com/api/stac/v1\"\n", 34 | "catalog = Client.open(STAC_API)" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 3, 40 | "id": "1a24f198-da02-4c26-a5de-7220fe63ac0a", 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "train_features = Path.cwd().parent / \"training_data\" / \"train_features\"\n", 45 | "train_labels = Path.cwd().parent / \"training_data\" / \"train_labels\"" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 4, 51 | "id": "e47ac8de", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "@dataclass\n", 56 | "class ChipInfo:\n", 57 | " \"\"\"\n", 58 | " Holds information about a training chip, including geospatial info for coregistration\n", 59 | " \"\"\"\n", 60 | "\n", 61 | " path: str\n", 62 | " prefix: str\n", 63 | " crs: Any\n", 64 | " shape: List[int]\n", 65 | " transform: List[float]\n", 66 | " bounds: rasterio.coords.BoundingBox\n", 67 | " footprint: Dict[str, Any]\n", 68 | "\n", 69 | "\n", 70 | "def get_footprint(bounds, crs):\n", 71 | " \"\"\"Gets a GeoJSON footprint (in epsg:4326) from rasterio bounds and CRS\"\"\"\n", 72 | " transformer = pyproj.Transformer.from_crs(crs, \"epsg:4326\", always_xy=True)\n", 73 | " minx, miny = transformer.transform(bounds.left, bounds.bottom)\n", 74 | " maxx, maxy = transformer.transform(bounds.right, bounds.top)\n", 75 | " return mapping(box(minx, miny, maxx, maxy))\n", 76 | "\n", 77 | "\n", 78 | "def get_chip_info(chip_path):\n", 79 | " \"\"\"Gets chip info from a GeoTIFF file\"\"\"\n", 80 | " with rasterio.open(chip_path) as ds:\n", 81 | " chip_crs = ds.crs\n", 82 | " chip_shape = ds.shape\n", 83 | " chip_transform = ds.transform\n", 84 | " chip_bounds = ds.bounds\n", 85 | "\n", 86 | " # Use the first part of the chip filename as a prefix\n", 87 | " prefix = os.path.basename(chip_path).split(\"_\")[0]\n", 88 | "\n", 89 | " return ChipInfo(\n", 90 | " path=chip_path,\n", 91 | " prefix=prefix,\n", 92 | " crs=chip_crs,\n", 93 | " shape=chip_shape,\n", 94 | " transform=chip_transform,\n", 95 | " bounds=chip_bounds,\n", 96 | " footprint=get_footprint(chip_bounds, chip_crs),\n", 97 | " )" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 5, 103 | "id": "c9784f23", 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [ 107 | "def reproject_to_chip(\n", 108 | " chip_info, input_path, output_path, resampling=Resampling.nearest\n", 109 | "):\n", 110 | " \"\"\"\n", 111 | " Reproject a raster at input_path to chip_info, saving to output_path.\n", 112 | "\n", 113 | " Use Resampling.nearest for classification rasters. Otherwise use something\n", 114 | " like Resampling.bilinear for continuous data.\n", 115 | " \"\"\"\n", 116 | " with rasterio.open(input_path) as src:\n", 117 | " kwargs = src.meta.copy()\n", 118 | " kwargs.update(\n", 119 | " {\n", 120 | " \"crs\": chip_info.crs,\n", 121 | " \"transform\": chip_info.transform,\n", 122 | " \"width\": chip_info.shape[1],\n", 123 | " \"height\": chip_info.shape[0],\n", 124 | " \"driver\": \"GTiff\",\n", 125 | " }\n", 126 | " )\n", 127 | "\n", 128 | " with rasterio.open(output_path, \"w\", **kwargs) as dst:\n", 129 | " for i in range(1, src.count + 1):\n", 130 | " reproject(\n", 131 | " source=rasterio.band(src, i),\n", 132 | " destination=rasterio.band(dst, i),\n", 133 | " src_transform=src.transform,\n", 134 | " src_crs=src.crs,\n", 135 | " dst_transform=chip_info.transform,\n", 136 | " dst_crs=chip_info.crs,\n", 137 | " resampling=Resampling.nearest,\n", 138 | " )" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 6, 144 | "id": "bf2d1197", 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [ 148 | "def write_vrt(items, asset_key, dest_path):\n", 149 | " \"\"\"Write a VRT with hrefs extracted from a list of items for a specific asset.\"\"\"\n", 150 | " hrefs = [pc.sign(item.assets[asset_key].href) for item in items]\n", 151 | " vsi_hrefs = [f\"/vsicurl/{href}\" for href in hrefs]\n", 152 | " gdal.BuildVRT(dest_path, vsi_hrefs).FlushCache()" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 7, 158 | "id": "b2c0e75c", 159 | "metadata": {}, 160 | "outputs": [], 161 | "source": [ 162 | "def create_chip_aux_file(\n", 163 | " chip_info, collection_id, asset_key, file_name, resampling=Resampling.nearest\n", 164 | "):\n", 165 | " \"\"\"\n", 166 | " Write an auxiliary chip file.\n", 167 | "\n", 168 | " The auxiliary chip file includes chip_info for the Collection and Asset, and is\n", 169 | " saved in the same directory as the original chip with the given file_name.\n", 170 | " \"\"\"\n", 171 | " output_path = os.path.join(\n", 172 | " os.path.dirname(chip_info.path), f\"{chip_info.prefix}_{file_name}\"\n", 173 | " )\n", 174 | " search = catalog.search(collections=[collection_id], intersects=chip_info.footprint)\n", 175 | " items = list(search.get_items())\n", 176 | " with TemporaryDirectory() as tmp_dir:\n", 177 | " vrt_path = os.path.join(tmp_dir, \"source.vrt\")\n", 178 | " write_vrt(items, asset_key, vrt_path)\n", 179 | " reproject_to_chip(chip_info, vrt_path, output_path, resampling=resampling)\n", 180 | " return output_path" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 8, 186 | "id": "49e6644d", 187 | "metadata": {}, 188 | "outputs": [], 189 | "source": [ 190 | "# Define a set of parameters to pass into create_chip_aux_file\n", 191 | "aux_file_params = [\n", 192 | " (\"nasadem\", \"elevation\", \"nasadem.tif\", Resampling.bilinear),\n", 193 | " (\"jrc-gsw\", \"extent\", \"jrc-gsw-extent.tif\", Resampling.nearest),\n", 194 | " (\"jrc-gsw\", \"occurrence\", \"jrc-gsw-occurrence.tif\", Resampling.nearest),\n", 195 | " (\"jrc-gsw\", \"recurrence\", \"jrc-gsw-recurrence.tif\", Resampling.nearest),\n", 196 | " (\"jrc-gsw\", \"seasonality\", \"jrc-gsw-seasonality.tif\", Resampling.nearest),\n", 197 | " (\"jrc-gsw\", \"transitions\", \"jrc-gsw-transitions.tif\", Resampling.nearest),\n", 198 | " (\"jrc-gsw\", \"change\", \"jrc-gsw-change.tif\", Resampling.nearest),\n", 199 | "]" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 9, 205 | "id": "1b0e52f9", 206 | "metadata": {}, 207 | "outputs": [ 208 | { 209 | "name": "stdout", 210 | "output_type": "stream", 211 | "text": [ 212 | "542 chips found.\n" 213 | ] 214 | } 215 | ], 216 | "source": [ 217 | "chip_paths = []\n", 218 | "for file_name in os.listdir(train_features):\n", 219 | " if file_name.endswith(\"_vv.tif\"):\n", 220 | " chip_paths.append(train_features / file_name) #os.path.join('train_features', file_name))\n", 221 | "print(f\"{len(chip_paths)} chips found.\")" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": null, 227 | "id": "0cf703b2", 228 | "metadata": { 229 | "tags": [] 230 | }, 231 | "outputs": [], 232 | "source": [ 233 | "# Iterate over the chips and generate all aux input files.\n", 234 | "count = len(chip_paths)\n", 235 | "for i, chip_path in enumerate(chip_paths):\n", 236 | " print(f\"({i+1} of {count}) {chip_path}\")\n", 237 | " if not (chip_path.parent / f\"{chip_path.stem[0:5]}_nasadem.tif\").exists():\n", 238 | " chip_info = get_chip_info(chip_path)\n", 239 | " for collection_id, asset_key, file_name, resampling_method in aux_file_params:\n", 240 | " print(f\" ... Creating chip data for {collection_id} {asset_key}\")\n", 241 | " create_chip_aux_file(\n", 242 | " chip_info, collection_id, asset_key, file_name, resampling=resampling_method\n", 243 | " )" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 13, 249 | "id": "b8cfca1c", 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [ 253 | "hxu12_vv = gdal.Open(str(train_features / \"hbe54_vv.tif\")).ReadAsArray()\n", 254 | "hxu12_nasadem = gdal.Open(str(train_features / \"hbe54_jrc-gsw-change.tif\")).ReadAsArray()\n", 255 | "hxu12_mask = gdal.Open(str(train_labels / \"hbe54.tif\")).ReadAsArray()" 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": 14, 261 | "id": "b3dc0a14", 262 | "metadata": {}, 263 | "outputs": [ 264 | { 265 | "data": { 266 | "text/plain": [ 267 | "" 268 | ] 269 | }, 270 | "execution_count": 14, 271 | "metadata": {}, 272 | "output_type": "execute_result" 273 | }, 274 | { 275 | "data": { 276 | "image/png": "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\n", 277 | "text/plain": [ 278 | "
" 279 | ] 280 | }, 281 | "metadata": { 282 | "needs_background": "light" 283 | }, 284 | "output_type": "display_data" 285 | } 286 | ], 287 | "source": [ 288 | "plt.imshow(hxu12_mask)" 289 | ] 290 | }, 291 | { 292 | "cell_type": "code", 293 | "execution_count": 15, 294 | "id": "661720f0", 295 | "metadata": {}, 296 | "outputs": [ 297 | { 298 | "data": { 299 | "text/plain": [ 300 | "" 301 | ] 302 | }, 303 | "execution_count": 15, 304 | "metadata": {}, 305 | "output_type": "execute_result" 306 | }, 307 | { 308 | "data": { 309 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQYAAAD8CAYAAACVSwr3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAjUklEQVR4nO3deZhb9Xno8e97jpbZPONtxgweLwPYxDYBAw6EJRCgBEMIGJJcnGYhKa2TBtKk6RJok5ukLbekaQmFQlMn0Lg3odRZCA4QCAGMrwnG2MSA9wUvjLfB9tizaySd9/4h2ZZHmhnNjDRHkt/P8+iR9NOR9Ho5r377EVXFGGNSOX4HYIwpPJYYjDFpLDEYY9JYYjDGpLHEYIxJY4nBGJMmb4lBROaKyCYR2Soid+bre4wxuSf5mMcgIi6wGbgaaAJeAz6hqutz/mXGmJzLV43hAmCrqr6tqj3AY8CNefouY0yOBfL0uROBd1KeNwEX9nXw+LGuTp0UzFMoQ9ejcTYfOIWy6ginh48giN8hGTNkq9+MHFDV2myOzVdiyHQGndBmEZEFwAKAyRMDrHx2Up5CGbpt0Xa+0XQtb/1yBgcaY7g1Ub49ZwmfHHXQ79CMGTS3fuvObI/NV1OiCUg90xuAPakHqOpCVZ2jqnNqx7l5CmN4Tg9W8eDkp+Diw1Sf2saUCQepdVvz/r1RjbMyEmVbtJ24enn/PmN6y1eN4TVgmog0AruB+cAf5um78mqMW8FbFz46ot+5OgLfnP9HvPOhUfz0j/+FWaHyEf1+Y/KSGFQ1JiJ3AM8CLvCIqq7Lx3eVohmhHqY9uJmbKptoDBRmbcqUtnzVGFDVp4Gn8/X5pazGKeffJr6afBbyNRZzcrKZj8aYNJYYjDFpLDEYY9JYYvBJoQ5DHvG6OHvlJ3imM0xEozn5zL2xdlrinTn5LDMyLDH4YGmXw+zv3cF5q27xO5SM2lvLuX3J5/jolhs44nUN+/P+8/D5vNRdl4PIzEixxOCDC8LdTLl+O8GfjmXGy5/m6g0fYVes3e+wgMSIyKOX/oDKJocdv25kT2z4i+z+bOwbfKj8UA6iMyMlb8OVpm8VTogZ1ftoOzwJeaKSvRNHsaOxiskF8q/xvrDw0p//M5CY4DVcVU7ZsD/DjKwC+a948jm/cgdPn3URo7d5BDrhbzbfTMOowwCUu1EuH72Jz1Y3+xKbK05OEoIpXpYYfDJ/VAv3faCZ8hXVeIEQPY9N4G0moAKxcmHZRWdw+WUP0Bis8jtUcxKyPgYfHWgZReB366jc24M6ECuHeBkgUPFGOR994zbi6h27GTNS8rKD02DNOadMC3HZdb6tiUR4su0catwuFi76MKHDCskag7oQq4DImERCqJvxLq+c83Nf4twWbeetnlOYV1kYHaRmaNz6ratVdU42x1qNwUezw2G+Pn4jXxqzk3sWPIK6EOiEQJeCgtsFFXscKnc77N82nmc6w77EuaJ7Cg/svNKX7zb+sMRQIK4oa+XqBa9w9h1vIh44R+cWJbe8cbqF3dExvsTm4hEQa8qcTKzzsUBUOCG+M2ENEY0y8/LpVK8ox4klXms9M8aV567ntpp9vsR2beUeLjzjMcA6Qk8WVmMoMGEJ8psPPEBHg9JVl7h98qJXeHjyct9iqnHKbXTkJGM1hgJ0erCKtz59/7HnAVwsh5uRZImhQIWl8HbNNicP+xkyxqSxxGCMSWOJwRiTxhKDMSaNJQZjTBpLDMaYNJYYjDFpLDEYY9JYYjDGpLHEYIxJY4nBGJPGEoMxJo0lBmOKxEju/VnUieG+lqk83+X6HYYxI2L2fXcw/YXbRuS7inrZ9YHoKNpC5YBtUmpKX/ADB7lyQtOIfFdR1xj+oe4t27nYFJRL37yZs1d+Ii9V/lfPf5QJ4VZWRnJzseH+FHViMKbQ/GnjS7S/U830F29jb46vR3rdxnm88I+X8Hc7b8jp52YyYGIQkUdEpFlE1qaUjRWR50RkS/J+TMprd4nIVhHZJCLX5CtwYwrRJ0cd5OOXvorX7bI+WpPTzz78kwbiIaG2LP+15GxqDD8C5vYquxN4XlWnAc8nnyMiM4H5wKzkex4SEesdNCeV70xYA3Hhn3Zcy8NHTiGq8Zx8bvc4YdyqA2xsqcvJ5/VnwMSgqsuA3tcwvxFYlHy8CJiXUv6YqkZUdTuwFbggN6Gak8GaSIT/ah3vdxjDVt4UpPnxyXx38c2sjiSu5rUrlrg1xzuGlCw66z12X1PL985cnIeITzTUUYkJqroXQFX3isjRFDYRWJFyXFOyLI2ILAAWAEyeWNSDIyaHOjRItdvtdxjD9tQf/xPvxKv4+1s/xx277iA6SuiphniZ4k3p5scX/ZD3lw3uM71yj2ilw51bP0p1uJsfnvZz6tzKvMSf685HyVCW8eKYqrpQVeeo6pzacdbaMAlnhSJcUf6u32EMW2OwigvDUabdu4G5X1pO6A8OEGyHsgNCcEs5n3zidh5omTK4DxVwYtC87FQ2rGjkl+3T8jbhaaiJYb+I1AMk75uT5U1A6tVpG4A9Qw/PnGxqnHJqnHK/w8iJsAR5aOIK/qHuLR4/+xHazogR6FJCh2HMeuH+X13H9GWfGdTohXjg9kC4RfjHl67n3pZpLOuGphyPgAw1MSwBbk0+vhV4IqV8voiERaQRmAasHF6IxhS/hkAVlMepXd1O9c448bDQsDTG5O8HePDQRVn98kv8eIVcPCh/J8D3f38Z9+/+A55on8GGnk5e7vbYHO0YdrwDNu5F5L+BDwLjRaQJ+CZwD7BYRG4DdgEfB1DVdSKyGFgPxIDbVXPUJWtMkZP2AO72XZSFGzh8RjmdtQFC7Q7P/Nul3Pmt16iS/jsdnG5BPNBky9uJQXhjOW82TWP1KVN4ZPxFtK0dR+25+3n57F8MK9YBE4OqfqKPl67q4/i7gbuHE5QxpUgr43hTJhAZGwRNnOBeANSBNi9G1QD1dy+c3l0nSqIXzxM8z6Fyt+DNztTVNzg289GYEfL61ffz4M+/T8WXd+NGoKtWaJ3qcmS6srDlAlrinf2+/4G5i4iO4oTufPEg0CkE9wdp3TaaWAU0b6xl5u8+xbqeriHHaonBmBEyxq3g9GAVRyJlVO1JtrAFQkccfvTaxVy39tPcvPXqPvsbLi1rAQ8CyfP9aG3BiULoiFC+38FzoXyfg7uymm83XU+n1wPAy92DG72wxGDMCPuPGT+heY6DJM9VpwfKmkI0b6plzduTeehwI3M3fpglHRVp73Vi4EQzzgAAEjUIdcBz4a3fnsny7krW9XTx9W03DSpGm1lkzAg7O1TG2HPepeOFxLxAUXC7IBx1iHaH+Le1lxN8vYonbjqPGyqXH3vfj1un48QSJ/5R0itHqCTKVCBWoXzxidsIHTqehLJlicFkdN6qWzi8YzQaUt531jYWn/a83yGVFNfxTqivi4IbBfeQ4LVWES+HcjfK53Z9gD+ue4kpgU4efuB63ABER/XduSia6IIQhdBhAU2MZPROIAOxxGAyumziNt4on0jYjXHxmG1+h1My9sbaOeS5tHeHk2dwhoOSfQd7uqrZs/B0/m7zVDomV6AThHjKiKamvDfTiS9HJwpIH9OP+2GJwWR0X/0qqF/ldxglY0NPJ4e8Mv5u+3zefm0SoVbBkeNV/1TiJfodNj43DZkEnRNGAckmRB/JILUJkfq6CoPPClhiMGZEfG3nzex7pJGOU4UQ4PQz7U8U8EASAwp4geyaAv0mh0GyUQljRkjlvihlh/SEjsC+TnjR4zdInNz9neCpx+aCJQZjRsDXJj3NpG9tpuUs74TEMNAJ3/u1gY6HPvobBpk0LDEYMwIuKXP4rynLuOJ964ilbKEwmBO2d59C7yTRX2fkYJsTlhiMGUELJy2j54yuREdi8uTNlBwy1QyO9iFkOumPHpuaMIbSt3CUJQZjRpArDi9e9gDRKj02LNlbXyd0akdianJITRapfRPD6XOwUQljRliFCLFKxYkJbndyGnPKCd9XAkitFfSlr8QxWFZjMMYH4iUnIPUxnNjfL34uRx/6YjUGY/ySoxN8OH0JfbEagzEjzEWIV8WJVeqgRyWknw7LXLLEYMwIc0QIVvcQq0xf8jiYX//+kkPv0QkbrjSmwLkIp447gozpOV7Yq9OwvxN6wJO9jz6LwbDEYMwIq3LKWHrWL/nq+b9FYin7NpI+OpHtlOkTpJYNsf/BEoMxPmmJVRJu0WPLo7Ode5C2GjOLJGFNCWOKxM6ucdRsjxx73te6iP76C4aybiIblhiM8clVo9ez5wNliZM9uddCpvUOmSYrHXsPffc5yDCaFJYYjPHJ/FEtzLt5OZFxSqxSiYeye182/Q5HZ08eSxa2tZsxxeP/THiTyTce5Ol338uG3afgrK1AYice07vpcOzETzmmr6XWmXaIyobVGIzx2RdG72bJtGe44cw38YLpTYMhjUykHAMl0vm4MhLlD7dfwdKu4+F9vukizn1tfs6v6mtMoYh4weMbuB4lJ9YSBvPrn82iq74UZFPiqdbZrP3FDP7sA6dw7ZQNtMXK+M2q91K+N8ChcwI0+B2gMXnQEQ/hRHutqCTzpq+9H/dlqE2JgkwML+6bzqn/upL2nefzqzMvJtwCo4FYBXj5WDFiTC+rIz1USIxRjpe4hH0e/cXe8/jVlrOIvVtOZYY5CkdlOsmHeuIPpCATw5mjm9l0/XkcPMulu6GHSG0iTC/sMcqJAmF/AzQlLa4en/7hV+hqiDGx8QDLh3lJ+f7M334lW//zTGpblc5a54Rt33rLNLFJpe/kUHIbtfxg0svw0Mt9vJrf7G0MQOVeJdgRYH/bBO5tOI2vjn07L9+z6UAdFUc8Wqe4Q56+DAN3VJZE56Mxfnquq5zqHT0EupRAh7A7Mjpv3zVp9GE669zEmTjAvo19zoC0/RiMyb9d0XEcPiNEPCxIHA5F+6nfD1Oh9pkNmBhEZJKIvCgiG0RknYh8OVk+VkSeE5EtyfsxKe+5S0S2isgmEbkmn38AY3JtQc0efv2NfyYyFgJdsGb/xLx8z3cPnc7eR6cSD3PCbKVMG7pmmz/620h2MLKpMcSAv1DVGcD7gdtFZCZwJ/C8qk4Dnk8+J/nafGAWMBd4SETcwYVljL8cIDrKI1YGkWh+uuKiXiCxEexwzw4/RiVUdS+wN/m4TUQ2ABOBG4EPJg9bBCwFvpYsf0xVI8B2EdkKXAC8kuvgjcmX8W4lb95yPwCuCBDM+XdMCB6he7zg9PSfHIa6q9OIXVdCRKYC5wKvAhOSSeNo8qhLHjYReCflbU3JMmOKSoUTosIJEZbcJwWATi9MoCMvHz3sDWKzTgwiUgX8HPiKqrb2d2iGsrTKjogsEJFVIrLq3YP9XPrXmBKmTu5qC0ePH+oU6lRZJQYRCZJICj9R1aOzPfaLSH3y9XqgOVneBExKeXsDsCftD6C6UFXnqOqc2nHWBWFOPl8cvZ1z5q9N/JQO8Re+d0dl787KodYcshmVEOBhYIOq3pvy0hLg1uTjW4EnUsrni0hYRBqBacDKoYVnTOlyxSEo3tB2cu5jzkOmJdpDkU136yXAp4G3RGRNsuxvgHuAxSJyG7AL+DiAqq4TkcXAehIjGrerqrUVjMmg3I0SLwOnB5x4/1esPsEQr5KdrWxGJZbTd0Xnqj7eczdw9+DDMebk0hUPEuhKKUj9xSflOpZCXoYl+2IzH43xSVw9VuyegtMDHL32jB6/nfBL3zspCMPqmxiIJQZjfNTdGaKjwSNelvn11BGGE19IuR3Vx8VphqIgV1caczJwxWHzlQ8DMO25P6Fy/fHtBNImKmVoShxrZhw7MPP3lMwOTsacLFxJVtp7VQnSagoZNmjR/poSR48fYt+ENSWMKQBOQDNecKYvWY9Y2AVnjClifZzpQ7lSdS5YU8KYQpA8+zPt6Xj0vs9rU9pGLcaUKNFBn+ADXul6oGP7YTUGY3y2OdpBvC2YqBX0em1QJ3SOkgJYYjCmIIRGR9BAEPpZPJCpOSG95jLkajt5a0oY47PpwUpWXPx9ekZ7/R6X6YTvvWiqd9lQWY3BmAIQFAcvNPBPfaaTPnXr+AE7K7NkNQZjCsDP2idTtn/gfUmGs/nKYFhiMKYAjHY76WqI4blkPSmpr6HNXLDEYEwBmFfZzusfvg/mHBlw2DKXfQl9scRgTIEY41Zw/+zHUId+aw3HmhMZEkOumhmWGIwpMP0ujko9Jo99DZYYjCkgQYnjheizr6H3LtAw/B2hM7HEYEyKFd1x7j10Gs3xPF3wYQBRdQl0gNtDn02F1ASQKRnkIklYYjAmxR8+9UV+e/lUHjx0gS/fP9rpon1alK7aEdzgMQNLDMak+On1DzBv+Ua+NNafKx6cHw6x/SM/4NxLN2d1fL5GJmzmozEpzg+HOD+8B6j0NQ5HNKvZi6kXmMllH4MlhiJwINnerZAgFU7I52jMycASQ4F7udvjW5+7g8DhbjZ+uZLtc3/od0hmBIScGOqADHCppj53kR4mSwwF7OvN7+Xp719K3YrX8SIR3Jb3+x2SGSHd8SBOFkkhX07azse4esS1/2WuI+2b787i5e7jMb24bxq1338FjUR8jMr4oTMWwomSfu2IEXLSJoZnuip4qrPK7zBO8LP/uZxbf347nV4PkDKMLYI7uoZ4Tcy32MzIur7uTdqneHgBMs5n8FzsSlT58N7QAWaHm/0O4wSdU6LUv+LxZGctf7P/bHa/Pf7Ya80fn8mauQ/4GJ0ZSV8YvZvqxsMZV1B6AeicFKPrFI/uWo94mBNqFrZRyzBMDhRWbQFg+0d+QPx6j5cjDm9cdyrT97127LV4UKhxyn2Mzoy0rkiQ8laIVXD8J1zAC8G5Z23HU4dzRjfxX69cQsXOAOKRWIAloMqAfRT9OWkTQ6E6emUi9bzEvy6AKqL+zoQzI+837/93dsyp4o9+8QXKmxP/L8SDWJkyt3YdN1dtwUV4tPp9RMY5hA85dE6N4lTE8NqDVL099NPbEkOBa/nsRejHDnLpKav8DsWMsMmBKsY63bhdcryZ4EC8wmNu5WbGu4la79+f/wQbZp3KkoWXc86srcyrfZ1fvnsea7fMQAfeFCojSwwFJqpxPr/6szR27QTg8Htg83mLfY7K+CWOUrFXiJenNBNCykS34tgx80e1sCa0j0cnXcZnJyznQxVRxrnL+OLY91DZBN1jBRnkAJwlhgLT7kWYco9HvLUVd3QN0TE2EnEy81Sp2Rmle4xL5wQHLwhudc/xi+EmzQ6H2fKZfz/2/KryOBVnteDtG0vXpBhO5+DGGSwxFLDOS6bzvllvs6wbLivzOxrjB0eElumJi9EEOhQV4cYz38zqvSvm/F+6z48RxGV5dyXX/vkgvnegA0SkTERWisgbIrJORL6dLB8rIs+JyJbk/ZiU99wlIltFZJOIXJN9OMYRoWdMGYFTJlC5ehcdHwvwlbW3+B2W8UmNU84bf/UQf7lgMaE2JdSmRLPsOAhLkBqnnAonxKVlg9tfQnSA3m4REaBSVdtFJAgsB74M3AwcUtV7ROROYIyqfk1EZgL/DVwAnAr8Fpiuqn0Onsw5p0xXPjtpUIGXstWRHjr0+GKp9wQ7qHP9Xe1n/BXRKJuicVyUKQGhyhl8FdKt37paVedkc+yATQlNZI725NNg8qbAjcAHk+WLgKXA15Llj6lqBNguIltJJIlXsv8jnNzOD/deQWlJ4WQXliBnh4Ij9n1Z9TGIiAusBs4AHlTVV0VkgqruBVDVvSJSlzx8IrAi5e1NybLen7kAWAAweeLwujqWdjm82D6DiaEWyqSHW0btJSwj95doTKnJ6oxMNgNmi8ho4HEROaufwzNNyExrr6jqQmAhJJoS2cSRSUu8k7t33MLWXXWcNuldKoM93Fj1OGEJElePjdEIFRKnMVh4Mx2NKVSD+qlW1cMishSYC+wXkfpkbaEeOLrwoAlI7TBoAPbkIthMFrXOZPcLk/jM/3qJr49/EwfBlcTU4YNeFze98kUa6w7y7Iwn8xWCMSUnm87HWiCaTArlwG+A7wCXAwdTOh/Hqupfi8gs4FGOdz4+D0zLV+djS7yTN3qqOCvUxvheHXRWYzDmuJx2PgL1wKJkP4MDLFbVJ0XkFWCxiNwG7AI+DqCq60RkMbAeiAG395cUhmuMW8EHyz0yddC54jArlN+FR1GNE9HokHqJjSlU2YxKvAmcm6H8IHBVH++5G7h72NEVge2xbnZER/OhiqjfoRiTMzbzcZgaA2U0uB2AbdJqSkfRbdTS6fWwpKOCDT2dtMQ7/Q6HoLi2c7MpOUWXGFZGyvjm9z7LX2z/GM92pk2PMMbkQNElhh51ceLKxePeZmrwgN/hGFOSiq6P4aryCE/+7XcZ75bj5GsnTGNOckWXGFxxqC/A/RqNKSVF15QwxuSfJQZjTBpLDMaYNJYYTMla0R2n3ev2O4yiZInBlKw/vfdL/Lj1dL/DKEqWGEzJciNKVItu4K0g2N+aKSlRjXPmb/8EpzlMbbtS4w5uE1STYInBlBQH4YozN7N3cjUbxp3K9NB+YIiXYzqJWWIwJcUVh4cnL088ORMsKQyN9TEYUwAePnIKzfHCafZYYjCmAOzqGUf3IK9o3hRrH/igIbLEYEwB+HbtOiYPYg1QRKP86PAconnaNdESgzFFqM3rYdGvr6Ddi+Tl80s+MRTKTk/G5FKNU8adNzxOlRPOy+eXfGL4yeELWR+1HZxNaQmKy201+whKfkZdSn648hu1rxOwIStjBqXkE4Ndw9KYwSv5pkQhaoq1F9SYtTG9WWIYYe1eN7es/wx/tusjfodiTJ8sMYywKqeMZe/9GY81vuB3KCXlQLyDxiULWHjkVL9DKQmWGHzgiv2151pUFbfNpUx6WNZN3ib+nCzsf6gpCa4IXtjj9Y6pvNg20xLDMJX8qMRQHIh38L5f/TmBVpdpF+7k6TOf9jsk048ftdbx/w5Px+10eKnpDC6o30mnRqmw64kOmdUYMhjjlDNr5jtMfCnG9gPj/A7HDOAfXr+OlT87m3CLEP3dWJY+O5t56z6d10VGpc4SQwauODx02k8J/uU+vnn2k36HYwYQCsWIVQACohBqEw6uOIU7tn/U79CKluggl3rmw5xzynTls5P8DsMUqdWRHjb21PP1l2+iamMIFNSBrgkeY6cf4vYzlvLZ6ma/w/SdW791tarOyeZYqzGYond+OMTHqvZx7XvXogJoouYQPuTQsnEsv9x/ri2kG6SsE4OIuCLyexF5Mvl8rIg8JyJbkvdjUo69S0S2isgmEbkmH4EbkyosQW6vfZGOM6J01yooODEItThsPTieQ57nd4hFZTA1hi8DG1Ke3wk8r6rTgOeTzxGRmcB8YBYwF3hIJE9LwIxJMStUzvYP/4CLLluHxEnUHgQcx7Oq8SBl9fclIg3Ah4EfphTfCCxKPl4EzEspf0xVI6q6HdgKXJCTaI3JQlA8vCDEKpSuiTGumbyRyYEKv8MqKtkm0vuAvwZS62MTVHUvQPK+Llk+EXgn5bimZNkJRGSBiKwSkVXvHrTJKCZ3wm4MLwQ9dTE+duFrzBu92mabDtKAf1sicj3QrKqrs/xMyVCWNvShqgtVdY6qzqkdVzotjQPxDg7YyklfBSROrEIpH9fFX9Uu59xQzO+Qik42Mx8vAW4QkeuAMqBaRH4M7BeRelXdKyL1wNHxoCYgdeyxAdiTy6ALUbvXzauRSv5k+ZcQV3nxsgcGtbmnyY2nOst4csV5UO0xsaaNOrfS75CK0oA1BlW9S1UbVHUqiU7FF1T1U8AS4NbkYbcCTyQfLwHmi0hYRBqBacDKnEdeYJ7trOOr93+empVleF0BDsVtgxg/7I6OJXTQhcoY9RWtfodTtIazVuIeYLGI3AbsAj4OoKrrRGQxsB6IAberlv6KljavjKo9cbyAEKzqocaJAvnZqNMkrOvpYnowRFBc2r1uPrrpY3REQ4y/cB8Now4zr/Z1v0MsWoNKDKq6FFiafHwQuKqP4+4G7h5mbEXlwrIdLFqwj4Dj8an6NUxwbQFPPh3xuljaOZ2G6s3USDltXoxdyybTXR/jybn/SlQdZoctMQ+Vra7MkRmhCl6c9URKiSWGfDnidfFkRwPN0epjZfWBKtYs+FccHIJS7mN0pcESgyk6v49UsqHrVFw5cTajbfybOza4a4pOHCGqpTPEXYgsMZiiMyfczhfGLmd8wPZbyBdrSpiiU+OUU+NA2In6HUrJshqDKVp1gVaCdpWxvLAagyla8yrbsdGf/LAagzEmjSUGY0waSwzGmDQl08dww5a5rF/ZiFfhsewj/0KDrWwsSSsjUQ7HE5uuXFzWRpVT5nNEpalkagzrdtUzcVmcut8Jv+tO2xfGlIhaJ8IpgTbavHK6S39tnm9Kpsaw7ar/hKugJd7J53d+hI9WPme79pSgxmCiJnh2qBWwvRbypeTOnDFuBf8x5VeWFIwZhpI8e8a4tvGnMcNRkonBGDM8lhiMMWksMRhj0lhiMMakscRgjEljicEYk8YSgzEmjSWGHIurR3O8gyNel9+hGDNklhhyrEt7ePDQBfy641S/QzFmyCwx5Fg8/fq9xhSdkllEVSgqJMRN1a8nL1FnS79NcbLEkGNBcZkddrHrVppiZk0JY0waSww5EtU4e2PtxNUb+GBjCpwlhhw5EO/i4cNzaPG6LDmYomeJIUfq3Aq+MGY1/9P2Hn7SVud3OMYMi3U+5ogrDuPdSq6s2ERIPGxEwhQzSww5NiNku0eZ4mdNCWNMmqwSg4jsEJG3RGSNiKxKlo0VkedEZEvyfkzK8XeJyFYR2SQi1+QreGNMfgymxnCFqs5W1TnJ53cCz6vqNOD55HNEZCYwH5gFzAUeEhG7JLExRWQ4TYkbgUXJx4uAeSnlj6lqRFW3A1uBC4bxPcaYEZZtYlDgNyKyWkQWJMsmqOpegOT90TG6icA7Ke9tSpadQEQWiMgqEVn17kG7opAxhSTbUYlLVHWPiNQBz4nIxn6OlQxlaUsOVXUhsBBgzjlltiTRmAKSVY1BVfck75uBx0k0DfaLSD1A8r45eXgTMCnl7Q3AnlwFbIzJvwETg4hUisioo4+BDwFrgSXArcnDbgWeSD5eAswXkbCINALTgJW5DtwUnpWRqE0HLxHZ1BgmAMtF5A0SJ/hTqvoMcA9wtYhsAa5OPkdV1wGLgfXAM8DtqnZZ4lIX0SjfePsm2jXidygmB0TV/+a9iLwLdAAH/I4lC+OxOHOtWGItljghc6xTVLU2mzcXRGIAEJFVKXMkCpbFmXvFEmuxxAnDj9WmRBtj0lhiMMakKaTEsNDvALJkceZescRaLHHCMGMtmD4GY0zhKKQagzGmQPieGERkbnJ59lYRubMA4nlERJpFZG1KWcEtMReRSSLyoohsEJF1IvLlQoxVRMpEZKWIvJGM89uFGGfKd7si8nsRebLA48zvVgiq6tsNcIFtwGlACHgDmOlzTJcB5wFrU8r+Cbgz+fhO4DvJxzOTMYeBxuSfxR2hOOuB85KPRwGbk/EUVKwk1s5UJR8HgVeB9xdanCnxfhV4FHiyUP/tk9+/AxjfqyxnsfpdY7gA2Kqqb6tqD/AYiWXbvlHVZcChXsUFt8RcVfeq6uvJx23ABhKrWAsqVk1oTz4NJm9aaHECiEgD8GHghynFBRdnP3IWq9+JIasl2gVgWEvM801EpgLnkvg1LrhYk9XzNSQW2j2nqgUZJ3Af8NdA6oKPQowT8rAVQiq/N4PNaol2AfM9fhGpAn4OfEVVW0UyhZQ4NEPZiMSqibUys0VkNPC4iJzVz+G+xCki1wPNqrpaRD6YzVsylI3kv33Ot0JI5XeNoViWaBfkEnMRCZJICj9R1V8UcqwAqnoYWEpiy79Ci/MS4AYR2UGiSXuliPy4AOME8r8Vgt+J4TVgmog0ikiIxF6RS3yOKZOCW2IuiarBw8AGVb23UGMVkdpkTQERKQf+ANhYaHGq6l2q2qCqU0n8P3xBVT9VaHHCCG2FMFK9qP30rl5Hokd9G/C3BRDPfwN7gSiJTHsbMI7EhrdbkvdjU47/22Tsm4BrRzDOS0lUB98E1iRv1xVarMDZwO+Tca4F/neyvKDi7BXzBzk+KlFwcZIYxXsjeVt39LzJZaw289EYk8bvpoQxpgBZYjDGpLHEYIxJY4nBGJPGEoMxJo0lBmNMGksMxpg0lhiMMWn+P6hvDNPz+MY1AAAAAElFTkSuQmCC\n", 310 | "text/plain": [ 311 | "
" 312 | ] 313 | }, 314 | "metadata": { 315 | "needs_background": "light" 316 | }, 317 | "output_type": "display_data" 318 | } 319 | ], 320 | "source": [ 321 | "plt.imshow(hxu12_nasadem)" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 16, 327 | "id": "9e94debb", 328 | "metadata": {}, 329 | "outputs": [ 330 | { 331 | "data": { 332 | "text/plain": [ 333 | "" 334 | ] 335 | }, 336 | "execution_count": 16, 337 | "metadata": {}, 338 | "output_type": "execute_result" 339 | }, 340 | { 341 | "data": { 342 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQYAAAD8CAYAAACVSwr3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAEAAElEQVR4nOz9ScxuyZYdhq0dEeecr/u722S+pupViXQJtmgYkCHTA00MCIY1MEBPZFA2DBkgwIkk25AHojzxiAA94dCDAiyYA8s0ARuQBgIEmZBhCLZI0TIBoUhTLLP0+LJedrf5m685TURsD9becf581eUV3pNvAnmARGbe+/9fc07Ejr3XXmttUVV8f31/fX99fz2/wv+/P8D31/fX99fHd30fGL6/vr++v/7A9X1g+P76/vr++gPX94Hh++v76/vrD1zfB4bvr++v768/cH0fGL6/vr++v/7A9SsLDCLyz4vIPxCR3xWRv/Srep/vr++v769f/iW/Ch6DiEQA/xmA/y6AzwD8xwD+RVX9e7/0N/v++v76/vqlX7+qjOHPAvhdVf1HqjoD+OsA/tyv6L2+v76/vr9+yVf6Fb3ujwH87Nn/fwbgv/1H/XDc77W7fdH+XypQE4AASAGgAARQ4f9rBBAUkgUq/DtR+zHl7wMAKqCd/b69hlT+t/+MBnsv4Wvy94SvJ0BY7DPYpQmovb1RFfvAz7IulfZ3UtfPDcDCsH2Qim9eyo/Q/lz42QC+vyj/X8N6D0K2l7N7psL30GDfNdtHies9AwTivxfW927vafdBinzjs7R/6/r6/lX8HkgW3ivh+/mzaff1eXJqN0WKffZo36366+t649Reo9rr+3fUZ89T15fVwf4nCxAUYZL2vP1la7Lfef7oAu+phm9+x/Yc7T01fvN32/O112/38fnvP/s9v8dQWb/v83Vr605lvR8af+FZ6Lou/sAz8e8Jf+58rfmzz96o6mt8i+tXFRjkD/mzb9QsIvIXAfxFAOiu7/Cn/8f/Gn9LuJDLVrkB7QbUxC/ZnQRhBi6fVkgF0knapqgDf76/l7ZxysDXLBtFjcDwTpDOAAIwX/G151uurDgJ8k6hAYiToOwqwijY/yygf1KUAbh8IliuK8p1gYzB7r5AuwpRsYekiKeIdBbECYgjkLfAcqMog0KHClkEYRZoAIY3AQhA6RXpLAgFyBsg7+2zjMD2a8F0Cyw3FWES5EPF9vOIOAF5Z991A4TJNpgtwDjzHpSNQhMgiwdPbvzluiKOvIe1572v24p0DAgz2qqvnUIKkM78//lGUXYVmhRhDNBecfW7EVA+h2UPTK8zACCeIrTzyA3+t22CdAzoHgX5oIgj70ftFbXjd6kdP2++roAC8RxQ9hXxKSCd+bnn24rtV3wW00vFP/Hf+hn23YT/9//nN/Hjn7zF53/vE+x+HpBGoDsqSg8sB0HI6/9r4JrRZPegs396Rf/A5zrf8h6WgWtluSnAUBHfdgiF9z2dBDUp8pVCO4XMwrXUK9KPzyj/eI+6q9DI+9G9j3bYKOSTEfrVBukoSCd+vnTiul8O/v4M2uksfNaJB0A68z7NVwwm0e5d2XJPpAvw9/43/9pPv+0G/lUFhs8A/Pqz//81AD9//gOq+tsAfhsANj/6da0dP3yYucABQTrxi5WNog48kfJWsTkK9p8FLAdAkyJvuQE2b6QFFSmCajcElQtVKrBcK0IRlAGYX1TEsyCOgCZBOgpqAsquoiYu2topxteKvBNu1KTMMIowEqcKmQIk85iIExdG3VQsnSBnoDsG5I2i7Lkg4lMEgqJ2inRiUEBlMGqZUWWAyzvFcs2A0T8CtRMuul4x3yi2X/Hzz3eKvFWkEz9D3iqG99w4YWZAxbOTOR8YTLZfBf7/FogXQLeKeAyQBQx4SdupHqc13mtinJciiLNAF77XdMu/KxsAPSN2uc6QOXwjIIQSeC87hUbbeNfcTHVTEQ4L8lOH/i2Pyu3vR4yfVOSXC+QSmU1Wfgfec/AQycBUEj7dPQIAfv+nL9Hb4REv/MwagP5JkTeC+cYCn52sNTKwSbH1+CTIG75X98R1k7f8HrIIM1IwqMdRUDv798AlogHI+4r0+oLXN0f8/tUG6CrCY2Jw8KSoU56LdmAAfG4hK5C5HzSJBX9mtLW3Q3MAiq7r2w+TdBbIAnRHYLn+sA38qwoM/zGA3xKRfwLA7wP48wD+R3/kT9sNjKOi9oJ05tHiJ75HYqk8RfNBMLzlQlpu7NR6F5k6C0/DmhRBBDnxhokCGhXpErAceCKhAvlQeQpteQp0jwJI4EFpDx/CjQflzS6DQsYADQrRAFiap7GiIDANBFA3FZIFZVaEDGRhwAoLkG8UuinAMaD02u5DnKSd9N2jonYCpIq8V0AEmoAwCmSJKPuK5Sqif0RLRUMRLFfa0te84akC5WsuB6YSGhQiXOhh5j91UGYrO0Wwja4KnqiRWUP/wAAJgKVcRLvvl9eKsuPGAACZIoNRUuie9ZicmFXIIqh9RbmqWAoXeiiAVkE8RyyWHfDUq6h9QP8uYFk6lgcLvw+UWeByxVsYFsEX91f4ydU7/kFUzK8LQkkIWVB63ueQ+b38NSC8N3G0jBLPyjMrPTTxkEpnsewpoBSBRrX1ZSe/BWONVqYCyFPC7eaCn28z8NTxnnQKHIF8KHz2v7eFRiCNVsZ6Weblo5UKea/oHrk//Co9y4/uyOcTMp9Bd+Z3rR+4038lgUFVs4j8KwD+PXDb/Juq+jt/1M975C+DoPaA2gaYt5bCVq//pJ2icbb3StywTPH4c2WjWO4y4jEiXmTdzMpUevy1AsmCdArI0aJ15Ybo3/MELj1TMY1MB2uviGcGif6emUTtLPUdKuLIFBdBW0mT7iPKVeXGzODpYA8znAN05sbyLKFsbVM5tuE1Z/YU2wKH4SsLmO53R36W05Vivq4twLCEYuorAErmYo2jnTKB2UDeodWnYWFAy/baUrhAq22QvFdmHRHQ3u595P2RzPJLIwMrA6esta9twDDZZsrC+lJ54nrQTGdBOicr6YC8Dyg970//INAoWA6KvLGM0F57vqkY3gWUf3TA39LfZPAeKqRwI0sGdLem5883fhxhu3HNWmvin2vgfckWIFEZCD0AarDgWAAEgVSWDrIIxJ5V+P0Bv7P8GDJGhEtAuSqQwueKAMimIG8D98Ii6J4sS90J4kUhymCNwENv3RNAd7L1NiqWnSBeGNT7B0UZBPMN7+OHXL+qjAGq+u8C+He/3Q8zcjsukHfrxtDIhe0ASyh8AKcfW31VuFHCwkUyvWAqhY4LrXvizQ8za3dNQLgEaGS2ALVA5MBX4oIIGSi2+JdttRQgtAXFgMUHkM6GNRS+T+2Z6suRAUAq+PAzF17ZsSRBEdRBW+kQFp5aDFJAvLZFYIEvB0V3YtoswtQ2FODpJ7D3rMAi6N9H1uU7O8HUPq9w4w3vgMsnQJwZZGuniBdBKKxb+7cRZcssR+zkCVWhVncDDB4Q1shhZpajHVPjurXjTQHtKhAVmAMQ+BlrtSyrArIExMmyqL2ipPU9GPzXZ1N2irJRDO8CNm+kYVLLNTB+mrF9fcbY7bH5KmL8eoswC/qvOwa7BMw39joDX18KbN1wE0oFSgeUK96vvGMWOb8skNmCxiSIi2B+xcNFFoFkQd0ouqfA1L5TlKuKeAqIF8ueKhCeErPXAv6d4TXxKQLXM+oLoM4B81NAjXy2kol/AMBwr7i8lpZJSGXgCjMzbQA4/Lyg9ILpNrTvVDv84ajfH3P9ygLDB1/PEG7fJJps8e4VSAqtQIWlnVnQP7BW7l5MKKdtA5AI3vTtNfNeUa4Kwj3Ljd0XLCcI2nHhla4yQFhZUDumqNOLgHJY2xLFggnA91Hw4QEWpBIzCig/pxSL9AIoDGQcGBTCLIAo6lWBVkG4BIjdg7LVFhhlEeRDQZgCvKGgkcEwLIKQCUbKHFp66SfY8J7lwuUnGWGbIZ9tkPfrPa/JgEjhqV0tMHqt6xsW4AkpmRt2RETZVYKatslZ4wtkZrsjLIJ8mw0PIECLJUC3TIXkEhgoer4P62bPQgDtgM6Cub9/3lXMNwRMu6NgfKnI1wWIisu7LYZ3ESrA8CaynFzWQ6am9bDhBl7TbLUAs1zVdm+ggjAJunexlWN8zkAYA2pfESpxGO0VddQG/IazZ1wGaBt4y5LMMswNUHcEUvNjz27QGNb1lIkxLHtb8/48DsQSAKBsePjFmc/g/DoCAkx3/Jzd0bKF72RgEKbJYeH/pjNPOxWm/nES5K7yZ1RQI2ssqfaAKhdi3ltEn9G6FMtesVwpkCo0RGYgVrc5wk7g3R5kBlJmqkrcAYBYmSCATAIdCNABzGDSSXjCzkyRl2tFOgHxKKgHLvY48uFmb6UBKPuC7j5CL5EnMCw9FUUBmEldBDIoyp6bLkwEuFoLqwL9PRCWgPE1uyUAMLzl56u+aVPF4TBiXDbEMCZLr4uDrSy54kUQ/TSyjod3CsK8LsB0EmhgxpO3FZvPk6XefB0vw7IK4pBRpgAs/EwyBwtsgmKbdzEUv3sfWnDOVxXLAZbqc1NsThE1seMR5oR0EdSeAKoOFXWwzk9AWyPMOvnvdEILjOkCpBPT7bJlFyR2PBzimd9VKpBG7+Awu1Oxv79EZgBZkPd1bQ0Ln3cZeDAQvJUWGKQywJYNoNuCUkCgdg4Is2FpBwAByEFaoNC0HppQPgPAvl8PzNeGL1gA8c8vhhN9yPVRBAYNfHB5Awz3/DP/QhUWOceAdBFGdLFW0kCwZbrvEYRgZJzsdLIefe2tVj9HdE/2gG+0ATVqQaIWos0h26awVl06M+pLFminKNtKcNM2ClN2bYuXwaggV5YXy3UFqjQwKF4EZU9QEgvLjO5RkHNorzdf8fXKTqFW50u2RZ5sQ22IeaSLoiZZ+R6JO8EX0HTLtq88dji9u0E/MhWt4ILqjoJ0jogz72m0EzYsbH0tB9tkPzlhvN9g/7sdQuWmKhsGgGBtWWZsDtIC4yveu/pmQBqtbIqsvUMJEAW6B+JApQe0MoPLnSK/WiBJoU+JALAyA9FIDKB/Zyfjy4LukwvyEoHM9FkHBtk6JZSRG2q5rszQgn9Wft/Lp9IChkZmDPEc2uabr9miVOMC+O9y87KD0n8dma4rUF4sCI+pHRIqaG32vFlLIQDQosDbDnVnGVSWtraHd1i5HRmNcyLFMtk7rpHhPTPL+Ya/m3eK0Cn6B2YeGoHhnWJ89WEpw0cRGGA999oxejs5pkVH4aKQzH/iTOQdQdG/DwgXQTlU1vMlWE9eGw/gOeEH+CZpKWRguWJ67z1iT7taZD5buj2KtSVhZQLW4LBXQHlapafY0kgIoLuCxWqAMAvboMZZAAxRnrm585afIx0D8k1t+Eg6rZ0TR70dCdfEjRonQZ1484pxQLQD8nWBzIGb1JB4D5ya7KS8OFDJxRYW3q984IId324BkL+QTusihCi6Y2AnpFj5sHNcRBEuDNL5hbGtLAA6+Ng9MdsSAP2bAE0MVggdyraiewiYXxRoZJkUFkFcAAiDow4V87FnC7MYHnIhb0KDQjtmmOW6QN6l9ly9dGj/n9hVgbJE8WeqicFcDZTMVwYQV94zVAY4voYCE3GGfLAgWARlXxAKcRsEtpX7B2lt1jIFlAtLtzqwNV82fI/uqA1jcJDYu3SeYWvgM/SWt//5cs1A1j2t2fi3vT6KwCDqaY/1aS0Y1ATAojXUSE+biu4YsXyagaQoY2dkJLS++Hxr6dRsi6dbTwFmItzc3ZPVbwvQzYK8QyP6eNpcegaGMliZodYhMHDT+915y4VUhwpNgppYU2tQwNLmMK/Al0Yu8hqVKeNVRbSAoUmRLgJNATXZAqvMbtKJQTEZ/6J2bO8uB5YB+cBsBoGneRwFKrEx4djf5vvnrYO9ijTy89WOGyBNyqxgGzDfgCUP2PEpG+MDdBWbLxNqsr6+ZUUOdqnAPqdg7BW6I1WvdrwfNSmmFwx2qMD0qjIY3LOWcPAuTAF4NWHqO4SJf9bAziwIpwjtrf2rAmQhAco3dBHIJbQN3cowhQGsfO7dSZArcPlRRhgZSJ1bI8qylCQsA2KflU5SWOKVwuCmlbhDuAhkCcgHkuXCTGKWJmDZ8vDafMXyaXlRQIYntyXLoGf31HgWAFZMpltZnemylk/9PTC9YMYDlQ9uV34csmtd+8Qa+ADylje/7KwvXMBNZmVHfIqI94np/yTYfp4wvCPxRQ8Z5VAa2QdpbYW1NmcAauLmGR6s1t4yqOQNcYkyMPOYXvBzLNfaugQENa2m3XhwE2AgiSnMgngJzFQu0TIiA9cAbL8I2H5BglL3JAijWBkEdI8R/YN9X/DE8hbkcs0ede1YKzfUGZbFLHYSRZ52sKyrDMosasfPq8KyLV6wYgLWMj39SDBf8c/SWe10LShbAo3VwMPuMRLE61cMwPGBsiW/xLOZ4evIFPscW0lWtxXlNqMMxHPKFUHEfCCrtWwV06uK/9o//VP8q//N/wDd3Qi9XbC8XtpnCSPJZWEUhEtEOAekx4A0skUN4VqKY8DwHoizNkJX2Si6RzuUCk9WKICBeAFZq5bVDZYVVg/oaBnSdKfEpAbDgWZntRro+GLCp3/6DdddZNZF4pMivB6xXDPTRKpGnONrhWwHzo73NI7M5pYrRT7w2cRR0T2xXMxbBn1mj4rhPbOvkPENzsO3uT6KjMGJI8tthcwC7ZXkFqwbMV6ENeYYkG8KZGL7KxiIVntDgychiSbyBPKSoWwryjZCF7STe76xvr23IAdtLUftFNlR6IUPLizGOIs8sedbBou8Y6sKAuSzte8SI3UYGXsdvIzH0Npkm/dMd3dfA5dXgV2SSTA8kKUXFp5C/AxoRKrukcFguVacf0ggzHvyUuy/O6AkXSnjPRe1dsyMiKew5Gi6kAKkJ0tbt4L5WjDdsocude2ilEOFnENjUjoz0lNvPlNtp+j4midZOpGRGU+h9e8xBdRBLaNLDaOQBQgWrD5/usL/I/1phKCQWIFTzw5HFXZ3FsMy7OR0vEWDYTobRZiJ1A/vuFFInFJoYp9fjGfSPwrC0qH2RiU30hdBbbYsa1g7QjwYDLOyNTC9KggjD6QqFfLY4yu5RsgrKYn8E0HJG+SrAlirF9G6DQOzQO+spTOD2nzFAySdebChA8Ki6B/5dxAgHVeuSd5SPuBt0297fRyBISrygTekbqkjaAvdU7/g3QMuAk8bwzHYQ+SNTSdB92Tsxk1tUTiOgSfARZH3wsh7sDbdlhlLegwNX7BGB1mJA1Y9htXui23YuqlI1zOWn2+weRPQ3YfGhZDKBVX6VfDl7bHjbxTULmL/+4ruUrF5W7GMTPm6ExCKonsMmG8ta1q4qMTo3HmvwH/lhPlhwPZnXXu/VrNbJjG9rEyzhTyGlp1F4PKDypr9LNCBi805/6VnRpL3lhKP0gDH8MQOBPkjzHjIJhTkpKgbZnbhTEwm7+xEdEA4KdLZOglBoWKiNQUgLOFCEcR7lk2X/+gV/u7hJXkngZ2h4C3WXYUuAdoWB8uoMqyZZpg9s1KUrWB4Z8xAK8+8TJ1+tGD70x7d0dijxshsWSIYUL0U8vqsdT42BkjPxlA9MZL3DwHLZUAToUU0TAZKLYmXdAAargTw8wPefhQDzRn8NK34iBPR/CDsnxTZOBC1X8H4b3t9HKWE1Yu6z0BXgbjWUmoquDhK6wWHc2hAE7n2PMHZuuLDGt4FdPeRoBSAfFVw+VQx3Vka7uSPxKgKMKXWaCWClTXekYiG5kMN4DEwMT1E1C83/CyJJzXTUgOBqpUYFYA49gEgMKV0ospwXzA8KvonRVzYaRjutaXnrqKb7wqWG/INSo7UaRgRhuIe3s+81bZxZWHmIjMDj5czjgk43dmxHKhlVHe1AYVlT1p22dW2aEkWYhnglyZF3RbLFox4NdRGnU5PDNx5a23FaMCr40pDxfyyEDAc+L5NRVqJHwTTpThvIswMTuli6yQ+C5I9uRzxItZiNQHVYgC1pelSBMgB04uK+Vab+jI+Y1byYOCBo3Et6bx0rB27Wv1jQH9PLKF7pO4kXsgKpdrUgkgRDG8DOs/qrphOVGu7hgVIRzSVbzA1ZXfU1lr3diiEAXDzzsowA/E3b5X3ZvwOZgwwpR+KtfBcJmsPQwdy8KHG5CtAmAPr8pkLoHZcDNjwhHYOQJgD5hcwFL2i9HwY8yttAGfttbUuYWh6PFuKmlf5dAXLBslcbMuep3P3ZAFlZySWsLaaXCAVsqBau4ubjdlJjcB4GxC3gjQpINZ1WBT7LxVhCXj33+CpigiEKVDs1SvqP94gyJpROWOybLg5UQXDV4kUb6eLX2fErxPbrYsgPVnr05SeTsu+/DgDnSKeE7afJQYju6+OH2CO6B/tuzetSUC5Lq3rEGZBnKI9t2eZQfDT1jQxW3vYAmAomF/xnss2Y3oR1k6QBUCXhoul8xQM2cmY+VLTi5VD0LQiV8zNQ15xpXjh32++SJheFmJYM8FRbNjJqb0iv17QfdkBasIzK1EgoWVoZaB+B9UPD0VCIAeiryhbvpca4zWNgJyAy6dcJ6689WAUMgNQWOwAM2xMKt+7RpZCecNMM28F0w0Psf5BrTxacahve30cgcEyBjnzdNfITeh1um8gqDQEuewrNAgE3p7EGtlNdIIAQATpydB+sbrroK2lxE27fhQy18QYjhERCgU3vfbMTnCOSGdF6QWAILm2ovdi3VJPDwqLQIu2k3a+ISgVJqr7uqPi6ScB268U/VExH8hPAIDt24rNl2x1ucq0TCYu2hvAF6K1r2St+Y196Ke5Bm5s2RRAElBZ73cPrJu1crFOP17Qf9G1elcUGN4Dw4Pg6Te1MTHDGNasaF4JNGWrkJ7pvbebKbwy1Wlvt2gMrc9fOys/lMEEp8QuRxHg3DeWonpWAwBV1vIqOxDIteQp+/yqIj2snASnNAM8XYe3Afmg7NLYmomn0Lwv4mLl02AbywhIHiDrRpHGgKqK5bZAtgXzNjZAVDvTS1gGWWYLyBkQo6N3R0F/5lpgz7ZCa+CB1QHLlbTyII4MjnnLboRjJcuVtvtcBiuxTK8TZwteH0h9/DgCA7hBEQFkaT1wNzZx+q+a3Fk7BboKRVjbNxOa1sKJIk4OKdcKfTlDLwnxGEzJKUhPDCiUbvOkZH0biMLfZsQvEvKVYvi1I8ZzD4zRCEZ8X7axTFp7NiQ6EqBSgyzYblxrd4CnrmTWlt1ZMU+Cyyd8sN3JAKhOsOwE26/J7zibPiQfrEcfeHLmFwvi2PH7T0yZiwGlUi2DMOpzPSeWF0Whk30P432UQRGeEuJZsDsmei5sGBzSkb+vQ0G8JMQLKelUFLLVJ4W9c7WU32v3Mks78YthM1Cg7gg2h5FcFO8Y1bRuvu4ptPsXDEDTxGemkX/mHQbvIrifQzwFciLsvWEx0ev8/pE4igu0vHyoZqJSe0UGA2d3FCQrS5s+xyjinsrjaFoIKxvjaDYAlklKAQFJGGdhU6ExcpMvaAdjNCk+lcSU3wfLgiQbblKA6U6tc2Qs1soS1PGmNCpCVvRHYNl+2I78SAIDbCMzvWXvHy0D4CkXW0qPDJYcM4np42tg+zlprU1GbJLt/gEYXwMhKXS/oOaejDBjSIoqac7R2kd26vTv44rYB8V06aBTxObnHTdJISEo/9YZ5ZLQfd2xBfhesFxbhhFsgdYVzwiT0ZHvycSUrCidoH9UjC8F0wu+5+a+QqMgKzOS2jsOoDj85BEA8PR+h363IMaK6cnIO4Ol3HbqeQqPTQVmaWkqNxBaIMs78gz6LxPiQibgfMOs5PTjiKufEqeR2STpYiQcoKkwyxZWR3PzO+1aAwGzvBGIy55nNOEPrLQIRpWOlv6XjVpb0soGKwmkMMDUfUHW2AJ9MF1NGfjzcUQTxMUzEGYryQQm7Ucz04EIYH4WNQm6oxHPXBjXoXWJNDKI9CfBfEOlr8zETuJZGoZQI4NfeLCWalXK7LfV2JYEyedbtIwhniwDTix5xMqI+YYZQzRJtlS09engatkw0LtQazkIpsiAm3ffyYxhPY00may4iFlyCXIXWwagUZvEF1Ep/MkCjWQb1mQgjZUItWOKNV1FpE1GsWCTt4BGSnKDoi0OP6nCIkAlASWdA8J7htx0ApxFWTtFjBVlDlhuC4YvjZiyrFoCDWz11cGAu4WnWPeVIGSWI3VREzxRPTfdCrZv+Pt5A4yvBOOnBdpXSA7Y9QsucwfMAbmLZP6FdZF4y9Dd5+qmsisBaUSvOPH+zDcA/tQJ8vkO3RfJgL0V8JSJGdZ8JejfRSoJrSxrYKu1CeebZ6WAmBbFAlQZzCkLKzCrXTCEn5JmgJswH7SBvAo0jYAoNxwEzDArOwuiltnYaZ0uxKzYekQjM4kC3clOVWvbemegsUkzqKg9MDD5Sb/cVmYwD8FYuFY22XqKl2c4vrL0rRuSrpagJG0JGqU9Xti5aGpVI7bVTqkHGtj63XwlpsewluWiWLwteeHnSMZaDRkIR75e3gDjC2aNZVq7G9/2+kgCA1s8yLaxAGtZrn38hh+Yf0K4BNQdT7AwBkx3iv7R6LhVEO2kqp0BiE8JeQzWITAee1KSdc4BGqWl5/ES0D0S2Y0mSHGDjNIbJRdc+Pn39kgByC8WLtoH+cWvtgKpPesJFWC+JiBJLwUYOEp3pu6RC3e6EZx+BMy/NkHOieBsAb78/TvW/0uAvusRF2vR7skFSU8rT4D4hqD0BXq3oDx0qLZhvexcHgd0l+fiJ36+OPLn0pkkHilo3g70BmBwzFurazdkfoYpMDAKN0c8MzvpjtLo6cs1PTMkh1aHF+ME1E1FPFG/ESdBzc4pWFF97SpJbrMF+U7bRg959bkA8AyDEqRRm67B/y4UAoCiZlyTpekMfA317wkg5oM2oZOL4wjaVugiVpZh9YScyKAMs5hdITkbTQV8YSnqrmPu0cguDIPvdMcMYgYxqbzns3BHLcdHuifrVm2ZJVRrZ7KVqR+0Iz+SwMANGk+hWXTBs4OhAtHbWoboj5GdB0stEchsA9Ccbpze63qCeBFgMnBT3IlJAPNkrB0XsbgM27wigZX1Vntnyq0byJmF/ZddS/tiAqqh1O6EVBMgY7SWKr8jrbkY1VH9fSrCFHH+NJj7kiI8dAij2OcDqoTV6MTS7OmuEtHeZpTSt0xFFtayUEAvsbW8mqcmgO3POltoJhKKgNgBGCdpuEb/PgAbhSpa350gGVNwjUrmZxaoZV9h4ULO+7V7QzxAEI+xtfjyBlCr1aN5WDhJh4QtBvIwedBzWbhwEZ+NyJRdGs5nETLR+fEF77tboPk6gNCOLixE9V1Ul80Fyz0ryoZrL0zEDKiJCWsHqlNz4gomkycdvgW40b+PtM5a2XAN5B07I909b3o8kwaudm/jSJ6JGuErHyq6x7VTEye1g40iOFoert8FAHL/CwfWn3B9HIHBkPzaEVvw09wDBDIfSDpLI5qUjSAvq3OQtx7T2YCaSIagJi667VcGjl0BzpF3VBx2sqm9VrD0rPZAVaCaC5Lz4r2m8wUWiqB7z/bYdMeT1AGp2q3UWvIF+Hf9A3D6sZmeZiL2xViBDdA8MBB43dqEX2NoXZeyIXCrPclcOkea1CxkXwYD96if0JZ+ShDIou01YgOwgGLtT9rJsTTSfn0mZaPQR0H/KI3eW7b2HJ4SOmthagRyRy4Cyrpx3WEoWA3tCLoU3qfVJAaNBi+LIJbAbM9JcFbOkThm+MOCtQU6AKjAdEvVK2nMa2B2LUwcmTXUZ2VR/nSmucz7hLJl+9FP6HiR9VAS4kZdWQ+dOFsAytJS+GoHjWSBCANR2axrl+5UZJPGCSRpidq9kLV82XlGK41rUzaCdFLr/JiuxzCfUIBltwaIb3t9HIEhKI1Y3PvQBDlqQiXYjXHMIMwG4hljrnaK5Zr12OadWuuQNXwNgu5knP9kdFLDCcIiWA6+qA1tTor4EJqarhr/vDsGU0HyobJEMZVbeWaPZp/feQViTMc0ArDa10/l/kGMNwCgXzdTMBuuZP59rj8IBhyS1UfzWlQi2PEYoR0NV7WrAALUBEuwhahxrZvLBs25KV9X5K0gX63tYPceiKMAEa29pgnQfcZ8lwi2XVZRmR7YdgtZIKMZ72ZALzR+bZ0iA5HZPrbP1wA+fm/AVI2dta47bXb4TpsnBsJys5o6lr6YClgZNL3U5ocIgH9vMuvuSVGN8HZ+XamtMd8MeUqIryYsVYCuQvqKokAeI8IlIh2dam11fOJzLXtF3TB4l+uMxdY0qfCC8ukMHSO2v5/acyDfA62MmC2DCAsdyat16NTsBNw1vVn/WYBqQilZD6C8QctqPuT6OAKDgu2tVIHM0KaOppeVaVg2q07AffrCTCPQsqsQ710aOEjhEe/adMfFli4gWNXL2vsOrj4zzr4befYwKzhYaeO1LtoidqJMtLSzBRSzQYsLkK3kSKe19vTWanpPnGG+Foy/sQBF0L/vmL6a7VoLWJ5imy15/8Rglvfk81cVanCWiHow56SLSbxPAf17wfRSm8GqG936wlJBo9l67czAu7YBNSrkElEHxRwq4mzW6N5KDMD0urAs7Ejrjmcz0bHADiMh1c6NVbkB3NeyN5zGyVD9IzO1+YabP84CzIYHWCdr2Rn1e3RNh1nbGbgXyvq8ZbTgbj4WdQfUq4IlhUY8i5eA8mYg3jWm1f5+qC1rgjKw4yKAqDlR2X0QQHJo2g8vH/RiAG6yH1LjpmxZJsXRPm9msKFuh9R8va4Nr6iW6dBaQDDfMrikiwWOjblD74xC/WEQw0cSGKoQ/d4VOtmMgTyFGiBBGvC47L2Fs6by1cEoo7du3vGmLnsAswC2MJz4Q62AmEkJe9/nHwrNOScuim8MDanmJXm3vo7Te50YpQlGIuFnyTu+jwM//ZP9VbPG50MtG2o35mvBsge6/Wyv1xED2YALblshuwyde6bBgXXmWEyQldcTYXjH7zAjUQJuYF/eabPHD2Wt2fv71FpZTvN1Q1Sm3WwfhkW84uMjMwl83drrg0zU2sG6SsD2PQHRONlshcEBTCAWour9g6XESVom5A5Tbuxbtqu8Oe+wCtpa+q8tm4oX1zfw3rmgTE1w58+rCssIkoNk5cdgreu7R5v5kLRlW9qzyxMuoZV2gJUy1hGJE8sWvI/tEFv2luFkqkvnO1r1QRhsNZrgqhK4Lf0zvONQDbgGtAik0P9i//uCPK4mN9E8GaqJErsnjhwgme/DtuTHERgC7cXjUFBOiQozq8c8Ars/XxkU6IHhnmVA3ivybUY4xUYbzVuSXvKnZrNtaWTTHViKn43uqlEhU2h997wFNm8BWM8979FqUgqjjHo88GGI17Pgz3tvOzxxsfrMgnix1mUHnH/ki1DQPfF1Tz/bExfolF2CC5BFgBczfuPTt/hHyyeQU4QKsRiXATd3n2XdfFKA9EhGZO2McRh4+i5u/244hKekUq092AHJwLtGjOqspFFBORRyCrpn729llHYV6TG2PnucyQmQyueyXBFQLi8L5BgRz7GZ3tQN/QtC8e6SlTUHMgvTvXcqAjepvad7UoZFGhGODEPej3RacaHm/6Ar9tPKjL6i7EKb1EX1pZ3WnZntCiBzWIfjbBW6EHgd3gQ4RwM9WukZZ67lsjHjoCIsNyywxbPhSjcFEJ7wZQDiCZASML0q/LxHjgyoAzGk6U6+0XqWbKa2ikbpd7fr72YpAdtASyCeMAfUQjEVZm7cODPl9M0JcKGHBejeJZSByLe4e5GgnShpBDCRJ+B1bt4Llh0fWsjknrsYppiDTpjW/nDUFdSpewOOigFeXjMHLkof9lEjsNxxcQ1vpaXlyx7Nl08sva5WWqibCsIW7SSYMeAfza8R33WGZ9RGqa6D0attgVfzO3STmv7e7PO3/JwK68js6RcR5jUDY7m2dmZqzxS8RsVytdqwIyrt75cIvV2gBigSPxDkm4L+HTsOXl7x9Lf7cwnInUK3FWVLdB0AT/SgmK+1LW7yCwQ1CvJtQT0HDO8F3VvBfGUyb2uduuuyjxwoJkRywpsUYkJOXXfgOVgQzdeW7Wgg4DcTJ5FimMYYbSPyuWsAW8imhXEX82xZlPM9/MBxXCtdYBwXAEqOitzNeP3iiLf/4CU0kFWaLoruCcj7gLwvKHeZ3h5enhhTU6t5MbhQSpnlLldGgipo5jrf9vpIAgM/tI4R6Cvba1mgUFQNbVxa3aNFZJ+PQLZXbe0tKCOuhrVViMpFOb3kQ+xOSuabOdsE65e78Uo8EWiUbO2kvTMy0dpA6UTD2OkFCTuuvNNgmEghuo+wgpWcE8BvnC6mnLP2bBA0lL1s0TwipXBaVPhsaNZr0LBqIhZB3RaoRLIur4DpBxnVxDplE4iIg58771jX61BRi0AvTKHj0dSQnbJVaeWUk6biOZBX1CnCOZKb0AHlmJCOAduvmMGlS8R8U1EjkBYHTzlVLJ3RCEySBZjD2gVw1mRQGq6M5LFoUAzvBLWPzVrfcRcH3LqnVRTFeY70ynC/CJY3Rk02GbiYTVwDdyuMFeqBVDG99LYTgxYnT7n/glO4hdZ5WYDATCJaR8sNdpq7Vwf048rObarWXqFjwps3V4jWFRse+N5xAYb3AWUXmbFkgdg69/Zy2ZpkW565cOW1Q5LOQM6OjH+76+MIDGrtH4AGoF7r9xWYApFuo+kC5oOXjIA0YqXWwmtLorFSLMsWSwcjzV3zVtpmdSygvxfkrUCvF5SakC6xzSmcX/CFuvfxGy1Tp1S789JiiLdklhvuu5j3thEudAlSYaBKBvzVDsbuo3zYVX+AgX4KwFBmN12tLlnOAI4GaLmT02JTsmYCgGWnTYnq4+PiQwICMwEXLElSzqSottDsVMxbG3GnaOP3SgmNJQoB5lsLbEmx+zk7JWxBWimTrN6thhmcQmun5j1bqVIEMoZWPhLQA4pqk70zzWdJstwVhMOCRQZIoUaEjsgUDnWPDBDTy0ofx4LG/3AdSZjWVNs/E/kSAhwsWLjcfgam6wo5ZOjbHmEKKLsCWMvUJ4qFieusfyR+1ByYZvpjeFByMlZ6oGZmOUSjzJv3qQVm7za4lyUnkUkrc2uHNm9keqUY3krj5jimVb+bpQRsxoACp7SKUmYusPmWPvyhMEuAAMvuGVHI+PDZBpK4oQUAM3Alj8FPGI0tDnFjCYAMbL4OmOeeQJAZ0/rUbQCr12BC84lAcVYfA8xiMzZrz6wAIg2JXw5ojDR3ZfbNXisgmxUk5UbnonZijc9U1ADkGyJf8RQaR2J8XVu/WuraJQAMFa/kDaQzT213UwoKm8nJjOe5aMfT47Lhz/NNSWzSnqcaSXVs8ZbbjDgzQg3v7d5W4gy1J7U67yq5DUPFjGTl15oGl21t7EDf0HEC5F6sFLNZEibdjhcyVLtH60Rc2Wlt2Vv+jRG5DNh/RsAwjazFawJ6c7Fypuh8qygK9BfeW3fe0gJ2PMYAjD1/9iVrf7gDuE0RW64UagQ6P3zcJcsZofmag4OrUGFZesXVbzzg6WfX0C8iBVHPAEioZVt9BWpogUADOTHURvDj1MQyQoUHm8vBP+T6KAKDe/N7ug6F9a3p5ZfstJtvePIUyxAc/dWkULWTdu+UXDdSXYkeADdvCeuGlPyMNTZxIdbeAohRWFGBdCTXnWBYbachfSR5KvAEX70kpIKDYsXRfeIOLrd1XKL2aINTHYiTRBsyvCM+ML2siD84o3y+Yy1vmEvduMBorX0dCaw9W2FhIsi43BbIQqArH0g6krq2JnWrPAFrbJ0JBSyr0TVYCE94CJAOC7L2kDN4n96lZrpbO7Nlv8LKFPXkTgGJtYm8fChs2fDzdkdjME4s/ZqJjMCMeiOFVkMyk54VYHN1I/AMeDb6OQD01o0aX7DlWbbashRZhKawptfwOR6ch2r6hGIDXypPfj9karcG/OZYZVmXG7qkk0ACgw4qb3W0Z3f6/95g8z6YSpKq22X/zLquU6ozh4rSB2wfGNTyFti88TKLTFWFeViCPqEt8H7L66MIDABWKyuASPfMTeRW8j4tKI5YWX92+m++DkYVBdRKj/mWPnfFXJilWBtpa/wDp47apGX1dNK4EcGo1UsBao50GxLLAqo0hmVNnN0QbR5jyNI6AOHE13UOhrMxQ5F1sfiJYPWguzHhzO9YnzkfLd2WIJedqO7OTLMQmIEL0/k4CeZeG06ARZAKpzOVga5K3dvEUsVcqWsn6O8T6dKB/XHAmJHjSnHWi9W70VFDa0PubeEboOrBzssRnwMpRZAeI0qllb7X2vmqNnMXAE2rUAZpJVcxmz0p1u1YTINg/gSbtxY9bB2FAsiXQ2N1kp7OrpWXgPmAFpiGd2RJll6h5gGqSYG8ZmE+EDmNRonuCsiMZADK29oUn56hhgyIsTo1WAlxkbUcBNdx90hMYLky7o4dgqsnKTMhTVwXunNg11vF/LnhnTQehwrQnb+LgcFS2Tbk1JV9uv7dcrWm78408+5DNMIKWWRop+dyR1AoXoLx+qWpBp115+3L5YYp4+5nkXXZ6IGCp23j+ffeyfAT0MfbM2cvG/oosgQxMY7w59MZbQaBD9hxG/BoKHKYuN/CsqbxHEgqiGMk6clMStOZ+IP7M4SZClM17gct6XiLyak3WzvT5hfLJpI5GDnt2hf1clPt/jG7KXu2IsMsBPK6ivJusOEmQmnzJNxoG8XyekEYCsJnG5Z6e3Dm46ag+6yHHAP6Rwq0wsIN1dSLBiRqpJYhna1eFqAGBr/Sk/xDliAwPJBFGq74XWoHbL/iF+PhoujO1ue3sXjdiWpF9wwVZZZTo0DM4Cfv2PYGqKGgATGB7LKrbQ2zxWqdL6Mm111Fd89Zm2UwsFnQvCO1V2y+iEb/BkKhslOKmrmvrfksiFayFHPRFjO20X51d4ozGn0a5oWq0aacf8D1cQQGPzXNbtwHrjiJyOnH0VqAwYRLMeIb9treZ68Jbd6kK+FcNCTrc2x0ap5M7mpspUkyPwD7HTIhTcQEAaw9Orxj16Tx3uH1KgNRtBJGMk+p6ZbDRrwD4PMmvM3ZZmqYAAwAwkJ/wGof3G3p/b2cmDO9LOjvubFcEtwmIoUVUISVAnVbUa2MyAcTso2pBSX/3A5GhktAfsEJUZgD5LFHOvk0cTTQNE4MJvV9Qn1dsfuv3uPxqwP6rxOGryJqvxKH8s58HoognkIbwuPtU56uvP/5QBwkjqQuty5KEeTOTvTrNUtJZ7alKcW2Z9qt/Ij5houvdmb3P60drc0stqG8zGQXCgrkFxlyCQiZ97pqbAQuAE1TUg8sa/PWHJwDmnud42jxyQ8UNGC8ddYSEDIPgOmFZc6bClwtyEuPZc/ffT6vtGzXPePMVQDIPpPzW14fRWBwTn6+Jk03Hm2M+vPU6G1ge8gWbLooNu9WQhNpvozQMglkpvWY694VjLTaVcRjNK8HIFa2r5AUqCT/pDNPA0+zgfUErx0ggf1FXww+HQqVn4HOUdYvh6ePrFPLtmLzNja6de1MsCXMDBZrycaJnzmdgOVaOCrNSg6fZ+D+AcvduiDzjtyF+cczQqqQn26aZ6AHuu4YUA5cNS5J1l6BqCQ/BRJo4ik0D4mG/8wB6gvRMq3ameJRvFukBgYGLDpg+/oRj5HMS59qPl8rEAXzy2rBZ9UBPB9EWwYACc2AJcyyDiI2laafrONrbTqCdBb0E7ONaFmU816mG7E1ZJLnAZB/kg5dd3+7A8R4BwUYPlMcf53P2c2I5ULdA4DVDfz5dC+w1HFrPwgw/iC3PwuXZzogeKeJjkybd4L+gc9l2Zt57Z6ZaPdAe4CaQztEnUiWznxvd/kWhZn7+MH2XcwYYIfYKE2TztmRMKOVYMw5PoBuYhsonQkiXV6hDSCBBcZoYh7ATuGt/Z3Vte487CnrZJ4CcWb6WTbPSwdpPfFyKJQdP0b071ezDxFpJKD+XhpQ6br5MnjL1QehomVEntr7xGhuAuuCHPg6jmlQp6EtiwmZnpb5qjYUXgqQvu7NtBVQo013T4Jqvgrh4p6MAlQFnlwnYPLy0XUf1qFQ24inSPr4pqBYre8bWqMgHdGk81IJoH71D1/RCWlBk8RzzJ2Nb0900XJmqhYgztYujYLphTalaX9vKf1BG9jXP5pYSEjyqYc1nY+TPwM+y9Jb1rmw7c1DRRFVIKliuVpp4wCadVu5XlWcPGy40Ry4TWeC59MLPgc3k3E7AVnYEanbSjzEypGy1ebNIcBKBhtWfCAuwPCW5KrhXvC0C42E5kExZGtz5rVbwbLIXL6330WMQVwMYouhq4CElt759OvaESTLO6aux18nnVjT2vf3PrUHCM8WWlo+hlY2xJFRermmSarOAcuVYHxNY9bx5are9AcmNkxGA9tSZUOBklOLvZ2qAY3qvFzxdGpOv3Dga+2G1J5cAGdDumgrmzLQfQVOPxLMd5XeCCrts4nZxHvLLI6wYhzN6ozj6FdQT82i3YkwUqSp/aSA/AZrt3LUn0KTtU4eOoiBNW5H7/qGZLJqGoTQdLXZ8gHN30Kjuy1Jy7q6oy2JsgbNkAWyMI32GQo18r6lI3EZPazlXpyMtbi3oGAqQz9VN29ZZi0HsfcLyOcd+mLDePY0yS1bEtgU2trIruL0QUca+Lnylm1jKjRZ6k2fFCCqEbcArWicBb8cUG2S9oHg6GLaBj/ANCqydUUANCDcuzXpbK3mR7WSlXuAuBbxqQ+5Po7AgLXGh4DcAAeDCqchOUhYEwAXMhVT7RkXXRMp0Rr5b3cldkQ6XkJrL3qaVQ3lrmMEhoK6dUdj2xxqfPtxPeF8dJxbsvtw1+2XwRx0lLMMZp5IUg3QMkFNi/JYMQ8XePGkldYehIGqGoDLa8sGjgH9A1/3/AMCYPFEIM8D2GLDV53wUw27iDYKzzkABEkVtQqiAbetXeu6EicG+YStgMZhEJvIVPb0gih7bZbs/t2cZ+IdoLwjD8FndoRFUIud8nFtK44vzejVJNbacRTc7nN2UPxarkykVNBat3XgZ3MaOp2a1J4/f3bZrch98zswWbrrL/KOHJrkvAETPKGG1ZNDyaoMmYEhXfi55lsa1rTpLa43Kb6xjQU6E7SNI4PdfAvMNxWbr0NzYYKKWc7xEEAyUtXAtTXdsq3dAqvynnsW1kR+3/L6aAJDqzHVTnX74r44fVG7galkewDC06BsiBOImcnWTimCMkTXDTQ1kUnnw1C4iCpVnUtAfGJknW+s9SXP2lcG9LmZilRAi5txrO0in4itYXURAtZsoPbMJhajOHvk96wmNvNXPtA6qLVuCXb64NLxhbYhJgJ+12xj68mnt3aYTUaKEzOs5WAlgPD7UGS0OklRim6fye6ZVHutS2jKTAjVhsXue92S36Ew16dtNS2GtNdqQ2tGEtrqVQaeEvr3oW3i8SXv5XytzYLd+Q5xZLDwYB8ysLjblqB5awQDDxWWKRi+0J0ZEH2cW/M36EHfzCpQ1cZtcIWpVGkZgUYySmm6ws5CMQBTLbgN740DcVWBzNQfxpXwGRw+2RyQll35Qdc9hkaEE3smy402PYiKtp/1TkfpFXq1cjcYaCw72v+SSwkR+TcB/PcBfKWq/3X7sxcA/k8AfhPAfw7gf6iq7+3v/g0AfwEkkv7PVPXf+xM/hZ2Uz1uAwArghFkA6/HPdxV1o+jfBSwHweaNokZpMmXfBM9nPAB84ARqFLrTtT1qCyoOBUUjyr6gBEezo2UpK1AkM09HKQKZ1lHmAFlzbhuXdwYqCVZ3IDMaqZGb04U22TjubYEWtHFl1TQb4i0wE8Ow927PaFkZmY6FxDE023KA71l7uv+oTdAOZtu23FBGHEcrvYIHY21EHz4nO90t2PKFCfjqUCAntjLjSH8F/718myFjbB0GKYK6q0CqFCYZb8EnimvHzQMxBysbWdes+ozTwmzN1oRlBXRjRhtO0ygNCZjuOI/Twb3m4uQjCI3HQgWqmKW+3ePMYJ5sMlV3oi/m9FKamK52BkQrO0m7zwVndCShufLTwPRiyzyeVnNet/Ib3nMK2fhidf0qpqjkl5E2IdxZvNEczjSs+BzJfYLuUdtIgm97hT/5R/C/B/DP/8Kf/SUAf1NVfwvA37T/h4j8UwD+PIA/Y7/zvxWRb1XcuHchmYDawJ18VVEGRXciCNM92nxIAZrBSEJbkIAhxXnVNEDFsgyYfNa6ECrQLQeFiGgjj3zD/8FuMBekNnINAOigyDb0pew4wh3gqZUu5Ca0BWgYA92gVmCJIBwasu2GqA5QpmdzEeKFuoL5ZcF8R0pwPIXmAOQTpdyswy3W3CsSCoyvWF7Fc2hZgweo6tOq9nXFIfx+ebCA3fP4zNY9ew8OKFeFw4mt01CthScK5OvS2qKyI8FjeBON8Wi064OiRpsRcZHWdYgXztiE4RDpwvt8+VFpuIL2NKxx8xivv93bkg8N1C9sVrDTA7tkKnH7e0UyotvwNph03zgwVREnbSatZUPgVHuyOJcDp1FPL/j6m3fSpN3dExmd288jg6NRwTdviHWEzCxjun1WYlopt3kr2P/cAOwL69Gy00YALMOaXZd+xZE4g1R++aWEqv7fReQ3f+GP/xyA/479918D8H8D8K/bn/91VZ0A/J6I/C6APwvg//nHvQcltuxh117pxX+Jq2NQXU9YPyl8pNyyl8aI9LH1EEWcApY7gj8whprTUqFoMx8VIJOvqyxFzoHZyyJ2QmMVvMA09b4hDPBz27Jkk6wdVU4nBWxegBRqLxbrMviijbMtXFkxiP5R1pF5Yp2GM5pKMkykLJP3wE2w3FRmA25OYiWNLOt9jhM7J2Vb6V/hDMPAiUreCtW+os6rcQmPXw+6JjDy08uCs5yigb4ResjQFBDO5gC9RJu2HFaA+Zw4g7SSNBQnvpYHSh/3hwrEhTJkQBrV2ksJtXkUcQSgJribgKiycjHsZ/t7ovMutCPlGYhhJU+17MjXf+Q97h/4vnHyTSgGZpKUV8WyVSNfzTcwxzHB5it20MLCbpdUm5n5rD0bJ0XqGfjyjviH0+M9KPv0M/prKOoO0KeAzVeC8ROWGeni69xKpyceUvUDQYNvkzH8Ydenqvo5ANi/P7E//zGAnz37uc/sz/7AJSJ/UUT+joj8nfp0ajMA0kkIPm4qEJVTimY3fWVULbsVSW9922qnnp3abVbiHNheM0wgXgJ8cIlGQMxqC0BTcsKqEJrFrGlmsPTNUWJvybWaHmjZhrMd/UTSIA0w1bBG99rxBOyeYLJqhdvA1Z4jzKdXKznFGYzNDwDr4mXQstRzxyG0ccSzsWyCdPYmt33WZNkTLDsx8BdOnFIgXGKbQA7DJdqoQCttvDRJZ0F44KaPlsVptCzIyoh4DvRAfPbMXNI+3BPbuf49tuY8W0sXtcyG/18GlhuyhFbb9w/SaM7d4zMgrjLDyHs6ZfnGyXsDdoUBxrOM8w/Z0nQgMl2ITVDTIpT698Bwr9i8ZSDn5C22yLun0Mre008KMzTz8XSmpcvtAXvuG2kKyORsVWtp18QOS5z4nvufBXQPPMDyFVmQwxvrktghCWVHZ7ninBK3Nvy21y8bfPzD3v0PLW5U9bcB/DYAbH/w6+qRjiKmiHxVmgS2JmnRmKxIT1HXt+tOQH0fMNumrIl4QBwFy4vc2Gu0ZrNec2DwQQ40iQGsYFPIQjyig2B4S4KRdzS0t9RxW5GOkeYwGnhyWOupe2JLddmjgUG1YyAraUWJnRjDeQZ8/eWaY93yVoGoqH1FGgOWQIDMgSiouT+5Db2swKOj845Ix4kLKZ4F+qYj6UeAugiHBm8r0jk2dWrtK1u4S4Ccgf4d7492ZFgGm6EgClQHg31a+I5t5fQkmF/QizFeQuMSeIZVB0V3DI0MJtWARRXM1/x7Xz3TC2ktuuVggV+pIfH5F4Cn4+w8zMZN8bSf08GsM2Oam3Qm0Jz3iv4+rJ2Yuio7/Vk5KQ0A3PujcQaqZY5ZLMOy5WnEJcmC/Rec3L35Gti8AU4/DCafl5Yt5h3XslT+bjYtxO4LxfBYUPpoXRuCoHQvV+Q7ZhjdkZ0z+n8QIxnerx2ib3v9Fw0MX4rID1X1cxH5IYCv7M8/A/Drz37u1wD8/E98NSsPqqnvwgJzPVYzQEHTFKCwreT0WFEOgJFCxWKYOfZruWOdXADEx2RTpgHdg8FgYTbhcxdiX5AV0EtoevdoNmEycVPnq4r+PqAmAV4sKFOEptiwjbyl/Ve4UCLustvq9ugV60kd0FhzGoG6Mz67qQIl27qaBOldajZmZbB7scgKaiozBE1qvpXaujx+b7VbJ3h3R2mIPgBkTYCAgCEA7Sq2Ly9Y5oR8jg2viSOgM6BhnacgiyBY4rlcEwREIiAcimWAyhOU90mhWZq+YzlUuC9BmKS5U/tIPvdyXIz3QOKZ09j5/d3X0H0SIeQo5K3xW+q6ocuhQkPAfM3n271jiRfNVn/zVpseJu8YoOZb/n86opHovNPRwNC+Qmxuic8DTTYntQ4UeeVBkFSRJkWcFdNtxHiganjz1vQh9r3SZR3k4zM98yagO/Pzbr8m1ydvOe2a5Thsghbas/csK17+5E39/PovGhj+HQD/EoC/Yv/+t5/9+b8lIn8VwI8A/BaAv/0nvRjBJTvBvH40hF53BRg9TK+n76raI/BUXsgzaTUBsTpwaGq5yaiX2AgwHKBLI5OQhXZqAGBRXyMfkIDe/nGkaelly0yiOwZMbwZIhOndtVm1VbEZijurXXcKhT9c1u3zi4r+bUQ6W93qilGxdHThd5Wnlf7rLkDdkUBVa9tVQ9VtcKy3bJ3O7SWQAnBhkS+YxX0qYffcsgcZKlQFZQkIM2ctjp1QF3LBqo242KJf1mzOx7iny4oH8TT1Wppj9/LBXJFNYdjk7iZcE9UG+DUbvaANe/ATsGwrNEQ0QltY/wkZiA/fLLvKxp7BHTMuJ9EN7+UbYJ3/N7MCGr8kV/r2AIxkVU3jImcOE/KAWWzgjE/lygfF0wE4/FQwPDK9uf5pQZwixpdomhx3H29BwejS3UXRPxUCvAOHOQ/vFGHPQDDfmiXBhiWPt6BdJ/OH5vJ/zPVt2pX/RxBofCUinwH4X4MB4W+IyF8A8I8B/AsAoKq/IyJ/A8DfA5AB/MuqWv6k9/C6eHiwgS2mea8DTxd3W+5OK/EGSvQ8PAY7IbR9eV+kwcVGVkfXHly4GyvGHODcFpQ5Ijwl8xswK3IhIOqnejpZSrZwhmEx/383DdUIzrmcjFx1QAOjtGOKO7yzPrhZnXuLsDvaqTeg0WAd7AozNRj5gDZQBFhTXilAUKErtqB5Gjj9uI1/V+v42OajSEla96QMhiscEyZR6CUhjQKF2KkHlLIG5VDZLag35Bv4EBafuO1puQ9iBZjqSpF1bmWmsIntSSMWKUsWABALJposcIm26WIO+PJUxmpDZ2WSLjRlqdEBTWDzVWj+BLVXTC8Um6+ldbnGl0T73YKerEJrhS+k4jt3Znhvm3jHNZZ3aLLzsgGkAbZongpSyUmRKuiOBbuvGT3jwrWvAlxeaxOT+f4Y7wKG9wW1E8yH0LKKkBX6RKOavAFvimiT4jueNr76Qyv6P/L6Nl2Jf/GP+Kt/7o/4+b8M4C9/yIcQQ2LTyHQt79EIJvFClor3myHu4MM+eXg2Yl1hNXXhAeJ97Zq5oKA2lcm+trPpAKDbLpingHBhY1gWT1n5+v55ONGIi7h7Cs31CKrrqWS02dqBdevBpK8vCjREU78plpuV8VajnfwGXhazppMKXH6gmL0FaNZmNdHZ6jmQSRVphdguJEeenzs9raWH049ViBdwTgUJRpw0rsASADtt0klQF27w5Yr4CQ1vYcFYAGEZIE/RWq7Pnm+2eZ9ircL9ytMI5rLdOgIWHPz0ZcfGgkk0YtDeOkPL6ovhY+jcI8OxFamADsy4HKQWJ5xNPGGXK7TDB8Faxr3zTxTdU8D4kvZpDayMoCmKZWE0zkGjj4dZaBZkYLJGB5iN9FYUyz5guhLESTE8VivRBPMdXaRc9xJGfv7xRWRX4hmYye+r6B/R7NymW2nBuyaWWs+Zot/m+iiYj02HUAGRtTceFiMheQdAgTwYA/KJ5qR0I3Jk3ECpifWqZxbxKTZ+BARtKpA/NGRBLdzVBJusrQZpOMb2C0pf805tGpVRpu1k84GwnlpiYfnhHQoPQOVQoabO45h0kw3v0Ig7NPRUlCs+0OmTguHFBfMXO2gnbd4hP685Zxviz+nPaK5Drjb0WQrufpy3Cp/HgahQVCAzcHKalQKp0kKt0uK9DmjTprsnabwHH2hSkximwYBEkZlgel2QnkjZ9tS82nuoGB7TGwfjaWVr1t7ackJ/AtrZO92aJCo3zs3bdZP6CU0vBwbR7kQgeLl6pshUs/zDMxAxs1Ss5kdZ7oxXkWm0u1zV9vrzLZoAzLtcgLZRdk5Hd/boJAQ69z+X1kmKdrLnTUB3In4QZm+pct13TwymTz8J2H6t5mrF2mm6Da28Hh4qNJiT2WDuVFaGDvcftic/isDAE5Ij4L2+jgb4uQjEwabpU5IPdFMQH1KbT6iR5BqIAmMy8o42RWI680TzOjtlIIw0+ig7RbUWXR2Muz5LA2zcRMPlq7XnFKhiTj6AAU4KQNYBKXmvtHrvKdLCJRIMMml49xTajEa+EZA3imAbuftTT7i82UFmwfz5nmn7MwWpVLtfpg1gi05aWu6bqJgXprdwgzEou2NA/zY2Mw/LQgEbD4hs6FrgAl9eZviEn5UDQcS/f+Tm4yxInuTOiwBoJSc1oDuyzOBmpvWcTIK0GKXc1KNt/Jt5S7B17YQny4JOYlmltR07YDHmqCYgRzSfSlGe9t3x2UAYWRWWunmeSQBQw3KcIyHWMhwFYp4hus8Ix/QNK3+IQCtLpGzzUGE0fZ/CPV853Z7lQBkE855ZVzopdl8ILq95D3RQyt4n3oe8swnpSSzD42vMB8F8FZAuiv6omMHg8Dxz+JDrowgMFLiwJbj7XFq9u/1aWtqm7qRs/oWw05GjvSyrCKxzfegIwIcdRBogqR1TDxVfuMJ2JQC5BEBXfnwoYjMKLV3PJqHu0eTWHCSznm6IQPc+0C78dmFKXoWaiou1/GxOZ9ko4r0BXTsjDlngKvuKf/bXfoq/2/0Yx39wx83fLNYA51IUy4QkU54s1kILptB0UFEKPyd5B8JT0bIYV1PmGwZdtzCTWYDARa0CoNKjQQOQ95WbwPgHeeFCzfvVn8K7LsPXkffDe/dWcvm0q+Xa9B72GpxjqY3DEG1CeGMfWrDpjuahuYe1fHXFgey0BnjIjC/53/S/4OukIwlyTjqLZnSSzmi+EW4B6GVTHAUh8hSWS+S96RRyCetg4ML1SuWrIlRpTMfuRIfr8QUzhP6prpO4em767VcVy95whIfAw7EAS8fPGidg7ljO9U+mUp24pplVW0fKDrP+UZuw69teH0VgAACfaJR3JHGICuKFZBApwPa9YnxloFYS1NmBOxq86MBjVOzkyTe0ddN5NVHpHgOt4A0td2MRpMrN23O+QsjgRl6kocLegmKram2h1Y3SQMO4CU20dFcpnhkK5F0PtRFo7BgE0oNvCqSa+49NVnJDl3AJ+Fuf/QYujxt0zzj/ktEUjq3Misx+UNeSBUDDSIKdoNHcoaWQHbhcMaVP54DqLEELoGkOVE4Wm1yVzETHgDgHMcMkSI8rQu+mMPHCrozklXcAAPMdmnAJ1kjBdYYWAY6J1OdRsAQ0302qU2WdCr5jdyJM9DBw6zkeKAzowfwXaXVmreSoQLbvE8CNVFb8KguJZduvCSQuB2m+CC5kAgDNwOYsqA9sT04v6toBMrVpK49NX0L3JYU8EigMWbF5XxAWRYxGorLyIBR6gtD2jlmYy69dgbl9y+ioAZivwlquXAt1ERsyM3dfFmhgqfUh18cRGILV7maRznkRfHjeomyUVVmppwApp5CAJSiwqU0gBADaVUih32PZkhiVjoE2b7tKtt4YIBOn+8SnuOrfk2kditeOaEaecbIoPQqycDHyNAZ/WdBwEZ0jW65VEJZgCLeaS7A0KzQATfPh+oL5Pz+gN2v4Zv9t4KQvQrWRdyrsEiALJFC7ITPZh14qOIknzCRIsVZePR3QV6BEhIuge3AHbG7KMkTknWJ5wTaczMHaeWxXujgsndYuCgzH9EBQ9hV1A6TH2HQcGoDwWU8vSEU7cR0MDJbBiH2WvBWUyq5NepKmg2hmvctKXnKG47wzctoTXcCcExEWBkcEDsRxF+zSA9Wcw+dbmwi+RcNyGmvR/t0dSTTKB87ylEpeRDracJsFEFu3Dt4O94ruWDBfJ4gqrn424fK6t3ul6I/AosD4ykhPR0F/D+y+rhYsFZcXCSHbWjmseIVRYUxD4ZyVX3JX4r+Uq5LO2qig1VFUbX6OjrQ7HdjBurLhqdXdR+S9uRJlgdxHkn4CmlWbKwfDLJw3aGPgw6O3o+zzGNAJoLkA5e0KvEkx9NuFRFkw39FfwNtM+98j/jG9KtCBpCcd6DvorTANABYuntqTgBRnlhNuCRayoAQCWGF0ijGMEYpnopoVXK2baqcLgcb5RttGCSZJlgXAFY1a0mOELICeYgu+8x3fMx0ZWFyngQKEZTW7aaVEv46jyzsLokJAcrk2fGNZBVfLNTGE7gRgFCw3JJrJA8loGvkZfQP3D0BcLIiKfOMZ+bBgAXGVZGBu2WgzmElHqkoXK0kqtKlVOZowtG5GuvC9dFpnXgZjQHoq7xgY1x/X7zxFdsxuMlQSNm+fqW9lVWZu3im6c13NiTOwHBL6x4LphqeQytpd6O/tPWfFsmWHZ9mTlwOTCXiXws2HpQD9mYKvvAnfzcDgaVocrXSwxQmQKDPf8ueyTfB1AREMwXc3pNk2maepYQor4GYpJXR1FyoDU2WAPepv+A9YL1pNwupOvZwgLW02Zd5rOw04VFVWEGsBEAHJ5FPILK2jkbfmRuUAXHaBkNXzrkm1EovvrcYjWP0NAKy+lOZBgKCQHEytiZUmbZOkSQUWLC+ARlgPaENbcyJewxoaTU7MtiwDW9nSHbt7CG1kmxS0NqVkQZqeCdvU2JPP2nou8pmvrbXXUUULMPPwbC1O3KgEpfk8+weeph60fHYGCUAMTNW7GzAdCGD4iDbAG4lzONkyJ9dlmQXDO2o7dl+YfV+2jSnfPJndqEcjB9707wXnH6bm7k3fD9M5vCMY3lvJoJGZ8eUVp2J3JzV8wFi3ERjemk4Ea+aaRmWXJgPdpeL8OjYsLph+iMEVWPYB/VNl2/0Dro8iMAB2k4V1kTMgvW7sHrngonDzLHvWmd1DQHeGjTPnKVoOBXXhQiPI6HW32MgyNvBbe3FYT30SZWqj4VYrEeY7Lu70ZPjGQCcdWK8ZWPvXKoAetOnlOxtLnw/r0A8fRioLEJKrHlnueG9ebf7DfGtly5n+DwRiubBrAurBBtxeAvKNpfkjWXguFdeuMh2fuTHjDA70PYY2eBVBgU4RuoI68gOKGi9iESzuuOSBdOT99UlLqIpYDbSdmf3F0UFbeiT4Re6JBXDbXJz5yHvmupHmeqUULznfpc2ifDbQ18VpjWU5A+hZao6fUArdHaU5G2kAUNAmeYmRtQCXVLO8cFauo/v9vQHPjWnJ5zPfsmztTqvGwscDQJj5ihpIGFgKaKATVY3GYzGNQ39ktrb9iuItsjAF6cks8wUoW1KsQw4EIK1s6M78/HFRFCGWETJB6g+5PprAAOuTP+9Bl2DMPyPHuBtS2QJw1qCwTgxZsGxJQQ32oCULym1BOAerk400NVJ+7P6BsAXtp6qfvLXX1uZRoTy49rQEp1MQN7AU73aAQ0U6cGMtBMfKhtODZIlsxw2cX5j3XNT9g7Wx7grQA+mcrI4UlH1pZh4+TMbf1517go1zo+WYlwtoRi7ReRNJMb0syFu6P5PYoI1ligrUKSK9S+v9XmyYj3EjNLrlPf+Zb7Q5Pi1X9COINprPfQLcOCROYvW9tkxlueZMS5ZqLHtCFlQhsat7XGdWSiEjsDxzP4ZpLPJBGy6xXNXWvZiv/XctkIQVzCxbOi8tBzQ9iM+/9DLByWPZWtBSgeklS5TuiWVRnNfDYbqzw8yIenEG0heC5ZqfJSz8ftN1pKuSdWm2b9nlCRkonSBNSst77ywcK+KojbMhBdgYb6H0xBhCAaBeOjDDUQHOryKGp+9gKfGcyuyL2k1TXf/gpyzNTgRL4MbIxvybD7WZdLqizs1eOMjV0mHlf5cD636i5WoFKk/jYmVDMyTda5NQu1sP6kq8cgETACy3bPnFp8iJ2Ea/VQk8lYul4ht2UjQELBqsLAqoQ6UYaV8gM9mHwTotxbKb/sw5Ck0artZxsBYsYCn8wMDTPfK4mF6TPVkOFeF2RnnqzEYP0G0BpkAUPQObr9eUf3ppWoVhbfkN72A2dWL3gBkOswwjSIHArxOulpvKkmUU9O9DM8HNWzT6dz4AajTqYn9eO6B/AlmBN9atiOumpTkvhUoq2sRdUgkQ+8DffOB0sngx3MPdtk07IZnffbnSVfTl4PLEzV02ldJ1RdMkOLms9GqgtbTvUzs+9uWKWcPwnutm2TM7EgW6R13buwVtV3rg6I+KdKqY7iJqFJtBoUiXisuL1ILk/vNC+XYiw3R4z+ymf+LPfsj1cQQGXenObsrSPfFLuVAIQJt2vcqYdZ0+ldEmTgVYSj+wVka0ITRDtZKFKWTZVvg8CSnPRqMFA/DAB153BTIFEwiZCajVqPESWgtRNoWTuotYWzTaa6BtDtjCiWMAjNdQtms5E08BTVgggEyhdRV0oFdim5s4C6qRfZwqjeilgQXGYMYeCc2+Le+BclmFR3VbDJcgo5BUYTQrsjb2/RxaViKVNfF8J5hv6jpkZlDoRqGWofg8C40KuZ1RLwklCpZFGt6jphBNJyoaacNvU6/FOxQ2hm7BakYSCLxWl3EnvjcM0Gsj9rakODsAqvs180kXEpHEbl/eqSklQ2uxuv9l7b3NaVmComUmfvmAo3Qhr2B8xWaPCpCvFcdfDxjeWRDcu5RcSZHeBXSXitIL5itBcRqzmeNKAZZrfq8YgdMnibhCdr+I1ZkqnbXpVKSwpfkh18cRGAw4KQMBucZb17U11NSUXmMaxZetSXNbMrcnVDFHXvatNZp2wdB6CJCe6KOgapvssk43gjKoyLJOF6JJKFP4sJh7r1uI2wxJNYkybhboFBt7r0b/LpadTLHZwPn3d8S+XBXEpwi5kN3DEWS2oJ2nUMC5icLXdFQe1iXRDXkgTkzKB2MNGsaAQDNUN8HRGJh6BaB2lTiKZUYk1wjyVUV8ChB4+xStBtekSG+58JYIaFegUTBvCQCHSSCzYOk6yD7j9vaE+3yLOPN3Nm9Ifw8zs8H5Di1VjzMHts43gtOP1XglbPf1jzx1ERl0pQhBW7eaAzenl2zJ2orau3+EBZOkCBdBvtamTgXAwPVMNAageUe0QcBCAZ/zOihgIgidzkbFPjjzk+B4HAXbdxVxWQcFT9eRmJF1rKhFYakQZ8VyCJhuBLXnd0+XSkewnmVXGRgUNu/p+YAzMN7xtdLEEuZDro8jMNh+CYWAjzsFhQWAiWK83vPaVBYAHRBPPO2zbfiyrai7wjA9xtYNkMrN1zj4nZpUOdjfmzjHeRACwJhksDo7nNnyqs8cowEA5RnQN1SCI4VTp8IcGxPTmZc+ks3Ll3hm+48nEgHU7iHSKbj3tij4Wd2U1th18RyYim+qfW5mCShYR+YlbYN0SfQS5D19JKQAOSrv1xzsWQi689oVSGdB2VtgUzFaM+/38B78jtblgQLxka1idAqtitwz0wmXAHWijR0Gnekn0mUlSQFo2YJLt50FyRKTU8jccZtYkWUshdT4mgO0qzaQR9ZT3xyqgz/zLev2UNhVqIMgv1iAkdPKQmE3TG04cjhTbNbfSysxl2tFPRSSwJ6SZVn8/GKliSZFOK8S+tlcm9OlIo0VZQi4vAwIRdEbHrDsgk2zlpYVODCZRkXeBlKknxTDAzsVZeDog3Sp1vWCKZO/i6UEGAzimYBJTWIR7rkVl6IERmFZjAYrDrDxtHGqMIoAU2zZAVcX/10N+ZdqHYnOhCfWslITIcFSdx0K5JhaLYoqJA/tMolEqaNT1NkAPRWo1T5ioKZEE4XB8D6zQFsOrsI0nsJMWizsz6g5cE4HML42xqGNyHOGHdtnPDmQrSSqbK06qOoWbGUHYBSzgLfvGgDpKjQHwNp2YaE7VJiB7ZfKXdtal8D2TW0npo9/S5V1edkKWX42lxHRacoCvOtw/3DXdB/pQvINgTvyGmabSlU7YHjPezPdogVjte6O6zv8wGhybBWEUVBEiCscA+XjAnT30dquFnA7tisB3ocwgwdBWE9Yz9JccSvzClRq8G5GhIaIzjw0shm1Du9tIE9foXOATAxkzXBHge6YOatSesNJ2FUIRRGMip0HYZnRscSYP4krTd9cwNRk3ruvMsJckTc9hkfF9s2C5SriQ66PIzDICiwuV/bQDUT0hS9nnylBefY3evfJmZHsKkSbUlw3teEWkgWSFFoYZKrjD0UosDnUdhqwXwpOXap22viEKwFFMZcEbExbYCdz9IlU50T/gqFaCzKQ6LLlAgtZmsWZDhXhGNvshHiMgLfAbrCOjq9APhS4xr6ajVswXgCzkQJERdXYvjPAAFcLU2mXTE8vnukRZgG2gOwy9JwMAA2NTAUhn8Tdp31adBoV27cVT3uz2Y9oMzEa/6KAm0xD4xk4My+drXPRU7no2EUc1xJuul3LjLxDM6FZdt6uRCvTyrCSu8Ik6N8nTK8qyqEiTlSIdg+Cy48LNCqGr22zCKc3uV9iuAROl7opnBw1epeqWvCI5ErYUKS8t0xRFAtiS9vzlgKvOAq0i6074mu+uyim64D5sEF3rlh2gYpitWCZbF2N2rA2B10B79gplh3XRJz4updXESFHSCUv4vxp943pV9/m+sDu5q/oslKidsDlk4rxhWK+M7S6J2/BB516fes3B8E2TLD0PunKTbBa0U97B5x061xbbp4wUpvgfgRqJ4lsCjDT7dizDo5ct8BRpW2+sqFuwo1YtWedL4v1+3tFeiSglne1jdST6ZmYyYJj98BNOd8VptsnI1IdcuuK+PeJk8nQnTJtp6oPfwUAeUrkB2y0pZa7zwP696z/u6cAnaJhM7Uh8WWLb/hWSrHMZiHC7v3y/l7RHRVxJiCZTkD/PqK/5/foHkObIekA73NTXBquAPvPK7onZysCvUmwlyuO5YOpZd3pSDsrPzqCwO7Nga4iH+o63RtcF9meD8DNLzY5ivwM3jefdg7wdQC0LkeYuF2o2OVaWq4rcDdzPRmJi10qPtA0AvufCYYviT/Nt9WwJ7JCPet185WQyVac7IQPi7YsovTkKQAsK+Ls1PyV+wAwcyidYHNfGpkvTt/RUqImLv46UPteo0KCMR+v0XztqJpD25xu09amG20KNBM3CAvTaw38+WApqCSFzoE6ibpShT2wxAudpXFOXAzBA5OJYXwTjsFYmCs+AUvnUZ0ybIzDTlGqfe5eoYkdDu80uC6EmQyaXwERfRNZFRK3GnApaJO53B073CfepwpmQTYouBoZiMQlioPyju8Vz/S/VPvs6UhexPSSp286CZaDS6X51pt3XIjLdr2HBIe5OfoHGHDso93WlqQUaazPdAa6M2tmqKfvsoqyFgtMzwIKT2mm0WkmUu8zHcsUGLAr71n3GDDfFeQtdSIuqJNCUlkoFFiFxbIvwO6xQquXLNrKiXAh8OzzOTUq5fSOP1RAgqssBeNLDpDJO0V+kREfWeIuV4LtTwvGW/o4OruxduxIVMvUwkKgkTwdQdkHdCcyGZedE5r433649hakl33kcGAr9z7k+igyhtoB4ye1TWymhBlNp7D7giQYpxrnvaJsOJGqDkzVAawdiUo0XK1r4bbaoQAQhY6Rbblno9M0gJsrAOXAfC+MYT1xPIUzwNAzhTB6i45pfjySjKQdS5lg7szEBbhZUWla6yVA7WuzOXNjl+6RQOP8stC2DiCYCqwn1xgatVvMfcpNVZvDtpOtqlBgZZ+7dtpES8UG/IRNNoMcpvnxvHIg8l5x/oH394kFDfdl5fsrW2QwgNCnYjklG0BzxHZXZw6aEcwHbgTawkvb5NRYoJHNlruC5a5ivl6dqdSUpWEycZSNjoMC/WNoBDRfV/NdbYNpXL3pu0AKmm18vc7MOG0/BftMPnm9zYM4B8gYIefYAE4xZS5flAeZKBDOsZV+YWEGQAcmeimMt/Ry9Ps3XwnOr4PhGLVJ6h3TkQr0TxVhUXRnfqfdG5rrLjtrXWbOs5gP38V2ZVDo9QI5Jp6wkOZAFC80p2hzIU3MAgS6ISUQJ4A9kGMkQm+0YQhs+rHRdSsFVnVgcIEvDDtJ3MHIF4TjHBpgE5pYotAirjYWYjjFVsbUwdqicc0iPGtQUfRPwQbh8rPHS0DdVWTPPm4zpCQCmptKnKETlESbdy+ByCmwjouTs1zY5YCrOVG5Mah7FLpbkUYjQh0WdH3GlLrWrdh8xQ1V+tVwdL5jNrDsBFIi5itiDenClHe6Ad+3mpV5RwyoJmC5Jamre5vQJnoHwxdCQJi9+8LPnX08X7XOg9nPhYKmN3Gn9rJhx8Hnmno55F0NAE2Jme6jYUNANGwnG6kpnUiiAkDPjNahAoHlwDZq7ZxjI0CsiAZgqvCAKWpZTuXnpQoYLXgsV5xH0cyPlZhDGitqR3zAuxNx0ubPEMoaHLpTxflVRFzss482JSuKqW2JYfRHxfbNh4EMH0dgeLYJ2aaU9uDcV++5L4JTgX1+QlgAudDqrdWHxojzje0kH18k7hepCaixQq4zcEkMIIE1JUy+HK1NyRYgX6AOq8TbXaLFJMwyh1XgtCUqjiqWkSiWW1tIinXgiihdp3fMgFwx6c5EqOwchPuEcijkBxh1208w7YlP1ATklwuQrb1aBQjVVKCUt0cfp25uUeWSMB07QMzO/I2sZJ7JTnPzOyw9kILRcLM2Nex0ZxvB/CNCZskxviBHQM2UVwVIdnLmPdrw1nQGFrOHF5OPAwyCwxsrFcxPsjpnxZI6qQRR1bCb4U0wstKK3wB8r86GIdfByoTA5ylFoOYhWez1oLDM0gxoXB16U1s2GabVHEZ7bf8OZ7ZBw2yOYZlmRLU3fc9+LaPmAxd/GokrxEXtubIFOV0HdmkeFeMtf670/Cw1CbtoAajR2qnHSiPcF5H2dt13sStRBeGho+zW+u0+2LV2LCM8eDx/IAA19sH48UwhCXvX60z3pKBYbgtP+CuyScLxD94kvaS2UQH+Oyw8pTyYxDEYOq6NlwCgCbC0N4uvjgIZ/j4/E92aSXn28sYDoQ/YlWzSYxs7l84EvKrNhFAl6p6eYvMspNRZbeNV1M5abUto8ymbP4KVWXFes4wKK3OK0DyhAvm6YKoRy+JgK0+42gG7nwOb99birWrpMEHB457PqjtyMZdempNWHIG6FeAcn6lCV5R+uiUFOBiDk6PnpBmiNm0E0NS4vtk5cWnN5gCYfJp+GbWnh0E4CtvNZkcfTWg23VVTrKp1GBTSkQ8jS6ATVPUAbFJsk+0/70o5SBkXyyJtjqh/xprMG7RQS1G2xBBUvO2sKP2aecxXAc7l6C4KXMh/8G5ETYLhoTIoXwupzyPLhmXL7M1ZwtPNd7GUsM2BqNBKggpgNX7lHMram+PQxtySZ8HwZcLmLXD51ArzAC5uAHKJq+mJbShf+JLFCDm64hEB5DQYK657Mhs063b4A/KWkbsm1cGchLLZty18/XxTUINxCoJCwYXUPcQ2Si4bltFYkUWIFTyjZmvkqUc14HqK121FSQo1MEu72rAMOisxoKR5TeVD1jYZu+x4AtbO7nenkFihFwKuTP0L+jfRJkxpo/uyp64te9DIzXv4jFLn8TUJUMNjRd5wcjRt+CPmV4WYjBnIcEIzS4Lxk8rgax0oBLS5Ic7rCMZB6R9XkZhGpdHLEtgyjrqWakqqvAZjK+5WHwtNaiAfmZFkGZL1WUvn4zot2HsWaRnWVYXuMuSYbIaD4SkmbnNMydWj6bKWpDqhlV5sF68b2NnwGlmi+f6Is2LZCcog6I+K7qKQ4niCiew6wbgxebvR2aUyExsev4ulBGwGxMhev1ZzOLZOwfi6Nr1/947add/Yy8E25WGBzmtUlGUlADlmEN/0aO5Oz0FHCxqc4uSbi5FAI+3YZeYpMN/a77tvpD/snsBX3doCUi6oNmcyAbqQcANYM+UUeRrauLXGwQdWrUIEtCdNmfxmA69GmrzmQ0H/Lj777GAaPwryTTXXKcuCEvvq00trw52NqjtUqAI6Rk7PtpZod0/5Ng10VrsyB+uKeQeUiNZ/5/uQBhxsWlbn1OkAaKrQyJ5+su/Su2tzjgz+CQYqC2K2+/Osvcnx9Kv3ZY1g0LTyMcxcO24G41Oky3Zt6ZWtoh4y2Z4A1EHZZNoTJb4DlbX9PcUVCAaASzR9TsVwjohQ859U6K5gUnaR+ifFdEtfB59R2gYJ7QXpoq2c6E8sI5ZtMGxKG5iogdlZtbJBRdBfCvojgUZK8nk4dSdqLnytf2f9GNwPUWNFeowr88xOyGwTjqLRVMuGC76Y8w4WG1ZrSL9YxeHDQmpl1J7vFPU2c4MtgdbfvZ22AzsG7lNQewWGSmFUj2ZEy8EhlvarwElUTpmmhsI2aqRJyHxX+fM2ZTvMzCDSKUAnA8B2HLtXe20mM/19QJ5ZN7i9/DdS2GByZuXJGU3kpRErN0NYJsiMJhVebirdsa4y0mZBnlMzZonjamySbEBq2dipl4DLK2YB268tyCVgvlkHytYOCMLWZboQmFz2NndiW8g4vOdx77J6B+Fc/5APaC1aFUCE4CKEczTb6HrDGeI5WMdIWgcpGoOSAih+Dwf88lVhgJMV1KQYi+Qx72SgKnkvOZgew1qzW3Jc/IR/PsJAhwrkYG5TfGbpbPfRBgotB3zDfbpsVhuBeR+eGfrKOsrQM1YjmOXhGcYA3r80sQRedgFSFbuvM+ar+B3tSgCNYNK/YQmQ92gIf3qK0Cwo1xlS4wogRmB6TSBOpsDFb1oCCFuDdSHolx6iKTGFG1146iMB8Z74QrnNQKBKTTJbddlS13LFI0uWQKcjBQ1rzSuBgiP73N2zuhOcelwO7I35SDbPElykU40i62Yj7ig0vJc26GQxjKQKhVVhDAhnaTMivG2bryuQaUxTByBAUS2raTb3Ruph2hyhriuxgOMycydE1UGxmCOSB7zxZUCcrFRL/NmQge2XMJqzNBKPW9Dpl0OTq0tleejOzqEASh4TLeW2NqEqmDenUcwB2GxJNR2NMRINBPR5DhQjMfvxUgQwxmUKKKCYzjUUGhRwlaqJ67RXYA5U0VoHA0nJVekrQo4cIutM3JGvTRk4O0J5K6sNXQHCGeZtaiI1Y42mypajFrYf8yZAVJ9lChRJzQfaxLdulJUsUoHN+4LxLrbhuMs+ogwfli0AH0tgEIqfwkRmoBuyOkAn3K/Qc+T0J0N+8w5Qd/8NTOHC6Oao2soG57i3tlNUyBiQjj4piA9OTgkwglPtuSidvIQq68axU5+y7wqVgHIoWG7JoHSfgab3F0CGCjx03/BlDGPAsqfkt5pACdAWPKTwvX24a7pPJHJNATLCuBy8V44zhGOEGqlJI54t2EBQ1kb1AYZrZEEZI41jJwYTYBVE+UDh/v0zAxM79ZKu/XixhUkfCCAfbDF6BmFqWXoTyqptgZ3oCRzjN/PrQEi84rPm84iTm+zQjcmVio4lPBeYiQLlJqPM3dqu7Mz81Ut3z66suxRPYdXRdLyfTeQWQVFY0kaVlzPXwXMcah12JO17pSNs8hQ/XzBwvRuxelrY52vtWmGg7Z+AoEZi2gO1CygD0F0cuGRXY7oKBCiBVpZON4atzNqIad/2+jgCg90ITYrpk4LN5xG3/xkw3wScfkSsoH+g4Sb3zor6AsFIPWhaCtcMyEjdgdf6GoGq3OTJ5iNIEZR9bSWIwpSSnQmsemNRHmO74R6pYeWEj3hDIs6QOzQylotsyvuOLbHKxdS95+tlAwG/IapS1udlVyEurzauRTyZj+W82qxpr4hPFAoFox7nLYBoHQgH8sxerL/nDIrykh9SHjsbqcauQpgVZWs1u5G6wrKebGXDjS5WnrVhJmrj0Ewqny4criIKhIkiKx913zaS1dqXnyzYvBhR/9MrpJHOznEmCLzcKA/wZAFhT9elclMQJ+N77GtbRxzKI8DCP19H+/Hvy4bBIY7EfHRfgDE0xasT68oBzYQ4LFTL4iozDo0EffNB+f7b+oy8JJALWkmjEahYDzzS03lPQ+F3oy28HV4AaH3Hko1sUcX+Cwag8TZgvLNnVfhV+yNnUdQUsWw9AzMfCsvaPuT6OAKD3Q3d0PKcNFjB8N746Hu08V3L3tx2IZA9bQTEWnDdyWm+zjVgfViVgCV9Fon8Swaqj3kzYDP86II8R5TSEx00l6bwC3fVsxsnFXEkvQAL2tAZjcaKq2tpEUCLORqErhlM2/jPNooHQKlk2813FXVbMHzRcQ5CD7bTxkicJJgfoZFuRB0kZX0O5zpENB9JCYpukzFfImoQyGNEMo/BdNJWv3ZHbXV6WIB6MlGV8fWHe+IJ+UB5d3dEKzH6Km3grAN/xIiwIvdBIGNEXiK66jU58YHhwU8Nlki5msVaFuQsWG450Rw2JEgtOLu/hXtxyCLoz9Jk5BwDpyg7QC4R3X2gLZ0P/+2A7iHSEr4jCKibypXqdYEYn0UCs11vQSuagUsZFNmcmNy5evPWytOez9s5C92ltgG8NZHuPNzT2+L8mnMrh8eK/VcF51cRy45gJSXcKz0aWLscK6j9YTvyowgMUsAT/hyh24LxtVl/+dTiSKVa3pmYyH0CToJUuUid5FM2fDLpGLCEShMSsyurG9aNnHTE/3ePBg2K5dwBS0CaBLXCrM6wsvTA05l0ajRPB/pH6NoFEetQeClh9b3Y+7rfYltfFY18FTLg1vFOV3bJdDT+Re3ZLoMKtKvoH+J6MvVs8eVrDtzp30bUTpGveDLqfWotvzpHzCUgniLKoawtPqyfC6BNWJwo2Co9pdDdhVbmeUOlqBi7L04MKm6m06TMgubSBTv9fVAtFBjeBdTHrblZ8XXmW7pGh0LMQSMH9dTeHLknpsrdIw1YpFoJZ3hDM1OJa4enrTeglWvEAwDdZ9RKiX3Z16asLHtmbtJVaBHIJbH1LQzC2ldmp94Kr2jEqeezPjXQi6M8JqSR93e+IUi6eauYrmObWbLsyQMpAxmOaaJSctkHzFfr8/FSoppP5LgRE1TREYqty7Vj9G2vjyMwZCA+cSS9XCK9HPeKbKcGQBSXNF6fc8CHGSYAVpMvhxVkcodnKeZpaM4+Ia8sNbgEu2fWEJ5SYzJCzYTU2mTVT6GKtR2Z5ZkE1oCti6AUQQ3GyT+T1ATwM5SOQQFA00pASCpCAGqQhq9w00jrYLh7EBQINrZNO6aL6WLofVnvqwZtvAZNdIBOl44MyFeG0s2hEcskow37WfYryBgvZkW2o2eCFABvrGY/MMDNt9R6xHtuhOXKnJ7cI8PqbQ/gPngHQJuLkM4k5WgE5muSjS6vWXrFGcCDIL+oUKWmQMXwIG9HGyEqV139MB3cNQ9Q6jNghrV+o+zfZmsnALqfJyuTBMssWF6U9ceDlSI2e3S5qa0T5JwEmVga+ozNGhlEwkxrPqlG3DP/Rqb9nCKVjhXdWZA37E7UzuziJmVb0sDG4UkR54rSB3RntiefB4H+WBvRLM4fFhk+isAAoWho/GEmd0GZak639E6kw5GTUtDqQw2s8crGPBu+sSmeofzeAx8qCgLiRdCdGTT8lGRqR3RbrbQAWK96auo8AclAvqkIFzvxsAarJvWeV6OUpsUwgKv27LbUIOiMmixLaF0KH6ybzsQXPBj4BgizoNwUhE0G3nESTPeEJjgKFmgBtKEq8Ryg02DkKIVMAplSc0WWTBu1+QroVdq9Lhtu2tOPGbDmW246lhhYM6kIyMjMbnyJJit3ALPsKoY3sQ3WcS8J/xnHZLqjd2j4d/NdRTqSTRgXIDwmti3tnrn9vRRp8vXugWWNYx1lq9/I6BwjcuKUt6blEluLc/u1tgAdss3gEEXo6W0RbDiPz6hQz4wqg5orgT1gUJEJkqisezJfsyux/8oODhGEooiXivnQYb4SbN9WSFWMt9FwG3Yu4kzTlmr8BMeCujOZj3kj5lvCrGLZf1i78sN++ld0qdikoSPtuNwyzTsJZV/XTWObo7ECrYbMW23kkzL4w/7m+0gVmpYMitnJP6aCLBujJXtWUJ97LGgTG9WNeSlYuuniJA9YdVNJqS1AmIMBk/IM2LIauD5DotOaIWggwNgIMNdUkQIwANUCUF8QuwLdZ5qvTFwE7G6g0Ybdcl9Mdu5GLZrMEMRq8aZANZ1DPvCexQsIek7Wi69Mi9OFG9hnIvgGWK4YrPNW2wAXKTDEn7/vuAsU5uFgykzwXnCyk7UVTeDk7zO8C0gPEc3GDmhrw4MJ1bergE372p572fF5MrO0719NjbopWG4cUyD1uz/Ra6J/E6GnRCl2Vy3TtPewtei4iGA9kDyga2JmFwwLWa4Ulx9UzLfAeBOQB+JCpROcftg1Xse8D00UxcOLpVuYtZGYli2t3MSyjv6pYvuOAWUdp/hdzBiCWV3NgjqvhhvLFU/YsqcsOR2pVaguaR5NVmvdAURFFtq212TYntXrGoDunlOon3sweCpKXnvAdFfX0sFT+gCUPfUWomK9U350nzRd9wXhYqq9xSTdFShm/OKTpVRsk1hmoFGNU2D+EZ02GnejildAYEDkPcU0uAyoaYBYD19NLuxaEqluZMp7EdQYger9/lX0BQASV5PT6QUlztvPEm3ilb4JGgS7L6TVtq01uaXYTIeK/suE4a0pJoFm5+/3MZ1XTAgA+geqZ+n3sAaYYifs5ucR08uK5YbmJvEiGN4JaufGOuD3VXoz5pvS1gWyELtaBNqj3WsXHC3WClbjSeiAhg0tO8H2LaDVLPZOgvmVrdeZPJiwCKqVSZyQDnjrmKCx29bb/Etbe/FiZUamDf/mvmLZkfNRE9N+hQUXpUKy9oYVZECjYLqNzZUpFEUZAudUFrS5E6Un3hAe+H0+cEv+8ZeI/LqI/Aci8vdF5HdE5H9uf/5CRP59EfmH9u+7Z7/zb4jI74rIPxCR/96f9B4qnF3gYFA1wEaHymxh5qlWNuspl44U48RTXGcimrS5fY78DHAypDkYyzBkK0esFq2dYjlUIGlzPvIUUao5Ki+CcA6NbBNPAe7rIDM7HeTc24M1fgV9ILnBOcbeauJxRc4hJPr4JG0PCDDkXhM3fU3MHNJRAGHgzHvF+MpFV7KWIKYoJcmHFOplr5hekszD7GUVYrmI7DlIly66zkUszISmWxsbKEyf+weCxeEc232LI01jo3kcwpBxH5xTBo5nl7y2QsPMbKF2xr48u2PUCiICjklYObKYtd+g3yj5SDwzTksTQRlxy5yaSPaiXycnfbE1zc4NcPokYNkHmqp8rejeR+gc+Ty3pdnPqQ3t4RAj6zA82TQuC2bdcQ167scwvCVB7PjjCI3S3KW6EzGL4aEiTiQ7bd9U9E8EIYfHwlF2wmBBMtTq7cCgTcA4DyRY6QemAN/mxzOA/6Wq/icicgXg/yUi/z6A/ymAv6mqf0VE/hKAvwTgXxeRfwrAnwfwZwD8CMD/VUT+SVUtf8TrN6RajaSELGasCrgasEY0I5d4ehbPzCLdJdhsC3nqHRrNFOCwUai0OZANE9D1BENB8zyobvohQGhUY8tQbB5F90DikEpYefpW5y87tktljDRXsR45wAXSPfE0zwduyOW6NqFSuPgMB7H7YLVk4MnY5VWH4SWT182SBTAiVDC5rw9FETWPwp5syGolRDlUBroZNlqOXaGyAcYXAp/n6W7YYeH05eGh4vKaTtXD19ZJStzk3VEx39LOzH0Skg18CQsXcRwV090aHAA01uVyWGnWy02hfduyehg4t0CjoruPGO7FhtdoI1vprtC9+ZyM6MY11bwhbRBv2bLkAzhirgyK42/wfpJI5eBigA6kSJPctALIPhvUB8ksByNUVZ7yTpYj5sH7/vBbwKs/8xWe/sNPsHlL38rzq4jNAw1Yzp9EqlmjoERpY+7dcWzamdYjre3jNJlp7PDMx+SX7fmoqp+r6n9i//0E4O8D+DGAPwfgr9mP/TUA/wP77z8H4K+r6qSqvwfgdwH82T/2TYQpYNkX1olubpIFuq1Ngtw9hOak84tUUFnMBt4wgjizlnYarNrJzf+211+k6fWft+mem7y4v0Pd1gZIlm1tWo6yNZDLmJYamTaWDfUOcooreSqQKekLOm/VOhPrqZ5tvJpnF82ANjGr4HwMIval56bvHs063VSU2Ug9jp04h6F/Qvte8SkCRczE1APrCho6Wad2DuSpsTntHmyIq2zfZFLNlbqKNh5vY4azyXQXpimp0TEgSsFrD3PCRkvF3QaOhC+YejGg3GS7h8yeyr6u3ZqOHZBok6edus2HJ9ycwUcFWraXpXWswrR2rDzTyjvFclWRrwrml5UHSwXiQ0J6cMcmbb+nkf/tDlR5u4KCeecgKYPF/MoUxAtQlToS/3seKgGXlxGlE4w3wcxh6ceweV/QODBOQJupwIwzKdQaCEyG5wa0H3B9UIIhIr8J4J8G8LcAfKqqnwMMHiLyif3YjwH8R89+7TP7sz/ulZnCuanGLNB9JXhXIh++g0tipJErGy0fYH8vzZOxnTg3KwjVrNguq1ux4wFxknUQiQtf+kou/EO3EnHAjVgOxqZTA/vM8RmGjnv2w7rHiE4ZkBJQTfwlmRuOZrbV5kvyPXiaBahnMZY5aa/QbD4CBYAt4N0btvmml0xlo1F1q1jKnegkXLYr07L0Cj1kpG1GHTf8rkskDXvH4Hb8CUHf4Q3LleW6tlZvvAjmK+D+t3qmtBeCYt5VgD2HGp9lcOYM5RZ2MIB0eGdtxIGnbNmQKOVtt3QB6qNgATkYHHJsuM4ptunbeWfPyDUNyhMe9pl5ohsQGAHd5ybPb7hSYYCirb4ClVJudjCYxYn5LUBXCz7OvOCfzde6ji3sK7r9gloC8mcbllOzkAGrwPXvAdPXr3F1YklQenYmVKw7cqrNAzIsxBvyJqHYdGypYHeis/JhqchDIBhZrVVpeMOHXN+6KyEiBwD/ZwD/C1V9/ON+9A/5sz8AiYrIXxSRvyMif6c8cfZcd78OQQmniHgR9O+oaaB8GIaQC+KRkuBgnQQq1xQIqz6BAI42+zWkSrckn0y1rTZ9ymrZizA1XAThEhHfduYnyJ7cclNb790XiH9ed5v2O+B1MSm4dVVrwrMHR5nR+Ale2rjXpPtOuIoSANQGswLcjD77EbDAWa1M6rUJsarV4O6/6NOXJFX85qdvGYhmbn6fy6AJbU5D3isWU4cC3OAhE7PgoFa+v2cBbhvvpC3/PZZn9u9Bm0/EdGdB28BHl9x7SxoKbL8QXP/DQGr8k9J7MZNJqklJMrJsaLmu60TxmZmmdubj6OK2jqSkMPMwad2iTK/L4a1Qzm5kOr+HzT9yuwZ3TYr+Adi84bTrkIF0tDmgQ0HJAfWJjFX3gkjHtQXfP2grD5xvMF9Lc4H2TQ+Qu6AC9CfF5VXAvCcvI++otnTQMW8Dskm3YVjEh1zfKjCISAcGhf+Dqv5f7I+/FJEf2t//EMBX9uefAfj1Z7/+awB+/ouvqaq/rar/jKr+M/Gwby0z+i5Ii9zTq2ImH1xModjJ9LSi+CTnsFsgi6HwJqQRq9FlEYRjQjgH9O8jWW1mZuJ9cIALumkQTAWJ58NHrAQhP17ZTkyGvoMtzGxdFM6t8A6BZRjbQkNYs7JfvzM3Otl7Zvxp3RJ2VRTxKSI+hbXMiQxQnBBtZK9oZjYFzTYOAY2v4ENSEEBKdCjMACy1TmdpbbbhLTkfZUvcJxk3wvkBlA9r2+xclEDprHXa833CRBv5mrTVu46lLFeC6U5x+jH1D9VmTLZSwhZ22RCzkELsobFOFWSwbkujkjv455ZtcRIMXyVgsmwxErQe3kR75tJMdL3NW2yOg8Def8tn5iCtmM+Dsx29DPCSSBOQHgPizzaIP9tg/9O0anZMUh1HtMEzbmoTDIztHxXDQ0FYbP6nKVW7p4LNw2oLj8D7sv+ioLuodSYU0zWnrjsVuv6y/RhERAD87wD8fVX9q8/+6t8B8C8B+Cv273/72Z//WyLyV0Hw8bcA/O0/6X000eQiPbFGnF5os0l3Fd18UyED0zRROgt5GeAprqefDmT6/IX0GJuQZLmpjT+v5szjI+J8VqQOlaqfhRumjaGzBRlHQXlpYq2ZqUFLYe2UdIm2GvWvmvEHUWwXhME8EBxUYz0Ne69srxN9AO6ezMliXzRMDFD9gykPBfSXAGdGYOS/1+GytuBHQa09/v7lx5CZKlMJBMmqDVJxFN2p2gTWpJ3MFGZVegnMzwbYPGN0pqO0NqnfQ06wNqesmazN5VobMcjB5BZwqhnLJkAKT+fpxdp2RRHgmJqaVDvF/KI2oLhs2PEJU0A9ZISnjkHp4JO6KnAJ6B544kOBy63NAjkxE0zu+6liA2n5HeNE/KKQZ4ay1dZZ8nUbMoNcY2ACcG+GOgr6E+eHbN8UaOIcy/5YcXkVm5N0d2aHoWyD8UYUm/faBv+ExTgMjwXLpx1doy2TSxf3lPz217fBGP5ZAP8TAP+piPxd+7P/FRgQ/oaI/AUA/xjAvwAAqvo7IvI3APw9sKPxL/+xHQm7XHDUP8nqUGPjw1xy66lt9xBbO86LFPc7qLPC1ZdSwBO7rJsxLKDLkg8PNU5BWEAq88DFUJeAOnjmoBABTUMCzVA0kJBV9jRy9TZck3cr6HwtgGbOt4AowiWugSH5MFSFxtD8HH3ykVQAnk3MrGG9JEKx1mnmAi09fz6cA0pfLfvgaa+JhieAk6TQpNylF4RXE/DFgLrR1oKrfUVNTKVjYRbmGZmf+q7a1E6RbapWfEyNOyIZ7fvBPBVptGsUbhtxrwFtviRg80XsVC0bwx96noSAAXSzAD3bnRSmWRt6FpROmXUV37Q04NXnggF9BtxNwQbPoLk/+5wSx0fkaHX+bGCl4Rpuey95zVLihUBvvWd2kHdoCmBs7DseDBRWwfwQ0B8rzW4WKyeUa1LF7AWE2cx0zRanKIVqm3cZ802ipuJcsewjNRO363AaqKD/Zc+uVNX/EH84bgAA/9wf8Tt/GcBf/tafwlI/73NPn7KGHDfEBHzzShbarO8VwzvzTrQev0yBJ3UHIFbyFYwopJsKrbGdINGHtqilY/LMT7LYCPhZIIYR+CZ2L4YwrSepmDVY3q+LLj1Fmoc8pZam1k01Vh9z48bMs7Q+LALtTeNxXgfEMOgEI2QJxCjV3i2J0yqpzXsrHZQAYDry3rp8umwJIMI0/+EcgKjo+oxFB8SjgWwmFHO+RTryXlCwsy6FOqC5ROWrQmVs8YCwlmJ1w1M5nviMyo5dFVGmuGqdDlmA/e8D5Ulw/oEFfV1l2sEC+2I/7/iOlwyru7iXhdJeQ2NFfIoIj7SV8/KvmCUfNLROF5mtxmg1ELMMK7+D5LuKdApI2YhSPcVfzr5c9hbYejSdBoVd1i62LAzwDErMYMZLEpsLUUy0VxgI4sLs4PKSZLraEYgkXhUQp4ruqaLG2ADgZScoHwYxfBzMx+Zuk53cYn33LMDtgpo7THec3luLQG8XZDst67Cy6xxVdsdlsbS2wtx3NpWuOReB+sxLozery6A9fbZJUK5t4AmzaiHSieAb2XdmWJuUZYBdYQoN6PT5Dw2A9GTHPmsx27I4CvpHwdhZOTKHNgSm7AxzUEFJhSnzNX9veEd2HK4XyD0NYaZPGCS0DYk14HRjcu0KdF8nTOMOKZPdFy9oFFy1AFSnaOpJew9RwMamhWKtviWuG7LyZ1wyH8/mrFx5GscRWO4qYO3CGtdaeL6h3L5/kBawKQKj6Gi+4jMLE4NrvmOLsL/nZOhq3aX0aGa4Zu3nTluu+KwbU+maRZuzYaeXJLmlJ3YzNPtnF1QYndpmRXJsnw3nmdeMghwG5ToLzzIcoA27DQvX0PBe0T9VG+ZMZyb3aAzZMoORkmziGIr+cWEA6wXLzg6NBejuC7pjwXKI6C7VAhrXo5vEfNvr4wgMRgjJJthxyS0CEKKauCkAFyLM0y6gXFXEt/6wDfzJa6uqbthyS2duYBUgjOau1NmDPaOx5gCeoM9rZN2aLsJOZ90W4Cnx9TqrhQfzA7BMzY1WGoBqxJmQwbKgrih4q1FhnQU73X2xMWWB2cCZoYxae8wIV3VXW7AKC5BPiUNUEojUX2LDM+KFKHXesbIrRoFOR5vBYNT0+UVh1jNYJ6d39J/fkcIz27CFPhjFBsvkPUsxAsQMGrRGN7T+bCYlo9hUroC6LyhF0D1SPu4IfDqbh8GAhl9o5OcL5qmhg5m49ELnZlevCrsE2bQRUkiQk0Wglt1pB8g5rm3vyGcdbEOnUaALmj6lO5HK7M7gy0Eb3hJnlkJUVFpwuFaIlZiONYgyUJaeWRNEMDxSWt2dK+Y9BVDDk6KbdJ1paRjC5UW0zIZKSh0VS2C2wSBhAq19QH+qrcQc7n/JpcR/GZdzD7xeU4HRYwU1k6oKZUROM0jMCSTJpJMwldtVpCM3UjpJG3zb5kwaMEkqrP2ZKStVmK6JMeJCNuQ/KlCIyEuFcem52fLOUvKg0H2FGk3aa968Z3AK1tqTjHW+JYC6K+wyjHRY0l9o4XFYbWhc+3yoQHDhjsHl3nHJvAfdiW1cnziFbH6GVlKFmXVuetNxkM4zvEGHCl0CyUrW8nQyD09nYNmUZqHeWpCVCzksAApPt5pIJCp9NPMcNKt3V/vRO9H8MqzOrx2xpP5RcfmEmd3mrTQ/yemTQsCxcRME3b27gSu69wH5wMww7yviJaJZpZmPo4PHAAOwE+CcUg1Xty4MSKSwczP7vfI15u5VbBdamToadd/KhHQW5OBU/rX089bxclCcfkihVHeudNW2rKF2gu5SrVwyO3mxmR0dLfxFLeBOlGBLWedRwP6uf8jIH6iu/CgCAwDMV2xFYmR5UP1EzsH8/blplgOQHiOZkvYAmcqFpv932i5zdWkOST6rkACkNu8+Hy9Gs9YA11yEfUbVDmI0XzoqSQOfyJojKl5dZSf8WW+vagLS24B0trakmb7ki6H2Zy767iio5kmgYkBjZwCfdwGymZOUlcsQik24QkCd0XQgzQegY+rt7TSOZLcWbyVLEgakNkpvU4jJKo0O6/wMCoFoAJNOvO9VVkCzbtgS9PZl80Sw9hlt3IUjCYW4Td0XDJ93PNl3vB/nH3Ec3PZLQ/qFsm30XpLxFHGmYvNfKAJU+YakXjt6N9DFi5uZbdHVTIcmtAHLXWmjAMLXEd2jlZ0urLMhOCSZkYDlAiaauzJga0ZjVpZA0pJ3WzTxM/u4u9rRsm33piBvApYdeQyiVE92Z8XwWBEy13UEpdhpVJsGRst5d8pyMtTmoSAstBT8kOujCAwaWT/rAkxiyP9FsNwVuJIxeA9aeaoEm7K03NTGXAtWi5NCjG8w2gCmvaKAqiBcAI3U3yu4WOOEVlvmPaAKM3cVLNfs92vHQS9twtRo6b5P0eorqp3UXi64lJl6efvSdUW1vVbtjhYU9nY/IhCCycCd5GSCHc88FIavbCumAQ3jqObD4NlTMHyjVGPoCV1/4hiQbzMwxja2bkl8Te0r5Cm2VNje8Jk2w+zX7lkGHv9UIdhq9yRdYJ8VK2NyopoyHVkSAGDJuM0Q7RBH6ivCYrwM63Dc/cMZD7nD+EJQ7ywjMiJWPhg+80RwMz5xrbjoDsDq+VgZTLUoZCQ1vfFgRFunyoHG+bYi7GQdB2hkObp282eoolRIBCYz53Uhnhgl2Wnz8Lex2ReuIr7+PcV8RSpzKGr2fdKG7wJA3gRoFHSnYuYs3sJFs5LvniryNrDMCCzxyouOPpgfcH0UgcGNQniyW+Yg5s9gdTFgP9PxgdctKdF0lmb9WDrKZ9OFabibp2gExTTHSMaczw94DnRWQ8srU9jaK+qpQ8wmTR7YIpRsgOKG2Yba5/IJ1LqzeZcm9HJNhbdXx1eW0s987/nOfAE8iJmhLX8J1soE6rYgnE1J6gizSpMS61AQNgXyxUCfiCkgPq4YRTRzl7o1BWGPZq5aj1ZyGDuzbombOOPTxV7LFYlXLnCTLIiX2OrY/p1N/+qI0C9XaCWcp7W1F9ToC1pWVuqbAWECyta7QibRHvlVjz/qGls0joBPfAbWIOk8gdqTsu4KT3eOylsKmMqOJR6JUOQFlKvaMCbPklxop5UDhVXWAOlzL+NlVX66EpQjDLVlGunItZaM0FQGbeQ8B7zLwBFzooplw5ZkmpgFdKdqLtEBUhT1JhpYue6hUIC8EcyHYK1LCtzyLmC6ltYB+bbXh+UXv6JLgeaNVweCYp72BvNklIqWPfAJsb0I4anQ3ZM6DTHDFkXTTmjHelgKT6E4kvZa09q3d+ptHbS58lCFSX+G+K5rLSyZwjr/Mpk+wWzDsZgFufEMxFLdvKdxyXJbMf4wY3pZWZdaJ2Z6UWncccP62PEDZWLSwEavHSHMUnwgbnhKwNcDhnc2pu2ZZ4QHIgArXhKcFGZSb4AZmvk0NH6C2a1zlifLBLcoc35IGYDpTmkG696KYQUM24bsQaQ/rdlUOq3vBZgQ6sLN3z+ZYnCySUzRT2EXLfG1unsGzHxdUXtiPy1YuPDNSFsUoVXTrMBG7Nk6tPJTk+EMmWVm7WsDl/391/tKDMKDkpvgNJq44UXAN0VVdI5a1/1i80jmA7ttecPnPTzRDJZMR05em6/Igty8KxjeF8wHwXhHAHN4ZIejOxkOpYrtu9rWwre9Po6MATylwyTI+4pQODsAQJNT+wQoZyj6HEe2tOo39ARSyJd3Z6R4CZAjN8dybRsmgNLjQtZd7XmKeKoHGKIu62u61p80XGNGzubJMK/pInkHRswRI8O4Q1Q1DMXwB+fit65GT56kLNZhMX1/eh+gnY2UszkZOhCQRA7mZyBtswPamHf9I8HQ9C7BGZV+42lUYov5Qh5C6flhwjmi7gqWwzreTVNtprRqgVxHYHlR0b8+Y54PrWwoA+hKZDMq04VZA2dXrO3IcGE2M9/QAj+dmDmFDGzek/EXJzOg3YeG5Yg+W+/GyIwGTIaFBwBJYUzpNbDl6r/rpirage3rsGZoz1m06Ctb0ce4AtdJmzbGsz3AKc5cy6EA4UjmYd4Z3Tqb0etAenXdMuDShlAaV4GeDIp0Kgi7iOk22ntRJyGVjtAaCTzKmVlH3gSkSTFfhfYcKhTD03e0K6FAcy/yeQ/cgevp4BwAiDauAs1KQyMExSdShJ3HXnbkAqRprXPVbMKgbPelp9AesttwQdktSKNgsTIF4Jh5LvoINSNVFDQH5HCOPI36Ckhs0l7qL7T929t4ted37EydWDermEcyjKaM1l7Ne7RsqAqB0v4+YH5ZzMzGbqql3VLZmy97MvlksY5DUJSbjDqaXsDKtNxpG6xbt4qwy9CniOF9wPhphg9qrVuSr3QJiL0gXATz2AG7yhIwEt/g85Gmr5DCLkuYOStkfG3PtEibi+EgIiowXQtFVnaSUy4P1O3abVHTnbjfQRhp569GCsudQvv1+UPQBF7+Z8FUqADt+ovb840BUjuUjYm0CtgiFW0SdOef+HBegJ/NOzw+FMcBdSfmQQXpkUEhbxkUyJzke+VdoCFsx2xguol0zL5UDpMRlhD9kZs+bwLyQOCRTEkGiM29Ip2/g4FBlEYhsthYOOuT070poEZtNaOCNzvfVLLd3N7N2kx1o+20kCKYkwI3C7IkpFNoabFPL/YeP1M66yzsCt2qVSAnad4GYTJ3YgtSaifrL+oKUAFYGRIkUEKb7TSyLMfNUEtinRpm9rbdiKZNvPbXFG1gl3YKGMsPSVcPBWt7xhEQZYAsA8wRiyl0f6JbkHZAeExtM/gGQ2Jm0d8L5ltF7hPHdFRwWtUDA3W5KpAcrI9v758qSl+R7yrQKYo5a4UFmG8L5jGiO61sxTLwBF9cQm/ZGdREU0+roSsEmK+YSXpQFUf9e21DZrz1XYYVmAtlHTvgYj237lNZO0zfkM0LyNLs1cqw0MoDXNagTm2LYWOzSenV1uje3J+3zFzqoKsa11ullv3kPbD7iutjfOEWWliFVVnQH2vjNLhbE4MNqdRS6e2YN6SIe4tTraT4kOujwBhQgf5tbKk7nXotTbOx8rAyqW4Uy4vSNAmOQWiAEVXMyGSnyPuK7jEgvGWobvMLBTQH3VW4pZiba2hSYOTraFJMn2amqBfLFLZ2KvzChqJfogUIT/EDyNLcmS/EoK1eFStnwswTfL4zvGQmC7Ka/Zh2CkTf4MZkdD+JAGgLoK5WrFjuKv0AxIKRKMIporsnOJjOQiBTYQCj2NyLwBINRlS6CAMQqHLVoZqADSsGElYFaAgVsuE4ejnzeTZNAqzssM3nsxz4kG2TyGq55n+XLhw60x0VZWtlY2UHp9nqb2mgUje1ZUnt8hbmIubF6UQrx66kqVtRvdysjRmJYP4Qk8+2WLEFX7uSLbAPLANrr8gb08AImvan9oZ/GQXePRxEgelWmTUsdIH2qVVh4e9PVwHpVLB5uzTcyaXUwwO/8HTFzCzO2qZih8wMo3bfxXalsw/tITjSKzMXbbD+PNtFFtULOw/ki/MhNG19XxFGQ9qTpd19RTnwKCDwGHja7iqCiaKggngyleJNhW4L4qagpIju667hARqBcKHZRtlV4JBRBmvUKxAfY8sKjB3cDG7dOQpVkA+lnVLakyLcPUQk904EUXztarObc5OQep2N1iyGsJut2bYCfYUc0wpUwjCEp9CQc021Ua41qgGlVG+WTUDZcZBL/z428VYYQ3OViufQ/CcdrF1OfRsAy3F8MEcngdQIVGI8jmkk80Kcb1dEn2a/sKAjmG8IQKpIMwTujixB8oEBsY6RXBcB+vfEd8pgnZjBj3+wvDIOQt0pnGUKrNR4rjexCVJe8gREm/TdPTCTKltqM+rAFnA6G5azA+ZeUW4LuvuImhT5wIMnX5vb04IWGN0xSiqxh9pRF7R9W6BBMNzPmG47liJ9wPmTrjk4TVeesTGL2Nwr0lhbSzbkgP3PLjj92gYfen0UgQFBkW9Ls2/vHqXZhdVO3e6Qp2cl18BR9tqBk4eMbgxVyBLa8Ne6MfHKJaAuJpTS8A1Fnotm0sVPQfAEnhPKHNa+vE2W9iAmE0jtDeZTMFREyzaaA3SqQI1kyb0Prc1Vt1RS1t4NaKQZ3jK1dfERMwaNChkqN8EsUAm2sHlau2WcLALsq01HCg209UE9ZTBc4yojpAqdewqh7JQNx7QqUd3N6roCz8a+u5NTA/AE6I4B6dwxcAoAcNCPDxlOp7Vk0wFmQafttGX5oN/oErjTE+tvovqh8N/VOAUQsF27KQRhdc3+gmU/9ZmDl2c4LEfU7t3aHVqu3TGc4+9gfIM4AwXEfMrOJN3ngP7k9Q8/d5zAPDxqa2XXyEAkdW1tRhuR57Jt95zYvtXmvUBmZEJ3KpCiGF+6rby2v0dluZG3garMEQhLRdkmpHPF+MmwApEfcH0kgQEsFfoKVC6o7gkYh/Xvva70ycJONmndABs7TlCOnYHn0maAryEmvtEBTeyjQfi6Km2DOVlq6QT1wOGpbnASZ2YdZaerqw+AdOIpWvZGmrHTOL/IOO0JFJITIPR+USs9zMU4HQPiLJivWea0dCPVJt/maDRphC+fVuUW5tgoYqrIXYXczBj6jPHLPep1Rp0D+rcR2acqfT004pNU66urNGp53inSyOwg9zzJyoF+l/EYoV2lxd4USEE+PZvfCNbnZfCevvlCFIGMJrAyq/vu0a3T1tkgYeHJHBZBNqJSebGgHhOZi/tqPAIbsQcAQ8Vypdh+Kag9T2bpAB3QxuSFhd0CzIBzWSTZJi7MuGoQlL3hPSb3LxbMRMnXmG8rjW/js2Bj79G/D8g20aqaQTC1EuEbIDrBT4VATNMBXP2MnZzpOhjzcW27x6kidgHjy4iQtdGi08h1MO8FNUUK2qqibs2cZ9QP5jF8HIGhstYVow0Xk7Dmm2JI9so6Y9FmVNvIiOviFihT7aBomxWWqrmACJXORNmksvESVo/Iq0qJdo4MNNHS/6CtBQbh53MxVvcYeILezlhiZ/6OPJH69wG1D5jvCnRLglSuoXVUHB0HgOQtQDeqtSE1dVOB0TjH0eqCAGB5BqTZyRwvgrIH8jkRWHxKmF5PwNWCH7x+wJv3V5Cvd+jeJeQdR+hpQVOQDm9Nkjyo4ROmAShAep9aBiNTQLlbkHYZ5e2AujdRltqpWmlvXwZBeblwJqmgZWdOFOKEMW0UcIBZQu20AYgeeGtSyBht2I37L1pHotKRqR4y8qsF89hxHW1MZq4Agqkkjabd6OvRhtkYT0NmmutIFshoLVajpceKRobLezTD3LIRE3+hTQF3JutyjYZrAHbYXKGJ56plhg6kjneCdLZOg9DQ9fIy0r3JplBx+I6YPoL3Lc6K2EvzjYwLs4r+PqMOBMA/5PpIAoNYu8nK9P8fdf8Wstu2rgdCz9ta671/p/80DnOuuQ5ZO6lkg0kVKIZ4EYTSiBYqphSqCCLkIrBvCqruKsmVIARyJd7oRfRmg0gShCKbQimrIkHUKkOCKCa1k+xkreysNQ9jjjH+03fqvbfWXi+e9239m+691xoDKzDWB5M55z/+8f/f13tvrb3v8z6HCBqhCrgoZ2MROlgrLNs5DQgWCBJYCXiAioFQeQB0XSnGKhel3OgqRyAbfqFm3+W6/nQShBIwDfSA6J5NJGVjUlEg7gXzDTjBsJ4njO7mBEAUw9uI+So0X0En96iZmIQjLdTiaIauVkHQ7ESauAcRjUvhRiFON/ZFrJELiF4HAB57hLsRu37CW3CxCeyzBoXsE/KrGSiC2XpsBzfTnp8hzO4hoOaNIcg7oEyRLVrhBMZ5JTA/hjgCRWx6E9j6xLNgelmAQHWkC7makM4/c+CJqoMinOw5URgDc/FG0E4tkxTQ9z20r4YNsH2BB/RgOSw8+MXBWq+4vN3JWyMXvQst46J5Naz47+F9aF4e3TMWx+snNKzCHaUAbkpO13dnKOeeUGXJ/ctJV55ExueeAiv+j3FVYFVUT0HVtGMStqeCnW8ZkFtWEWUQCqs+4vVpbAwK440TLYvWc4ZjIJgmyjIM9tzZTB6imG8LsvXD8SSokAZ45bVNAQr18tzdLYRl4txcA9HgOhQjTdHKHgDiRGQ9PSZTxrHXnLd8QCib5keQQPmvpuUkqYO2cVeYCViWlSDfZGgnDPId6neCdn3mr50Z1ECoBVBBOIrZ2LNMDTOnNDIxP6NslBwCewbC6zNqDqg54Gfvb5GfeiQBS+wTK5fuOWDWRHB2a5ut8RjKmv4T846ndjwbYOraE8MchneBoSamPvSRn1RAnjro9cwqQGmPT9m4XJTi/Ozz1aKQlQLA8BgIGZKlknlZV6Qv+8JypS1JSWJtRkC+5vfFkb8jrwl4OnaVbJPzTdyFWMGmYKEAJQGeWubycQDNk5LVkbF1lSSj7tkmK4nPQ7UnNx19A2FEnYOzPAxZ/c47wfbL2gJjNALrdxm1E0xbkpe0guNIm0zFUdEfgOGRXgylZ/vAjUyQDnUha33g69PYGAA4hRawi2w3HRIa6BiNX94W3goIVzPqMaEa2NW8CSagywJNZCa6hXhZV04k9k5KASCKeIg80Q34i5bm5D6w1ei31WzgPDy2DPy59ZToP7mp0E4ghSdk/xQwXdNkhvkFQHpM5ghkac32oPgvjGdBLX5cwPwcXNPBz9kYePbKO1Yj4bxsgvP9QDq4ACN4bbpnO11TQN5xLNq/D8jbBfgELwlJXYOd+FXo8HSIKHcz498CULYF9ZhMCMfNrK4UNSikMOEpS+JG7QE8F4lVbk47X/NEdDZoWcEIayzNimk7mO5l9nsDsYZ4CBAjRuWVjYOtdC83GXgkLyPvOGlQq0q8RSiryvttVGonzjWBm420gWViEkYgiY0ctxfjbuH/zzsbO04UahXjMIQJGC7cp8vgUxpAJypLRYHt1xnjbUQVwbQzUV4Q5IFMx9IRoB8eKYYDgNPLRD+GsnA0apTmV/KRy/ETednueentGE1II7PNmm0s1D0GCOx0fe5I0VWYvdciZQ2FWY/d49LPB+shvVSFmp7fo8We3DHJQSdF3hXk1zOmKxrWztdEr/PGDEgMWQ7mHo2LVqNG8hd8Vs6MSeY8qtvWOxsRXFx10AZ+LoQo6yUt2FYdb1CSjerNgi6FkYi69hVICulZAfWfH1FWdJV2s5j589l8EGx0NpA45tiOzNIyIOuai7J707XAmnAm6zJf8XfUXlG3BdqTbxJmY6bagu+/6hp2Usxj0isTZ5W66xGqWIq5tEXW3wek+wTtbDoQyDFoDMgxUPAmxlItgrItDMZNNuVacaOOI81cgpmsaDCMysbj0w03pHnLA2C69gvMk19Mxn9Jbrt0qq6GgVBVKs0dOh3se9wy4AyLNrT3F/n89E90vp6u+f/r95kmr5n3fvW+on8ulF3bZpDOzKdIJ24YNTHpOo4fVzJ8EhWDKKWrecP4NR8bpjMMmJRWcnlfp4D13MFGfWhoeDzZbmm9pVtpaQA0AxLM19CAu2KmKz7nT8Y89FiycA7QwhPqdFcgk2D1rZmoWMiJZIKb6WAimK02N5/06HH2aJkOEI5V/YQuAx9geFpSoRmt1EXR18pB0wWEMxmgAICLLIp4BnSTcXV3xOGnN8CrEbvdGU/3G4QdORDhyfworwpmi1gPFuHmG6W6fgRsL7SrqKvQevXuIVoLwDZMRRvmkB5jYwpyc+CkgCU8WXl5t/TN6cQqoQzabPTTwVpKO7Ul2sjSLNpaVWc4jMyCcADqmTdeCr07aqetCk17gSg3ac+x6J7ChehKMLyHWcAvI0YIDxpiHPyzeOaB4ECtb67UlCwTCbG+n/kQfGZc3xPdJbsjCKqwUe6aoTHOdoQI5m00MyPe//6p8JlY0fptvCHIm04GxBfiEzJVzLtfQYyBpaQ277/mvmsnRZzM7s1dhc2YNRvn30eIMCntfI3vSJe9LSlr9pWlcLRZ1trYb3DptXlCRpP7xiMAhAYklRUaJjDck5xTPBKuI7pcAh1/yMfQFgzj4BJ/H9sDTRfGoBPLjDpo0zZ4JeKLwVHxMPKhwlNs5rDaVxpOzQE4Rxz2K2hSrNcTfnDziKe3W/IKrvkwd+8Dpg2NcLRTYBLK0x8SWwA7sVEj78vARZKvC/q3ZFGev5/bJudVjPf/8STIVyQi1cRcS/IOQANYJUYSj9I28UY7NspzGdCCWtwVPGShC15vjlc9T19NC14BQfPk9JGfGLW4GoW+TXRmQPx6wqTRa5q9LgxTwKnaIQPZdA+CZaJRe1aIq3fSGLs+jWgsxrQ8j9HEdRrJjIUSfJ2vArbfUDLN6UPFeBWsijabwqzIm4h0LCQ1Ac3+bbwOVF8+0rdBo2C4/7h55SexMbgRibiL8wmQTjG+qugfmD4Uz4r6wjaNDqQkZwFs/t447zYb9tM5nhndPt7Z71IsC0nNssvpzSMXs5upSCGw4w49ZSXQjifzdMtyP575XuRM2benUstM6nFNrGDCBIQEINDe3JWTzh5UIYBJaXdl8rJXNEOFtsSsxZmpUZ7tZMI5NZESANSnDoiKnCP+0c8+R/e2w/obwTh1S2vzdd9Kd89x8JI4uEsRFuouDWf4IJe1Al2FmD1890z3Iy7eaG7QFbrNKDVBqn2mC08CuBs1HLR1DISLeL6qzU/R8SO/N9U5JF7KezlvpK6yrg3DQRX0e8OflL8jWzvgwGI60CRmvKNytY6haTLKGkadt80kSbsefo8hMP8O+7k2BfNKwjf3PKAFEnv74NWHt9EQmqwAYCsyc7QcZlY+LqLKqwRRYLjP5hvJiQSA5gQ1PFVo+lUcV8ImDWby4dMD78GlMn0Ipk7UXUHYzqiHDjIGQ5dtpBYV6Rwp3bVT6PgFwUuxbIPFXhwWfaeN4uupweOtWFKQIMyK4UEx3gjiSuwks3i2DMTHuPSHzoq0cWPIQHcAzi8NqTZsoUQ6SntOQzQ23nxdgU4hE9rird5CKMeCc/Cjyhta42QcOWnJAOIYm417Plm/43N4154Enurj6wJnEMo+2abFyiAeaD7qLMIwCsosxBQUFJtFRXcyXMc2tDCi5T3WfLER2YbmblGiAAxjcW1Btw/QzLayaRJ8UwoE9iBojFQ3qXULuRKWv1OTor8PrepynCdv+HOG+8WrIm/dLIgtarcnDlFsZNs4EDCGo72n4X5pdcuKk+Xu2cBIayPc1JZtFYzohCbsggGQMtMNC7CpSM+2QgM9KYZHbRMgCPkOeSXI29jUot7ydHve5HT4VW0lBG0RSSXTzc084hm8wR0XigeB1JAgWTDcB6QDGr4gZeE8OF1YRS/GlYBbm8ez+TMk462rIq+BvOHf47hIWn/IXAibowcA0Da2rFcV87oy8Spyhy5qfoA9Z+FljQu3IW4EZcMyUIzYRfkvZ/ylZ5/vFGUIgK5CJXAsaaNBN5x16W8cl/j4vFF0I7UPYVzcnzQB/ROW7MyBOZ4uXU4HgcwcF/fvLWDHlIEQoAyhnbQaGTKM6uAdb4Zv1N72hEmQo7rLHe+7AcqlLK2SOztz87Oqy+TvCMs1JImpoq7N7cs9O6Kyv3fQ2l2yR7TFU8xnMx38mUAjQOmDYDI1ZRn4njyhCuFigY8EJHtL6563/J3dAY1P4KbEpVcjZ2HJGh35+VgFa9Oh5I0ST0ggMUkV/RPvu7/6J8XqPuN8x7CZMvD99PvKcB4FpChW72ZbD4v+5kNen8TG4MDXdKNtN1WTWtdEbkw6M9bK+eHxibbo/f1CinJfvrziCdo9U3BDGy0rHU0V6CSU9AzMJqiqJnmcbjhzrr0gHbRpAob3alFkfK9uUQ8AMgnSmeUdNweCiDoFzFdMgY4nQRmCqRpZQnefnVBKQHkyzYJdknpRyZS1jQxV6BA1caHWdcXwJllUH99jWS/eB54f6Q888YKlj5cMYODPQdTW+mhnfpAnQV3xuqXjYpcu2U58Aeq2crMy8FVmmu1ESxBjC4BFJ2HlfjgDoUqbStSI5m1IJy9toDNNVnQBRV3G7inkFylb85VNe6awlOc+vlQmRLtAK28NfGwLWZG3vJbrN3YgZJisGq3N8p/l7kz9I//edGPclUlakpYmq5AmaaxIDaycykqRns1Edm85qpaudXpJqzcYsOlSbI1sMei5sIxP01GbuzQU6I4VeRugwudtuvq4VuKTGFeGgpZx2E7++eKm2k0I9kD2j852FJS1ncQ2fnO/vXQ0HwAbK85Xyww7HQXDA9Hn1VvB6muDgy9GdS6VLYNguhbkteD0ueD0mTQnXhU0D4R6k3Hp+hOP/CzzbcV8VTHdsvph0lNFfpFR1xXTvkcQxY/+8LfQFxMB2KMZx/R1sXUbQ+Ni6FAXG3qTZ7PSses5+3tnC+WW9N7f68VpViPQv42QU+Bm16s5RqNRe6lc5a2ZP5upkEyLUKy/mog1GEM1XZze8UQyliZ31eJo1J2w3MNTcEFVdgalLN/np3pdaaOw157BMMN9aKlP4tZ0xn1IJ8HqWzNXXbMldTyi2/OaTVf2jHWsIMLslRSW+b9VN1zkBpjveD98lFl7/vl4y4mUmFlQHA2naIcTkPZUarKdsA0vLvyUsjI7t8rFns50bVIB1u8L1m9nQASduTn59/YPGbsvJ8bYVW6AUGD9rn7cmvzINfwv7cWZsqB/MIfgaeEStIxB4yjEs+nxMxe+n2Td3ubeFxRrgDfMDUs1muXZaA/FDZqaEnNAeo7t77W+1v45v6o4/9q0gFZWodRBgdFj9HiSpaOgeyBSX1cM/shN6iu4er3Hqx8+IDwnzI8DhpSxuRppcW9mqfGB/X73RGBPinBG7xwDC6M9f69YmOryeV3Bl06LeUlNCwrf7fmZxN4PVICbGZ5qFE/STngEMCQ2AOE5WS8vcI3L9H4FOVNUpcYAVBO2uSw+G/XYKc2+ANI+oH8fWnyb29xp4GRGYZ+12ijzEBZR0Tm0DdrHi/6eYMAs7fOlLfK8Jo2Yz5C2arOF0q5swV+8/D3VnqDzfIVmPScKnD4zJ+5xwTlCZrm/+YYhvI6vOMW8HYA+VhQDxe9m1AE4v1TMG2kAuFSOvoengnQomG4SpiuTvs+sEKBA3kaUlZnazjSKGe7zr6ZL9HfKNOX8erpjEnGNJISgAoz85veWFRe7p0zlNcvSOHK6oQGYblhq5kGRrwofKpBcM2+oJ+gOwPmVlcjmpTjv2H7kjf35C8XqrWB4H5DHrs2pPWhWKrD6mn6KxRKdHFCM+4C61pYDKZkbxmG+Qfqj96jXGZubE16v9nh32GAC+JSkCq0CJMW8pd6CLk+Mo2eqc4UqT+fplj4K6SiNDHUZjiuZjssk6/A0z2u06qd/FIxDBIaKfEWKdTVGYKUdAPUcJ55u806pKxnNLl4Bsad9eklg0tuJclVa8jffV+DY0BZuOgkNhnwErQwubiYrFY3b4ie3G9rWeKE5MZMbsY1TI3EOTxEnJZlO3es3/Hnd3liW0fImbdGGmW1H3gryCu2e+wbVP5r+wYKSwpkbio++AfIdfKP18Xk6orWn4y0317Ky63AU1LG30ThaknUVwfBYEE8VTz/u6X25EZxfCu7+CfsakpwYNjMZ0NgdFd2+YrpJmDe/guAjYADdhO/IbsuuIu8UdSAg098bSjwsLUb/wIcSsAtrAqTaK+ZXGek+8QaeieB7D+YjvbwF5tczMAf2+IW8BrXsiOkKmL4/I5Qeq28NgDN84vBD+iqsvuJlnG5NsbjNmHPfytD0HFppb0JNpKPg4WGLuMo4H3v8528/x/6wQr4tSE/eT1ISrquC8RWMrutIvDaTFk0k+BShzXg0WrSPGMtgC0wNa9kaQDkZkGrluvthuD8CR6OhpTSVFSstytYr0mM0U1v7ULbxuSV87Uk6Sg+8Ps4NUDjusWAI/T0wX1t2Zuc/i4txvKst4i1vtBGGnHRULOzHq5Ca0DYtgL+n9opi1kehcNFONwQD44h2DRyDqR1wfiltIhGMnwJgoY0XthAaAdjnKWu2EP2DVSm95U8YzhEm4mVSlwkHPwg3xHQW5rQeSajbvMk4fK/D/ouE4Ymsxjj5wQc8/jhheDTW7rFCAw+PzVt6OORNQOnlV9MM1hVn8w4tyjyOwll+thPQduzsCku1XtDKZCeQlEJSTdoLysoYfVnQP0oz4fQ0qbwrkB2t29K3XXsvAHd418jHdUZZ8WltI7GBvzfcRwwPvEnxLJhXrG09+r2uFektn6iyqhzXRRv/PXQonSI9Rzx/M1j/bIao1UJPgqLMgcSjkXTrsuIGFPcGTK583BgboccrmTCSUanrgpA7jN/LkL5iDB26R2NvXhcaygDQXiCZ3hPaV0y3bEfKqwl47CDF3pfQxSieA8qLCfFr1uK1Z7lPglFti4ZgIXGh+YrXtT/aYikk7kwiy2LvFdF2VsqctbWY/rwQvLDblgmEyhTaxt3cvYIxGIUVoDMVvbJr2My0VChNVHXxTLhNvE8kPGWqWk5JEwPCKlqrRLzFDMYVqRGoa24qntUKWfIoHNidt8DTjztuNHs1wxZiCacXXbMpnHeCeFKEThAyc1n2349Y3SvmNeXZv7KthGRhgG0Eyq6iDmZ3JoLhnbRZdV4xb8DFS5K8bEfrsbOVhO5S7MEq7qCsnSL3HH31qxk/ePGInzx/geHbiPGzAmyB1ZtoxBmFfrNC/0Cgh3PlRY23fsNTBUr8Q0NEHqggTAcBDhFhtNHdugLHiGhuSulIQNHTm8kAJCU8vTX7sg3Lag3RtPuVOIN5NXZPwBxi4+Qzd1GaoClv+HU5R3R7waiARIKAZVCEHx8wiKJWoTWbpUshACVwl4nHgPK+h3sgxrNAY4DcTcjnBHnqGlAJkOMQjPDVKM1G/CkrbtrOJgx2co53aCPKasDlfFsQ97ERhjQQFBOzWtducVsWBV2ThsoEsXNYGKcX+SHztWJ4Fxrz0TMk3V6+dmjKx2R5lTxcXH4tDXNIJ2444y2rs24vLWDGD5Z0knaP070gno2taendUpZNKEw8MMSEelKpkxjuzYQl0iU6zKyQgkXtyXGpoKcrTtXKQOv97liNzPVxU4lPYmOQwsWuB/aw1Nsrhm8pe84bNBZeWSuymZwUiwMDFvCIMeuLaed0Vzka7NDcnuKFW/T4NOB38wuEE09fKIDrGZOBn06FDRPQP1ecb0MjMDlV17MYi3kjEuNgQ6yBi7usaHACMWvvzIcpnszLAKGN4xhaYgQnNfrujOYqhJlBNgBxDLmngnR8ydDZ/NmM//p/6R/j//6TP4JySpB9wuobwwHGABwG6KqiXFXyRnKEPvXo71kNuFIQ6JqtWfcUML2gqCdMZrIyDcC6NictJ5BRqKao1ZKeEluotnnYCBNyeeras5ABdFiIWMGjAKRRh/kccArigbZlWxGO3MyrJWVp5+3YMj1yjodb3DmwCQMw85Z41PCGb6hGRbqYkLVnTdEk98XG4y3ZzJiYzRk8Gj18BXj5EU/avs8DlUOmZFsKN53plhuMtw/j9cL3Pr0y/44XDLkd71jZ5Q1b2tU3AcdXAcMjgW9XYH7o65PYGKAEbpx8QiTWkHIhHuAMsZD54dtDpmiLXrL5Ec5kAFKaXVFXgCY+RA4scZasCPsEvOtaeEn3EKDPA1sZY8mNKy7u5x+yHpuu+LajJTipoPXgUACHhGD+jfnK4t4mQThbeV21laflqlIUY9UJKqPd+ic0U5ncAE1jbSrtw1w2rlZ+p2eO7cYr4O15B+c9IGjTAXSGd0ihxqJ8s24j3DALMKNJhOORm914q41fESeh+9NVRvq2x+obPkJ+QhIvCMRbjPzkbEWOkWmoE6q0+w2gRQn6yR0UzSquuUwHNMcjPxDm69o0Gu5lIRN9KzRdmOeYq5Z7Y+StHRLWhpILwMMmPcWGfcTKKqAkmyrBJmYFGF+Qz5Lv2D/IY8dQWxunOslOFM15yauSMEsTTPmmVExA2BLHbXOZtoIw8P+7I1sJV+/2Zk47X1Xko5kTqwf6srJb3dfmJP2hr09jYxDrIc33L5oBpxpRp43H7FXWhkLP9PWbbyoQge6eYy8Y0Oe7sYouhhkCBF1yA+mebNZcG2XiU9XlRAssEQEDkcRKzbIQhS4lu+koKLPPpBm+kk5iEW32+y1xOp759XgK7VQLs7EVn6X5U6izAK168ZzP2nNiI9Xn4Xywu7cdfvvwh7D6wR6nYyJH4Zo/Y7or6O5GlFMHOUTIKOZU5cY25gfRe68rzUGZqlMAOzBDYsWo+TLYibmp6O6jWenZgpwFJS55no0OrUuPP90ama13LoQ2klRZaYvM88zM9EiLt+nWcJG4bMxhpGelTxGcEOfjwPlGUVYEZz0ZvHSLkrN7ZsU6vqwYviU2VK2CucyEqD1azqisCnTkdQiToG7QYhYh1jrZ/XKafnmxtCfppAhrMfaksSxhIGjPcavOJo0vZOP6gcgLgCYSRATp9HYw1Y6bQzo5e+zDXr90YxCRFYD/C4DBvv9/r6r/UxF5AeBvAPg1AD8F8G+r6r39nb8M4C+AtPF/V1X/o1/0O5q7jo2jSloQ5Xjp0SALwq7CD44VFzc6xXy9RJBBWG7qUCCHxFGk2aqtv6bj0IzaZMbp0ZTLxtf3zWW+MgVmZg/MEadxAyaWq9lcmpK1LC4Bb+M6G3Eh8GuO3jONmvTnvFNUSPvZeY1WVXgqVbmqcO9LTQDsdOU1NOcrkEMRj4JpuoL0CmeWnn8wszp7HFpaeBxto7WZPB2i4pK/cVH2S7bKYowo9ytGCW4VZVvonWnaBed3aORmmNeL+UneqUmfSSGWlQOE3FgJKpqYbgKKOCWdXgvOhszmnuSj2KLmWLRWIJkFnQGBblUn1nZoJ4C5Rzm92Reuk9ZqEobyGDchntFs3VwhSS4FIF8PyLcZeVcx3BtZDpbofWsmM/3y/OBi/OoeDd3ennN7dtJJOUWayaxMo+L0QnB+GdE/KroD37urffs3ZKbOVwScm89Hz593+OK/eEr0COC/qap7EekA/F9F5P8I4H8E4G+r6l8Vkb8E4C8B+Isi8scB/DkAfwLA9wH8JyLy66r6B29Z6v2YA1g2a692g9a8QekMTCvFfEdwy3Mt4ylAjRwz39RmxhrOoQmQqgGCbojhCHe0h3h8Rccd9zz0UaP3jGWlKF+MCN/2zf2n2xNNP31GfYEmjkj7N4kbyXpxkO4sedqrnWphpny4jYwlBlgdlgrAszJIyxaqSk2+XIaFoKMXCxfgn4cCyIkTmTADiIrhasT4fo3u2UxqO57U/c8TpyxzbOXt+JLtALkRwPSqoDzF1orNK7tmR/YzAjXloTY9QLkqCLsZeDPwe42PorBpkqCdwlQicld3jCE4Nd6ownE0ib7buylbOlGClU3PsK1Ij6EdKDBtSoSloJv/ZukU3VfRiGpYtCZhGePGEc3TI6/tWbUNZHxp+oj3qW3oYeJm2rgJ7u1Q+DyFsrSJFWTXSgGGZ2ZctjZpu/zO0gvp7h3HrMuIntewe1L0D8B4F9oGxufBNrP/oqcSqqoA9va/nf2jAP4sgH/dvv6bAP4OgL9oX//rqjoC+ImI/A6APwXgP/0Df4n3215uRl28EytJLzIL5i1PaJ+3+8WBAsNDwLxV5JeFQbPjoqTkCSbtJPJ+mOGjbA0IkFmJbyMxKcK4e7V8wRNPAw+kjWdBHaRRj8MkCHvLq7QH2oGtOKKddLRJM9emirYp0KJcMV/b3/XxlxHAKBQCfSw1mPYCbYN0f4Im6f7RGfpmYPjIDPRfd6ibGRBWOPFIG7bOeBNlsM8wsq1yG73mhRDNcWnFSUWcrEQftPlEQFi51ZVt0McAnIemD9HAlCbANsmBEvM48v6EkQvUvRTCbC2OAXtlQOOY1JVHFPL6dPe+wHldPQfVcaW84+HQNiADeRt5yVrWlowd2HbUznCPacFEfEo2vAvfcdoCL0EDutPJYB7HOgwXazJ35USGAi9po9NqeRykgy+2gH59oIsEvHbA6XMCl95yhsl8TM5G2b79ZSv9u68PwhhEJAL4+wD+KID/par+P0Tkc1X9CgBU9SsR+cy+/QcA/rOLv/4z+9r/78/8DQC/AQDxxS0Za0Ys8tRov4mOZANMSpYSTLHIBZz2gtVbwxyQkHd20h2k3WgNC4BXO+sxk11kAF4ihFna2JPjLGlhueufdQui3bFs8wonjhw/Mc+CvAbnZFA2rt9xYgoFSPfWati82xOJ3NkHQCuPNSm6B56A42u0k1bXpNHioYPOXDhYsxwPsSB3PL1XR7Q2AuCica1DoxabwWk0CbX22qje/TEg24ZZzHq/DNQqdE9hARIdkT+T/OR5EekQGj+gheAUAJO0AGLPe3QsJW9MB1CcJm+nelrAxzhKw0Rqgn2eC+Nfyzet/t9jACJt5dNzbKI9x7mayMkIUtkwl2ASdl/wvhHWzjb9eVFNAmjUZ69OATQ9R783LoPZD5ZkJ7rpWBhtIMuJL2jCuHim0JBcFTfgBcbPCqRECsI6tNDevOIGMrnT1we+PmhjsDbgvywitwD+AxH5V3/Bt/9+cxH9PV9Q/WsA/hoADD/6kcYj06Gk2NjNcyECmhGqg3MhC86vFixg8w097vKWY6VwChjecwdNJ3orPP96YXSbGZF6b156l2R7ab/cBLHxlvgIyj5J8YrhtOz86cibPt1wUTp20RK67bMs1QR1DnmtSwRfrwiHgP6R0t04srQ8gyQcZyzyRCBgGEagPHY83TZsmbr7yN7T2HTdnqCVA5fkF/CE1o4neIjL5qTRbNLOFiAT0IA+z4HUCFq1r138xionmpNV2ZD8VBNQrgvl3BvAg4EoQQ5NYl231fQSy+PjkyPHINLRKpdAxygYCEtPDS/vl4g5KQQtfeLUAGw1oVpefo8Dvf4ZvXrzFleVdgDB6NVBeSKLtcGXbFwPPs4GDocZTQiogVOtOBFk9IOl0b0V6O9l4Sn0y8Y13hnGkxn4S49UtTFlaBszFCTLmUNUNor/x7w+aiqhqg8i8ncA/BsAvhGRL6xa+ALAG/u2nwH40cVf+yGAL3/pD3fdfTYke12RDlzEwR1wMpohBsEoQfcomHfAeCc4fW5GqqeA0+cVGnjzpxvAE6hlNsBtxeqB3vwLKOQeBu5eDLHU5Jlg1LizPtoAqdqZZmJL7ENWxRiCdtMT2shKZiDOgrLhw1zWy2mmQZt1+nRD4EkjKdnxbNXNimV8eortgeJpJHCb+Xi00vqzEeO7NVbvIsJEXr4vejfDoeOV+QGsvMKySgdohjQtS7TANmxenzJRUNXtOb0ArLQdDB0vVnUEpYt1UnT3AUnFPCDUpgF0cCYJSalJ2bK9QxXUbUE4cgQKFYRDXByQIpivm9zPwHklBjccjetQAM3EHjiaNAekHauSeDbHrUgVLoL5V+QFI2iLxjxFS4+GF3jbR/au3fuKdqJrwMK8LUAdCE4G8DmiEYyaU5hJ5JVVXLXRpOMJrExIrOv20uwIfaOL5jZdjdilpkL9mNcv/W4ReW2VAkRkDeC/BeC3AfwWgD9v3/bnAfwt++/fAvDnRGQQkT8M4I8B+Lu/8HcU65cGk00L0D1Fzo+tb3YE+fwSOPxasb6QN3H/44rDj4v1YeaibKXl8QvB9IqUYbo9yUKH7cBe1Jl1piMImfPpJtRaseyuHX8mkXkzH5nZygAAUoW873ji7/ngxskXDO3mzt/LyBvaiXv6cgsocSDOEPs2YjPHov6eZXs8WeTZaASnahMS84+svdImbqioSTHdAMcfZ+Tr0jAWztTdzARIz1Zt2fSm7MriXQFqUjZfBfQPlL13z5yguKhotmBbl5bDqMXxLMAUbBTJk9CBvHRYwmM1LmW8i4q81Qknm3bMxoa1qi1vdPGaMFA57+w+WeRAMPLV0uIEhDEYwYmfzXkS7Xe8mKG7jHhaLOYl+3iRP6/bOyBMkHDewOjIaKpOF6g5ztQ2B6tIQ0bjyjgOEidt2I0UVhzOkPSJyCUhTANXsfMn8hZt81m9F6zeBqTnsIDSH/j6kIrhCwC/aThDAPA3VfU/FJH/FMDfFJG/AOB3AfxbAKCq/0BE/iaAfwjqzP6dXziRsFftQFBuNAPYk9BdqQPC3k7nAY1PDntYykqhLyaeLEUYzRZ4UuSdWmis0ttA+UDEswFJKph3tbn8hBFNlu2odToIqvEE3CHJpbJhIhpM0Y9AQ9cYgGEE6tVi0+7jVx+5uUW8TwAoVVYUAw8hCzjlFUX3HLH7XU5Bzq8W2q5LzMPJgNtVBfb0e/QTCxZ9B/vZPvakWMemG+adKZNAKkG1/iEYt2JZ0NUALjdKkVmab0C0uPi058aeV2oAoQux0KYo629olgIlOWve2i6k9L0EQOt9nySN9N/Qzqz47Bpq0MZaDaaQDZNF9ln0HQFB28icoZrNL6JpGGxzOkeEc8DwwFM5Gw8GMNzDlKnkMXA83OwHL35PsPbX76OrPvmG0Hgn4x2fsy5SOOXVZt4uUwV/HtxizicjcSRmdmk0mze8LtmYwb7BfMzrQ6YS/28A/5Xf5+vvAPyZP+Dv/BUAf+Vj3kj3ZCdrTzAmClsIP2E00XvBrdfLdV6UhjO5AcgXD8VkISbBbsY+UabcsZkTBYox5ji+4kOdd+476Mw8gorO6otGc+4s8pwEEsApsi06ThZQzBeU1CUfYbbFEQoJNnXlPfzy8zhp4EJITwHzteJ8XhiDmhTTHSsPR9WhApzYakQTo40vOMaTc0Q6Lia1ZaBcOx0E8MmDPYTi7FChLJ0XWiA+k8JSMksBJCwnoINt6RGonxkQN9ImrmxtwSdBfo4Uu5m1WRsL2wLvngPOn2VokMYbSPvInI+rgrSPGO8qQ3TMJi8c2Ko1mXvh3+ueBdO1NtduJ1j5yDgUSqnjGRjPidT7zXexBwVbQb5/vwdov8eDiFxoBZiBS6KwydmK7onplYOf+qRO0ydiuhFzSl825M6O17y6aGOioNsr5itzQBsJuNeO718TA4UaGe8DX58M87GseAI7COPeCungCCwu5tw2llrbYjrHBpgxIwCNDReOgYvOHIbCWQyM899pp3OyMk14Cjtzj5oLplq5hLl2PDHiTPyiDGRH+qIuPSAdN490MErtRtE/CDBLK51d08Eg3oW16axDUbSUZDeFdTYfpxXVjGMDPN27Do4zkD2Y9hHdU0BZy5IYrpZrYDqBdBKUCkBoL1bXFXVgKR/mJXNhfMnFG0cyTmsyanOEfX5WFufvFax/Hpf7ZRVGXbOd88Ux3yi6x2UEiSoEJxM3NY5LSXpoCeKjNG+HmgyILAFBlHwK2OZqICeitNLcqyQADfPxVqM70C5t/bai2wc8/1gaxd0l82kv6B9t7Kw8wfsHaTwHMeBPuuUeTXd0Og/mN8n8CRPhzVzc3UFaqxJmA9FB+nOYOTJ1dSYBXPtZiuY5yiCbi9g/4XNWdXGs+pjXxyES/5JebYf1mfPEBcC0Yu6QXibFo2B4F7D+OrDkXXEbTWbsAbDkbIQOO/XpxaCtn5t3y3gKwk2kumGn2cLlLcGbvMay4Cv7y1Bo4QU4Em6gkiUdlW01vrqV1gdzXt4YIGRMSAc4NVIIhIqltO0oqCo9LF+BHPjmoD0HdO8SUID5iwn5qjRn7e45cKEJmtKz21NDMt1VO5EX81ePq1NbbLiacfOjx8b85EyeJ21eq5mxsCJJZp0OGPOwcDP0UV63l5bWhagNy+Dv46bg0wZWXvIdP8M4MeczHC965UaJNxq9OWRLXTgk3qeXFXEMjr21OVP5tKuseLLPO8H+hyRwbX/+3bi+tCem0qYUQp8I6nR0cYOyUaZPveKZ14yCP7sGsGcuAeMt8SSS22BuU94malNFFjsYnVnrvpMAlpQp2/yq4XFmP7FM2j7i9UlsDA7KOPXUmXbVRDXAMo0YX9ZFw64CtRMgZAcezeWphU4CbhYqZTk9XJzjIyT/cxfUlDUaPRVYgKRg4Te1A+bbYvwE/jwI2YG4yvRs9L/rC93JQaM5O9lCpChImggKlSd/XhtCLtrMXvNGCZoClBgH2wSmQDv6VVnep0l+3R359HltkuZoTFJ/kFpmg1UUekh4+OraTjcFDNjU5L4IXKTdM9A9obU3ac/NIq+5+MaXvA8czXHR1nVdWIo2BUEglgL45ktLO9jDDWABAisQNpnipbCU9QBa1oSPiwG0DcLJRVBfPErHLfNbrImjRJqgcLPvn/g++ufFLdwXpBvapBM3lekaxkzUZklYkzacQy03BUDbkOarymDisrwvfjPZjq2trIvQsJpUvFnRW2aEfy0deR1m08e05/MjXp9GK4Glt86GbntJixBbWU3kliXrfAUw6CUChRWCit9UlqUek8Z57nLxAJj+ncnI8USk34UywyOnH5fobzyhSbunK/5Z9xhbK3J+yaAZDBwrBGNmMtWIpyQErVVwoMz7SC8HnSQTLc2pEYFgD/K2smS2P8s2Pei/TRjeC05jb3N8Lq7hHsg7tJaGZXZF7QTFwKwwcly4/po4hobFLp6sRoFMfLDT3vgmfkgVLFb0w1JOIwDTnSJ/b4LMfcvNqFuFDAWaAyTHhgFxvGdEJmM7upeBGn7h/pNhFKZtOaAZFBojumfb5Kx1KZZy1T0TqJTJjXbEzFUA1MUr1CcJ0w3fRzxz0lB63uPuoJi3bCPLyv76QKcnjcDwwMU7X1uqtm1W8SzNh6L22tiN3qrILI3tyhG4mDktPzct4xZMokZFLNJSseLIgyX0CyU7zGzD45mWfpfkqw95fRIbQ6Oxwnr0QdvMvCaFeMR5BfJVxfmzYFJkIt6kyvJGlzWfpFDYQ/r8l9biBkjZqREmIL8odIE6CzoTATkQ6SgwYA+93azZQKzumT2ny2s1KjBGrgsTsnjrwHEof38d6NoUJiDfEhBdfZUan97HdqIWxGOz9DIoZJtRa2cJ1OzZwxjaONfHpGXtbdOCWKeDLKj6hu0DAqnWl1HxTmfWKCi3zLmMJ2Gy1I5ih3RiDoZGaYQlL7GHe2magvyUzD+TO0l8TChb+jn4CR7PC8eiuPYjADksjlbV/BOC8ReQuTkG27xo6yZtMXnJrh3I/txVoJj8vRDbAPh7khHV/D473pXO2ox0pahtIop5x2ta1oCrHD2lWqzX9yq43GZoSq1C0GSFkqWhxaPhRxEI1cfHy+SLuSqC6ZaAZe1hNGl+b1mZkKuQqFcj30s88Rl0RWb9lUyiqt4/qT1sym3f/BfCtDAIu/c0ElVX1xW0sJPhXWwLyiPQGjp8Y94Is5hxrO3AFu+ezuyVOQ+28sQ9ImHVgmDp605m5BKMTNKbfsBIMV6+xVEw3qIh0q3UNcAVkSfYfGWeCT7r7hRZuJGob1jripQq6igIp0iT1ULsoAW1DHxv6cATQwNwes1rMd1W4GaGTgFyDm3UmK8KykaAG8H2Dz2hiwX3X95wLOmf3yjFSEr7PNMd1JGXxYNVyBY04O5Mz8hLzYJ7T1KWrphvK7qHgFiYwiVZbHM3oNHK97Kt9jwY3nSMUOdGpGWM6ECyt0Q1absngC3IAoQ1zNiWFWB39JaWJ3L/xNgAd67WyMXpZsQuH9cAm4DRfczbEseyMDMYKEzB3LvddQoNDKZVHKn4obA1qGIR99GqlhXaaBWyTGn4/EmrfmKj6HPcWQaaIA0Py3TlQ16fxMYgQNt5g9me1asZyIGpzL77B+4XbkYKUaYv5yX9SJMSc3Mue283ba1Ndq3C3aNGnritr7Z/+8PF2T0BMlfLURJrXHzT3+eNIt9mhGNE9yRtEWTDKZJZsbfEo2MgCNbb1KQ3zoQlPo2v+XXgomIxX4J86CB20ughskQ3dyJapVd48nYZyBOoAx/02gvmLgIGzsHeW64+uVGIKG7WZzyUW+obTBU6X9sE6BjZzhkbszjb0pH7k92/H5zNDs4cqgIokOvQHLTKzshKPexkW4xkw7QQoOqKWhWv2NiWLdVX90QSWzX2Ylkpalick5rAze5hvWAxSrVqdS+I9uchLNVEMwUy3sB469earSN9Mw0sXSnqutDWH1z47ujdrPEnz4tY/C+0CEqi8W8cOaqPE0H3vCZ3A3UBzj15zVOyXKLfODoGfqYDQdXTK7YTH/P6JDaGVlrZ7hnOQimqpQmlE3um8U4bLz4afThkOuF0z7yxo1UC3V6ajLt78nm+thMwjILQKxOeLcchTLaQop1oa3L+3a6srswZOSnUhFTRgnBDTohHnjDTLZrGP040sPUNo0SCid1jsA3I3J4NZHUilfsG+nREjSkpz7GZkqSDNMCVBrOsLsJM7gUAnO5MDGRlr6jRg9OiNA2zIJjL7nF/g+erHQ+7a3IF6HBsStOZfy8d2BfH/aI58LzGEAVaxE5KGy9eZVRzsiJKbpVhYI5n3UiTUQdz7yor444YyNe0LJH3qkagDhV1jpCJ1nzOgHThFeXnAjmrjaS1XWfX38RMYpFL9DUCwaIFNQD9o4HRCsaFXoz+6gCcB21Rg/yiLH4iJ4E4WHgxui3WSvgCcF6KuK1eNZ/G4O9TWswglaaAGL+nrLURu2q3TITYQsNUsx+3Jj+JjQGBNzg90+VYA9gPHkPbCccXXjsR+e4Nsc4rcgSYjUirq9qx5NOINmqUGRT19Mu4ys+NeF4swOihR76+m8Fuf5qsTGZ1kVeKdBbMLzNyplktw134fjRywwnjAvrkrTbCVF0p6ricaN3B8JO195XS7NXa7v/EUzZvqbJUV+S1DXUBKeldsJilqCwiMXeUDvfJxqGhVTwyMxMTfQVWhd2cUYtlDpCOfJA5RfQP9B9AUgMxpZHQyq4gftu3saNGhZo5rOMnIQuKiaE0KrSrEA3NRRqBzlZlZQ7H4UKdKoAG9nXOWXDQ0k1UfUzXfDVOgvGPzEBUdG86Kj6V98y1DOMLVjy+mOgfyvaiiaQKnzfJwPCWblXznVVTkwBmchNmw0U65Z6mnALVZFMLA5zTiLaxO75ET0viBHmLhTRmZsHU+djEBssm4KS8+QoNc0knoNbfG6Lzy16fxsagtmBsMbj9t5tltsCQ03LC+ctHcz52dLsrX5DpaEjtDOQKo/EuE4DqII6hxWVX0L84oxy2fB9RW/+sJgZKexJ8hq/4y9xKft7Ze3WfwF7NAoyEpTjS3ARFWqZAiJZeHLT5JkzX9FjU2X62JXJRG2C9sikY+/fR1H8+Q9P20MzXtknMQO0NHM3LtYvnQB1GUEhfIZsMeVoBpwhdF8bbZ1ZuSAp56Jr4yn0gvPKoPaXMEEDWBXoOPNF744okM3KtaBuWjAHDu4jxdeEU0ctkBEx3leG6J1sMa4Ke7nFRHYuKgBzYx7uDkluiubZgvsv8DJbeRXWluXKlpQJw3Yd7YQDGhE0erItWxYQszbNCLDx3eC8t9o4TLG7Gnnfiz5Fb/IttZiVyo0h7Tor85fLpNC1+lC1k2Q4ED+xxjgwrU7pGSdEGXHf7j1uSn8TGIAVY/5xS4bxluEj/Le+WE5Dcm1+w9H+eJJWrsQQNBPJT173/uVhZynU5YPWWD/Z8VREMXQ/ZnZoKfvjyAT/5Zk0NwiMvkfPcgwGEPqIb7xSnH8yI9x36J2kU3LzRNu7zMWvIQM7S0OZgp52zEDHxhkJgAqnFX9JPrEbVVkBTaGVojTBRF39+/2TEpG6xkO+eCAR6O9X6awB47JoFWnqKDGepwPCe9Oq80++EuzJolwInqVZ2W/Bu92Xf/AtYlgvkTGCWC7FCVxXpPlH2/kzwl/kP3BzyWlCuWF7EEaiDuThdcFsk8z2mE5PFy3aJAtQA9E8BUhSaAuqmAJ0ivu14LQ7LODmdDQtKhmn0vOGXEzJvDbIRvvLWgS80JSW5I2op2KZcteq0mLUbFM0uwC3jvf0pZnMHG53XjfEibvmrnBDmoCeAFpajtonMV1YlJ3o6jLdLsvvHvD6JjaE9aHaYeXkIoJm6AjY2qlh21UvCiVrpd7q8uWh9ugZuOp6gPe9MuTcG1C9GFADxqwGYAn7y219geBt5WpgNvBQy3YZ3oc2fs0mVy2MisBnthg78LPOOD0n3GEgmCl4WyoXwBoam84nR5Mi1z8u1lcWAjciwYBbVAKiyrUAIDIE5BZxfSLPcX05p29yOi3CoGb8al8Et7VdfR2Qj5rgGQioWJWQRlv+GMRAcJeU8msLVU53cickdjWQfMb5YRnphondkXVV0+9hIPtpXlK1NZSJataOBExpa+IXGAgwXHgvpKNj+XDHemLO4ZW2UQZFsXBsmXu+5g02JCAYmI2OVoaK+mjFOAXIisCwWKVC3hZMdAcKJblZlAOnMDh3Y/eYols9rPAvUBGfBJOI+smUWprSF7iNJjXZwFddA2GjewO90soxOSw6HAHVTEMfUDIenm1/FcSXQJLAAmt8jYLLiM4yHr+3Urh0o3DHGoVOmXazkO7DbcTlPvqwV59fOtDRiy32PuimN4Reeva0BpISlFTjTk4F01iVRe56sxTGAx09vPnzcFMJEhDi4os8YiXnD/l9U2uYYDB+YrzgeDCc+1IgKaOJ40j+TL/p1Re6tPH9vpJYVAcEycOOYeqtobNJSdgU1B2hXUQCk3Yx86FA1YgZQruirWNagQMkNYtcMmw3rjJIDsijC9Yzw9YD+niCgKw99t5dZWkp0aYnV2tSCTnSq9pniKMC71FooFECHivgUTc5N9WYYeYpXGxUy80Gw/oZ8AOd/+KFDoxh+TzwZXdps/rxNLWu2XxoBPcfvWPTBMizQVYSn2CjYGhYtjVdVIQNiuEg8o3lSuLt53iryTUX/LrR4RiePlQFmZgOUlTTTFtdVkAxI/wiP0dMrEtDy9yYMmwnlfscYgv3HbQrAp7QxRMBdgNzCXAPaBYSQr9A9mKdCtV7OjFSCOxjPgNYFsGkR8NXGOBnIV4UjuwPVhlBBLkag6QvC3EGyYP5XTsDbwUpzgdikI9+YAejzMkUY7r2FcABpcfzNGyB0LFnzFdpprfaZfTPzzEU3PvXAVMkkBAFL5cB0J2C+5bgQRudmvB/ZcCrS+llasVca1M6CdAxI3yRWJS8KMAbkfYf4HJsZra4K5NmyCqw66x8Fs0YKraZIpieAeo6QtWIM1RB0EoqkKNRWZevnKyi+srEfPFGqEphju6TwYBrtrNWKinxdOAmZ2EY43bhcFcAYjVIpbju/hvlgaPOBBNBMXpwdqRG0XJ98HMoNkAHEsVnLc3zJ3yf71EbrUmFGM1y4NV60axdtSPdkmhpdWLTaVWgMzakpb/WCr8AquDuQhzBdG4hsbXM+kWsxJzMaMk1M/bbHNCQEw3/c0OZjXp/MxsA5NhFqbre2kO1h8nk+fQABN2j1nR7gg1dWsKwFUKnWSUt2AtCqAoC/hhJrzvyxUmhheSgVqE8dOq8ULoBNjYpggho3mZFMkIr+f/x3n/j3PPjUAcdonH+PGAOWjay4aYydgN/ZKG2DKysFHgSr94K85YkVD9Re9E8mAFtJmwDEk2kXkn32QlwFhsqXKaB7iMhuT18E8QjkfSIhq4p5NVTmgQJAUISnhLouXMCjTXE6RQ1E6DUCOii0ghuSpXtVC8mlQxE3kPRkIriwlNdhJA7jPAnvMdwRCxWAWcgX+xlkAyrOn5Um3faDRbKgbip1EpsKTQZm+ggzwUbTVhkZ3yOOvC+1c6en2Ehc/uwFG3v7gm/PGgAZeM/SkQClzECIrIZnU6fGkcYq0xUwvqpLhWrjUU5+zN8jMKNyuK/Ia1Zo+cqyTAc1vURsxkL06vgVJDg5OOd8gmocd3ovanPB8UQnWnBxgTl+4MQXMYGVo7/AxSnu8/gercR1M9h0EtSVQPepcQjWX5K/WgfF8Qu3dddW9orx1PNWIMLSNYLvLZ21nbJhlmWyEe1m2zxbMkN459tCGnVh2S0B5BsENHk2gJanKAoM7xTnV4LprlCeHOnNKIU023nH3tRbH5kD/Qp2Ben7J+jvbtFsEI0FWvvKCYbjIcY61U2G7NMiSDrE5iFBD0YDVW1ECRhy7rLfoUDG1E7tcDLfgN5OtM5K7OzYB5opbW/j2bxRi7k3kdQE5N7t0owabY9UmOheNN75KJSbSXqIxAO2F/fAyWqjtEiBbHyZdLAy3hyfumfLb7gtCCdiGnVQk8SbRsYqVr3ISvV76KYsbmufnhjDuPmam9d0JegfiJs4TlaT/bea01nHDWh4UPRPjLJr1YptBNRe2IFbta2FD319EhtDo3au2fdCgHikwKZ2MPWZLKQVkMLq/gnxbDc5OrcciGeiyd2BZrDTtZq/H5AeE8qmmu8CAb1shCFAmpuvJywDF6d4QEPPpQA18WFOZ2e3KfIKTXobJyAUAxPTxedNwLyCBdF4qI3ALb7Uxp4utspD/Y4YRwN9HD1otfa1jXxrB6BHC8MB+PD2NmGQEpHLumU2xAOPPe0r4vWMPAb6LK4zygNzNDBG4GZGeJ0xv1/RjNVO2rgqKBPzM/09l53lPpjnQDx3bZPtvn/A9GYDTZWuU+HydDbQr5N2+oVJMF1bO2F07HjwyEFtm7X2inlTEE7kEjAMh6xLOXPD6o5iOpjQWsya0By03KQnmWvXdGPS/w1L/LJaAD4XyzXm6t5iAy8qjfmmID3G70QeuoHsZXr2+OLi2d5jwQ0C38N0w7+7++ekShNU5fPdPVvIkk2ovNqKBkxqBObtryj4WNa6jASNzefhJLQOc2TcevfKhJ7pWpoOng8eL2gVXqnS02kpm82a23l1j5EUWOP3q5XYfAjVZN5Wyg9A3RXE9wnpKJhsrOQ3WA0LiH76GvmmPyhKJ0zwHkwqLlwoubMTz7wdW3qTnZxNamwaiLKuqClYT+ols5W3+8AoeyEu4A+98/ahgG4L6nNAyvQtCHP4TlVVNhU//lfe4H/8o7+L/8Obfw3/9P1LjGPCPFRAAuL1hPLcYc5GgKqC9J4kqTqR4h2OZkjSAciCcjfTRMcNdCznY3xcwb0XODKt7T2kU4QnTGlE44G4A3O0vAWNStKO6WU0KOP2nhPhg2xEpJmbiatRyTdZnJzqsMTp+fUuVvq3SdDF9+StNkBYOS1G2ls5v2O1ljdG2beuWHCBcVkVOe9YkThG0u1/HwGYVTOu6ZAROH3PNrEgGK8D1u8KzncsQUMGTp8RTwlnEudagM1H4o+fxsZgzsUcL3LsFyw6zU0w1VyIfYdNJ/5Z7Snv7Z65UPJmMVxp0mcTAMkU+O/niGRBHDTaWDCEmhbBD/tIQ5fnYKGi5L8DaHr5MLMiCLM94L1VBGtp4ajpuJSjPsKLI70U3OxVk5GnvO2pFwDlaG7Hs+VHWhnc7QX1VulpWRagiUo/sgvrujJ/D2ijLoWNVRM9IrurEf/q3Vf4M5t/jH+4+z7+2f0LDEPGXFakqI+R9vvPiZXJhqpUZDGFI9+ndvzhUgDNhhnpcl8u2xAZQxOfaXLwliPiGk2IZmPO6a5C+4r+LSWcZVeJQUzCRSrSHJX1izPy/oIp1FcgKLp/zr5xvuWi7R8D8tbG3COfkxLZEvpIVsDvk0ovkLohyKnJWl/hn4eZcXSt+lC0jZAEM6sKTVEqadH86Cni/FLbhpjE8TJteFcTyq3BUXTm73n/OmF8wes63BN8xEmM6esTMkXrGT/w9WlsDGrilx4I1eFcmOiJ/1s7aVz8YvbZVC+yivA+sM3Fr8gCG97Tj0CmQJQ9h++YXuSNyYzNEFYAC2jlA5qeLrjTsDTtajwEQ6rjCJRr9odhBoYnhYePls5OFiMl+RjMpcre4wIwIZIDsYAbwQJc5O4D6W5QKqTxagDiQ2q/I+05rpx3NJOJVzP0zdACerIJyrx0zwrkcY2/HX8df+/bH+Gbr2+Bme5Y3WO0cNuOPz/zutettR7H1Epnr+Yol19cteJJSOJqi9E2EAA6VJTEDAsi+kA0n4q8BrpqPAAXnCXiGOI5dzCS0pEMQoKdwmmJe4Geg3E+tKU4cSxp1zVU29gNd/IKtOVbmr9CBuJuRjkl4BiMFMe8CbYK0q6ruhuXUcW7p8WYNp7IrUhHoE6cjJWNIpyxVMZGzPP06unGrAItDXvuKP+e7gq0V6y+TOif+cw1y4AJzZdTP3Klfxobgy2CkAkwOrEmHoIxuHiy5St+XzSdOQwLcPJQHIHVtyyRp1v2/JtvK86fCSm9c2htip9e0bT+aiMfhVUQyp413xQM3ySEI2m3MFp1TXayZzVaKtuGvAHmK0GYtGU1zjubskxsy/MaTcOfjlxIeU3U2v0O3FjUfRDdQyJ5ypK952xVFcD3qz61CEJ9iSjKKSKZO3QZ+L6K9T3kDQjiQXAOa0w/30Ki0Y0fu2aG6l4IfkqiSPNvrB2rDimRWMquNsNV5yuIAmWXkacOHltPn4gATdWMcoSjSyzVUl4p8m1hjJ1NZjQZENzxlC0D6dhtA3nXs5TvKzAFViSRm6S3FGLTi2IYDBmyJkwDGIuoHIu75qLsKqIKJCrq3Qw5JIKogFV11ppkboplTVzINR5hJqaFAOaPGpdCKiAHaTyYMNOSnnRqbmr5ugBwDgdahRkmSrRFgdKxkgiTNsOX+Yr//tVsJcKCERCwk7bDy8xQGRfTdAfyB9hqoPXQHhsGQ++9Jzx+xnKWgizu5p4klQwF755CM2Ipq9pozRAA0dmPME48WvBNU8UF/rcbd8QzE6ScqelCKHf3aUKf4KCrlfcmq61DpXHq5O2QNJWot0BO5vF5d72iLlgmnpLnzwrklrb6ekqNX+/KvtordQazLCWvcQu8J9VeUZICldqJslPE9127FqQ4u7+EcffNnYqIuCyc/l65kEZgvlXgaoYcBqQngUq4CA+2NmelqDuW7bdfPOHhq2uUGlq6krszedXmrSiGgqpWRd53DZso0Xd929h7xeptQH3BSUd4Xty4ALBdGRZTm/qSYULlHCkmO1s7eVUsjGiR21OUZVRky6bwKY+3Gf4iKxSMqbuwqOsfbcITnPNi4G4hRjXfLByX4NiWT2q20nQi/CVt0vvBr09jY7CphCPs3RMFQLP7C17kLNS4CIkANJ17NCFVnICqVKVNN4rxlcIpp/O1AmtuEnECVm/NjNMQb1p/2Q12B+KhoGw4E442nvLo9Hazq9FhLUEoToDnLJRBmruPL5Awhfa+z7fkDkRDzd17UWGnV3M8ZmXUP6gZzQhqVw0HMTLROUK7ivmuYvv9Z4go9k/kUKssQCNZmoJuH1B6RbGMBJmEVYdnUKSKtMkoeUB631GBae9Ho0nSjUMR9nRqChMTx8sFj6KYVsOVidopcI6Nbl5WHJH2D8RPmny6Z8X48O2Opq+rijDHJnJym3Q3v4knQTayiQ51wXKORjM2FyPP02jKy+NSoUlmBdBVbthx5AMqJQIHkr10Du1ZYStohC5hldtEgPaZnf9Sk/t3AB4Y7C1vmG28PNP85jLWjqFGAd0B2H5VMe14WBKUNlangZrpyDkoDW5ZHfr6+ZjXp7ExKJB3BWmfgODOMwb+VBM7zYL+gReyrJjdx75wmfM62cQlrPPLTHdhc4LqHkNrI2pcdO3pSHJQ2RFrYLXBfAKszCXpJDZeMgpzpmBFw+Kl4NUBI8OW9+V9LcBKZv2GXz+/UNQ1MyMcVK3gCpZq8/Ttd+fpeSPt+gTL0cB1Bk7RPAoE3X3AIV83ZDxYaG3tgHzDE05GOxGNMeoZHN19aGlJmgg6egJ2fOZirisDOydOKOpEO3fiBgH9feDv2lYDdvmwUpptPbh7BpyMK2E2em5gylYhMD/kkBoAW4w7sXrD0Sut1U0zYJZqtHcPZuISWhuGKnR9yibNfzbMxpync3IdAts6TxGD8pSWzGciHjge1EGhwsqr4VBVmkzc6sx27aGeK8Ln5lJ169Z80cRzKmgpaJfXbbwOF2pQaZv4dFdR+2DmPM4Hqgg2ir4kXn3I65PYGDiSCW00V80qu8W7d2CvPCzJQZoYtAGAycBWKc43TJFKRyr6WE4t3n2XbDIPSplvuPjjIbQ+b76lQYsAyC9npLcdx0gODlm57OPRUDwViZiCVJ7sbvftoynauHNzCzeC4U38jtgmCABZRrYuA44jLDQXjd4bJpblOhOIc0/JMFMrcPoee26NBKVQSfAp22oYi6BuvMdWtk2JJWvpC+LBxxs86bunYO7PHFd2TxE1BZTrgu5qwnxOCPf9UhJbJejcDLorUbchlqLNB8DajgGoawVMKhwyUEeOQplkVYAp4NIgtw6Kbs/PH2dAj7Swqz3FZLVTjK9rA5JrDajXGbpPrd1zbkrLhgCvvYO8lN4rMID+ERciLjFTlnLNa+LMpeqEqbyAf+RiLEKvltJtoUW0818qUsefnAk6XwOnz3UhXK3r0h5VoE7ajHDydSGmNjknp37UmvwkNgZXR15auYeZO3PpFf1DaMox10MA4AhTFjyAqDnQnVgaDm8jpheVdmdVKBR6Ct8JIMlrIN1MyIcO2ebpcvY3Yf96Tq3v5k01PYLRTB1LaOhvpdOwayeAhcqdt4yYqyYA0rSMSLUDQ3pvWB7HI8vr/gGN/+9cfTU5t1OK2xRHFAjLtEaHDGwUeYwIe0PAqwCR17KseS3SI52h3Jg0HmIb+XqeZ5gAWaEpDPNazXcxYD515C6YFb4bvTpOJIWMQecsuN2/2+W7LiIcA8q2sBJQ0F4umy1/pRtUsA05r5W6F0TIDH6QwOsQrmeUIULmjmV/YC5EnYBxRXKWOyiVNSsnmI+BZ0EA3mbatQ2uPSDwSkVqgdSAsI+ou2IbG6z1VcxXnjfhFR4w2T1svhaB95+ZJkb085Rr+1jTKzIttVPkTWFquzF500EuXJysqrVWJp4Ml9r8Ko4rHbCxBeL2194XuSkJACsnF9lwC6S1BRnsdJXKstRHkTBQjQAjf+YZ5OLnhx6yzcCTNYMBDAI9CFSsvbFNqXb8b5Zx1keb52I6Ui+RVwY2bpkLEc+yuFZXpnNDtE0j4sSTYd5UzNdoCUkMa+H1Ge/ozUC3I1uQOSAcWXFoXwlWZhKJ8ob8Ak0J6y/2uPvshC+/ucUcej4sZqMWzSMx31A96ZWUW7VPdxYca7oO9ytUJdWYGzMrmPgUG2AmBWZxro0C3j9xN2Y76AYyaIYuCpAoNQajcJuSMIEcinNkq3aXEWy6kfZcPekoWL1THJOgewiYQ88WwvCUumLwrtv+12Sen0BrRzlu0YYbuLM280Xd0LVSvzEtU5EwcZObtgY6qkBOC4/GDWA18DrBCwsP1PFJWcf77KE1s6kxfR1opzwEJupS4jk0fCJk/12wh9zEfQ+sSIb3v4obA9CMPls/FhYfgsaFX1U6KB2pJaCJhZd0aL2itw3V+rJwtrHapcdeFkyvS7Nfr11EOvhIknZt/SPHbOeX0iYAbipbewBHn9srzq+l5RPAFoLrMHyWX3ue6P0DCTLnl9ypiliaE1jydY/WGgSfQPiDC0ugEoQx0kzVxFZOhNFOEZ7CkhwlAaf9gFICdA7sm8WYfV6p9QpNFbUz+zXlpjbvqvXiFkvvOZwT2whXA+qLCXqObTQ3X2tLuHLVYzgGzFve53xTiE2UxFNzVxDOAfmOhroe1acCGK8N6V3Hk3GlKEZDdm1FmM3h+6RYvQOmTKFTWTNFrK7VWhUDhLuK7sFCdzdmZivEEbr7wE3DWoFGMssL1dkJcR6E3DCRe2ZehlEWPUQAZfz2fqeb2qY5Qczmb7LDKinqdUbYJ6TnhWqtQ6VhkE066kSH8FqVHJ28rCN6oIolkVnlGtCq7A99fRobgwDJ4tJgpKPmcmPAzqX02A1KOCcX5E3lCegsSaPSRjPOJHCEpnWIowGDWUhv3QfEtzS1mHqFbkg77vfs7Q4/kLbZFCOtuDBqvkLTKIwDyUVx4gPt7YoTmtzgpduD7cRQG0232jhNKvtwUUUV9t0qNs0oQLkcddlDWnpdKMZlmcenIwAhcJXnBFgIsG8KPoZFAMLRlIvq2hMDYE2W7EBcWWtzonZWJyxN3NscAA1YyzcgdtGz7I9PEekxQpQbyXRNvcTqbcB8bQavq6U/v/RC7PYAVDALUNYVGkjxDiaZLgOvfffMkFcdBdGi//IAw5AERaRZqoUTFxA60py9rY1HXjePJXS3q/QYLdBYm1kwJyoR628FebVYvoWyTD68zWXoDO9dd+CpH4prZmCJYtJat+LApo2UpNDqTTurDM22kCQ03tPumREJeasoF8/+x7w+jY0Bhsqu1Uw8CDL61xzsK2s0EonHx6v11mVlVmqRsWPDW9PsCxefm5WEMTb0WlNA3hXOsU1Z5+Sm80tFHANW75b5N0HGCxcdoPWi7svopzw3AGlWc46hhAwcv28yXLNRjzabj6Ng7it0o9CzGZ6Yx6CP6MJsJ+wpGkpeWRHNAo/lc6zGF1V57pjxafFwNKsNDU13vwB3MXIlKOPmgHnHqiyZtqCuCzI45uv2AeN9z0rLksSDaVCQaBwD8HTtHlPTOYSR5J6wFiOxAahAubb3uRI6I1nlwaxLA2j3kWEt3zshf7XG+o1g/b4azqNQCQiZmwNE0MXYjHm4YXFcPDwskv28YVsnUZeK1cDIJq9OFWUrmHSZbjnoSys5l6jbePSiMpOCJpyqPc2GwwRIJJnJW6c0ceNpuMQMyDk1sDUdFvvA+cbut+k+umcyJMcXi8SAXqlYjGo+8PVJbAwKtAtd14qq7Ivc08+1955C5Eg/AKjtvo2fv+KFcsOLeLLJROCDAdho00pvVzTSR09bVeGuzW6v5i1NjXpBU2aZ7Qs/WrDtdMuHK56kOSPXXpt+gdJoQb+n4Kb0/MeDUcLZ0PsdS26YqlBm4WK2fjUeAyRTb1AvUOc6EGvw/rd/GzG9sOtl7RVMdKSDVQC65Gk6V6GsgPW3i5uUVDJH6xhZNRnJCwFI1xNEFDNWSPvQ2hUfRXLxiPkgKMIcMd3ymnTGX5AsmG8N+R/qxTQjNKC4dkA1vCmPCSJk+qVTxbwNmK9DI5B1e4rouidBeqa8ndoNjr3FmIfBFlrekGnZPfO+NCLbaHwJ44kAPOW1WMsDgoxxFAz3pCrPN7VRxDXwd9TE1tdZsE4EI6lNEU3WX9aLZ2gxH43as+UZ75wyb88CFN29X2+0Q5PtnhhWAay/uSg1P+D1SWwMiED5fEJ42yE9htaPOZehe5BmnClK5l468SQRhSn30ACt4dvI3g9cqPmGAGQ4Wu5iZd+pMCAt6RKMKoq6KUiP1B7sf8ifUwbF6Xs2bnx0XoCyXAea9bs7SbkhpzPfio0ypQJyDJhvC/Jo1nI9/457GYRii+oUoFXoJ7DJwHNHm7cg0KuMnCL6eyJopee4UYxTkDfSEGk9CuYbMUv5xdUnngU6melqWdiDaU+eAU9KjuPCakkD06BA5D2RQiVfrYIQlltKCbvdg8jWMG95H3SoyLvaUrTJbCVeIdsMed+zajJD0+YE3hOHk5HVYB0DhvcUYI3XxDz6Z8W8YXU1POoS6PuZQB6pqi0rYLorKGte83gUrN7REanJou16aOTmqmtwc9bAhX02wFy5kc233DidpaoJCCdbqJ1CY0AMRh0/B7Oc4/UZX9jmr8uoed6ZJ4RwkQdw8de+omwpoQ+nBbTkgVShZq7bP9Gxet6aOnf4VQQfFTarBuPDTIXWTcGcdwGsWZ6GAmhwWzCexOmZUuK8VvR7aaW0j3C8bwTQiETTLYwnAYQptFg4AEj39BrUSCxDoyJ9/4iuKzh+ucPmZ9HQctdLUBFHFyZtLEb3AZyv8B0fy5qITvsGCOfjO6U2crOTyodGjRzTovsUfJD6itLHxtjD6LkNXNgQ86XIgvk6GBYBBMs9iJYmJRqaJkJs5OjAZN5YHsJAkVsdapsaANL8EvNDjzxUgsIJiI2bAeoXzDFbQWRdMv+J2cJvdwX9yzN2qwmPzx3iUFAPbIznHQluyfQEIQpbooFS9LyhgE0UuP6pYvtNxnQV6dUxmeuRSIuIm68VuivAMVKmE4DJpP1l0Bazd6n21cgKrfbGw8iBrttJoR0w3xVqYsCxY/8+LHmdRjALk0BOkWNR85p00VV/HxpXJcyK/pGReIgm4HoOZlQrjczXP4TWTs83FXVVG4sTalkSCqzeLSS8D32FX/4ttqBEooj8P0XkP7T/fyEi/7GI/BP7993F9/5lEfkdEflHIvLf+aU/vALyrjfQBQvaHRXdEd9RMbpPoM+ePZnHW5F5R4zBHW9qx7FaXTE8tprU2me8Tc/vmojCMJtsAJIKW5PpfoXD11sT3/BtM+SDLjrxbKj4e0U6KdIJGO45csobNW6BjVl7taAVGwFamVkGbSO21te+HiF95cm0zc3uXU4RKG65tmAQPoVxmzEnzwRrG4JxPOLJacKLa5bbruXbTAzAgm/yhvdIkyK+Gjl6fG9EHRXM14V/9pBYeWwqphtjUh4E6TlYIhVdneNzbEBxfjm3xO5SArbDBOxyezrnlxnVzFFqb1MGo4CHQ0TtFdMNW7fpRvH8hxgZt3o3Y3jIyCvB6XXA4Y/OOH9/Zll/FqpHjX4uhQcATWmXDdzNgVTIp3DuhXbVJh58nkhC40Rr3vHeJ4+ks1dZUejl14GYh9GxxwXrAGg9P11zA4JzEY5owcEerASgPVtqupfuMWB4WD4Xpf0K8ZitD3x98MYA4N8D8J9f/P9fAvC3VfWPAfjb9v8QkT8O4M8B+BMA/g0A/ysR+YWYqADtNIjHxTDTATtvI1w6qm51BSvNAcgM9PeBoS2uvoSNsh7pISB2OgNAf88y0k/8eAxIT7HlNiC6U48CWYwqbUDazAvunhAMjOHXjp8H1MhTvaxtwW8L3BeCY0/2fxASfhzXQLgYa9rX6hih5qCklvAM4zJApZnGurWaB5e4B2TeWJvjU4jAjWA2R6v5ihfEeRs+M3cuibss+7XMD4xbLsY/iNOyGdXB8IMTT/S8rZQkm1V+PHOk66lSYeYYMh6ZgCX/Yo0v/8lryEMH/Xag8cshIpyJETRGpbVByWT4ea3LtUvA4fOI6TahrEID6mQoCNuM+c5YnxP9HuuqIl9VYkcdNQktdnCmojLfUJVZEy7cm6ytHQjo+kRDqmlmzuYFaizNS1Wv8xYAoH8g1V+jYrrloZY3aIljMgumO8Xpc9voEzfA2hswb9cDCuIyYQk+cvA5HdEq5g99fdDGICI/BPDfA/C/ufjynwXwm/bfvwng37z4+l9X1VFVfwLgdwD8qV/4C1iVIo7S7OCpk5AWLusxYgAswQeLdn02lP8MpL2LmNi3+wkNM1X1Es5/JsSIUDYzdmJVeg6IJ8HwPmB4F5AOzGxw2nHe2mblYGCkfZbrI1wAwwBcGotcIsPFHubmJqzLSDOMnI9LAbpvOyAHyKosgbJjAITmqlKliZnSQdA/mr1aILYyX9miHtHCZL2Fon27k8UMZ5ml5UB6NoQKmpeAZIGuK08zAxgRvT0RYF2oOFxnukbZpsJk69LckCgOWgxPBbxn8RjQPwTs/nnA+o1g9Q1xhHSUFiKU9gH9A0d6AIHN8Y7JVU7yqUmQVwGivF96iqhPHa+BtWzpZBjTipC/S/Hzmic/Q485JncBGi3hw1JtVDTXah+nnz5XHL7vdn02OYvLuDFbxJ2UZYPwyiTvKP7qn0hKihM5DwjmdK1sSaab2tpk99eAEtiefPMjTmpchn85GMP/AsC/D+Dq4mufq+pXAKCqX4nIZ/b1HwD4zy6+72f2te+8ROQ3APwGAKTbuyb3dUKPOuaQWEa5jNQ5DDUpk56nZcNQIfjk6cOcfyu6A+25T9+zh+fSq6+vBBojyTi1V6zeuASXO3NeO3oe4S7GOkqjPYeybFw+ofATn4E5ZM01KrcJiJp+fzLMJC0jsFBCa6HoZFxRtxklLTzZMAY4x4PAFP++/05Yi+JMOlcDqqH9tTM03Jy2q20YTeEZ0PIO6q6wfYlAWGfgMHAzC6SZ156ZlRKUBrAHPlo+CvVpR75iH9wcu5JtkE5kMz2KU4K9otPgvhu8Vuu3inkrmLOge444v+bm2D9L4z3EsSILBV3DN4ngnBnXqvBzAQCKLGQ0cKMpLidPBgKbAhYCVDvxJXOR9o/2864V/X3A+KqiXBdoTJYvUts9Gt4F5J22UN/p2kRTXlNbZZm3y2jSK5iyViCZClmluUBT9GabuJOgeqorvf34WKOWX1oxiMh/H8AbVf37H/gzf7+t6fcUMqr611T1T6rqn4zrLfvNneL8ecZ8W9C8CraK8XaJbnOE2n0Y/NRxXzxSqhVxYl9VBkE6Wt93ZAXQWc+LACCRpFK2FXGbSQbaKqZXBePr0rwd40laBJ07/fi8v0YjBQXYfFxpO2YAXzwQrOwONt4KaGAUwAUZzwZGfv/U6N15oygrcizqOZKgpEA4BXTvSahJJ/7Mui2Yrwvm20LilBHC1ARAPnpz+fW8s9L5YOO9spyArIgWPkO7Z0a71se+nfRtE4ygycoUbWoQ2maYzqwEoocUb+pFRSeNaEUpvGD3M21JzTWZ2tbasngi0cnbiuEBzVFaMu3XyffgRGW6sglRAKDGNBwqEMigTc8BMtEzk5oF8hygxnXpuIDzrjaWrQZmk5QNN9J5txjEBiMxUQJv7Ek3+TWjGScjMV3qu5sC8z8U84vMk98OnPlGG5XcbfCcdNcwkTm0A68xWiOvY//4gavXXh+yj/xpAP8DEfnvAlgBuBaR/y2Ab0TkC6sWvgDwxr7/ZwB+dPH3fwjgy1/0C6QQTJnuKH6p+45ApCny/NSLRz4E/aMA4fIh4D+lp3uSmHtu3oj5LJpxajIawEw7LmYfEPzp3kZMx4DkDlJXM0JQTAZIaog0Yql8OH0TKCurAGzM1R0U3YmnWVmZrHg2Db71fBA0q3gNivkFJbO6LiiFZWrZuBmJ5U3mZQ+va6r0puuLAJQxLOYphnTzD2wmPvJz1Q2JIXKOQOIiyGtWS6KxAbrFx4neq84BsIlR9SmPEgisAMI5cNrQF8iBE4HuedkI3SQmHonkQ7jBd4XeEhDe1/6Bh0D/zI3JN6DT5wRj19/yY4WJo7h0NpZjQFNKOgsyZG2+nM6ETfuAslEG3daAcDSfDqDleoYT4ExSGG9FLN7A8z4a4OejyVmQDqzCuoOpaoFmZzfdsQ0dN5XCuPuA8WVtk5D0FKCW9SGFq74YNyUcQ/PJ4GiU0vl4DkBmZZFBbGS+LhD7u+EsFsUoFhb84a9fWjGo6l9W1R+q6q+BoOL/WVX/JwB+C8Cft2/78wD+lv33bwH4cyIyiMgfBvDHAPzdX/YuqqnM6r5DeoxmUSVYvVVsvtG2+NOR1UCYFOs3iv7Retjefo6dJDXa7jwC6eCnNzC+Ljj/cOJFfz0CqRKJX3NE1e15Coc3Peq+I/V3dCCPvdt0x5EXbbPsZ0+upddmwOntT3cwoGpFU47+wfwfDIgkyl0R1hn9kFFXFeXSMMXX+Bi4AIXeEdNnuZ1o6qVvRANV01ma3RmUtnfpyajPFeYQZXLwp9g4HmEGVt9EM6NhuxVObF3KujY5OMQ2jABor5BTgJ5ILV99G4zgZaCcGamImZjS95CeCMM9QcK84oJOZyBkhbthpZOHDgtOr/jP4QeC8Y46lry2k7MI+ide8/65wL09F/AUjSEb93FJMHuO6N9GmqxMC27BB4seDt6CANysXLtTLUTXCVHdAe0zeqnfpl6yWLWFmRtnTfwdPk50GzzutkbKs1arv49Yf2040aa0SssNjS8dqmDTNE6+tG1+H/r6/4fH8FcB/E0R+QsAfhfAvwUAqvoPRORvAviHoAD131HV8gf/GL6qWZ3H58hMx/VSSqYzsP52KTfnHU+FdFaEPXDoBfOd9V7W44vyopYV4MrKOgBf/NFvsesm/ON/9H068YwU7aSTtD7Xy7DmGRD8hF9OYY0s5eLIBzrMPOXipMirZfzk2nmneOedl4AEGEMOyNWyLOaIsQQzMtFGSCLduHLhOdV1KNAqCE9Cs9NOl7K08s5WiygTY2S6/6I7BseRVvlOt3V0n9b8LOHroDRlOTM52qsdmD0asLQhUKGCNKPN5L1a0aioIJ27uzsj/PbOqilFPbJqKCuGp+StEY/Oi3OVzLwP7oYUZqDfL8+Jt3ebbyvSieau8/ri/jsxNFiLdlUQT6ndT9eEkHqtxi0RaPXqhj+ffh3CyhRodGdWNbV5Q7jIKo6WWJ5tM+mIE3BzECBVmubYlE2TIvumVMlG1QBG+tmGEg+R2RurxQNEOyqJ0VfIkXR5bxu5Mf7LAR/5plX/DoC/Y//9DsCf+QO+768A+Csf87OjofeehUCvQEFZCeKo6J/pvDxdOYzPGDangpJQhIbEloGmF+4FKYZJfPnzF4jrDAzONoIlXi1lIYUuhhjb9SwWSOOmGQCQr9D8KTVxKlH62NKpiPQTIK1rNIJK3lLKHLJgXinLVQHiveU0rCtdjp+6BipJIhejORGdqcd33wZxzESUlOgRjfodsjSwsaxrG3fqyIc7TKa5sNAbqUY6crRbSGySyp4cApTkIzgueB+baaR3gJRE6q59LVkOQ+krUqqQ0cFkaW2g+wnMK7YAmwNaJcFkaFhsHWfz/bPi+HnAaHTk7c9ZrY03Ed2R7E94SyNo4bb5qkCGgryhTJysSoratClYrTVzynnPyiu8JRHp7M5ANiVo2IW7NJkpEIBWNYgaHmWS7Oklx9g+eUhHwdQBusnk1wwFZbZ2zMciYj2rO2DDNqdRIHNkmpq5ZfvIug4V+qvKfPQSNhu9s38IGO6BOLK0Gq85clndKzZvKuK5YP+DHvOVx78pVMiHL8Nioe2U5WqocvfTHtC+jfG6p8XFx9sCKda3rYkR5I1C1woElo8yhYb2utX4dKUIawpWcqGYxT+Tg3jxZInPkb1fHDmWmmtAvimoVploFlSxsZ6fJPuuEZho/ArIGIEqyFeFMuIAQAg+edXRWSlfBrYMuy/2OO4H3H5xwPVqxE9/8hmnDdaytPFrZUVREBAOhnvsuJlGk7eThLX02/EQkLcUQY2fZ8uAABC5eZW1ov+qw3Sf0HUsJ9MJbVOuHRDOQDQHp/Mreiy4nX4z6FVuKOO1tRETiVinz/iMzNeK3T8PKL1xYsoCkNZOIetCkDRYud/ZppGUhYWC7dqWArUG6MG1M7wnbizsHBGZDOy1iVN/pm7GR5XejjBs2acdRnSabcwMHhRQIW9ll5kCZgpQT+FKD7FtdmkvbcyuJxob56tiKVzWRj1/DGXpU9kYYCDiGWCd7KQmRbenKKUmlpbTTpBGYHzRtditMAMI0pB+avSXB8k56enInZwLnkpM/3regqCU6RuYA8jerG54wsyJN0OvZ+iRK3Yyj0JgYWa67uKSYNKMUW0ci2CCGivrXTAG5Xsryh4/jgF5RwIOBWUC2GkGAR+ioaKsA/rHgHmrS9mM5f2UFRHu6d0G3W7C6+0BwU89kx87mFpWtTkmkzBlAGjx8RkwvlSE12fU5w5xH02mzJ8lZvTarNKySdF1GYOWlZW3bp+uaOrDeDYAcU0WYP+kdi0WslsZgN3PKxACzi9sc75VE8MtPgSXTtpOSqrHSJn1WcyQtTYvyHQITeU83xTUmwxMxGaKK1ONEenUd4CbGVPUzeptXTFfGSHN2q90ljZtUpPGS1kyL6Zd5TU4JGhfgcwyWIzqXmMhi3ewZ8VaCARpaKG/n/QczbmM5jIf+/o0NgZdTupqM+h5x52431eks+B8R+cmCAUzdL5RlDVn0JJZYoqNDYt5BgKMsstrc04CLBNREJR97aw84Z2MM19bXsFGUXcZ3W5CShWnOiDcdzBZGxfNeTGVBYiBAKRDjy/kogfGkkQ1ATIAnq4VCiB7y9CwcVS1nIYy8KEFgDBZv3kMTRkaJ5i8mMpAb4ccKW9s0Wh9ck7Yvt7jJ9++xPQ0IByjtV+K+cViDSfG8nQGowZuiFMfETLt6Mu+s5RrMWapIr3rmKdwN6NMoYmp5p35DiqrOSZOsY8fHghChpl5HWXNicN0S13GeMtr7FVeGxsbQFksgLY0ApA9U9naRONowDZrdIr13Qnz+6vWGkYLs5EMJlolmwiZuCmdGOvHaDu0TbhuattgpNqpbZhE3qipbwlMkp/AdpCWddIctLOxbF3UJ32FZoGcAtPGEqAhNk9HDYCastITvi8NghfiFJ8b+VVMopIKrN4aJ1852tOoqDHg9DJieKyN3JSOxkirQJwNIOsUIlwE7N3BseK4nNw+T68eFmtVW1nxdzmrzg1iNHBHn1YB88MK+hjRz1xweVehk4FPBYhlaVl8bux8i+lGW0hM3rBHTmf2tN43+viurCvWnx1xelrRP9FYgiVIA8BcHi51cRRyWrQLobRXBLMk87EVhJtW7QSP91umNZmBitj0QiaBQJgnsTZnIyuvu+eAaR0N0FWbMCSUbYFWY01mwdVPFXkTsb8O5DUEsVGblfLXM4oA8X1q189PP1YVrCQ0APoYGnks77iAGCMIpLzcWzdVdRA0HRdJuIO4YqBqPAv6H5xxsz3hnV4Zld3MZVcXPhsBjSpf+yWYplwRP9Gq8JRv5w3EAysr7XwUTrk6lG2Ue4iEs6lDTecCWNULQbkuEIvUYylB9WcEWu5m90zWJ5OtlzYHQAtnCmdBOoVmQVc/cqV/EhsDwPJ+vhK7mWikEI3AeBOMQcY/q2KnrKHp806RDmhAEnym7XqDfgn9mK6tJ6xAKBxPMi6eFFbSab0nXGbIzXdPuGl0pu2oiRsUwCkJqxVpYbtlTSCt8ResxekfgPpy6VfjUdA9J5xkA9lk6By/Y4OGLMjXRPKa6UfnqL+dmpFOWF4phAzAvBFqxwTp/GqGBAWOEVgXbkBuv7a30npd2c+alLtJ2s2uPK9p0MsYPrfN44Z0+AGvj5qKMF9R8OSjyzkk6Iaiqby2sNjAakGFoHGNy3i59MDwHvDNwrkG8xbNSl0yEERaVuNlohNFTxcAZAecvl3jm2OH3u4fYMDsiwxkQf9N4u+4rdBIUle+0UaGSkZUo1Ufpw8MP+YGoZ2iBh444cygX4461VyuPerQqjqg2dRpiKhXYIsoCtxOOIcO3UNo71WKu1ZZxTlKU87WvtLodooItlHGk6D7SHXlJ7ExaAROn9uHtdGPgK7IjZFHPAanV/bQ22IMMwFEVyQ6Ejxv0Xb9dAZchqoRQAHybSXrzwRXeQ2EnuVmWStLxXX9DkhUBqPInoMFrtK1x7MephvadXnLMF0bqeWlAUznJXg3nvnA+ucqG8W0Loj7yLDYvkL2AIIirTPyGIFTtCg9k2DbKYzZSterirz1ObtVWJZHMb5ksIucInQNqjsTOQpQAF1FeVFRT5HJ1k89T9gD5/362Yhf/8Eb/ON/8TnDavcdhVTriu6RI99spKy6UnSPdG6eXhdiICkg3BO0De+6VnKn49IX561AiqI7AdOt3fdCrMGzFxC4cXA8aLyIijblCGZ84mCm/1nI1l4W679N9p3mpUWRoAhPqf39aNiKK2/LSltsonNQxMC9dBba7gkgOVruam3AurNynWbfwNRK4DFvK6Jlos4DPTVYqgE6VMwvrIVUtmTTLb+++jo1C8F45mQCAMpNRp5J13Zc7WNen8TGAJDmGm0B05qcfVcoBIcaUzBZf7rNSG87fvBigabBRlrTInvlNMJK9s5bDUEdnN9eF9acLvZpYbKJw7pCjgFqlmWqC8p/SWtdLO35T0vMytJanWrZA25FJ478u1uTCktIPy2qkMdfBLJnqdR+fjLn6gOFNnOndItyOfN2Kb3j2ctlLrYs/B39t4mn+LUifzExOm2bUcYImaTlMqTPTvjs7hkpGIhlyd+aiMTTdJfMRRenlV6RijDDcceKh60ge+Tjj2eOBGtEdzC8QcwYJet3ZMi16QMAnBcuw3jHvrrbEwj06QJsQ4TyOrhztTqHYVONGMbqML+cEZ4T4pse3SM37LxxvEZby+YtD4Bmi++ba90vUuowCTUkD4mtmLd48QKoPi0gJx2tZGGrgn8gU0R8pK3bfFcMO/Ddx1q/GSg7U3juw/J7DGsowxK38DGvT2Jj0LBsBum8fN3j2cREPvMd05e7Z1p10zJtGTk5xXi6AVbfSkv24S9BowvPV7WlJbnEe7qrXGSnpSeTAsC8F6OZk9aAZuSRV9x4qAxlxVJ7lrQ4s3QkoxNApy0ERcwUxE8mukvF1neiCMKqtgwGsRJx+Iby8UUgBtuktHkGqo3gaNLCb6qZGwAAM8lJREFUxeGkpbIzeXAA5GzOTAVmAda3dkSElRYUqJuK290Jr9YH/M67V9BDgigJYZOb0EJaZDuR8gokwZwUyQ18r2fMQ0QdSAeWOaB7CA3XkUrWoIPOnly+fmO0dosK8LwK7YD5ReZ1PXeA5XnGs7QMD+Y4ouFTgLWXFmTEkt7KfztYaDK8AHwAgK5CNTSVJVsHbY7i4Uhxnet13KcUisaWJLdhmcrkrRkB75cNM2/VPlMFZpLWauE4snvP36G2QUVT2Hrmazgvm4panGJdKaahQGP4aBHVJ7ExuATWy8u8tRnyzDuTTqZfUD4M/ZuE7m1HbbvJfV0iLFkg1m/RJxLkN1isW/dMOatXH7XjSbP+0uzQN9oAmzBJm/y5X8R8VRuRqs3AjfkYZipBwwyEwPd9/swWz8WJUFe1ZRzmrbaNIt8UehCcAqp2tE4fKmIqKCE1Vl5eozkXA2jaCCcKAWibjPtI1k4R98E+hzQ/hGLSc74vNf9Fm3KY1Pr92ys8Pm9QDl0joQHcaPOwjCUZQMOH0j+rCgjErQzsFAKJYpFy8cyHOx3M+PQZmI2YRCKQNsmwbxjOTu3fpraphAyUyEplvimQHJGC0bAVDbui6GxJ/+qeAsY1P3P3HKyyoO2fA4q5r4Z3GfBt4TaeyNUAVKOKezvjRr5qU0u1SUdzju6Uz7jYoZLUvD+o9oVxHJw6XdaKNEozMSprEuW6JxLyalJ0Z8HUmVtWV5EeUlOFfszrk9gYLl2Uy3rhHZQVWo9UE3vDfJuRN7S7ClhuSk2MKgszx7/zzghCg1GnzeEoHfn/hx/YzNz4+9XUm8m8AqbXBUgVcV1QsyDnAdgCdVcQ9gQAh3vB+EKhX5yhP19RfGMnjXtALiM0YYzYykp+e3hI1XZshKW7bgtQpHEc8hTJ2Rd7yFZ8UMOJJ2403wpvRaRazqWJviDa6LS1Y+ndSF2Rv7+sFNhlzJparoVUID1FqESUHfEPllfSYuexzagSeZpWQTSQz018vSQPT3zU+gezhavyHbmxg8On12EhhM1ATQtwWxPQPwFSKK3Pa2kAM705jET18oxZ14hfxaZjyeaUFWySFUZWKKcrbW7UdMTWNs1wFiMKHaulil17EtmmjW0u+8BxqCzvw4FJ2JjYtRLOpWAYMN2rVYB8W+DCLRcQyHlJAQfQODruX1J7HqDxnFgdbYBgbFFS460ClY9vJz6ODvUv82XMw3Yi2KIYX1RODQyJjc98kryCINPRSsNMrELKcnLWCJxfCAVPkQ/F+QW56Xm92K75LDmvl7IcOaAcE+nHavjEYbElE6VFvD709oCwFZq3/CzztTkHvzdfxirN0boMaPTY5kmp4OKe7LZk/reW0MZfBBQDMxKsnaDHBP9KGbSRi6hQlSYwK2s1K3a09+s6gzooup/32P7zaA82KwIaoqCV22GmQhEAdFMQ+kL3q6Ng9Za+Aa65cHCy7KppH2xGX2l4uvmmojtQEp/XzGTIK1r3A2gkp7xZ2KN5A2hYpPQNcLT3BwD1J1sCzBttBisuJZ9utGEFbcRrG663LHm76FRqBMLo3hgcAxLINnGZ0ZnzlbbRZyNCXWwWl9eNsXpYLPZcdl1okiNzaLb7NBZi6+S6i9orppcF6+/v4faF7vNYVosuQ6bQ8BXHZT5iOX4CLwHGG5qmerAKUUA1G3DejOl1abRcL2cBXrQWI555ImpaZtKOAguA86vKPlKI6jZfx2GZtXfPZvs+CdJ9QnpMpJgai86NVqr923vP8U5xes33lk4s8RQUJHnmZphk6UHh3pb8/R7SIhOzEOn/qNBjhIfa5JtKmfR6YbNp4MlB4hZY5sJKWQM4GZ5qIy0j8pQeLUMzHkOTjjMB3DYsOJ4hLedAHVidA8qho7+FgcPpbCalQFMoSpElVNVclMn/F6STUluyWiZSADc413oAaLqVGkE59Uow3sIs47A4fFVOCJJtVq5wBQxUztLwim5PYxWneOetOzrz+7mZoXlqMjZQkC06zg8JKWIkJzswzAsjWtJ03lZr94zxafLpMEvTk8CnQ9UA6KDtcPTqLG+1ZY30d2fkHEnDtind6p2YazrNaJk9uhDAPub1SbQS3zn5K0k5qCylUFkS10GBVHH96oCnb3bciZ+DWcYLRMiIW78tGO9iG1XpGQ3kQ3WSEAAIahdamaaBQFs8kNGWNwyEiaM3Z2QIqs/yN4rh3oCgMxrTzc1ZmFzkpBQbpY5AtZStFsUH3lTX3jP81P5frBKw/rYMBLPUUpPE2JQIAAouPADdM1Ibl6KJfYyTwbEmy+zxTi0dWTCbOMvHgPO1pSoZuEXw009Cuhd7eUz2JZaJjnDE5hUZlGzG9TecyTeeiUnT46wMgUnSNAScHPA60beD7+v80jaos8UH+iam3Oh8UTmwzUqL92MywNHblNpbVoifNYq2gcwvfdwayTKcBLrTlgLGE1mb0tI/5yX7MNp4m+0qVbv9Q0C357Wvib9bNgWqhQIpNyk2KX3wtm9TEJ8j5q83SEdBZ89R3hiQKjAXaQMms4Owy0H6Ia9PZmOIZ87hMbEMCmboIRWYfCz3kPBUd7zpsiDYrqLkCM8s1KKibBmQ2j+a5PnG+OcPgu55qVBqT5+EmkIDqWCjMzG2Yxujvsgk7oC5i9uvmGMwXy9pxc2LMgMaLR/AcIdmF1/AyHsr48Wt34yjkB4jS05Xgc6LzVeNPBmyWZPJTHYhCgN70pN7KVil4MzKDZOpq50wDMhRHL+vFmwTcf7hhO5NR9u8s4nJbGNzS7QwGwkKVAZy4rNMDjyiDcL3E86hKQpxM0HfDujfcvJzfB0Rjdw070hbd8s08HI0V29NwOGHBJB9LFhW1g5NQDBWa7BqrA7AtFVj1vIZKJGL3qsMHhrSDGubVNlPWdvUNCjmm4ruiUevTxjKSpttnbc1Ponyn+VmsI2h6FXRipM2yRxrO+CJfJm3CiDZ1C0TnS/bCnQVOcZmfDNfwZ4FNHyjbCp1Lgkon00ftSQ/jY1BuLi7B44Q1RZOUxb2FTpGJl7bDQkjs/tqr8jVKKaD4umPOEinwLpAn/tGLonPNsK5USP+EOAL2UxdrBTMWwZ35FQgJVr2gpW15lJUhwpIwLwzq+9B0T9Js63v9pYkNCxjNmf0OT6h9tl9s2DYDT+jVJt1m9dCNEt4j3hzZh10Qd15sdBcmKa7SgesbYFkO7mDotvTaUoFpj9R9NsJc0r4/NUT9i8GnH9yxTwEq7TcgVptPAmgneputXd+xTEw4O2K0BA2KtKR8/j+d3uUXnF+yTL6/FobMFZ7IO8KgoXjSkXLrUh788e0sTHcB9L8QFsFY9c5nYA5OkBcMb4E1t9YNkZn06wMSy5HA/ScjOSYlbedLTfV2i2P4avm4VB6ha6WHBMnoNWkSM+LtsadvctKkc3kVRPMCo5qzrqp0EE5mkzEjOrabm6wycWJyloNfGbqhtc7PYULwhPdqmQWyPuPAxk+iY2B6j8sAFy13TXYg28kGn+JWcRrXMZAYhZgs2EQSAqco5GN+KCkjkSgfM2gElf15dWit+diA2Qk+4w9HW8YKuh7kDuW2VcVyXIaIAvI0+254PLaBFmZ/b5rFyQLPDcy7gkippEb1JzVHKU5zpvubCRWYbJygiVirsTu+TfdcfPAmf9fLEZPhddCURFOEfU6Y76OKCsxM1RF/4MD/od/9P+Fv/EP/qv45utbSKrsTmxS0z0Lxo48CD0Fc9AShIfYfAeLz/+V9O4ayb7DGIwoxcWSnikcmq8VeuBnvDR9BUIzrs272lSMDuAN98ZxMBYjDHz1SsbFbH4vvMrSCJxfcDpVrzOmFDG/jzbmtLxKa5F8esDRbkA13MB5EqiwLImLicEsyLsCrdEmTuZl6UVCBmZfbabZqAOgx9i0OgWB2R9nLm6fqumWDuMyS8vtlGKhOwZMN+KVHUJ5V5pZcPf8XbPbD3l9EhsDYMpA4wY0E82JJ3q00wEhNAGRKGfww/tIL0PrnX1m7+BNvuKpDyyipDBKqwCau5AtAqwKcIqUPldmJYiF3dJ4he2JP3A+WvVTgAEyJvm10yhOZNOVdUG4mlEP3eLMY5oOsZ+RzpxJl7Wi7LhRxaOBiQNLSExWpwa0dCXtK4qXqGvO331BSKpQBMTPTxi6gmnboTP1qBSgnBN+dr5F6grytwO59Ua8cbWoJkW4m1D6hPA+LSPCC6JWOorN432z5vt0ULVa4I87gi9tGxbNg/XseVubH4KeSXYLxwUvAMAFuuLv/Q5ICds4PJ/ENu35utIvdDRl48pETlZ2B0uMInGOHIN4AqBMRCuJFdPwQFs5DyIG+Pdh48xw5IJEEfSPCwhaVrxPCnp2lG3hprmpKJEVrVv/12QHxKbw/TrL0t2dMviM24bo4TTaKbSScQp7TBxY/5jXJ7MxCGBkjkBnG8D6Nn5QuhwL3Bq+Rl+Y5DSQaGSnZKdAXnTsUsGYN+GEwyXZ3iKkEyWz44uC2xcH5BpwqFet/wyTl2yc5fupEW2EmPZ8QGvPUVTtgvk6GsHKbnQ8RNRKVaa7BbtCMG+08d27vVgOYW2z6OE5IN/6GM9GWdsKbDOnFrMFqGwojKoD2yVNgNz3LOlrwPxPN9h+7QYmjFyTxzX+b9/+cZ6Se2kAVph4nfk7BdlGaaG1XAoM9t570xF4e2MiuOYbYeCnJzI3QNFt4FYEJhm7Ju0ZCIY55Q0gBii7t6KrY5sQzSYIIQPDnu9xvDXquI2F5622e+oaCVRpsXsKa+FWBfMuoFxTfTQH9hClF8SExj6txn6EEmit62rYgAGByUFbMIO0ZVQCdWZrK0NtBx/Av1t7BXYZsavQR+JZZVuhvY+zIsIxUp5fDbfKC9clzICTrqD4jgLzQ16fzMagwTqHRMZW1YB4YbfuSDHUJhcWcOrsx5Y5sSFANN/Q9CKeLDF4NKKJGE1azLjFeufxVqFXGV2inVZwOWu033EKkHNsAqV0FMxbbY7AteMhEfcE/vJGka8KEmLb2b2XdQtyn5/XTlGuC4qBTqu3Af19xHQHtjdXGWOwSgRsaXQw7wTT2rcUaz9xNgVZGVBDKbmiPHdYPy82b24FRzZgaIlFziXxTA23KasPHVWVRuKKJ1ZF9TYD52BtR2jjzLKG9e7ShGNSYbJhtF44ZEBnXo/pxqz+zbTWg4UuTzy2jPRw6A7A+RX5BioMcg0Tf/Z0zXvnhw4nRbXRocugjRYP9WoFFxGCivhk0vKhUlRlMXkhG2nKHJkQBO5Lwb9vZCigtazdIyP1uNnbs7lRSKqQWJF3tqEGvpdyjihzQCyU5HOD5SbQwMykZGDO7IEawUz4jE7XrIZ9JPuhr0+DxwA0qSwqyPqDzfa3BPrSkRbYlynKYbIMRXP/daPTYgKX7pllXPfE9N9oKjtHn/MWmK74T94qfu2Hb/F8XGH/L64b1VqcHnxd4DFrftLHM3EET932fwD77ym03thLZPdQdBabu06l95T6asf8AHcAdpxFu2qiGb6veDAizGTaiyyo67KAkIm+f8Xs4jEbScqcsVzoFIyOLZnjvP5JsXqrRq/W5tnoi7122tqA4T3HdZgCkBhMC7kwYfE8hcmi4EzD4D6Obn0Xx0VbUDdMzwoZWL0XbL9Es+v3tsPdnsrg41HDm3ojA8WFEOVtjusRgo17GXOoDVT1n+HgYbB7LEpQMz1FdE/kHrhIyw8JF96JVQ2ORwRjLnq0HG0B6C3p4914CqhPHfSx5/1fLcY8cc+q1/EvFCA8x5Z7Gk+8//7Qacc4PbXx57xTc7Jm9N3HvD6NisHeMw1BgbSPDQ+AUsLqpee8I9Gje17K1Ub37UnuyNtFRNPtYW7FaD01x1wXs/5emX4MWKz58jMax9wWqj8ITnnWoC0DA5CWWsWJgyHCGdCVtUKz2O+v0I4px2reieHkkl4FVoDcTQhRUd8N7QGvRm6KJ5ZYYj9PToJ8BVqUzQFyTPSauFLLQVAgWj9sOQ6OQRQjgOWNVSU+PYlsjSRzc63mNpycdpvQRmwyMxeDjFTB+Ycz+jcJbm3mDknzhkBwHRRFSS0eb8V4/zZevcnAvkM8AXkj7VR330afWkHsPZjqsEKg9nO6g2lYRlKvoaQwuyw/nsSmLoLxs9LyNutWOXmaHdBji+RTjP6R71kDAAuWdbq2O0Vpovdkt5cmr9bAz8CcjNA+T5wEcSQzdr7hNAwXVUdTdYI/313A3SAm7gMKEg8SA86dA+FVYTjK8hx/4OuT2Ri6vVz489HYNZ4pKXbevZfwzRAjUYxDPYJAh4I6cCynlRuFE2n8VCRD7mJTWC2eBD/9Z0zZE6s4vFwLY0B2O3crf/OaBCfPfowjMNnvCZbrUHppcerB7M8dHA12EpS1tlPYRVuco1dgjhiGEeNQIWZKWgDougKn0Gbd7tHQPQRMr9TGXpFovVUh4RCb+1MZzPUpgGYskEavdsJRHQx7KZFA6Hrh+teei7ulg60L9BjRbydMRvkO6wzAvA2M8RnPF2BlZgYEKhADOSUaSfcuRZo9nRPFqtGxp2uOhdPMakEjML2spj0gX8K9IRvxSgmixiMXO6/L4oIF2O+ahFOBMbSvh1Nonhbe9vjz2D9xM3Wsqoq1u6ZJKT1bze5gz6IxdFdv2bKML8yObRKUobJSvljAdW3ga897Gp/4i8pWUVWb81R8Ds25CVho7nECYC0ZSX0f/vo0NgYfLdkM2R+idDLdgZW8Tkhx8guA7xhgQKVFxfkOfSmySUeO6Gpvp7zSNh0KJjMBnBErSHE1glKY0BYy5NIZGFY6owFs7jo9PPAb2oNZWYXEM+nBdbBT3zcSK9mrJRaHU0B4jBhdTKWmkDyEdqLX3khLtjlKIsbhadIOerr09/JVViy33QuQnIYFwPVe2VWIzC8ww5I1oEEwfka3ajo0BUwPA4lSVVjp9Pz9YfZ0b96H6UYxfpERp67hGslzN6wlVGHSmKYlnrCsq/X4i5dkWSlkFOhtgZ4DXZx7yrUlo9HXne6edxWeGVF7xXxnlaKYNZzxBqQsJX8jPEWgKD97mNHCjeIE5Mhn0C3w03Ghvo93i/yfY13iWzwMtY08ATA7ZFXpAzJGZoZOAZIDnbYA5nwMFbUkusnb9CNMxruwcXWyTZJU/I9bkp/ExuCWa+w3yUWPJ0G19KmyBkqwENsRy+jLZuPxzAUMWFlsJ4HnRXioqz8cBOuAvKqNZVl2dgwEYeLTzIWSr5ebgQrMp468AztFiqHyzIHkjej2TE/SKA3Vd1qy+xZ4yV47ngwOftEFmv8N4clbpwhNFfUcrazl5/LxKXxyEtUeQANEe59iENkvK0V8ChgelQarRsaab3i981ZRvzhDIgE7Rt4TK+kfraQNlL5LXxG7ivq+R7gnTN+9S5hvC0/luYeYzD2dOFrWBPQnoHYCBG3VF8VoxgxNAI608oNtVr6pMGdETfuxAMdS0UZ6vYm4qJTE4vRVgNlMgPNFlUYbPQLLUDQwVwrQv43QzjCLFVouiLe+TmnXZHiMgYo1KfpREAxkTUcsWI2g2RQWy5YsftJbtmUNAbie+WuyVS9iLU5lm0KtjyI8BxPqAemktBTsAYhNzs5AmL+7+XzI65PYGCCKcpNRp8Ak4WBlf5ImLmpEkUnM1NQ2EfMijKOinoNVAI5Q2fdN3DFnQ6ldBef6+DCTrDPfFiAp5Aj7u6QX104B+z6ao9JDTypxC3fMafP4Ahy+FzC+LuzNI1BWtTEJ66CcdfvHz+xpRQEZlzFsmAX1qYN7S0A4oiwGzoYMJEO6PbFK/CQ14EmKuQnthfLsznI1e2B8USAvJmgOyE+J/e2B/OO4y7SXO0X2ruCpPr6sNCsVRXnsDLy0Sc2BrUft0ZyLpARiF2784uX4HCyoFU3oJTaSDpOxUIXZlpfU5OG9NIkxwK+1qidqS57yiUTZsJVJR0F/L/5XFjLUl0OjDzvBIp4E+Zox825Hnw6COehyH1xQZ4caA3r5llyA5pMyxxkkAzoA2Q6qOAmmdbXrR1VmmAQoAj0m+jEYGIoorTqTU4QOlVUO0GzvauLmkCFN1p83XDP9868k+CiMXDPhCm3RjSF3y9M0HhnmOd/Rl4HJVQA1E2QTtvHQxO/vntAIL7XnDl03BekhcRHOS45gMzjZR3TPDHqtQ0X3RKv0mqhgpEsSS93xpWK+rm3MlTeKeUfOvxQ0MooapiAZiEUAMXQbaCdXs1RPigKi81VBxqXydNCoTKiqAjlG9A885cYXbG1cgRcmAmlIFaixPVwOvEJNZxHA2PqLUUo4kc1YbMQZzixhHfzVpJBYUQ8dhm8JennKlFRgeBAzkllk4mVtFGTTU0CI3jfnKWMQrh4EWWFKWf67OxCw7J64GPk1OmV5K8dyXJrMHGqxcIUbosfdx7M5OvXKCghcoP1eUI4R0w0nAnnL07b0iuGdLUgBfIjnJ78TwPonam8a96PHQnuP/P9mCZB5n1PmCLeuFeJu5h0TyRqJaZbW0vgBxSxLpV7G8KraC0ol27Z7RsNW4hGYbnndpo9EHz+NjQFA/HpoZeFs0uLa8yTWrnK0lwW6Kah9QN6VFgICFchF1qNkhntQv47v8OPzFJo7kyh3bcnsiQHeFKdIw0p1KdzpNSivWICh/YCTRyQDASwdp9vKvu7MXthBJ29rnCHYJgA+blvVBlC6A5Iv5hwBZ3OKVQdltaQQ0XiFBBsEG00iWE7EQtfWqMjzoiepcwCeTQop5D+4tRj8IU2UdPePguFtxDl2/GxH2wDCUtK3UOEeoDJW22kfTFhWBmD789D4CBrNEn3WRpHWSK2A55R6DOG8YxvmXAveR0X/JjY1Jqcmdv0qsP6Wn9erjLorOG4LunepDezF2iTZp4YxuZQ+HWxkvebhkJ6dis5WUTKfs3Tk52+gbLb7npeWOGRiC05sc+2Pmu+DVxb82lIplw0PPd9IXe3qjlPAwsJ1o+KQvZpG+7MPfX0yG4MmWng18Um3jAsVaNMBrUZpzmEh9diD5/NbJ7AMD4yX93LTbenDbOzDTlGMdNTm/5XlejwG4JkOO251FqawuPEEYy4Waw8IwPPUHypKtwhv3DLew0CqiXRI3uEmkXtQSamAaIDag8opgELXpQGceE5IB246bhbjD1OdolGkuTGJPcAho8WvhZk/qnuMwENs1O16igv4Nob2cGMiiNo/A3gG4jkxbKUnycjJUG6Q20JxVzxNz68qxlcV4csItRK89I73oCkVp1ubaBgxDUBzhPZJCGzxd8/e2wOrb0LjjxQ7xWtveI5eWN7ZoRn2ZAx6pua8U0wv2EaGA/np6bwklV36WTpt2keosRDxrwM3njhicR1XLNqNSJwlWfBy3ixU7nKd7eExDKGrjcnqZCWx6qFZCppMPPpzUFgg+vXTCJTgwDka1vWhr09iY5AKEpO2rAIwkYQCZU6CaKQnw4Zmpn5SaLSRjlGaq1l6Q9hrjneB0eqWX+DkGjreCMJJGtd93ulC363mOjwoYCk/dWVodmEUPHaK+HXX3kvdmvNw4my5mbl0aOo7f3odtJyvayvtdagQeyjroG1WHY98j2cru4NNT7SjvVkc0VqRsgYkgk7WsKrIiFgyA7CJQzBNgpfqNdLhanpZkB4DpHLyMX9vgk4deSVr2uSHmSfydA2cX9Nb0SsBdAuY6EAvPR8EVe16mI2dFLYzKuQGeCt2eW/7J74/jYAariTZ5etLm9i8L43qntdYrO6EEYfBfAk0MEVK7gOmW7qDUSNTW+ZD9cmMHTKt6sHye50H0z3TT9TbixqXsaRUTiR8giSZ162lslvJj6is0AKgK1LaCYSAmoiLcX11Ih+szRRWr86lcap/dyAbNJ3pjuW08Q99fRIbAxQoVwWvfviAd//0BUvt3sC0Eo31RnMSTQST8pXZZw0VJdrJbKo0TYDmBTeQaqMjs7xyD0RHkV2BKKPQrMUCQGtfkc4Uo6AjJbUWQfcQkXeViVQRC6/C2YoCshCTYkRqLLm803aTWy5EwOIGXcwhaFNJxe4qpoGYiuME0XUhVzRWcZ5GOgmGe4KK85UiWCZimKy0thGd27r5hlIjWjpzOPHkjSdayq+vRpwPCcHYo7SDU3QHxXQTgMDpTbfXZqo778jvWJyYgO3PqHEpPdAZODrdLEYsIfM0ddv+5rVRBPOW1yhZeZw3lgNR+bP8Z/hG5BVROi2fed4ZezLxs8b9Asp5hReeTI9g97IM9Ogo1j7w2l8Axqbs1LRsFP2jWQZuORXJDYxepil5V1F7aW1XvipAEQxvknlvhtZSalToVYEcksXZ+Q5o0nNhlT3fVKy/jI3ZCyWHpnbAuOYG7JjKh74+iY1BKjB8k/BWbyG4mKU7Up9N2ebiFfFqgsEhuiMdUW3WzrkvmlsvAKiLWQo4hy424y/SylC9EJqwhTAm4qYi9AX61DcbtwZQrgvFWkWQ9tESqsnqg/Khy3bc9PfcuZ2IooE33stFnUJzZvZ0Y0TT7RcBoqJOTJ3+r/1rv4N/8OZ7OP70GgDDXwHfCPjgjC+0YQdk2fHPqVfg9Zy3nM2jctGUgbyBuqrIbzYUNSka208DXZw9AHe+VqzeA3HSlqHpQKRrEaQK1t8qhpksx/nKALijIFQYrwAmt7ZnwnwnNdnPGdCMe/t7afgOr6ONgwGISGO9OsnJFzBl8BX9o3l5uAq3Y+SgT5SgNhVa86TvHkJT9JLvYVwYcAF2e07Q5q3ZsK0qSiVtHeqTKwq4yoahtBrZ/0NA+8ATUI3lWFd8NmRVoIVW/XnD8KO0j4sdoTmdxUPk2ihANs5G3mrDt2q8mOJ84OuT2RjSEaj3sQFPcQyN+JOOQOl4inmCbzwaSNXZCGliGS6bQmT3FDFdAav3vAF5ZT+nB1JeSnx/cNJToC9hVEN90bCEsJuR+kKP/mOwFoFTC5kD4tl4DwO5+tXbBtMC61AxbxQaUxMP8YMDyIHJT+fUiFt1ZSCjbUxIlf9t1VDYzfjX7/4RzrnD/+d3buzkIM9jviKQxyh0TkzmqwXT8LLdTXCcwg0rg8tVATqFBIXsE0dgRyML9SxLnTg2fX9GeEzQSHNWhq+yihnvrP26yjjeRgAJq/ds8fJObVzIkzSYSxbBYDSim/fFrCq4mTteM62wsA0v3KbF+msngfH6877PN7ZoT+Q7lB5AB2Y4rCpKJ4j7SGxhUOZmFIEMWFibgDl+cdEzVNiIU/Ysuyw/HdmGlJ7f5x4OwUx3QuY4tLU5Yhtc5OGmZgZMDIzTiGJmNWrPaTjF1j60fM2V4WdrXqDhvbT7/aGvT2JjUDFDk6bp97La/vw7IBzpwAJAhfqCCgMcZ4EWBqKoMBZd1GbKPdu15iFYl5/pTr1hDKSmVoGuKwG/ypnyNEYgcwaVb1n+pQeG3yDASDOAVDu5zrFRreMxoL6akW8K+m8jghpIdjWjHBPj4MS4CC0n06qErlryMScN8SzI73v8r//pn8bzYUV1ZwRl5ZO3KbBRHR/Q6UWh6OrC7cntv5xiPpnFWHpMyK8naKWPJpOYrNKxyUbwLI3eKOiIyGtpgiRY69c9BMRvBky3FFCdEoE+3wyma1swa24Cnc3js6WJTTdoIjMN5F8wVcuwBzHikfkNpKM0wRXkgsOSl1EwETrbRQKgV1SGhm1G3XeN6VhFAWsD/Bp4RkU6SJN3M8XanqNjwHAvC7U8AsE2NZ+qZaXjkljOajoaqAo002IADO3J7huhjcSlXUUtgT/zHIyrEuDZIv4Ko0++aJz7K0lwksqL7aEaUjzIFBhf0Gotnuj2M0frnUdgsL533i36facZa8fe8NSbnsATiBMl1MFRfCtXwwhOQ86Rp2YiGNXdx8Yi1MG074WqSyfQOBK8ehtaoIoKeBIZPXY6JI791heirSkg3TNcpOwKtfxZqKozWivOsU0FwiwWuRfw/s01fvCD9/jybkNTFaD5D/pJLDOMLeogVUU6xMbYi/bw5OuK7fcOqFVw/nILjHFBwa3VcsyATtzEDuLPVkjZbyI3RfcGGN4HpAuNgPf+ZUNsqIqwf36fqLrM0lyrnWnoQHGcWAE1FmEFtPI99I8UWiUHKQMnBJL5DDm7sw6G6+TQfCrzdQHs2tTnjkpHn2zZaBxjwPCO5XszZvHWp3J86hmltSePxePypKD9rtrzGapDBbKgtxQuryDzlpcxzIIiChkjGa3zUu1NLxgGrIOStWuO0mVTm9Whj66d9apJMd3WNuX50NcHbQwi8lMAzwAKgKyqf1JEXgD4GwB+DcBPAfzbqnpv3/+XAfwF+/5/V1X/o1/08y/dgMpKzWSErcH4eQZE0T92xi+PGO8Wq/cwA/2zoHaRydCwCn1bEXYzZD/wJmegXBfEp4juiQy+OBofvtoRY8BbScLWxBl3pqDUanPmwirBeQjFtBfxBMQZrUqBsLSfXrAXTI+JC6OvCJZJ2D1aStaGoSYIXDzNY7CrVgEpqnJmX23T+eb9dbtmvaUhR0Ovgy55EMmtvXo+3MxQ0IWkcwg4HXuIEDupccEkHG0XRVNh+gkerCc+fo/3sQyK6fWM/m1qpKXpWr8Tlde/pzXZfOuAq1Uh9r7zrbYAoHSUZsLjce/zTtAdDY9QV4Ty1A2z4vQ5F0Dn5jmWVQIr8etQyTNZC5Aq4gPdqDoTItWeZi1hElS9aP0UKNvFCcmduQBguA84G/vU8RO3uAO4AUMU8y2rsv5B2rSlDKxffLTaRvSJLUUVLv5qbW9LMPPMDLFxfPFN0bwgBk7HEKjkbWDbB74+pmL4b6jq24v//0sA/raq/lUR+Uv2/39RRP44gD8H4E8A+D6A/0REfl3V83V+70ts3qtrXkwNRK3j2ROA0Jyg5+1yIo53Fd2eCcH9k0C78F3w6qlDMjcjjZxRe3Q8YCYkIyuQ6TXj4dJBmISsQE2VE4IAQI2Q5GzGvkL2rE68dJ5uOR0I47LRMYg2LBkLszA+bc8JRBwBBAGEBJ281cZfIAXbKMd1eWhETaMxRiST3453FXVXgKgIzwl1VbH+FwnBeAJxBPr7iP6RPTFkwTriCJT7HvJiYoLX6B6TaKcjgBaUGw3gdCm4y47zlm5EnjEx3ZoHgQmOPJd0uiamwxNhmZI4zZ1SdgDWFtVOIeFC2WoZFC59Z9VAINBdvZ2FKGohLRtarolxZWrHdo+u2mRhAmhqVPEIgF7b1Anw9kEWd+gsqCtaEbZg4jGY0Q8ayChZmqzeOR/xzFvthsFpD1q8ve9QrkpTedKfIdhEjb9CB1rEuQlQCdKqBt3Y+xWCmPEYPnoqEX75t/yBrz8L4Dftv38TwL958fW/rqqjqv4EwO8A+FO/6Ac1BZ+d/mTBWdk/srcrPTGDYmYfPu6LJ7N6Szbj9bFVZVtRtgScfDd21xyeEhe5l8EWhC46irZzgxmHYTTzUnPqBQx0UgPoFPBkIzcTiTO44w/VqgVz/R2WReW9uROzoECxBCe3k6+mLASI8sfnCHm27MbPzuh+eKDHot1/z3MYXzBdq6xowOoWdGFcgE7JZDTiy5WZiaC1R+kojbBDRN1CWQJw+n5p1mp5Q6xm+GcD9RhXlB27GY0mArrkgpC+7MYp3pNLBfp7CxiyzRFqHgqiLYOxDhxvxpFch0Z7NwLRpSWdE99UtDl3Na8F5QbVzHp7Plvdo42/zevTWZ1SjL8QuBGQOGc6lLPALd7URtuaSHnOO7aQm68C0j5gvik4v6q8F9EOKANKfZwu5iKGSiyheTMArFZHsy48RYgFErm9vJsW09yIwTOXYdEf8vrQjUEB/J9E5O+LyG/Y1z5X1a8AwP79mX39BwD+xcXf/Zl97TsvEfkNEfl7IvL3yvGAMGsbrUihVp9ZETypiwe15GWBu+puvlEzuahL6RcMYbcHjMYcYtyI5aarGIo8ktXovHqZBEjcfGSSdvNcvRnOAenMHpyWZTyt/CHy09YXuYOQ4ewKOS7UvOX3uP29ZKFh6LYAtmGoj9UCf65HwmuvtB0rgpQqwssJoSvtZPXPEmwDKoOZ1WYsXg1hORGdFwDwv4f3S0jvdMv3xJbJ7sc2Q6Niuianow72swSt4uEIlH9/fKFIR+D2H1esv+XINB0Aj+1z5N+j+5zT4P4CnnTtlYRkiob8dPRKyjfH6ZqHiRv4FiMqaecLjxtpWXFxp4MtxLL06DDNB4CWcXHJ0Wj4hQD9u0g8x3CK7tnHlRX5qrIy8M1dbXLTe1Vl1UC0a2gj2Djyma1DRe0r8nWheY4R17o970c8BHR7wfobYiLpQN3E6h0Zqx8bUfehrcSfVtUvReQzAP+xiPz2L/je369m0d/zBdW/BuCvAcD6ix9p7Q1oUT+B+JB0FgBbAqg9NxOMaFx2F0dpUsRHXpCyqnDrbkbM8/Sshg+oRd81PoE5AHl6UNwD6AU4mNmmVQJ5Z/32yBNnujW2o/Xc/jvyGgs3ItC/0FsJN/Uo24rwGJGOJN+Md2jz6XQ1o+QAHQRhit/xciSmwA2TGQQF6+2E86mHiCJ0Ffl2wu7mhOvViK/f3WB+OzSSFcAHOd9myMwTjK7QpkMwk9pLDkixhxenjrhMB0yvMuSQMN0o1j98xvGbLfBqRC6CekwIh4jVW+In81VdeABOMjopps8W5ya3YVMjXGn158ROZUuR8kUZrV1zN6pitukE/GjXR6ctK8UriXLhaKavUZvTODGUxcqN5CuqHeMxoPQ+IkSLGISqVXM2FjX7NslA954J05JpPThfU7w3XxOMxlAhj4szWTLLPVrT2XM7ekV60YFbFSsjpxEaAtTASVd3uiYnuXpUQM1E/v2W5R/8+qCNQVW/tH+/EZH/AGwNvhGRL1T1KxH5AsAb+/afAfjRxV//IYAvf/kvuTSz0ObJ4D1uOgrOn/PkHd6H5rO46A7sQprTkMeNS2XoSE2cY4dZMLwLTf3WPQG1F4x3Yv09kWUx4k3c09JM+8oAm3OEVgJXv/6Hv8b9eY23//QFRC370WTV/cMyGgzZ2HpYJiOwwNTpWrGaeTKXDdO48hiBMRJxNt1GHZTTkLJYhTOfQjF0M9b9jPunDbRE3L3Y43m/JkWjCHSbmVpkWYq1U6R7Coi6Ryd7AW6C0yY2Ru+tHdA/8FT3tuH68z2e7jdAFRy/3fL0/XIFJGD34yecjgPGacXZ+mcj+iFj/GqD0kccP+NmP92pnX7UB4SfdlRAGkfBK7+8Jo7QPyvyepnJe/pYmADtADEvjNovxjfaK018zRQ4Of/FNiJMhmEYuapeeiNGoFwxttBl5Uz2sgXopjXJpym6jCZ97BiBcCb+lQ0DQvHKVQxA5YGUr6oxfANNdZNijkbT3lSyb0/R0sLRDkcFq4vhLVsGZ/wCgFTiNVF/z9n8C1+/dGMQkS2AoKrP9t//bQD/MwC/BeDPA/ir9u+/ZX/ltwD870Tkfw6Cj38MwN/9Rb+jxsXlpgyw0onlnkYFTlw4wNKPt9wDsVL3hjcdIDjEEFcr/0xd6elC/ZNivBPbrflgbb8UlF7aaYxgWoZDoB1Cjcyc8MDRAHz1fIWX2yPe3s7AYWiqyXBmi9I/kQ04vSBpKD5GAldEjZg41AnmkyHtMzjHOUVONooABW0cRfKOth4WGiDHiPffXjM7wnQU92UHedtjfN4CLwv5CMFm/aeFv7/+hsSvvFrGZtXCZEPmCBBAS+hynYBGYJpJQ5VU0f+8a0IeUWC+v0V9XRB+fEQ9dsBzh1mAZOSwvGGvXr43IkZFfegpgbcWhPN3U77aSG/emevRgYbI8xZNGzBfgZvWAP6AwKnE/7e98wuRqgzD+O+ZM7Mzri6uq0sERhp0IxIlEUEREkFmUVdBF9112UXRRShC0GVdRNdRXZWJUEF4EUh/6K601FozU0NEEv+ksq7uujM7bxfvd2ZGZ1nX9rjn2/h+MOzxm7PuszOz7/nO977v802OhtuIZl4ol1vb+e9l1W6D3Exe55BnBRTeC+j0WFjef1Fp+6Jws1sfIOve1+fWf+B/vK1VbZiB2tWM5kgLqm0sy7p7Slo3UOXVvvXL0Gqo81ztSpXpkVAx2VS3lb6JF3BVjak1bhsH+U5jYqYhsiljYOL2ChnmM2O4C/hSUn7+TjP7WtI+YLekV4BTwIsAZnZY0m7gd7ym6NW5MhL+ynvuvzVIJ287cDE3rwj3yS2o/+Mlw14b0PX8y6dwreXWidR5Wa9vJhPcehvtsF25T+HzdJ1lQL5NWs09BT0PntFc7jnmivwDXAnRu7KiyZW/h5gYHMQmM/KtyPN0oDcMhRRmcIjKDWjo7Lbthf5WhWwqLHY2/MpgU1nHAbg67tVtzeHQMNbMc2b4tPFCjZlGm/qljHbdaK6GxiWfAvvVqd15Da8Pw+jGc5w9v5LJSp3aeMggBLOR/PVoV61z5a5e6/oNdMx0WxV3TZqs+ur7ZMgQjPs6AsqYWlajNtik2axTOdXwYqXw/kyPGFm1TetatZMirU3487UJ/3B3MjvheHq4O57fdublv5Vp35gIgjty2GckN3L1ku9uxqg51O4sTPo9pnV8NfI1ovyq3h6gY8BbmcEbwhptqtf99mRmwC8U1Ymw7V3NdyW3WpvsdM0tBVeGEmyA6e7u4PlMtzkYshADBtfV3XcjLNaqHVK9WdcntBVax3OrQbego2OK4zNA/3+mVt1enkF2m1OMO4Gk88BV4MKtzo2ANSSdRbNUtC4VnTC71nvNbHQ+3xxFYACQtN/MHi5bx61IOotnqWhdKjph4VoXUseQSCT+p6TAkEgk+ogpMHxQtoB5knQWz1LRulR0wgK1RrPGkEgk4iGmGUMikYiE0gODpC2Sjko6Hro0y9bzsaRzksZ6xkYk7ZV0LHxd1fPc9qD9qKSnF1HnPZK+k3RE0mFJr8WoVVJD0k+SDgWdb8eos+dnZ5IOSNoTuc6Tkn6TdFDS/sK1mllpD7wV/QRwHzAAHAI2lKzpCWATMNYz9i6wLRxvA94JxxuC5jqwPvwu2SLpvBvYFI6HgD+Dnqi04mVYK8JxDfgReDQ2nT163wB2Antife/Dzz8JrLlprDCtZc8YHgGOm9lfZjYN7MLbtkvDzH4ALt40/AIFtZgXqPOMmf0Sjq8AR/Au1qi0mjMR/lkLD4tNJ4CktcCzwIc9w9HpnIPCtJYdGObVoh0BC2oxv9NIWgc8hF+No9MapucH8Ua7vWYWpU7gfeBNvGMiJ0adcAesEHop2/NxXi3aEVO6fkkrgM+B181sPPS0zHrqLGOLotW8V+ZBScN4383GOU4vRaek54BzZvazpM3z+ZZZxhbzvS/cCqGXsmcM/61Fe/E5G1rLKaTFvCAk1fCg8KmZfRGzVgAzuwx8D2whPp2PAc8Hf9NdwJOSPolQJ3CjFQJwgxVCEVrLDgz7gPslrZc0gHtFflWyptnIW8yhv8X8JUl1SeuZR4t5UcinBh8BR8zsvVi1ShoNMwUkLQOeAv6ITaeZbTeztWa2Dv8cfmtmL8emE9wKQdJQfoxbIYwVqnWxVlHnWF3diq+onwB2RKDnM+AM3oh9Gne7Xg18AxwLX0d6zt8RtB8FnllEnY/j08FfgYPhsTU2rcADwIGgcwx4K4xHpfMmzZvpZiWi04ln8Q6Fx+H876ZIranyMZFI9FH2rUQikYiQFBgSiUQfKTAkEok+UmBIJBJ9pMCQSCT6SIEhkUj0kQJDIpHoIwWGRCLRx7/NqBhWooaZCwAAAABJRU5ErkJggg==\n", 343 | "text/plain": [ 344 | "
" 345 | ] 346 | }, 347 | "metadata": { 348 | "needs_background": "light" 349 | }, 350 | "output_type": "display_data" 351 | } 352 | ], 353 | "source": [ 354 | "plt.imshow(hxu12_vv)" 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": null, 360 | "id": "da9b64d0-3675-4813-9a06-53b1dbdd573a", 361 | "metadata": {}, 362 | "outputs": [], 363 | "source": [] 364 | } 365 | ], 366 | "metadata": { 367 | "kernelspec": { 368 | "display_name": "Python 3 (ipykernel)", 369 | "language": "python", 370 | "name": "python3" 371 | }, 372 | "language_info": { 373 | "codemirror_mode": { 374 | "name": "ipython", 375 | "version": 3 376 | }, 377 | "file_extension": ".py", 378 | "mimetype": "text/x-python", 379 | "name": "python", 380 | "nbconvert_exporter": "python", 381 | "pygments_lexer": "ipython3", 382 | "version": "3.8.12" 383 | } 384 | }, 385 | "nbformat": 4, 386 | "nbformat_minor": 5 387 | } 388 | -------------------------------------------------------------------------------- /1st_Place/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | from catboost import CatBoostClassifier 5 | from loguru import logger 6 | import numpy as np 7 | import pandas as pd 8 | import rasterio 9 | import tensorflow as tf 10 | from tensorflow.keras import backend as K 11 | from tensorflow.keras.layers import Dropout 12 | from tensorflow.keras.models import load_model 13 | from tifffile import imwrite, imsave 14 | from tqdm import tqdm 15 | import typer 16 | 17 | 18 | SUBMISSION_DIRECTORY = Path("submission") 19 | ASSETS_DIRECTORY = Path("assets") 20 | INPUT_IMAGES_DIRECTORY = Path("data/test_features") 21 | NASADEM_DIRECTORY = Path('data/nasadem') 22 | JRC_CHANGE_DIRECTORY = Path('data/jrc_change') 23 | JRC_OCCURANCE_DIRECTORY = Path('data/jrc_occurrence') 24 | JRC_EXTENT_DIRECTORY = Path('data/jrc_extent') 25 | JRC_RECURRENCE_DIRECTORY = Path('data/jrc_recurrence') 26 | JRC_SEASONALITY_DIRECTORY = Path('data/jrc_seasonality') 27 | JRC_TRANSITIONS_DIRECTORY = Path('data/jrc_transitions') 28 | 29 | 30 | def bce_jaccard_loss(y_true, y_pred, smooth=1): 31 | intersection = K.sum(K.abs(y_true * y_pred), axis=-1) 32 | sum_ = K.sum(K.abs(y_true) + K.abs(y_pred), axis=-1) 33 | jac = (intersection + smooth) / (sum_ - intersection + smooth) 34 | 35 | return (1 - jac) * smooth + tf.keras.losses.binary_crossentropy(y_true, y_pred) 36 | 37 | 38 | def make_prediction(chip_id, models_nn_1, models_nn_2, models_cat): 39 | 40 | logger.info("Starting inference.") 41 | 42 | try: 43 | vv_path = INPUT_IMAGES_DIRECTORY / f"{chip_id}_vv.tif" 44 | vh_path = INPUT_IMAGES_DIRECTORY / f"{chip_id}_vh.tif" 45 | nasadem_path = NASADEM_DIRECTORY / f"{chip_id}.tif" 46 | jrc_gsw_change_path = JRC_CHANGE_DIRECTORY / f"{chip_id}.tif" 47 | jrc_gsw_occurrence_path = JRC_OCCURANCE_DIRECTORY / f"{chip_id}.tif" 48 | jrc_gsw_extent_path = JRC_EXTENT_DIRECTORY / f"{chip_id}.tif" 49 | jrc_gsw_recurrence_path = JRC_RECURRENCE_DIRECTORY / f"{chip_id}.tif" 50 | jrc_gsw_seasonality_path = JRC_SEASONALITY_DIRECTORY / f"{chip_id}.tif" 51 | jrc_gsw_transitions_path = JRC_TRANSITIONS_DIRECTORY / f"{chip_id}.tif" 52 | 53 | with rasterio.open(vv_path) as fvv: 54 | vv = fvv.read(1) 55 | with rasterio.open(vh_path) as fvh: 56 | vh = fvh.read(1) 57 | with rasterio.open(nasadem_path) as fnasadem: 58 | nasadem = fnasadem.read(1) 59 | with rasterio.open(jrc_gsw_change_path) as fjrc_gsw_change: 60 | jrc_gsw_change = fjrc_gsw_change.read(1) 61 | with rasterio.open(jrc_gsw_occurrence_path) as fjrc_gsw_occurrence: 62 | jrc_gsw_occurrence = fjrc_gsw_occurrence.read(1) 63 | with rasterio.open(jrc_gsw_extent_path) as fjrc_gsw_extent: 64 | jrc_gsw_extent = fjrc_gsw_extent.read(1) 65 | with rasterio.open(jrc_gsw_recurrence_path) as fjrc_gsw_recurrence: 66 | jrc_gsw_recurrence = fjrc_gsw_recurrence.read(1) 67 | with rasterio.open(jrc_gsw_seasonality_path) as fjrc_gsw_seasonality: 68 | jrc_gsw_seasonality = fjrc_gsw_seasonality.read(1) 69 | with rasterio.open(jrc_gsw_transitions_path) as fjrc_gsw_transitions: 70 | jrc_gsw_transitions = fjrc_gsw_transitions.read(1) 71 | 72 | X = np.zeros((512, 512, 3)) 73 | X[:, :, 0] = (vh - (-17.54)) / 5.15 74 | X[:, :, 1] = (vv - (-10.68)) / 4.62 75 | X[:, :, 2] = (nasadem - (166.47)) / 178.47 76 | 77 | temp = pd.DataFrame() 78 | temp['vh'] = vh.flatten() 79 | temp['vv'] = vv.flatten() 80 | temp['nasadem'] = nasadem.flatten() 81 | temp['jrc_gsw_change'] = jrc_gsw_change.flatten() 82 | temp['jrc_gsw_occurrence'] = jrc_gsw_occurrence.flatten() 83 | temp['jrc_gsw_extent'] = jrc_gsw_extent.flatten() 84 | temp['jrc_gsw_recurrence'] = jrc_gsw_recurrence.flatten() 85 | temp['jrc_gsw_seasonality'] = jrc_gsw_seasonality.flatten() 86 | temp['jrc_gsw_transitions'] = jrc_gsw_transitions.flatten() 87 | 88 | pred_cat = np.zeros((temp.shape[0], 20)) 89 | for i in range(20): 90 | pred_cat[:, i] = models_cat[i].predict_proba(temp)[:, 1] 91 | 92 | pred_cat = np.mean(pred_cat, axis=1).reshape(512, 512) 93 | 94 | 95 | pred_nn_1 = models_nn_1[0].predict(X[np.newaxis, :, :, :])[0, :, :, 0] 96 | for i in range(1, 5): 97 | pred_nn_1 += models_nn_1[i].predict(X[np.newaxis, :, :, :])[0, :, :, 0] 98 | pred_nn_1 /= 5 99 | 100 | pred_nn_2 = models_nn_2[0].predict(X[np.newaxis, :, :, :])[0, :, :, 0] 101 | pred_nn_2 += models_nn_2[1].predict(X[np.newaxis, :, :, :])[0, :, :, 0] 102 | pred_nn_2 /= 2 103 | 104 | pred_all = np.max([pred_nn_1, pred_nn_2, pred_cat], axis=0) 105 | 106 | pred_thresh = pred_all.copy() 107 | pred_thresh[pred_thresh < 0.5] = 0 108 | pred_thresh[pred_thresh >= 0.5] = 1 109 | pred_thresh = pred_thresh.astype(int) 110 | 111 | except Exception as e: 112 | logger.error(f"No bands found for {chip_id}. {e}") 113 | raise 114 | 115 | return pred_thresh 116 | 117 | 118 | def get_expected_chip_ids(): 119 | paths = INPUT_IMAGES_DIRECTORY.glob("*.tif") 120 | # Return one chip id per two bands (VV/VH) 121 | ids = list(sorted(set(path.stem.split("_")[0] for path in paths))) 122 | return ids 123 | 124 | 125 | def main(): 126 | logger.info("Loading model") 127 | 128 | models_nn_1 = [] 129 | for i in range(5): 130 | model = load_model(ASSETS_DIRECTORY / 'EfficientB4Unet_512_3_{}.h5'.format(i), 131 | custom_objects={'FixedDropout': Dropout, 132 | 'bce_jaccard_loss': bce_jaccard_loss}) 133 | models_nn_1.append(model) 134 | 135 | models_nn_2 = [] 136 | model = load_model(ASSETS_DIRECTORY / 'EffUnetB0_512_3_weak_1.h5', 137 | custom_objects={'FixedDropout': Dropout, 138 | 'bce_jaccard_loss': bce_jaccard_loss}) 139 | models_nn_2.append(model) 140 | model = load_model(ASSETS_DIRECTORY / 'EffUnetB0_512_3.h5', 141 | custom_objects={'FixedDropout': Dropout, 142 | 'bce_jaccard_loss': bce_jaccard_loss}) 143 | models_nn_2.append(model) 144 | 145 | models_cat = [] 146 | for i in range(4): 147 | model = CatBoostClassifier() 148 | model.load_model(ASSETS_DIRECTORY / "stratifiedkfold{}".format(i)) 149 | models_cat.append(model) 150 | 151 | for i in range(4): 152 | model = CatBoostClassifier() 153 | model.load_model(ASSETS_DIRECTORY / "kfold{}".format(i)) 154 | models_cat.append(model) 155 | 156 | for i in range(8): 157 | model = CatBoostClassifier() 158 | model.load_model(ASSETS_DIRECTORY / "model{}".format(i)) 159 | models_cat.append(model) 160 | 161 | for i in range(4): 162 | model = CatBoostClassifier() 163 | model.load_model(ASSETS_DIRECTORY / "region{}".format(i)) 164 | models_cat.append(model) 165 | 166 | logger.info("Finding chip IDs") 167 | 168 | chip_ids = get_expected_chip_ids() 169 | if not chip_ids: 170 | typer.echo("No input images found!") 171 | raise typer.Exit(code=1) 172 | 173 | logger.info(f"Found {len(chip_ids)} test chip_ids. Generating predictions.") 174 | for chip_id in tqdm(chip_ids, miniters=25): 175 | output_path = SUBMISSION_DIRECTORY / f"{chip_id}.tif" 176 | output_data = make_prediction(chip_id, models_nn_1, models_nn_2, models_cat).astype(np.uint8) 177 | imsave(output_path, output_data) 178 | 179 | logger.success(f"Inference complete.") 180 | 181 | 182 | if __name__ == "__main__": 183 | typer.run(main) -------------------------------------------------------------------------------- /1st_Place/reports/DrivenData-Competition-Winner-Documentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drivendataorg/stac-overflow/481c80ccb6dcb7c960a1d043e094e35fabadc58c/1st_Place/reports/DrivenData-Competition-Winner-Documentation.pdf -------------------------------------------------------------------------------- /1st_Place/requirements.txt: -------------------------------------------------------------------------------- 1 | albumentations 2 | catboost 3 | cv2 4 | dataclasses 5 | GDAL 6 | loguru 7 | matplotlib 8 | numpy 9 | pandas 10 | planetary_computer 11 | pyproj 12 | pystac_client 13 | rasterio 14 | shapely 15 | sklearn 16 | tensorflow 17 | tifffile 18 | tqdm 19 | typer -------------------------------------------------------------------------------- /2nd_Place/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Max Lutz (Max_Lutz) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /2nd_Place/README.md: -------------------------------------------------------------------------------- 1 | # Floodwater Competition 2 | 3 | ### Presentation of my model 4 | I use three UNET models trained on three different split of the training data and take the average of their output. 5 | 6 | 7 | ### Installation steps 8 | 9 | 1. Create a new environment from `environment.yml` (it should contain all the requirements) 10 | 2. You can also install requirements from `requirements.txt` if needed. 11 | 12 | 13 | ### Files 14 | Notebooks: 15 | - `EDA.ipynb`: perform simple EDA on the training data. 16 | - `check_prediction.ipynb`: Calculate the Jaccard score between the prediction (in the `output_data` folder) and the label data in `/data/raw/train_features/train_labels`. For this to work you need to make a prediction based on the .tif files in `train_features`. 17 | It was a way for me to test my model before submitting it to the Drivendata platform. 18 | 19 | 20 | ### Execution steps for training a new model 21 | 22 | 1. Add training data in the folder `data/raw/train_features`, this training data should be in the same format as the one given during the competition: 23 | 24 | ``` 25 | |-- data 26 | |-- raw 27 | |-- train_features 28 | |-- train_features <-- folder containing vv and vh .tif files 29 | |-- train_labels <-- folder containing the corresponding .tif label data 30 | |-- flood_training_metadata.csv <-- csv file containing the metadata 31 | ``` 32 | 33 | 2. Load the data from the planetary computer use the `/src/data/load_pc_train_data.ipynb` notebook. 34 | 3. Train three models by running the notebook `/src/models/train_model.ipynb` three times. 35 | Modify the first cell each time: 36 | ``` 37 | MODEL_NAME="test_1.h5", TRAIN_TEST_SPLIT=1 38 | MODEL_NAME="test_2.h5", TRAIN_TEST_SPLIT=2 39 | MODEL_NAME="test_3.h5", TRAIN_TEST_SPLIT=3 40 | ``` 41 | 4. The models will be saved in `/models/temporary/`. 42 | 43 | 44 | ### Execution steps for predicting new data 45 | 46 | 1. Add vv and vh .tif files to predict in the folder `data/to_predict/test_features`. 47 | 2. Run the notbook `/src/data/load_pc_test_data.ipynb` to load the nasadem and jrc data from the planetary computer. 48 | 3. Run the python code `predict.py` from `src/models` (command: `python predict.py`). 49 | As of right now the notebook is set up to make a prediction from the three models in the models folder and to output the average of their prediction. 50 | 4. The predicted images will be stored in `output_data/`. 51 | 52 | __To run inference for the competition, simply run the following script: `src/models/main.py`.__ 53 | 54 | 55 | Execution time of training: 56 | 57 | Google colab 58 | - CPU (model): single core hyper threaded Xeon Processors @2.3Ghz i.e(1 core, 2 threads) 59 | - GPU (model or N/A): N/A 60 | - Memory (GB): 12 Go 61 | - OS: 62 | - Train duration: 30 min 63 | - Inference duration: not done on google colab 64 | 65 | Execution time of inference: 66 | - CPU (model): AMD Ryzen 5 4500U 67 | - GPU (model or N/A): N/A 68 | - Memory (GB): 8 Go 69 | - OS: WIndows 10 70 | - Train duration: not trained on my computer 71 | - Inference duration: 9 min 20 sec 72 | -------------------------------------------------------------------------------- /2nd_Place/environment.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drivendataorg/stac-overflow/481c80ccb6dcb7c960a1d043e094e35fabadc58c/2nd_Place/environment.yml -------------------------------------------------------------------------------- /2nd_Place/notebooks/EDA.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "4b22d653", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import pandas as pd\n", 11 | "import numpy as np\n", 12 | "import json\n", 13 | "import os\n", 14 | "import matplotlib.pyplot as plt\n", 15 | "from pathlib import Path\n", 16 | "from pandas_path import path\n", 17 | "\n", 18 | "import rasterio\n", 19 | "\n", 20 | "import warnings\n", 21 | "warnings.filterwarnings(\"ignore\")" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "4f76325c", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "# This is where our downloaded images and metadata live locally\n", 32 | "DATA_PATH = Path.cwd().parent / \"data\" / \"raw\" / \"train_features\"" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "id": "65d67688", 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "train_metadata = pd.read_csv(\n", 43 | " DATA_PATH / \"flood-training-metadata.csv\", parse_dates=[\"scene_start\"]\n", 44 | ")" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "id": "d066717f", 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "train_metadata.head()" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "id": "dfe14e19", 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "train_metadata.shape" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "id": "a1ad0cc2", 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "train_metadata.chip_id.nunique()" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "id": "044b3211", 80 | "metadata": {}, 81 | "source": [ 82 | "We have 542 unique chip id, every id has two images _vh and _vv" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "id": "df1e93c7", 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "train_metadata[\"feature_path\"] = (\n", 93 | " str(DATA_PATH / \"train_features\")\n", 94 | " / train_metadata.image_id.path.with_suffix(\".tif\").path\n", 95 | ")\n", 96 | "\n", 97 | "train_metadata[\"label_path\"] = (\n", 98 | " str(DATA_PATH / \"train_labels\")\n", 99 | " / train_metadata.chip_id.path.with_suffix(\".tif\").path\n", 100 | ")" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "id": "0a7bfaf2", 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "train_metadata" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "id": "0b5c4079", 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "# Examine an arbitrary image\n", 121 | "image_path = train_metadata.feature_path[0]\n", 122 | "with rasterio.open(image_path) as img:\n", 123 | " metadata = img.meta\n", 124 | " bounds = img.bounds\n", 125 | " data = img.read(1) # read a single band\n", 126 | " \n", 127 | "with rasterio.open(image_path) as img:\n", 128 | " gdal_mask = img.dataset_mask()\n", 129 | " \n", 130 | "with rasterio.open(image_path) as img:\n", 131 | " numpy_mask = img.read(1, masked=True)\n", 132 | " \n", 133 | "f, ax = plt.subplots(1, 2, figsize=(9, 9))\n", 134 | "ax[0].imshow(gdal_mask)\n", 135 | "ax[1].imshow(numpy_mask)\n", 136 | "plt.show()" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "id": "7a89a5af", 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [ 146 | "# Helper functions for visualizing Sentinel-1 images\n", 147 | "def scale_img(matrix):\n", 148 | " \"\"\"\n", 149 | " Returns a scaled (H, W, D) image that is visually inspectable.\n", 150 | " Image is linearly scaled between min_ and max_value, by channel.\n", 151 | "\n", 152 | " Args:\n", 153 | " matrix (np.array): (H, W, D) image to be scaled\n", 154 | "\n", 155 | " Returns:\n", 156 | " np.array: Image (H, W, 3) ready for visualization\n", 157 | " \"\"\"\n", 158 | " # Set min/max values\n", 159 | " min_values = np.array([-23, -28, 0.2])\n", 160 | " max_values = np.array([0, -5, 1])\n", 161 | "\n", 162 | " # Reshape matrix\n", 163 | " w, h, d = matrix.shape\n", 164 | " matrix = np.reshape(matrix, [w * h, d]).astype(np.float64)\n", 165 | "\n", 166 | " # Scale by min/max\n", 167 | " matrix = (matrix - min_values[None, :]) / (\n", 168 | " max_values[None, :] - min_values[None, :]\n", 169 | " )\n", 170 | " matrix = np.reshape(matrix, [w, h, d])\n", 171 | "\n", 172 | " # Limit values to 0/1 interval\n", 173 | " return matrix.clip(0, 1)\n", 174 | "\n", 175 | "def numpy_mask(image_path):\n", 176 | " with rasterio.open(image_path) as img:\n", 177 | " metadata = img.meta\n", 178 | " bounds = img.bounds\n", 179 | " data = img.read(1) # read a single band\n", 180 | "\n", 181 | " with rasterio.open(image_path) as img:\n", 182 | " return img.read(1, masked=True)\n", 183 | " \n", 184 | "def gdal_mask(image_path):\n", 185 | " with rasterio.open(image_path) as img:\n", 186 | " metadata = img.meta\n", 187 | " bounds = img.bounds\n", 188 | " data = img.read(1) # read a single band\n", 189 | "\n", 190 | " with rasterio.open(image_path) as img:\n", 191 | " return img.dataset_mask()\n", 192 | " \n", 193 | "\n", 194 | "def create_false_color_composite(path_vv, path_vh):\n", 195 | " \"\"\"\n", 196 | " Returns a S1 false color composite for visualization.\n", 197 | "\n", 198 | " Args:\n", 199 | " path_vv (str): path to the VV band\n", 200 | " path_vh (str): path to the VH band\n", 201 | "\n", 202 | " Returns:\n", 203 | " np.array: image (H, W, 3) ready for visualization\n", 204 | " \"\"\"\n", 205 | " # Read VV/VH bands\n", 206 | " with rasterio.open(path_vv) as vv:\n", 207 | " vv_img = vv.read(1)\n", 208 | " with rasterio.open(path_vh) as vh:\n", 209 | " vh_img = vh.read(1)\n", 210 | "\n", 211 | " # Stack arrays along the last dimension\n", 212 | " s1_img = np.stack((vv_img, vh_img), axis=-1)\n", 213 | "\n", 214 | " # Create false color composite\n", 215 | " img = np.zeros((512, 512, 3), dtype=np.float32)\n", 216 | " img[:, :, :2] = s1_img.copy()\n", 217 | " img[:, :, 2] = s1_img[:, :, 0] / s1_img[:, :, 1]\n", 218 | "\n", 219 | " return scale_img(img)\n", 220 | "\n", 221 | "\n", 222 | "def display_chip(row):\n", 223 | " \"\"\"\n", 224 | " Plots a 3-channel representation of VV/VH polarizations as a single chip (image 1).\n", 225 | " Overlays a chip's corresponding water label (image 2).\n", 226 | "\n", 227 | " Args:\n", 228 | " random_state (int): random seed used to select a chip\n", 229 | "\n", 230 | " Returns:\n", 231 | " plot.show(): chip and labels plotted with pyplot\n", 232 | " \"\"\"\n", 233 | " f, ax = plt.subplots(2, 2, figsize=(15, 15))\n", 234 | "\n", 235 | " # Select a random chip from train_metadata\n", 236 | " #random_chip = train_metadata.chip_id.sample(random_state=random_state).values[0]\n", 237 | " chip_df = train_metadata.iloc[row*2:row*2+2]\n", 238 | "\n", 239 | " # Extract paths to image files\n", 240 | " vv_path = chip_df[chip_df.polarization == \"vv\"].feature_path.values[0]\n", 241 | " vh_path = chip_df[chip_df.polarization == \"vh\"].feature_path.values[0]\n", 242 | " label_path = chip_df.label_path.values[0]\n", 243 | "\n", 244 | " # Create false color composite\n", 245 | " s1_img = create_false_color_composite(vv_path, vh_path)\n", 246 | "\n", 247 | " #visualize radar image\n", 248 | " ax[0][0].imshow(numpy_mask(vv_path))\n", 249 | " ax[0][0].set_title(\"Vertical-vertical band\")\n", 250 | " ax[0][1].imshow(numpy_mask(vh_path))\n", 251 | " ax[0][1].set_title(\"Vertical-horizontal band\")\n", 252 | " \n", 253 | " # Visualize features\n", 254 | " ax[1][0].imshow(s1_img, cmap=\"gray\")\n", 255 | " ax[1][0].set_title(\"False color composite image\", fontsize=14)\n", 256 | "\n", 257 | " # Load water mask\n", 258 | " with rasterio.open(label_path) as lp:\n", 259 | " lp_img = lp.read(1)\n", 260 | "\n", 261 | " # Mask missing data and 0s for visualization\n", 262 | " label = np.ma.masked_where((lp_img == 0) | (lp_img == 255), lp_img)\n", 263 | "\n", 264 | " #visualize answer\n", 265 | " #ax[1][1].imshow(s1_img)\n", 266 | " ax[1][1].imshow(label, cmap=\"cool\")\n", 267 | " ax[1][1].set_title(\"Image with WaterLabel\", fontsize=14)\n", 268 | "\n", 269 | " #plt.tight_layout(pad=5)\n", 270 | " plt.show()" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "id": "3f3ab369", 277 | "metadata": {}, 278 | "outputs": [], 279 | "source": [ 280 | "display_chip(3)" 281 | ] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "id": "e76c7bb6", 286 | "metadata": {}, 287 | "source": [ 288 | "## Check if the data is well distributed between the flood events" 289 | ] 290 | }, 291 | { 292 | "cell_type": "code", 293 | "execution_count": null, 294 | "id": "d9bebe0a", 295 | "metadata": {}, 296 | "outputs": [], 297 | "source": [ 298 | "def count_pixel(path, value):\n", 299 | " with rasterio.open(path) as img:\n", 300 | " data = img.read(1)\n", 301 | " return (data == value).sum()" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": null, 307 | "id": "72649da4", 308 | "metadata": {}, 309 | "outputs": [], 310 | "source": [ 311 | "#count the number of white, black and missing pixels in every image\n", 312 | "# Examine an arbitrary image\n", 313 | "for path in train_metadata['label_path'].to_list():\n", 314 | " train_metadata.loc[train_metadata['label_path'] == path, 'no_flood_%'] = count_pixel(path, 0)/(512*512)\n", 315 | " train_metadata.loc[train_metadata['label_path'] == path, 'flood_%'] = count_pixel(path, 1)/(512*512)\n", 316 | " train_metadata.loc[train_metadata['label_path'] == path, 'missing_%'] = count_pixel(path, 255)/(512*512)\n", 317 | " \n", 318 | "train_metadata[['image_id', 'location', 'no_flood_%', 'flood_%', 'missing_%']]" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": null, 324 | "id": "846be776", 325 | "metadata": {}, 326 | "outputs": [], 327 | "source": [ 328 | "df = train_metadata.groupby('flood_id', as_index=False).agg(np.mean)\n", 329 | "df.describe()" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": null, 335 | "id": "3149e5bf", 336 | "metadata": {}, 337 | "outputs": [], 338 | "source": [ 339 | "import seaborn as sns\n", 340 | "order = train_metadata.groupby('flood_id').agg(np.mean).index.to_list()\n", 341 | "fig, ax = plt.subplots(4,1, figsize=(15,20))\n", 342 | "sns.boxplot(x=\"flood_id\", y=\"flood_%\", data=train_metadata, order=order, ax=ax[0])\n", 343 | "ax[0].set_title('flood_id vs flood_%');\n", 344 | "sns.boxplot(x=\"flood_id\", y=\"no_flood_%\", data=train_metadata, order=order, ax=ax[1])\n", 345 | "ax[1].set_title('flood_id vs no_flood_%');\n", 346 | "sns.boxplot(x=\"flood_id\", y=\"missing_%\", data=train_metadata, order=order, ax=ax[2])\n", 347 | "ax[2].set_title('flood_id vs missing_%');\n", 348 | "sns.countplot(x=\"flood_id\", data=train_metadata, order=order, ax=ax[3])\n", 349 | "ax[1].set_title('Count of flood_id');\n", 350 | "plt.show()" 351 | ] 352 | } 353 | ], 354 | "metadata": { 355 | "kernelspec": { 356 | "display_name": "Python 3", 357 | "language": "python", 358 | "name": "python3" 359 | }, 360 | "language_info": { 361 | "codemirror_mode": { 362 | "name": "ipython", 363 | "version": 3 364 | }, 365 | "file_extension": ".py", 366 | "mimetype": "text/x-python", 367 | "name": "python", 368 | "nbconvert_exporter": "python", 369 | "pygments_lexer": "ipython3", 370 | "version": "3.9.6" 371 | } 372 | }, 373 | "nbformat": 4, 374 | "nbformat_minor": 5 375 | } 376 | -------------------------------------------------------------------------------- /2nd_Place/notebooks/check_prediction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "7c4f7904", 6 | "metadata": {}, 7 | "source": [ 8 | "# Calculate the jaccard score for every prediction" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "d33e1d84", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "from pathlib import Path\n", 19 | "from loguru import logger\n", 20 | "import numpy as np\n", 21 | "from tifffile import imread\n", 22 | "import typer\n", 23 | "from tqdm import tqdm\n", 24 | "\n", 25 | "NA_VALUE = 255" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "id": "bc7d17ee", 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [ 35 | "def iterate_through_mask_pairs(submission_dir: Path, actual_dir: Path):\n", 36 | " \"\"\"\n", 37 | " For each tif in the actual directory, find the corresponding prediction tif, read\n", 38 | " them both in, and yield the (pred, actual) tuple\n", 39 | " \"\"\"\n", 40 | " for predicted_path in submission_dir.glob(\"*.tif\"):\n", 41 | " filename = predicted_path.name\n", 42 | " label_path = actual_dir / filename\n", 43 | " assert label_path.exists(), f\"Could not find expected file: {filename}\"\n", 44 | " actual = imread(label_path)\n", 45 | " pred = imread(predicted_path)\n", 46 | " yield pred, actual" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 3, 52 | "id": "6183bdb9", 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "def intersection_over_union(df, total=None):\n", 57 | " \"\"\"Calculate the actual metric\"\"\"\n", 58 | " intersection = 0\n", 59 | " union = 0\n", 60 | " for pred, actual in tqdm(array_pairs, total=total):\n", 61 | " invalid_mask = actual == NA_VALUE\n", 62 | " actual = np.ma.masked_array(actual, invalid_mask)\n", 63 | " pred = np.ma.masked_array(pred, invalid_mask)\n", 64 | " intersection += np.logical_and(actual, pred).sum()\n", 65 | " union += np.logical_or(actual, pred).sum()\n", 66 | " if union < 1:\n", 67 | " raise ValueError(\"At least one image must be in the actual data set\")\n", 68 | " return intersection / union" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 4, 74 | "id": "af3cb4b0", 75 | "metadata": {}, 76 | "outputs": [ 77 | { 78 | "name": "stderr", 79 | "output_type": "stream", 80 | "text": [ 81 | "2021-10-06 10:44:40.424 | INFO | __main__::6 - calculating score for 30 image pairs ...\n", 82 | "100%|██████████| 30/30 [00:00<00:00, 44.64it/s]\n", 83 | "2021-10-06 10:44:41.145 | SUCCESS | __main__::8 - overall score: 0.6553508561416426\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "submission_dir = Path.cwd().parent / \"output_data\"\n", 89 | "actual_dir = Path.cwd().parent / \"data\" / \"raw\" / \"train_features\" / \"train_labels\"\n", 90 | "\n", 91 | "n_expected = len(list(submission_dir.glob(\"*.tif\")))\n", 92 | "array_pairs = iterate_through_mask_pairs(submission_dir, actual_dir)\n", 93 | "logger.info(f\"calculating score for {n_expected} image pairs ...\")\n", 94 | "score = intersection_over_union(array_pairs, total=n_expected)\n", 95 | "logger.success(f\"overall score: {score}\")" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "id": "88be4d25", 102 | "metadata": {}, 103 | "outputs": [], 104 | "source": [] 105 | } 106 | ], 107 | "metadata": { 108 | "kernelspec": { 109 | "display_name": "Python 3", 110 | "language": "python", 111 | "name": "python3" 112 | }, 113 | "language_info": { 114 | "codemirror_mode": { 115 | "name": "ipython", 116 | "version": 3 117 | }, 118 | "file_extension": ".py", 119 | "mimetype": "text/x-python", 120 | "name": "python", 121 | "nbconvert_exporter": "python", 122 | "pygments_lexer": "ipython3", 123 | "version": "3.6.13" 124 | } 125 | }, 126 | "nbformat": 4, 127 | "nbformat_minor": 5 128 | } 129 | -------------------------------------------------------------------------------- /2nd_Place/reports/DrivenData-Competition-Winner-Documentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drivendataorg/stac-overflow/481c80ccb6dcb7c960a1d043e094e35fabadc58c/2nd_Place/reports/DrivenData-Competition-Winner-Documentation.pdf -------------------------------------------------------------------------------- /2nd_Place/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drivendataorg/stac-overflow/481c80ccb6dcb7c960a1d043e094e35fabadc58c/2nd_Place/requirements.txt -------------------------------------------------------------------------------- /2nd_Place/src/data/load_pc_test_data.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "ee1cd18e", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# https://github.com/microsoft/PlanetaryComputerExamples/blob/main/competitions/s1floods/generate_auxiliary_input.ipynb\n", 11 | "from dataclasses import dataclass\n", 12 | "import os\n", 13 | "from tempfile import TemporaryDirectory\n", 14 | "from typing import List, Any, Dict\n", 15 | "\n", 16 | "from shapely.geometry import box, mapping\n", 17 | "import rasterio\n", 18 | "from rasterio.warp import reproject, Resampling\n", 19 | "import pyproj\n", 20 | "from osgeo import gdal\n", 21 | "\n", 22 | "from pystac_client import Client\n", 23 | "import planetary_computer as pc\n", 24 | "from pathlib import Path\n", 25 | "import shutil\n", 26 | "import errno" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "id": "bb676d30", 32 | "metadata": {}, 33 | "source": [ 34 | "## Get the path to all training files" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "id": "85f130f9", 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "DATA_PATH = Path.cwd().parent.parent / \"data\" / \"to_predict\" / \"test_features\"" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "id": "becd1a2d", 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "chip_paths = []\n", 55 | "for file_name in os.listdir(DATA_PATH):\n", 56 | " if file_name.endswith(\"_vv.tif\"):\n", 57 | " chip_paths.append(os.path.join(DATA_PATH, file_name))\n", 58 | "print(f\"{len(chip_paths)} chips found.\")" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "id": "0ec09418", 64 | "metadata": {}, 65 | "source": [ 66 | "## Clean external data directory and prepare directories" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "id": "43c8125e", 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "DATA_PATH = Path.cwd().parent.parent / \"data\" / \"to_predict\"\n", 77 | "for files in os.listdir(DATA_PATH):\n", 78 | " if(files != \"test_features\"):\n", 79 | " path = os.path.join(DATA_PATH, files)\n", 80 | " try:\n", 81 | " shutil.rmtree(path)\n", 82 | " except OSError:\n", 83 | " if(files != \".gitkeep\"):\n", 84 | " os.remove(path)" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "id": "5b46d4fe", 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "DATA_PATH = Path.cwd().parent.parent / \"data\" / \"to_predict\"\n", 95 | "directories = [\"nasadem\", \"jrc_extent\", \"jrc_occurrence\", \"jrc_recurrence\", \"jrc_seasonality\", \"jrc_transitions\", \"jrc_change\"]\n", 96 | "for directory in directories:\n", 97 | " if not os.path.exists(DATA_PATH / directory):\n", 98 | " try:\n", 99 | " os.makedirs(DATA_PATH / directory)\n", 100 | " except OSError as e:\n", 101 | " if e.errno != errno.EEXIST:\n", 102 | " raise" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "id": "7abb851c", 108 | "metadata": {}, 109 | "source": [ 110 | "## Connect to the planetary computer API" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "id": "11797668", 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "STAC_API = \"https://planetarycomputer.microsoft.com/api/stac/v1\"\n", 121 | "catalog = Client.open(STAC_API)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "id": "7ba22ed5", 127 | "metadata": {}, 128 | "source": [ 129 | "## Define functions and class" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": null, 135 | "id": "01a7c9a9", 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [ 139 | "@dataclass\n", 140 | "class ChipInfo:\n", 141 | " \"\"\"\n", 142 | " Holds information about a training chip, including geospatial info for coregistration\n", 143 | " \"\"\"\n", 144 | "\n", 145 | " path: str\n", 146 | " prefix: str\n", 147 | " crs: Any\n", 148 | " shape: List[int]\n", 149 | " transform: List[float]\n", 150 | " bounds: rasterio.coords.BoundingBox\n", 151 | " footprint: Dict[str, Any]\n", 152 | "\n", 153 | "\n", 154 | "def get_footprint(bounds, crs):\n", 155 | " \"\"\"Gets a GeoJSON footprint (in epsg:4326) from rasterio bounds and CRS\"\"\"\n", 156 | " transformer = pyproj.Transformer.from_crs(crs, \"epsg:4326\", always_xy=True)\n", 157 | " minx, miny = transformer.transform(bounds.left, bounds.bottom)\n", 158 | " maxx, maxy = transformer.transform(bounds.right, bounds.top)\n", 159 | " return mapping(box(minx, miny, maxx, maxy))\n", 160 | "\n", 161 | "\n", 162 | "def get_chip_info(chip_path):\n", 163 | " \"\"\"Gets chip info from a GeoTIFF file\"\"\"\n", 164 | " with rasterio.open(chip_path) as ds:\n", 165 | " chip_crs = ds.crs\n", 166 | " chip_shape = ds.shape\n", 167 | " chip_transform = ds.transform\n", 168 | " chip_bounds = ds.bounds\n", 169 | "\n", 170 | " # Use the first part of the chip filename as a prefix\n", 171 | " prefix = os.path.basename(chip_path).split(\"_\")[0]\n", 172 | "\n", 173 | " return ChipInfo(\n", 174 | " path=chip_path,\n", 175 | " prefix=prefix,\n", 176 | " crs=chip_crs,\n", 177 | " shape=chip_shape,\n", 178 | " transform=chip_transform,\n", 179 | " bounds=chip_bounds,\n", 180 | " footprint=get_footprint(chip_bounds, chip_crs),\n", 181 | " )" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": null, 187 | "id": "b6ba7e2a", 188 | "metadata": {}, 189 | "outputs": [], 190 | "source": [ 191 | "def reproject_to_chip(\n", 192 | " chip_info, input_path, output_path, resampling=Resampling.nearest\n", 193 | "):\n", 194 | " \"\"\"\n", 195 | " Reproject a raster at input_path to chip_info, saving to output_path.\n", 196 | "\n", 197 | " Use Resampling.nearest for classification rasters. Otherwise use something\n", 198 | " like Resampling.bilinear for continuous data.\n", 199 | " \"\"\"\n", 200 | " with rasterio.open(input_path) as src:\n", 201 | " kwargs = src.meta.copy()\n", 202 | " kwargs.update(\n", 203 | " {\n", 204 | " \"crs\": chip_info.crs,\n", 205 | " \"transform\": chip_info.transform,\n", 206 | " \"width\": chip_info.shape[1],\n", 207 | " \"height\": chip_info.shape[0],\n", 208 | " \"driver\": \"GTiff\",\n", 209 | " }\n", 210 | " )\n", 211 | "\n", 212 | " with rasterio.open(output_path, \"w\", **kwargs) as dst:\n", 213 | " for i in range(1, src.count + 1):\n", 214 | " reproject(\n", 215 | " source=rasterio.band(src, i),\n", 216 | " destination=rasterio.band(dst, i),\n", 217 | " src_transform=src.transform,\n", 218 | " src_crs=src.crs,\n", 219 | " dst_transform=chip_info.transform,\n", 220 | " dst_crs=chip_info.crs,\n", 221 | " resampling=Resampling.nearest,\n", 222 | " )" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": null, 228 | "id": "ddfd939c", 229 | "metadata": {}, 230 | "outputs": [], 231 | "source": [ 232 | "def write_vrt(items, asset_key, dest_path):\n", 233 | " \"\"\"Write a VRT with hrefs extracted from a list of items for a specific asset.\"\"\"\n", 234 | " hrefs = [pc.sign(item.assets[asset_key].href) for item in items]\n", 235 | " vsi_hrefs = [f\"/vsicurl/{href}\" for href in hrefs]\n", 236 | " gdal.BuildVRT(dest_path, vsi_hrefs).FlushCache()" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": null, 242 | "id": "bfd29e81", 243 | "metadata": {}, 244 | "outputs": [], 245 | "source": [ 246 | "def create_chip_aux_file(\n", 247 | " dir_, chip_info, collection_id, asset_key, file_name, resampling=Resampling.nearest\n", 248 | "):\n", 249 | " \"\"\"\n", 250 | " Write an auxiliary chip file.\n", 251 | "\n", 252 | " The auxiliary chip file includes chip_info for the Collection and Asset, and is\n", 253 | " saved in the same directory as the original chip with the given file_name.\n", 254 | " \"\"\"\n", 255 | " output_path = os.path.join(\n", 256 | " Path.cwd().parent.parent / \"data\" / \"to_predict\" / dir_ , f\"{chip_info.prefix}.tif\"\n", 257 | " )\n", 258 | " search = catalog.search(collections=[collection_id], intersects=chip_info.footprint)\n", 259 | " items = list(search.get_items())\n", 260 | " with TemporaryDirectory() as tmp_dir:\n", 261 | " vrt_path = os.path.join(tmp_dir, \"source.vrt\")\n", 262 | " write_vrt(items, asset_key, vrt_path)\n", 263 | " reproject_to_chip(chip_info, vrt_path, output_path, resampling=resampling)\n", 264 | " return output_path" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "id": "3a69c44e", 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "# Define a set of parameters to pass into create_chip_aux_file \n", 275 | "aux_file_params = [\n", 276 | " (\"nasadem\", \"nasadem\", \"elevation\", \"nasadem.tif\", Resampling.bilinear),\n", 277 | " (\"jrc_extent\", \"jrc-gsw\", \"extent\", \"jrc-gsw-extent.tif\", Resampling.nearest),\n", 278 | " (\"jrc_occurrence\", \"jrc-gsw\", \"occurrence\", \"jrc-gsw-occurrence.tif\", Resampling.nearest),\n", 279 | " (\"jrc_recurrence\", \"jrc-gsw\", \"recurrence\", \"jrc-gsw-recurrence.tif\", Resampling.nearest),\n", 280 | " (\"jrc_seasonality\", \"jrc-gsw\", \"seasonality\", \"jrc-gsw-seasonality.tif\", Resampling.nearest),\n", 281 | " (\"jrc_transitions\", \"jrc-gsw\", \"transitions\", \"jrc-gsw-transitions.tif\", Resampling.nearest),\n", 282 | " (\"jrc_change\", \"jrc-gsw\", \"change\", \"jrc-gsw-change.tif\", Resampling.nearest),\n", 283 | "]" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": null, 289 | "id": "e8a5d501", 290 | "metadata": {}, 291 | "outputs": [], 292 | "source": [ 293 | "# Iterate over the chips and generate all aux input files.\n", 294 | "count = len(chip_paths)\n", 295 | "for i, chip_path in enumerate(chip_paths):\n", 296 | " print(f\"({i+1} of {count}) {chip_path}\")\n", 297 | " chip_info = get_chip_info(chip_path)\n", 298 | " for dir_, collection_id, asset_key, file_name, resampling_method in aux_file_params:\n", 299 | " print(f\" ... Creating chip data for {collection_id} {asset_key}\")\n", 300 | " create_chip_aux_file(\n", 301 | " dir_, chip_info, collection_id, asset_key, file_name, resampling=resampling_method\n", 302 | " )" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": null, 308 | "id": "2346acc1", 309 | "metadata": {}, 310 | "outputs": [], 311 | "source": [] 312 | } 313 | ], 314 | "metadata": { 315 | "kernelspec": { 316 | "display_name": "Python 3", 317 | "language": "python", 318 | "name": "python3" 319 | }, 320 | "language_info": { 321 | "codemirror_mode": { 322 | "name": "ipython", 323 | "version": 3 324 | }, 325 | "file_extension": ".py", 326 | "mimetype": "text/x-python", 327 | "name": "python", 328 | "nbconvert_exporter": "python", 329 | "pygments_lexer": "ipython3", 330 | "version": "3.9.6" 331 | } 332 | }, 333 | "nbformat": 4, 334 | "nbformat_minor": 5 335 | } 336 | -------------------------------------------------------------------------------- /2nd_Place/src/data/load_pc_train_data.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "ee1cd18e", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# https://github.com/microsoft/PlanetaryComputerExamples/blob/main/competitions/s1floods/generate_auxiliary_input.ipynb\n", 11 | "\n", 12 | "from dataclasses import dataclass\n", 13 | "import os\n", 14 | "from tempfile import TemporaryDirectory\n", 15 | "from typing import List, Any, Dict\n", 16 | "\n", 17 | "from shapely.geometry import box, mapping\n", 18 | "import rasterio\n", 19 | "from rasterio.warp import reproject, Resampling\n", 20 | "import pyproj\n", 21 | "from osgeo import gdal\n", 22 | "\n", 23 | "from pystac_client import Client\n", 24 | "import planetary_computer as pc\n", 25 | "from pathlib import Path\n", 26 | "import shutil" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "id": "bb676d30", 32 | "metadata": {}, 33 | "source": [ 34 | "## Get the path to all training files" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "id": "85f130f9", 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "DATA_PATH = Path.cwd().parent.parent / \"data\" / \"raw\" / \"train_features\" / \"train_features\"" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 13, 50 | "id": "becd1a2d", 51 | "metadata": {}, 52 | "outputs": [ 53 | { 54 | "name": "stdout", 55 | "output_type": "stream", 56 | "text": [ 57 | "542 chips found.\n" 58 | ] 59 | } 60 | ], 61 | "source": [ 62 | "chip_paths = []\n", 63 | "for file_name in os.listdir(DATA_PATH):\n", 64 | " if file_name.endswith(\"_vv.tif\"):\n", 65 | " chip_paths.append(os.path.join(DATA_PATH, file_name))\n", 66 | "print(f\"{len(chip_paths)} chips found.\")" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "id": "8c2a562b", 72 | "metadata": {}, 73 | "source": [ 74 | "## Clean external data directory and prepare directories" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "id": "1dfdb341-df11-41a6-a997-7932531b1a20", 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "EXTERNAL_DATA_PATH = Path.cwd().parent.parent / \"data\" / \"external\"" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "id": "2d3bf880", 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "for files in os.listdir(EXTERNAL_DATA_PATH):\n", 95 | " path = os.path.join(EXTERNAL_DATA_PATH, files)\n", 96 | " try:\n", 97 | " shutil.rmtree(path)\n", 98 | " except OSError:\n", 99 | " if(files != \".gitkeep\"):\n", 100 | " os.remove(path)" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "id": "53a915be", 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "directories = [\"nasadem\", \"jrc_extent\", \"jrc_occurrence\", \"jrc_recurrence\", \"jrc_seasonality\", \"jrc_transitions\", \"jrc_change\"]\n", 111 | "for directory in directories:\n", 112 | " os.mkdir(EXTERNAL_DATA_PATH / directory)" 113 | ] 114 | }, 115 | { 116 | "cell_type": "markdown", 117 | "id": "7abb851c", 118 | "metadata": {}, 119 | "source": [ 120 | "## Connect to the planetary computer API" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": null, 126 | "id": "11797668", 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [ 130 | "STAC_API = \"https://planetarycomputer.microsoft.com/api/stac/v1\"\n", 131 | "catalog = Client.open(STAC_API)" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "id": "7ba22ed5", 137 | "metadata": {}, 138 | "source": [ 139 | "## Define functions and class" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "id": "01a7c9a9", 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "@dataclass\n", 150 | "class ChipInfo:\n", 151 | " \"\"\"\n", 152 | " Holds information about a training chip, including geospatial info for coregistration\n", 153 | " \"\"\"\n", 154 | "\n", 155 | " path: str\n", 156 | " prefix: str\n", 157 | " crs: Any\n", 158 | " shape: List[int]\n", 159 | " transform: List[float]\n", 160 | " bounds: rasterio.coords.BoundingBox\n", 161 | " footprint: Dict[str, Any]\n", 162 | "\n", 163 | "\n", 164 | "def get_footprint(bounds, crs):\n", 165 | " \"\"\"Gets a GeoJSON footprint (in epsg:4326) from rasterio bounds and CRS\"\"\"\n", 166 | " transformer = pyproj.Transformer.from_crs(crs, \"epsg:4326\", always_xy=True)\n", 167 | " minx, miny = transformer.transform(bounds.left, bounds.bottom)\n", 168 | " maxx, maxy = transformer.transform(bounds.right, bounds.top)\n", 169 | " return mapping(box(minx, miny, maxx, maxy))\n", 170 | "\n", 171 | "\n", 172 | "def get_chip_info(chip_path):\n", 173 | " \"\"\"Gets chip info from a GeoTIFF file\"\"\"\n", 174 | " with rasterio.open(chip_path) as ds:\n", 175 | " chip_crs = ds.crs\n", 176 | " chip_shape = ds.shape\n", 177 | " chip_transform = ds.transform\n", 178 | " chip_bounds = ds.bounds\n", 179 | "\n", 180 | " # Use the first part of the chip filename as a prefix\n", 181 | " prefix = os.path.basename(chip_path).split(\"_\")[0]\n", 182 | "\n", 183 | " return ChipInfo(\n", 184 | " path=chip_path,\n", 185 | " prefix=prefix,\n", 186 | " crs=chip_crs,\n", 187 | " shape=chip_shape,\n", 188 | " transform=chip_transform,\n", 189 | " bounds=chip_bounds,\n", 190 | " footprint=get_footprint(chip_bounds, chip_crs),\n", 191 | " )" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": null, 197 | "id": "b6ba7e2a", 198 | "metadata": {}, 199 | "outputs": [], 200 | "source": [ 201 | "def reproject_to_chip(\n", 202 | " chip_info, input_path, output_path, resampling=Resampling.nearest\n", 203 | "):\n", 204 | " \"\"\"\n", 205 | " Reproject a raster at input_path to chip_info, saving to output_path.\n", 206 | "\n", 207 | " Use Resampling.nearest for classification rasters. Otherwise use something\n", 208 | " like Resampling.bilinear for continuous data.\n", 209 | " \"\"\"\n", 210 | " with rasterio.open(input_path) as src:\n", 211 | " kwargs = src.meta.copy()\n", 212 | " kwargs.update(\n", 213 | " {\n", 214 | " \"crs\": chip_info.crs,\n", 215 | " \"transform\": chip_info.transform,\n", 216 | " \"width\": chip_info.shape[1],\n", 217 | " \"height\": chip_info.shape[0],\n", 218 | " \"driver\": \"GTiff\",\n", 219 | " }\n", 220 | " )\n", 221 | "\n", 222 | " with rasterio.open(output_path, \"w\", **kwargs) as dst:\n", 223 | " for i in range(1, src.count + 1):\n", 224 | " reproject(\n", 225 | " source=rasterio.band(src, i),\n", 226 | " destination=rasterio.band(dst, i),\n", 227 | " src_transform=src.transform,\n", 228 | " src_crs=src.crs,\n", 229 | " dst_transform=chip_info.transform,\n", 230 | " dst_crs=chip_info.crs,\n", 231 | " resampling=Resampling.nearest,\n", 232 | " )" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": null, 238 | "id": "ddfd939c", 239 | "metadata": {}, 240 | "outputs": [], 241 | "source": [ 242 | "def write_vrt(items, asset_key, dest_path):\n", 243 | " \"\"\"Write a VRT with hrefs extracted from a list of items for a specific asset.\"\"\"\n", 244 | " hrefs = [pc.sign(item.assets[asset_key].href) for item in items]\n", 245 | " vsi_hrefs = [f\"/vsicurl/{href}\" for href in hrefs]\n", 246 | " gdal.BuildVRT(dest_path, vsi_hrefs).FlushCache()" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": null, 252 | "id": "bfd29e81", 253 | "metadata": {}, 254 | "outputs": [], 255 | "source": [ 256 | "def create_chip_aux_file(\n", 257 | " dir_, chip_info, collection_id, asset_key, file_name, resampling=Resampling.nearest\n", 258 | "):\n", 259 | " \"\"\"\n", 260 | " Write an auxiliary chip file.\n", 261 | "\n", 262 | " The auxiliary chip file includes chip_info for the Collection and Asset, and is\n", 263 | " saved in the same directory as the original chip with the given file_name.\n", 264 | " \"\"\"\n", 265 | " output_path = EXTERNAL_DATA_PATH / dir_ / f\"{chip_info.prefix}.tif\"\n", 266 | " search = catalog.search(collections=[collection_id], intersects=chip_info.footprint)\n", 267 | " items = list(search.get_items())\n", 268 | " with TemporaryDirectory() as tmp_dir:\n", 269 | " vrt_path = os.path.join(tmp_dir, \"source.vrt\")\n", 270 | " write_vrt(items, asset_key, vrt_path)\n", 271 | " reproject_to_chip(chip_info, vrt_path, output_path, resampling=resampling)\n", 272 | " return output_path" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": null, 278 | "id": "3a69c44e", 279 | "metadata": {}, 280 | "outputs": [], 281 | "source": [ 282 | "# Define a set of parameters to pass into create_chip_aux_file \n", 283 | "aux_file_params = [\n", 284 | " (\"nasadem\", \"nasadem\", \"elevation\", \"nasadem.tif\", Resampling.bilinear),\n", 285 | " (\"jrc_extent\", \"jrc-gsw\", \"extent\", \"jrc-gsw-extent.tif\", Resampling.nearest),\n", 286 | " (\"jrc_occurrence\", \"jrc-gsw\", \"occurrence\", \"jrc-gsw-occurrence.tif\", Resampling.nearest),\n", 287 | " (\"jrc_recurrence\", \"jrc-gsw\", \"recurrence\", \"jrc-gsw-recurrence.tif\", Resampling.nearest),\n", 288 | " (\"jrc_seasonality\", \"jrc-gsw\", \"seasonality\", \"jrc-gsw-seasonality.tif\", Resampling.nearest),\n", 289 | " (\"jrc_transitions\", \"jrc-gsw\", \"transitions\", \"jrc-gsw-transitions.tif\", Resampling.nearest),\n", 290 | " (\"jrc_change\", \"jrc-gsw\", \"change\", \"jrc-gsw-change.tif\", Resampling.nearest),\n", 291 | "]" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": null, 297 | "id": "e8a5d501", 298 | "metadata": {}, 299 | "outputs": [], 300 | "source": [ 301 | "# Iterate over the chips and generate all aux input files.\n", 302 | "count = len(chip_paths)\n", 303 | "for i, chip_path in enumerate(chip_paths):\n", 304 | " print(f\"({i+1} of {count}) {chip_path}\")\n", 305 | " if not (EXTERNAL_DATA_PATH / \"nasadem\" / f\"{chip_path.split('/')[-1]}\").exists():\n", 306 | " chip_info = get_chip_info(chip_path)\n", 307 | " for dir_, collection_id, asset_key, file_name, resampling_method in aux_file_params:\n", 308 | " print(f\" ... Creating chip data for {collection_id} {asset_key}\")\n", 309 | " create_chip_aux_file(\n", 310 | " dir_, chip_info, collection_id, asset_key, file_name, resampling=resampling_method\n", 311 | " )" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": null, 317 | "id": "2346acc1", 318 | "metadata": {}, 319 | "outputs": [], 320 | "source": [] 321 | } 322 | ], 323 | "metadata": { 324 | "kernelspec": { 325 | "display_name": "Python 3 (ipykernel)", 326 | "language": "python", 327 | "name": "python3" 328 | }, 329 | "language_info": { 330 | "codemirror_mode": { 331 | "name": "ipython", 332 | "version": 3 333 | }, 334 | "file_extension": ".py", 335 | "mimetype": "text/x-python", 336 | "name": "python", 337 | "nbconvert_exporter": "python", 338 | "pygments_lexer": "ipython3", 339 | "version": "3.8.12" 340 | } 341 | }, 342 | "nbformat": 4, 343 | "nbformat_minor": 5 344 | } 345 | -------------------------------------------------------------------------------- /2nd_Place/src/models/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from loguru import logger 3 | import numpy as np 4 | import typer 5 | from tifffile import imwrite 6 | from tqdm import tqdm 7 | from os import listdir 8 | from os.path import isfile, join 9 | import os 10 | 11 | import tensorflow as tf 12 | from tensorflow import keras 13 | import rasterio 14 | 15 | import keras.backend as K 16 | 17 | def IOU_coef(y_true, y_pred): 18 | y_true_f = K.flatten(y_true) 19 | y_pred_f = K.flatten(y_pred) 20 | intersection = K.sum(y_true_f * y_pred_f) 21 | return (intersection + 1.0) / (K.sum(y_true_f) + K.sum(y_pred_f) - intersection + 1.0) 22 | 23 | # https://www.youtube.com/watch?v=BNPW1mYbgS4 24 | def IOULoss(y_true, y_pred): 25 | return -IOU_coef(y_true, y_pred) 26 | 27 | # https://gist.github.com/wassname/7793e2058c5c9dacb5212c0ac0b18a8a 28 | def DiceLoss_square(y_true, y_pred, smooth=1): 29 | y_true_f = K.flatten(y_true) 30 | y_pred_f = K.flatten(y_pred) 31 | intersection = K.sum(K.abs(y_true_f * y_pred_f)) 32 | return 1-((2. * intersection + smooth) / (K.sum(K.square(y_true_f),-1) + K.sum(K.square(y_pred_f),-1) + smooth)) 33 | 34 | def DiceLoss(y_true, y_pred, smooth=1): 35 | intersection = K.sum(y_true * y_pred) 36 | return 1-((2. * intersection + smooth) / (K.sum(y_true) + K.sum(y_pred) + smooth)) 37 | 38 | 39 | def make_predictions(chip_id: str, models): 40 | """ 41 | Given an image ID, read in the appropriate files and predict a mask of all ones or zeros 42 | """ 43 | #logger.info(os.path.join(os.getcwd(), 'data', 'test_features', chip_id+'_vh.tif')) 44 | try: 45 | 46 | dirs = ["test_features", "test_features", "nasadem", "jrc_change", "jrc_extent", "jrc_seasonality", "jrc_occurrence", "jrc_recurrence", "jrc_transitions"] 47 | endings = ["_vv.tif", "_vh.tif", ".tif", ".tif", ".tif", ".tif", ".tif", ".tif", ".tif"] 48 | 49 | arrays = [] 50 | 51 | #os.path.abspath() 52 | for i in range(9): 53 | path = os.path.join(os.getcwd(), 'data', dirs[i], chip_id + endings[i]) 54 | 55 | #print(path) 56 | #load image from path 57 | with rasterio.open(path) as img: 58 | 59 | if(i < 2): 60 | arrays.append(np.uint8(np.clip(img.read(1), -30, 0)*(-8.4))) 61 | elif(i == 2): 62 | arrays.append(np.uint8(np.clip(img.read(1), 0, 255))) 63 | else: 64 | arrays.append(img.read(1)) 65 | 66 | images = np.array([np.stack(arrays, axis=-1)]) 67 | 68 | #logger.info(img.shape) 69 | 70 | #config = model.get_config() # Returns pretty much every information about your model 71 | #logger.info(config["layers"][0]["config"]["batch_input_shape"]) # returns a tuple of width, height and channels 72 | output_predictions = [] 73 | 74 | for model in models: 75 | output_predictions.append(model.predict(images)[0,:, :, 0]) 76 | 77 | output_prediction = np.mean(output_predictions, axis=0) 78 | output_prediction = ((output_prediction > 0.5) * 1).astype(np.uint8) 79 | 80 | #logger.info(output_prediction.shape) 81 | 82 | except: 83 | logger.warning( 84 | f"test_features not found for {chip_id}, predicting all zeros; did you download your" 85 | f"training data into `runtime/data/test_features` so you can test your code?" 86 | ) 87 | output_prediction = np.zeros(shape=(512, 512)) 88 | return output_prediction 89 | 90 | 91 | def get_expected_chip_ids(): 92 | """ 93 | Use the input directory to see which images are expected in the submission 94 | """ 95 | mypath = os.path.join(os.getcwd(), 'data', 'test_features') 96 | files = [f for f in listdir(mypath) if isfile(join(mypath, f))] 97 | 98 | 99 | #logger.info(files) 100 | # images are named something like abc12.tif, we only want the abc12 part 101 | ids = list(sorted(set(f.split("_")[0] for f in files))) 102 | #logger.info(ids) 103 | return ids 104 | 105 | 106 | def main(): 107 | """ 108 | for each input file, make a corresponding output file using the `make_predictions` function 109 | """ 110 | logger.info("Loading model") 111 | custom_objects = {"DiceLoss": DiceLoss, "DiceLoss_square": DiceLoss_square, "IoULoss": IOULoss, "IOU_coef": IOU_coef} 112 | models = [] 113 | with keras.utils.custom_object_scope(custom_objects): 114 | models.append(keras.models.load_model(os.path.join(os.getcwd(), 'assets', 'model_floodwater_unet_pc_augm_diceloss.h5'))) 115 | models.append(keras.models.load_model(os.path.join(os.getcwd(), 'assets', 'model_floodwater_unet_pc_augm_diceloss_2.h5'))) 116 | models.append(keras.models.load_model(os.path.join(os.getcwd(), 'assets', 'model_floodwater_unet_pc_augm_diceloss_3.h5'))) 117 | 118 | 119 | logger.info("Finding chip IDs in ") 120 | chip_ids = get_expected_chip_ids() 121 | if not chip_ids: 122 | typer.echo("No input images found!") 123 | raise typer.Exit(code=1) 124 | 125 | logger.info(f"found {len(chip_ids)} expected image ids; generating predictions for each ...") 126 | for chip_id in tqdm(chip_ids, miniters=25, file=sys.stdout, leave=True): 127 | # figure out where this prediction data should go 128 | output_path = os.path.join(os.getcwd(), 'submission', chip_id+'.tif') 129 | # make our predictions! (you should edit `make_predictions` to do something useful) 130 | output_data = make_predictions(chip_id, models) 131 | imwrite(output_path, output_data, dtype=np.uint8) 132 | logger.success(f"... done") 133 | 134 | 135 | if __name__ == "__main__": 136 | typer.run(main) 137 | -------------------------------------------------------------------------------- /2nd_Place/src/models/predict.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from loguru import logger 3 | import numpy as np 4 | import typer 5 | from tifffile import imwrite 6 | from tqdm import tqdm 7 | from os import listdir 8 | from os.path import isfile, join 9 | import os 10 | 11 | import tensorflow as tf 12 | from tensorflow import keras 13 | import rasterio 14 | 15 | import keras.backend as K 16 | 17 | def parent(path_): 18 | return os.path.abspath(os.path.join(path_, os.pardir)) 19 | 20 | def IOU_coef(y_true, y_pred): 21 | y_true_f = K.flatten(y_true) 22 | y_pred_f = K.flatten(y_pred) 23 | intersection = K.sum(y_true_f * y_pred_f) 24 | return (intersection + 1.0) / (K.sum(y_true_f) + K.sum(y_pred_f) - intersection + 1.0) 25 | 26 | # https://gist.github.com/wassname/7793e2058c5c9dacb5212c0ac0b18a8a 27 | def DiceLoss_square(y_true, y_pred, smooth=1): 28 | y_true_f = K.flatten(y_true) 29 | y_pred_f = K.flatten(y_pred) 30 | intersection = K.sum(K.abs(y_true_f * y_pred_f)) 31 | return 1-((2. * intersection + smooth) / (K.sum(K.square(y_true_f),-1) + K.sum(K.square(y_pred_f),-1) + smooth)) 32 | 33 | def DiceLoss(y_true, y_pred, smooth=1): 34 | intersection = K.sum(y_true * y_pred) 35 | return 1-((2. * intersection + smooth) / (K.sum(y_true) + K.sum(y_pred) + smooth)) 36 | 37 | 38 | def make_predictions(chip_id: str, models): 39 | """ 40 | Given an image ID, read in the appropriate files and predict a mask of all ones or zeros 41 | """ 42 | #logger.info(os.path.join(os.getcwd(), 'data', 'test_features', chip_id+'_vh.tif')) 43 | try: 44 | 45 | dirs = ["test_features", "test_features", "nasadem", "jrc_change", "jrc_extent", "jrc_seasonality", "jrc_occurrence", "jrc_recurrence", "jrc_transitions"] 46 | endings = ["_vv.tif", "_vh.tif", ".tif", ".tif", ".tif", ".tif", ".tif", ".tif", ".tif"] 47 | 48 | arrays = [] 49 | 50 | #os.path.abspath() 51 | for i in range(9): 52 | path = os.path.join(parent(parent(os.getcwd())), 'data', 'to_predict', dirs[i], chip_id + endings[i]) 53 | 54 | #print(path) 55 | #load image from path 56 | with rasterio.open(path) as img: 57 | 58 | if(i < 2): 59 | arrays.append(np.uint8(np.clip(img.read(1), -30, 0)*(-8.4))) 60 | elif(i == 2): 61 | arrays.append(np.uint8(np.clip(img.read(1), 0, 255))) 62 | else: 63 | arrays.append(img.read(1)) 64 | 65 | images = np.array([np.stack(arrays, axis=-1)]) 66 | 67 | #logger.info(img.shape) 68 | 69 | #config = model.get_config() # Returns pretty much every information about your model 70 | #logger.info(config["layers"][0]["config"]["batch_input_shape"]) # returns a tuple of width, height and channels 71 | output_predictions = [] 72 | 73 | for model in models: 74 | output_predictions.append(model.predict(images)[0,:, :, 0]) 75 | 76 | output_prediction = np.mean(output_predictions, axis=0) 77 | output_prediction = ((output_prediction > 0.5) * 1).astype(np.uint8) 78 | 79 | #logger.info(output_prediction.shape) 80 | 81 | except: 82 | logger.warning( 83 | f"test_features not found for {chip_id}, predicting all zeros; did you download your" 84 | f"training data into `runtime/data/test_features` so you can test your code?" 85 | ) 86 | output_prediction = np.zeros(shape=(512, 512)) 87 | return output_prediction 88 | 89 | 90 | def get_expected_chip_ids(): 91 | """ 92 | Use the input directory to see which images are expected in the submission 93 | """ 94 | mypath = os.path.join(parent(parent(os.getcwd())), 'data', 'to_predict', 'test_features') 95 | files = [f for f in listdir(mypath) if isfile(join(mypath, f))] 96 | files.remove(".gitkeep") 97 | 98 | #logger.info(files) 99 | # images are named something like abc12.tif, we only want the abc12 part 100 | ids = list(sorted(set(f.split("_")[0] for f in files))) 101 | #logger.info(ids) 102 | return ids 103 | 104 | 105 | def main(): 106 | """ 107 | for each input file, make a corresponding output file using the `make_predictions` function 108 | """ 109 | logger.info("Loading model") 110 | custom_objects = {"DiceLoss": DiceLoss, "DiceLoss_square": DiceLoss_square, "IOU_coef": IOU_coef} 111 | models = [] 112 | with keras.utils.custom_object_scope(custom_objects): 113 | models.append(keras.models.load_model(os.path.join(parent(parent(os.getcwd())), 'models', 'model_floodwater_unet_pc_augm_diceloss.h5'))) 114 | models.append(keras.models.load_model(os.path.join(parent(parent(os.getcwd())), 'models', 'model_floodwater_unet_pc_augm_diceloss_2.h5'))) 115 | models.append(keras.models.load_model(os.path.join(parent(parent(os.getcwd())), 'models', 'model_floodwater_unet_pc_augm_diceloss_3.h5'))) 116 | 117 | #logger.info(model.summary()) 118 | 119 | 120 | logger.info("Finding chip IDs in ") 121 | chip_ids = get_expected_chip_ids() 122 | if not chip_ids: 123 | typer.echo("No input images found!") 124 | raise typer.Exit(code=1) 125 | 126 | logger.info(f"found {len(chip_ids)} expected image ids; generating predictions for each ...") 127 | for chip_id in tqdm(chip_ids, miniters=25, file=sys.stdout, leave=True): 128 | # figure out where this prediction data should go 129 | output_path = os.path.join(parent(parent(os.getcwd())), 'output_data', chip_id+'.tif') 130 | # make our predictions! (you should edit `make_predictions` to do something useful) 131 | output_data = make_predictions(chip_id, models) 132 | imwrite(output_path, output_data, dtype=np.uint8) 133 | logger.success(f"... done") 134 | 135 | 136 | if __name__ == "__main__": 137 | typer.run(main) 138 | -------------------------------------------------------------------------------- /3rd_Place/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Will L. (loweew) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /3rd_Place/README.md: -------------------------------------------------------------------------------- 1 | # STAC Overflow 2 | 3 | Third place solution for the STAC Overflow: Map Floodwater from Radar Imagery competition. 4 | 5 | ## Prerequisites 6 | 7 | Install dependencies by running: 8 | 9 | `pip install requirements.txt` 10 | 11 | ## Model training and inference 12 | 13 | Notebook `01-ewl-stac.ipynb` should run end-to-end to reproduce the trained model and setup the submission directory for prediction of the test set. This solution assumes that training features are saved in the directory `../training_data/train_features`, training labels are saved in the directory `../training_data/train_labels`, and the metadata is saved to `../training_data/flood-training-metadata.csv`. 14 | -------------------------------------------------------------------------------- /3rd_Place/flood_model.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytorch_lightning as pl 3 | import rasterio 4 | import segmentation_models_pytorch as smp 5 | import torch 6 | 7 | 8 | class FloodModel(pl.LightningModule): 9 | def __init__(self): 10 | super().__init__() 11 | self.model = smp.UnetPlusPlus( 12 | encoder_name='timm-efficientnet-l2', 13 | encoder_weights=None, 14 | decoder_attention_type='scse', 15 | in_channels=9, 16 | classes=2, 17 | ).cuda() 18 | 19 | def forward(self, image): 20 | # Forward pass 21 | return self.model(image) 22 | 23 | def norm(self, arr, mn, mx): 24 | return (np.clip(arr, mn, mx) - mn) / (mx - mn) 25 | 26 | def std(self, arr, mean, std): 27 | return ( arr - mean) / std 28 | 29 | def predict(self, vv_path, vh_path, change_path, extent_path, occur_path, recurr_path, seas_path, trans_path, nasadem_path): 30 | # Switch on evaluation mode 31 | self.model.eval() 32 | torch.set_grad_enabled(False) 33 | 34 | # Create a 2-channel image 35 | with rasterio.open(vv_path) as vv: 36 | vv_img = vv.read(1) 37 | with rasterio.open(vh_path) as vh: 38 | vh_img = vh.read(1) 39 | 40 | with rasterio.open(nasadem_path) as vh: 41 | elev = vh.read(1) 42 | with rasterio.open(extent_path) as vh: 43 | extent = vh.read(1) 44 | with rasterio.open(occur_path) as vh: 45 | occur = vh.read(1) 46 | with rasterio.open(recurr_path) as vh: 47 | recurr = vh.read(1) 48 | with rasterio.open(seas_path) as vh: 49 | seas = vh.read(1) 50 | with rasterio.open(trans_path) as vh: 51 | trans = vh.read(1) 52 | with rasterio.open(change_path) as vh: 53 | change = vh.read(1) 54 | 55 | # # Min-max normalization for original chips 56 | # min_norm = -77 57 | # max_norm = 26 58 | 59 | # vv_img = self.norm(vv_img, min_norm, max_norm) 60 | # vh_img = self.norm(vh_img, min_norm, max_norm) 61 | # elev_min = -64 62 | # elev_max = 2091 63 | # extent_min = occur_min = recurr_min = seas_min = change_min = 0 64 | # extent_max = occur_max = recurr_max = seas_max = change_max = 255 65 | # trans_min = 0 66 | # trans_max = 10 67 | 68 | # elev = self.norm(elev, elev_min, elev_max) 69 | # extent = self.norm(extent, extent_min, extent_max) 70 | # occur = self.norm(occur, occur_min, occur_max) 71 | # recurr = self.norm(recurr, recurr_min, recurr_max) 72 | # seas = self.norm(seas, seas_min, seas_max) 73 | # trans = self.norm(trans, trans_min, trans_max) 74 | # change = self.norm(change, change_min, change_max) 75 | 76 | # mean std standardization 77 | vh_mean = -17.547868728637695 78 | vh_std = 5.648269176483154 79 | vv_mean = -10.775313377380371 80 | vv_std = 5.038400650024414 81 | elev_mean = 151.06439787523334 82 | elev_std = 147.7373788520009 83 | extent_mean = 3.4183792170563305 84 | extent_std = 28.79923820408129 85 | occur_mean = 8.270102377747257 86 | occur_std = 34.48069374950159 87 | recurr_mean = 12.422072491522645 88 | recurr_std = 38.354506653571214 89 | seas_mean = 3.918482361684426 90 | seas_std = 28.87351299843167 91 | change_mean = 236.96356944404405 92 | change_std = 47.62208238871771 93 | trans_mean = 0.5896631853166981 94 | trans_std = 1.9514194857824525 95 | 96 | vv_img = self.std(vv_img, vv_mean, vv_std) 97 | vh_img = self.std(vh_img, vh_mean, vh_std) 98 | elev = self.std(elev, elev_mean, elev_std) 99 | extent = self.std(extent, extent_mean, extent_std) 100 | occur = self.std(occur, occur_mean, occur_std) 101 | recurr = self.std(recurr, recurr_mean, recurr_std) 102 | seas = self.std(seas, seas_mean, seas_std) 103 | trans = self.std(trans, trans_mean, trans_std) 104 | change = self.std(change, change_mean, change_std) 105 | 106 | 107 | x_arr = np.stack([ 108 | vv_img, 109 | vh_img, 110 | elev, 111 | extent, 112 | occur, 113 | recurr, 114 | seas, 115 | trans, 116 | change, 117 | ], axis=-1 118 | ).astype(np.float32) 119 | 120 | # Transpose 121 | x_arr = np.transpose(x_arr, [2, 0, 1]) 122 | x_arr = np.expand_dims(x_arr, axis=0) 123 | 124 | # Perform inference 125 | x = torch.from_numpy(x_arr) 126 | x = x.cuda(non_blocking=True) 127 | 128 | preds = self.forward(x) 129 | preds = torch.softmax(preds, dim=1)[:, 1] 130 | preds = (preds > 0.5) * 1 131 | return preds.detach().cpu().numpy().astype(np.uint8).squeeze().squeeze() 132 | -------------------------------------------------------------------------------- /3rd_Place/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | from loguru import logger 5 | import numpy as np 6 | from tifffile import imwrite 7 | from tqdm import tqdm 8 | import torch 9 | import typer 10 | 11 | from flood_model import FloodModel 12 | 13 | 14 | ROOT_DIRECTORY = Path("/codeexecution") 15 | SUBMISSION_DIRECTORY = ROOT_DIRECTORY / "submission" 16 | ASSETS_DIRECTORY = ROOT_DIRECTORY / "assets" 17 | DATA_DIRECTORY = ROOT_DIRECTORY / "data" 18 | INPUT_IMAGES_DIRECTORY = DATA_DIRECTORY / "test_features" 19 | CHANGE = DATA_DIRECTORY / "jrc_change" 20 | EXTENT = DATA_DIRECTORY / "jrc_extent" 21 | OCCUR = DATA_DIRECTORY / "jrc_occurrence" 22 | RECURR = DATA_DIRECTORY / "jrc_recurrence" 23 | SEAS = DATA_DIRECTORY / "jrc_seasonality" 24 | TRANS = DATA_DIRECTORY / "jrc_transitions" 25 | NASADEM = DATA_DIRECTORY / "nasadem" 26 | 27 | # Make sure the smp loader can find our torch assets because we don't have internet! 28 | os.environ["TORCH_HOME"] = str(ASSETS_DIRECTORY / "torch") 29 | 30 | 31 | def make_prediction(chip_id, model): 32 | """ 33 | Given a chip_id, read in the vv/vh bands and predict a water mask. 34 | 35 | Args: 36 | chip_id (str): test chip id 37 | 38 | Returns: 39 | output_prediction (arr): prediction as a numpy array 40 | """ 41 | logger.info("Starting inference.") 42 | try: 43 | output_prediction = None 44 | for e,m in enumerate(model): 45 | vv_path = INPUT_IMAGES_DIRECTORY / f"{chip_id}_vv.tif" 46 | vh_path = INPUT_IMAGES_DIRECTORY / f"{chip_id}_vh.tif" 47 | change_path = CHANGE / f"{chip_id}.tif" 48 | extent_path = EXTENT / f"{chip_id}.tif" 49 | occur_path = OCCUR / f"{chip_id}.tif" 50 | recurr_path = RECURR / f"{chip_id}.tif" 51 | seas_path = SEAS / f"{chip_id}.tif" 52 | trans_path = TRANS / f"{chip_id}.tif" 53 | nasadem_path = NASADEM / f"{chip_id}.tif" 54 | if e == 0: 55 | output_prediction = m.predict(vv_path, vh_path, change_path, extent_path, occur_path, recurr_path, seas_path, trans_path, nasadem_path) 56 | else: 57 | output_prediction += m.predict(vv_path, vh_path, change_path, extent_path, occur_path, recurr_path, seas_path, trans_path, nasadem_path) 58 | 59 | except Exception as e: 60 | logger.error(f"No bands found for {chip_id}. {e}") 61 | raise 62 | return output_prediction 63 | 64 | 65 | def get_expected_chip_ids(): 66 | """ 67 | Use the test features directory to see which images are expected. 68 | """ 69 | paths = INPUT_IMAGES_DIRECTORY.glob("*.tif") 70 | # Return one chip id per two bands (VV/VH) 71 | ids = list(sorted(set(path.stem.split("_")[0] for path in paths))) 72 | return ids 73 | 74 | 75 | def main(): 76 | """ 77 | For each set of two input bands, generate an output file 78 | using the `make_predictions` function. 79 | """ 80 | logger.info("Loading model") 81 | # Explicitly set where we expect smp to load the saved resnet from just to be sure 82 | torch.hub.set_dir(ASSETS_DIRECTORY / "torch/hub") 83 | folds = 5 84 | models = [] 85 | for i in range(folds): 86 | model = FloodModel() 87 | model.load_state_dict(torch.load(ASSETS_DIRECTORY / "flood_model-{}.pt".format(i))) 88 | models.append(model.cuda()) 89 | 90 | logger.info("Finding chip IDs") 91 | chip_ids = get_expected_chip_ids() 92 | if not chip_ids: 93 | typer.echo("No input images found!") 94 | raise typer.Exit(code=1) 95 | 96 | logger.info(f"Found {len(chip_ids)} test chip_ids. Generating predictions.") 97 | for chip_id in tqdm(chip_ids, miniters=25): 98 | output_path = SUBMISSION_DIRECTORY / f"{chip_id}.tif" 99 | output_data = make_prediction(chip_id, models).astype(np.uint8) 100 | imwrite(output_path, ((output_data > 2.5) * 1).astype(np.uint8), dtype=np.uint8) 101 | 102 | logger.success(f"Inference complete.") 103 | 104 | if __name__ == "__main__": 105 | typer.run(main) 106 | -------------------------------------------------------------------------------- /3rd_Place/reports/DrivenData-Competition-Winner-Documentation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drivendataorg/stac-overflow/481c80ccb6dcb7c960a1d043e094e35fabadc58c/3rd_Place/reports/DrivenData-Competition-Winner-Documentation.pdf -------------------------------------------------------------------------------- /3rd_Place/requirements.txt: -------------------------------------------------------------------------------- 1 | pathlib 2 | pandas-path 3 | matplotlib 4 | numpy 5 | pandas 6 | rasterio 7 | random 8 | albumentations 9 | opencv 10 | torch 11 | pytorch-lightning 12 | segmentation-models-pytorch 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright: See individual winner LICENSE files 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://www.drivendata.org/) 2 |

3 | 4 | 5 | 6 | 7 | # STAC Overflow: Map Floodwater from Radar Imagery 8 | 9 | ## Goal of the Competition 10 | 11 | Flooding is the most frequent and costly natural disaster in the world. According to the World Health Organization, between 1998 and 2017, floods affected more than two billion people worldwide. As global warming continues to exacerbate rising sea levels, prolong rainstorms, and increase snowmelt, the frequency and severity of extreme weather is only expected to rise. 12 | 13 | During a flood event, it is critical that humanitarian organizations be able to accurately measure flood extent in near real-time to strengthen early warning systems and target relief. Historically, hydrologists have relied on readings from rain and stream gauging stations to understand flood reach. Though helpful, these ground measures only measure water height, are spatially limited, and can be expensive to maintain. High resolution synthetic-aperture radar (SAR) imaging has strengthened monitoring systems by providing data in otherwise inaccessible areas at frequent time intervals. Specifically, C-band SAR from the Sentinel-1 mission provides an all-weather, day-and-night supply of images of the Earth’s surface. 14 | 15 | The goal of this challenge is to build machine learning algorithms that are able to map floodwater using Sentinel-1 global SAR imagery. Microsoft AI for Earth has teamed up with DrivenData and Cloud to Street to investigate the applicability of machine learning models for detecting flood coverage in near real-time. Models that can effectively use remote sensing to improve flood mapping have the potential to strengthen flood risk assessment, relief targeting, and disaster preparedness. 16 | 17 | ## What's in this Repository 18 | 19 | This repository contains code from winning competitors in the [STAC Overflow: Map Floodwater from Radar Imagery](https://www.drivendata.org/competitions/81/detect-flood-water/) DrivenData challenge. Code for all winning solutions are open source under the MIT License. 20 | 21 | **Winning code for other DrivenData competitions is available in the [competition-winners repository](https://github.com/drivendataorg/competition-winners).** 22 | 23 | ## Winning Submissions 24 | 25 | Place | Team or User | Public Score | Private Score | Summary of Model 26 | --- | --- | --- | --- | --- 27 | 1 | Moscow Hares: [sweetlhare](https://www.drivendata.org/users/sweetlhare/), [Belass](https://www.drivendata.org/users/Belass/) | 0.899 | 0.809 | Create pixel-level vector representations of raster data by flattening VV, VH, and auxiliary bands. Train a set of CatBoostClassifiers over 1000 iterations using sequential, regional, k-fold, and stratified k-fold sampling, and average predictions. Finetune pretrained U-Net CNNs with EfficientNet-B0 and B4 backbones using samples of standardized, 3-channel images (VV, VH, & NASADEM) with flip, rotation, crop, and blurring augmentations. Train one model on weakly performing images. Ensemble CatBoost and U-Net predictions using the maximum output. Missing pixels are treated as zero. 28 | 2 | [Max_Lutz](https://www.drivendata.org/users/Max_Lutz/) | 0.908 | 0.807 | Create 9-channel images by stacking VH, VV, and auxiliary input bands. Clip VV and VH bands, scale all values to 0-255, and concatenate additional flipped and rotated augmentations. Train 3 randomly initialized U-Net CNNs using different train-test-splits and a consistent loss function of dice loss with a squared denominator. Ensemble predictions using the mean. 29 | 3 | [loweew](https://www.drivendata.org/users/loweew/) | 0.898 | 0.804 | Create standardized 9-channel images by stacking VH, VV, and auxiliary input bands. Apply augmentations including cropping, rotation, translation, scaling, blurring, affine transformation, grid and optical distortion, grid shuffle, and brightness contrast. Use a U-Net++ CNN with an EfficientNet-B8 backbone pretrained using AdvProp, which treats adversarial examples as additional input, to assign difficult floods to the training set. Finetune U-Net++ CNNs with an EfficientNet-L2 backbone pretrained with Noisy Student Training, and use Focal Tversky loss to address data imbalance. Take a “cross-validation as a jury” approach to average predictions. 30 | 31 | Additional solution details, including tips for using subsets of the winning models, can be found in the `reports` folder inside the directory for each submission. To request access to pre-computed survey weights, please [contact us](https://www.drivendata.org/contact/). 32 | 33 | **Winners Announcement: [Meet the Winners of STAC Overflow](https://drivendata.co/blog/stac-overflow-winners/)** 34 | 35 | **Benchmark Blog Post: [How to Map Floodwater from Radar Imagery using Semantic Segmentation](https://www.drivendata.co/blog/detect-floodwater-benchmark/)** 36 | 37 | ## Competition Sponsor 38 | 39 |

40 | 41 |

42 | --------------------------------------------------------------------------------