Skip to content
Snippets Groups Projects
Jupyter Notebook Block 5 - Object Detection and Segmentation.ipynb 518 KiB
Newer Older
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "dWyPGNkCGhIX"
   },
   "source": [
    "# Part I : Create Your Own Dataset and Train it with ConvNets\n",
    "\n",
    "In this part of the notebook, you will set up your own dataset for image classification. Please specify \n",
    "under `queries` the image categories you are interested in. Under `limit` specify the number of images \n",
    "you want to download for each image category. \n",
    "\n",
    "You do not need to understand the class `simple_image_download`, just execute the cell after you have specified \n",
    "the download folder.\n"
   ]
  },
  {
   "cell_type": "code",
Simon van Hemert's avatar
Simon van Hemert committed
   "execution_count": 1,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "8rckz3ZuGhIc",
    "outputId": "6f615f06-759a-4eea-839e-658155df8d36"
   },
Simon van Hemert's avatar
Simon van Hemert committed
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 2 image links\n",
      "Saved 2 images\n",
      "Found 2 image links\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
      "Saved 2 images\n",
      "Found 2 image links\n",
      "Saved 2 images\n",
      "Found 2 image links\n",
      "Saved 2 images\n",
      "Found 2 image links\n",
      "Saved 2 images\n",
      "Found 2 image links\n",
      "Saved 2 images\n",
      "Found 2 image links\n",
      "Saved 2 images\n",
      "Found 2 image links\n",
      "ERROR - Could not save https://upload.wikimedia.org/wikipedia/commons/5/59/Marion_Cotillard_at_2019_Cannes.jpg - cannot identify image file <_io.BytesIO object at 0x7f1a0b4d6d70>\n",
      "Saved 1 images\n"
Simon van Hemert's avatar
Simon van Hemert committed
     ]
   "source": [
Simon van Hemert's avatar
Simon van Hemert committed
    "from selenium import webdriver\n",
    "from selenium.webdriver.firefox.options import Options\n",
    "from Image_crawling import Image_crawling\n",
    "\n",
    "# Specifiy the queries\n",
    "queries = [\"brad pitt\",\"johnny depp\", \"leonardo dicaprio\", \"robert de niro\", \"angelina jolie\", \"sandra bullock\", \"catherine deneuve\", \"marion cotillard\"]\n",
    "#queries = [\"Bart Simpson\",\"Homer Simpson\"]\n",
    "limit = 2\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "download_folder = \"./brandnew_images/train/\"\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "waittime = 0.1  # Time to wait between actions, depends on the number of pictures you want to crawl. More pictures means you need to wait longer for them to load. \n",
Simon van Hemert's avatar
Simon van Hemert committed
    "# Set options\n",
    "options = webdriver.FirefoxOptions()\n",
    "options.add_argument('--headless')\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "# Create Driver\n",
    "driver = webdriver.Firefox(options=options, executable_path=\"/usr/bin/geckodriver\")\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "# create instance of crawler\n",
    "image_crawling = Image_crawling(driver, waittime=waittime)\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "# Find urls and download images\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "for query in queries:\n",
    "    # Craws image urls:\n",
    "    image_urls = image_crawling.fetch_image_urls(query, limit)\n",
    "      \n",
    "    # download images\n",
    "    image_crawling.download_image(download_folder + query)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "CRHl9UX6GhIs"
   },
   "source": [
    "Please check carefully the downloaded images, there may be a lot of garbage! You definitely need to \n",
    "clean the data.\n",
    "\n",
    "In the following, you will apply data augmentation to your data set."
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": 7,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "3SX21FtcGhIu"
   },
   "outputs": [],
   "source": [
    "# General imports\n",
    "import tensorflow as tf\n",
    "tf.compat.v1.enable_eager_execution(\n",
    "    config=None, device_policy=None, execution_mode=None\n",
    ")\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "import os, datetime\n",
    "\n",
    "# Shortcuts to keras if (however from tensorflow)\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Conv2D, MaxPooling2D\n",
    "from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense\n",
    "from tensorflow.keras.callbacks import TensorBoard \n",
    "\n",
    "# Shortcut for displaying images\n",
    "def plot_img(img):\n",
    "    plt.imshow(img, cmap='gray')\n",
    "    plt.axis(\"off\")\n",
    "    plt.show()\n",
    "    \n",
    "# The target image size can be fixed here (quadratic)\n",
    "# the ImageDataGenerator() automatically scales the images accordingly (aspect ratio is changed)\n",
    "image_size = 150"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": 8,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "rN_Mp1rmGhI1",
    "outputId": "6417b1f9-e7d4-4d56-a213-191f9d17524a"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 480 images belonging to 8 classes.\n"
Mirko Birbaumer's avatar
Mirko Birbaumer committed
     "data": {
Mirko Birbaumer's avatar
Mirko Birbaumer committed
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOcAAADnCAYAAADl9EEgAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAADLgklEQVR4nOz915IkyZKmCX4sQFXN3D0iIzOrTlX1TG3PNA0t7V7M+z/EEg3tzi4N9TSY6kIH5MkM4O5mqiqA94JF1Mw9HAVIUE1HkizD3ExNobAw+vlnUVX+Mv4y/jJ+e8P92ifwl/GX8Zfx8PiLcP5l/GX8RsdfhPMv4y/jNzr+Ipx/GX8Zv9HxF+H8y/jL+I2O8NSXMcZfLJT7WNRYRJ7c5vz7T93uU8f5fu/vr3/XPxeR7XX+9/3v7n/+2D5EBOccoNRaKKVQa0VrodaCKiCK9N/ZHqCdcggeVVCt5FJwzvbnvYda8c4TQsB7T0qJlDK5ZARBnCPGSEURgeB827sCgjgI3uODIziHlorWiiLkVNAK3nsOaaHUiqJ47/DOEbzjaoqMQ2QYIgVPKpVSKmldqBW0KlorPjhqVdKa8T7gnMOJo2rBe0cIgWmaKCWjWgkhcDweySWDlu033nvWlCmlUGrFCYg4BOE4z6SqlKoUVWqp2z2s7c392aVg9x9BVe2c23yotX40H+//nXN+cHI+KZy/1vgagvRz7u98PLYQPCR05+8f+uz+9w8JcB8mnAXVilYFlCYrdl4ITvrfQq0KYoIWXBdd2SZVRU1wtFJrwYkyBI84m7RKpVYTzorYd2KTUdukLMWEqDbhrNV+owpZazu+LRjRe3wTiCVVck0ccwXxaLVJnXLGtQtSwIsDp6gT1CmVauelFS1KBVhWwAQi5UJVtUUgBFIqdo5aqWrXUdUEy7WFzfsADpwqmjOl2P4FQR+YRtvjV1D0USXzOeM3I5wvEaDntOhvbdwXuqe05Pk2j+1LmqA5EWot1FJQNYE53Y/+e0XPjlm1a1WHd55aa98KwSZZKYUqgNp33jucc4gIuVTbWjEt5gMCVIVSoVYQVQq6CWYupR0DqOC8Q8SBVoLzOLHVIxVlLQVNBef8popyKQTvtnuizoEqKlC12qXaaZkAqbbrtO1rtd+H4AnRk5J9T1UTTrVFDLW/BbXjbzfEdKWe39az0W+56kl7nk/Lh+bop8zb34xw/lsb903cPoHM9OTOd/e3ecz0Pf+uv+/CsW2P4oIjUMmoCdPZtufnpapm+rVzyjk3YZbt+1qrfb/NNJq2UyTb5Pbe4X1g8N5+Uwq+/abkRK0CYsfJ1TSkijPt1sy6EAJt1jct5NGmwcc4kHNmTYnjspg2biZ4CB7nxEzhcUIRigq3xxURIfjAOHjThrlwnFfECSKOIUaceIrCOq8McbDfl4IrZbMkail24e0e1ra4lFK2+9fvq52b3hFMu66+eHbteXd+fI4y+TcrnE9p2p/LjD2f1Od/v8SEfcz/fOicH9tXraWZjYlSTWsiJnh9EnWN2H/TBfDks4L5rU3l9E9Ut9+KCN655je2CSjS/DLAQSq2fUqVKqbCtNBMX5v09681lwxVccBhWTbfWBa7rtJetWluASgVqXYd19e3oFBqIaXcrg9CcJuv7bynAlWV23kmJE/wjt3gGZ0JfCmFknMTbkfR5iPXSsV8au893nnmNZFzIZvJgLbFq3vcXUo363YT3i+37P7NCuevOZ4yVx/b7v7259+/RKDNp6vUkik5NT/z8X2f7+u+lrc/bfU/3+bOotP3JdJ8yjtHIhXzLXM1M7P7W7VUnPc4LAh0fj61VqhmbtdcOPvi9FbNk6RpeOVktuey0sWg1IITtwm0FzP3nTMztSiUqqhmVB3RO4KvZsLWSs4F7z0hOPDOvNfmgLom5CH4k89cz8737J6eDI67mvX+ff+c8Rfh/BnGU/7kSwNF59uqKsuyUEs2rdI05p1HrxbVNMP3NDnO93F3sTAzTEQsYstpYnWzLobYBIQWSDHzT1WpKbfduKZJaFqtbubhuYnfTcRKjxb7poUqpeSzyGvTPM13pTT/1zn67rolYO5iZU2ZwTucF4sWi8cjhBipNYMqS8o4Ebyz6PKaEhFhwDOOHtVCKZmcWiQ5WPRaMV+5lIWUisXcxLVA0l3L42uPvwjnI+O5dMxjJu1jWvEhX/Ql/mj3fXrqhE27dVPOAjRbYLYFRUzjtFSKNCFFcOJw3iPSo6mmEfpx7pxP05pAM/1OJpsJi7SJ2s9JGWLYBHPz187u6WkxEERsMfFtPyJCKWwRVLoGPz0VALwTnPOn81Q1jVuhUnA+IuLIKVtapSrOCd4Lg3iG6BEv5Fo4LDMhKzF6YgzE4PEh4J1HnDBpQFBSytSaT0GkM23/3PjYcnmZIP93K5z3b8CX+qEvEczz75/Tks/tA1r4pAnQSTBPpqf0jcQCLbpNGL2zDwc4OWnK4BwFmvmnZiKr4sRtQt3N335KPUiEqgWlRHEtLmqCZe7veQCLbfv+5/kzOV2Hk9N90Gpaku4v3/Ph+vY9iistz+mcmIZr2p12jlVARVtUWc8WEotg55JN2zvTkCG47V45pwQv1CDEICxOqC0V89LxnCA+NS+fFM6HfvhvIYXxueMl1/YSbfecT/mUcN655yItj1m39EY/T9c0DWLBj56+AMBZQEbVTLTQEv6KCU8MoflQSs6AVpw4fJRNKOw4lQ4iqy266QSic3jXQyKWfnDe4bxrASQTppwTKgacKE0z9++2+9BSQ10gVGAYIiEGclXmZSZnC8Q4Z9t5L8R2PCeOXJRhGAhDZF5m0IpQmQZPrkIuSkqlpXeEXKsFrIr5nqVmalsIvAuoigmmCN5DVGGMjltsocy1gp5cgU8dL1UU/91qzq89HhOgh4TrMaG9v6+H9n8+DMFyAhvYNtJSGyY09jmI9+C76dg1jCd6Z2ZgFzqtlLyQcqGomXtDCBbEcY6CmgldKqUoYMeNwW+m+Sma2gIw0gNWhTkl07KomYZi54MIwzDY75ugCv1+OcQJzgtTCMQYCSEwikVTU8qknNsxMc3pTMOGGNhJQLG0TkoruyEyxsAweFJVUq4cRSwYVTG/MgRUKoUCOEqpLEtikAQknBMu3EAYPGMYCXEE8dweFj7cHiknD+NF8+ZTv4PPEM5PNQ//LWva+4GUj8zOFwrmQ799bGz3S3VLnXSBs/2cmY7bvTUBEXE42PxPaXnE2vIhPegvpZl33eSUzb3DqeX1RQyE0M1nR0cDse3TnV2v+XwdZaQNLHBKpwTvN63az98EzTUhbmZxRwR1/9R5CM23PjOr+z2iVlwM9t4pwZmV4BtMr1KpHmLwaFGkBc4qul2Pdw4v4EU2811V2n0zv9lHx24cqRXWXJgXM4db/OvB8Zh/+dxC3cfPrjmfOvi/BcF1Z/m6/u+n+JyPffck3lIbjK5ktJmfp99I05rnudaK4DZ/UlqqpAeUQCnn18D28+3YPQKqesLnBh+2gIxDSCltGrzU2jSia9HcSi75zDcE0YrpV884DKxpNaF2ptUtYOQb7ldPucb28t5QRC4EvJdtodJiaCC7R4IEcM6bcMVCaJFfZ3cFL45hcGhukehcyCVvC1T0ntAivWjD0qr5v6idfwie3TRCg0KWeqSuGdW83ddPwXS/ZNF+UjifEp4vDbD0ffwWBfQ5DfjU+6eE8iXDOdcCNKC1tLSImZ+2Spv5yLn/5gTnbeX3zcdDTWB6/vGU29R+QjjvGIbhhIGtmWajWhDJNY9ThFwK4gSP2yK43rWFoqVEOEvPOBGiDwzDYNsIDDE2sH5liEOL9tKEGjp4tUemU0obGH8cwmaen3zPSIyDgeRTIpfExX5qUWXISRACo3dcXUZKgXVdub65NXD+KQNkGry7AC0SfDgsqAohKrGaqS9iWjh4R3aQeLmS+dT58Nma8yVVJC8ZP5eAvuQ87iN9Hnv/UaDmge2+RDDv5Mu6KVttBRdlMwc7cOA8WihOiCFsQZUeqdz+a4KpHRjfTODQfMhuXra9mW/ajqe1oX/O9mtbWaDJnZnWza1E1LSsE7dVvpg/e0IrlYbuse9N8Gut1GZul1JP19gCUSqRvkgNMW4C1e+L80LAKmNqscWmVloVigmdRaRpLzvZ0haWXOxz72NbTATVtGlx1RbBbeftXT//l/me5+NXM2s/R2jPv/tagvpUeddj277UdH3K17z//UvO83zbWgt04ez7gy2lIP03nCB7MQRLatxLPahyJ1lu/qWdW+gAg5YvMT/1hC01U7VYVYoIW7XL5gu6LdXTz7/7pZZSabjgNom993YdtSK1tsltyX5J2UrBcjnlU7t+FgMilKp41/KcwVML7RwtUHQyfx1VTDhzrg3cILhW8OVE8c4CShmoxSwMM91hGIbtmm1B6ZFyf7qWe69cXp4u+ZQYxC8Wrf25TeQvHY9px5eYrs8J40MPp4Op+8q8bVMyoNty3Cs3vEArigKstCl4q7MsuZif2gMyzRiWDYzdfM8mhCYohp1NaTW/WsTM1ha4oaGRXEu6az35pfb7fk26RWc5C1YJJkS9ssWJcDwccQKXu4HLy0twBgNMa6a2mI5mpUjX9s2/00w5HNhFz1gjISRQ3wTI2SLSzOlSFOcDQ/Rcvhp59/Yt65zwbrSFzDvGZl539FGVarlV56niKAjBCfuLiXEcETF/2yyXivcwTaGhnSq5pP50X/TsXzrfPznPeX/8Fn3G++MxLfqUs/6cYH7Kjb5fCXL/WFsu0xxNi4K2Sbdt58SCFDZrT6JRyykQo3oXVtZqJ+8fz/xR27f3ntzTFE3wVFtZcTNpP1q0OGlt5zzrspgZu0EKOzqpBXkUMoUheGJ0jFNgXRfEe1yM7HY7vE94l5o5qy2odTq+Ewc0/7YotVrBtfeOWq24uoMmfM8LR8c4Bry3COswmDCPQ2RZE8FbzrSU0qB94Ki49l+HNYK5Aeu6bAG23W6gAilXqxutzyugT1VCX6w5P/WATyF3vqagf4ov+5TZev73U37nc58/eS4t8kirSbRjne2P8zXZ/D8HVr/YoH0bcOCjLe9eg21zKhXzIZBS3qKwW+W+PmI52A42rdU1rYiBAoBtAp/8VkUqjLuRYfTEwXNzPRMQ4hQYRst1Aqzr0hYZA9ArptWdSMMNW2CslIpzpyj2XQukIlLR6hhjwDvH4TgDnPK6zVJwzpGdbmCIDli0heoEuQwhkNq5CTAMgZRbRNl5nkMN/SrC+aXja2vel96AhwTy/LvHNOdLjvESv7trOlCrum8vLyZ0VIuG9n15BRG/SakAWiqlaVrd9i13lGWfvOfnX6tReMQhMk0TIJSSqaXYNrUHne76op0uJOdMCIGcMyndImIAA6vZPLE0pDVBqETvmaaR/W4kDhEfAxIhjBO7i1eUck1xZUsRRS+EEHjz+hKVSCrKh9sZKcVM91JPwaWzgnPve/2rAmbGxxgIgIoyDNEKwnNGxEAS4ziwLLUFsExT+u6nOkvxeOfZTRNSMzlnSjVkVc2GGJJm6fAAJcn9ufMp4xcXzp9LUz63z4+rMh4X0KfM1+eE+rlzaO9O+cT+EgtJeLEoJCIseWWIBsJG79UItgisVBPGDnZ33m1pk27idn+sneW2i5wSh1opObcIbrgTHOsTVkS2AFU3fU/+qyN4T2yv2qBxFSiqTOPANA5c7C8Q540apMC0u8D5wLJklnkh52SBGRHj70mVdx9mXMiA21I6KORsPmatlVLPwfqcrlWk0ZTYZxuEsZWkqThUWimc9sh2bZq553zrhpwyIQ24wRaQ69sZwUAPtazNR/6641fXnL/GeEzonjJr7//+oc8fEsqHBfVcMBv6p5uK0sP8LZfnnCXgtQUNlc1eNaxMpaq2tEbzTfsGG83GCcdqJ84W9S35LNrZ8gKG/PGb2SpgILezcrDu9zp3wu66flVdSnyr9BgMjle0X7ljmCZQE4SqpwCQIhtAXZdMaEB4aUErminvvF17xw/3fHCHEhpMz3KTls5xdGOlKq0Y3I7VNaSZ464BLM4sjoa08j5gGrkSvGMIniF0EXpYOl/qCj00fpZUyueo8J9rPObjPuVTPiakX28IwZt/04MmIn2yC6qWJ9hPltuT9re5ZV2STUC0mVN2vm7L0QEUJw2IcNKEHa8nyglw7k6+qCo4Z4l/d8YhVLWyLKsVfJ/5d9454wMCg9IBqPmQg3dE7xFVbucjzgdiHJjGkf3FJVUhrStlv2dZM7pmcjmwFrXqkvZbUSW2G6RVybkYSCKY0E3TRC6FNaVmaudWjxqabywMMVDLCQYZYyStifl45Ns3r5nnI4fjjNCtByVq2Hxx5wEfTFvnzOtXr5jGlRgPvLudG7D+6+T++/jqwvkpJ/IpQZtPHY8BDJ4Szvvvz79/7Bj3Tdn71/QRTA9bvafgjB1PoVcRd53n6OVQ3eS18izXsbI99uDsf7XTwjWTuHPo+CmScmrIlpP5W7JpQB884zgSYjCakFJAlRjjli7J2QACog6Pa4rRUEnBW0HyEKNpnqLklBpgHob9cOe4vr0vuVBzYRgiF6+vuLrc232pwuFvfsf763ccDresaaUkq8eUdjPEO5yLVCopV9abA4d1bTlVx7TbcVwzxznhXMGLGNtBB0Z4e75jMErQmgvHw4Lzjov9jmXJVCql2D1MKVHrCaJXSyHnzLDbEYJVqwyjt6qW9S5bwlNz56G5cX/8qmbtz52G+RQfs//70qDP+XhMGB/Dz3af0PUi6JbQ75K7nYeAa9sF34QZjHrS1KH5d1W7FG/7c86geSFJywO6BtSuZAzU3YNCQxyoaowEqDEgmP9px6pqGqsHStSfcqJDjIzDYEn/Usg5mQAgDThviryjl7QW0rpy5Ja02vGhlZ05xzh4dsOA1MI4DcyH2VI92g10My8VO96aC3Vecd4iz8MwUBWjT8kJESEUt517UNdSKMaxm50j58IYIjEaLcmacruW0hBA0t6fgm09ZuCdEINjdS+fLy8dz+Y5/y3kMft4SZT0sSjsY0L5Eq15//jn9+2+BtctbWJR0OgtotiOdodky/w/8A52Q0AsjIoWg6jZrHekjuTpgRoxDpzLi4mUgmnEpgVKqRRfKaqEGNmNA3EYDe6mBmbo5FYA65woxczFcWiggnCqFY0xstvtrXA5Z1Ja8c5+H6IZBSIQQ0ArlJSY08y7t+9aWVql1kyMjmGMXF29agXXntffvuE6XrMcj8zzQhUleM9uZ7jcZVnR28MpTeJTo/1URByHxVIfXhqkrxTGwTOOwTC7wROHyHxcmGRgHAe8g+VDZl4S/jDz6tWlEW2vmWk3mB/uXAs2VcQJQxAWB6s9Qp4SmU9Brv13ExB6yLd8aRT2uQDQY5/fF8Dzz+9/1/91zgiVL3Yj0VvSO4wR5wJOjL5jAyXUQhAlOGE3RqgJhzDGSPDBfLaqHI4zBaWKULQijaYyOAjRo9FRRQjRNyZ100TDOHJ5edGgboXOuVVzIukCCF4K0yDUEAjBeHl2+73xvjb+n5ub20YErQQXN/s8xJH9bsL70Iqts1GH5IRIAWcRrnHojO8DwXskuAahc0zjiG/7W+dMzoV3766xdAkgYpq/1byu80IQx36MlHVpYAvzEwuRXBVZMz2v6hv3UCmFdU1cXUwsRcCtrCmzpoxzQhyCsfy1YFjJSpBAiANvrgol3bIsR6qWJ4XzU8ZnV6X8VsZToIbzv78k6PNSE/dxM7ZrT4BWyR89UwyM0UPwqAq1Gsqm8d3haiY6CE4Yo0eqoVimYaQUy0OOLjB444vNWlmbfynOMYZAaKmA6oTDcSXlTGxR2XEcuJhGlnUFzY0sujGuqwWLrnYTAPOyWnDEe0KIIGI5v1LMLystTxtOUV7vvC063si8fIx2Pt7BHe4hsaBSM8elMSuUnBsoolWNNAujVoPS0YADPjikNDZB1Hx0NXfAN9b6EAIibIwH2qPNIo3yhIZmMpBCHuCQjIIzeOHi4oIe7HaNv7eb7OM4MAyLUZm0wp5u/z4VIH0uePpvVnN+igl7/v4xDfnQTfocv/Mhn/OOKYNFOGMI7Hc7Xr+6ZKmFdckssyX3gxOCgwFPdLL97dXSFuM08f7DB7zzXO5G3OWeVDJzSsy5oGJax8eB/W5PHCIqyk/6gTWdgk/DMHCxHxGyweWqshuHZnYb6dWbb94QQuTHdx84LivF8hCWs2yVH2YuGxhgHy+IIeBDaEl9oZeCTeOA886qT/0tYPDBdV1PFCstUOWcY11Wi+Y21oQQQysXyw1D3GSgVZSotnyoGjjDS6M8CdaHJVXDLaue5oRzQoyR5kWQSyUGz16E+biwLKu5FbuR2+OCYJYP9HgBjGNkHD1DdMwfx4Q+mgPn8+spBfhvVjjPx3Pa8vz9cz7mY/t8bGxtDR4RzruCCUIlYLnEUio3N0eG/Z6qhSWvOC9cjAOXY2TnI0EUD3gq0UWGELi4uOD7y4noPBfDwH5/Qa6FlDMSR8IQUXH86c9/bhX7K2HcEV5fnVFX9igq7L/5hv1+z26/44c//7k1AjINHUKkKkzjhOKYl5Xb2wPX19cs60pKidffvG5aqTZNLYgoOa9bpNPaMBSGcWDaX/C7v5oAQ/tcX98YSfbW88WsgmmMxtmTEzfX183/dsQYuNhHMzGdCVFKiZIy1NrK6Dy73RvTzmK8R1GG7bnEYWxBKgPoG+2Bmd6dlFocBDfgfWQ+rBzn1KLTjvl401x+T3CRadix31VujpVKr8M9zYOH5tNvWnN+7YDTc4GelwZ7PtWMfc6cvbNvpHX08hvpcsqlpTGMmGrwsB8cu2gPyANeldE7hhi4HCMxjAzes4+Ri/0FBWsW5IcdRZU1Z9J+4uAWUq7gBT9Eq18UcMGTa2VJhVf7C4ZhIDrH1bRnSaatLEXSuIxyIqeVWrI1OYoekUj0jovplDIRdyL5qkW30rEO7au5kJcFN0S8OKJz7MZIqX4je9ZiHc5AqNkEzkkjGVNtlodRWIoTnAozwlIMFbVVwnjXigLMt43B6kBLrcRxtPOpFY+yISPFUAqCaVBRS/1cX9+S2hMspTCMgZKteVMIELxFbZ2ItW95RFN+ynhRVcpvyfd8zpx9iXA+pjmfus6nKkvOPzv/96Ptmo9ikDdL9ItzrGtqlSFWazh6YR8d0yAEEQOIK4yhCecUuJp2jDGwi4H9tEOdpziHixOH+cjhWKmXOwYnrKmQ1TEE6zOSUFwILLmSMlxOe0SgpMJ+mHAKiUR0njUb5janlbwuaK1EL8hupNZIrcrlbmqpH8P4dqa9LMVSHN63pH/b13zEo/hoTAYyjZTW1nBGWdfU/M3WYEgrQ/AspWz5WCcGG/TO4cdAzZXsEqg29oSAiBFh12qpHeMxEqAQGtmY9Y+pWxF1KQVRM6OH4C1QljMfrhf8OCDiWFPmYh9ZteGHfcU7JQar7yxVNjP5/vzoc+8lMvUizfm5AZGvPZ5C+zwnnOekzo8FgZ67zscE76Ho7P3fiFhusahswZBSLaUxzwmhMsbAq4sd31zseLMfyHnmYtxZYKcqY7AJczlFrnaRIQxMw8AYR3AeFSGXTIiRyxh5czGxrCtrLiylcn1YOKyJ9wdDw6SiWNDUhE6L+Z4Xg0fGiaLKECJDcOQ0EYRm8io5LYgEQoy8evWm5UkLYZhaa4PaUiuJXDJpTQxiRdZD9Lx+dcE4jkzDSEVZ08qyJtKukFLZ8oxrNua942JBopyNmvJwXHDLiuDY7/db+kjECsljND/T2gFaO8FcShNEK+z2IRLGqfXvbED6RtqlCs4L5IL1ToO0rORUOC6FZRmNTMwb5HKInv0usp889VhYq7DRWHzm+Kpm7ZegIV467ldYPBeFPf/7/m8/59gPffaU0N497zNoXS1IARC0lubfOC4nz270DDEwhZHdEI2WshTTnMEzBCsajl4a/UbPmzqclo2BIDrPFHdUICOMw4Hb44IXJb+7Zl0XlnnldgwGPPAO1czFdMk4ThyXFR+tbvFiN3B7e0BVGeJgKZoWQBmnfWu4u+LCYIByLFC0rLOlMVLCY/DE4D27/USMg/EKAUwjChznheN8ZF5WlqUho3Bo8TCMrD5DyizLQm9nmPK1QQ9FcK3dXwj2isOECKwp8/7DB5aUSWnhsBZevfqG7777luvDAR9Mw+fjAZXagl4QhgHf+INUsWN6QUuFXnJWLH01DoFxCMxrJhdbeHlAe57P46fGL+ZzvtR8/Jx9vtR0fc7HfM6svf/+MY35aFWKfQlNs5SeNNHepkDYRYv6heAYXWQMnuA8ghKDN3Ip14moWoNcauOzPGNjbxA+FwJ4q/B3AmPweFGOx5maV5IUtKz46JliRGvmche5uNgxDp44TohzvM57DvsJRNjt9uz2e0o1rldxFnFdl4WK5QJVxLThMlDyiubcCrKbgLZorm+AdN8gg2NwBLGgmdeKo5fRRRCHS9an5Hg4AEIRY233MRCGiPOmQV3wiHcM42jooJB5f3NDVWVNBV2OXOz2+BasCt6IrPVwRHGo9C7eEVVvvVCLtjSR0GDRgNWW+tbdewhWPypn6ZQ+Jz41xvKbjdY+5Vu+JGf5kFn7uYvCcybsk37m2SilkB0b/aOIgJq5HZxjCsYUF0WIokzBExw4Cs5pq1cE6LQgFlEUbLKgSnTW8MdJbZA266KlOPzFnm8uL/gf/+Z7/v7v/prbw5F317dUEdNiw0ipiWm3Y5p27C6vLKJbldowtoqAC4RhRDHooDETFGpOHA83G5tfqRekdTazNudToKjW1tezUurCuqzU1SE+8O3lJXvZsY6BWi84ritzSlwfFt7fLhyXRHCCFEPxzMcjWSuDgATPEEf8MBDiYCV1PuBjZIoj0+4I4vE+Mg0eKPzh9//Mq4vXOG/A+OOStjIxGgSxswTWFhcQhJIKpUASpaSENI7fMUaCeKQ6am4FDXKaO+cW3HPjNyuc98fnBHy+xISFx7XhS/3N+9v3dnad+Q5aJDQl8AODDFwEz84L0SleFKdW6eEFY+YTS5z7xstqERMzq7r29d60kw/eopAOJDhcaV28qrIfBoYQuLy4RLzHh4gfjKe2N8uNw3Rq9ZBLK3LGtHAMGG2I0alocdQAPjfyLa2gjsUFUobFG2hA2/40NsZ6hHJh2F/nHSEOjF5I2XKkSx5IpXC5W3FyTWwtH3yILClzXBOHw62Z7jlTYrSSMzDaTDUg0jAOvHr1ihgDNwLWGtCeTyqF1BgAc6uscQrTMLDf7/DOkUtiZW6siCecsVXoKbUktPZFVPGuNrvo8wEuvzng+1Oa56EAz1N5zKfSKM8d61lBe6G2bCdg59zOO8bQuHpsktBMt8E78yedCaPlRbUJYwv/6VktqCpSbfaJgBNvPDittYFvrRJEFGvsJdRiTXglBgbxhsYJwfh8gqGVemMh76MJZK2oc1v5WaXheDEBykAVpRZPjQF1iha7YkcgOBCM4tLUp2uLSjsn4ra44BxOA9HZd+PgyVUZY2RNFec8RQVfFB8LEgK1ZpaUyY2JoFR7jd4ElVKs3d8QKcUYG3I6FWnnBqCoxQJWfSkVEaRz6OvpUYqF3Btu2ATUkEwV78VSK0FwmS3f+TlK4hcXzk8ViJcK32Pb3P/+/r6fE6yn/MsXCSZsa2eI0WoZdzti8A2MDYM3NvH9bmLwjuCkMSIIQYwsOnoTDoqiqVDcio8RGXrNo1FTGmRONiCANoF2eKILqFhFiYaIuID42FjnLP8p3nKI0TsCnkVXKuYTltoIKyU0X9ki0E7r1rov7HaUtUPvrGojVQdqGFWHs9KxXBqUDmg+qgl+JURH9cEaDoUILT0xTHs+3C5Mb9/zh5/etUIAj+73yLywrNZUOKeMOMdVCByPR8D8YmpB1BrtVtfbEApLSm2dEF5d7knJEEg5Jd4t75oZaucVehosGr22ASlaZzSEkmA3GbvfWqxPS+3gintz8DcTEPqc8ZT2e8ycPdeoDwnnYxGz53KXT/maL72W0PCmJUMtS9unhdxFGoO6nIqgfQv8hHYtQ/QEF9iN44l9QDjxqYo0k0yhgKog0aKQIQ4Ye59Rjrho9q6ilAZrAxB8KwL31uuypR6CIdZQOiN6izyLo8RAzpG8rqR5xoWCRym54LRFW+OwFXVLVYrvC4qC6/3KTi361DkCjhANCVQyiAvEaL1TjiXhjwsyp4342rfi6qLKcjzyj//1/2K3N/hiyYXgrMrn4uKClIwPKOXUmA0BlPW4MgwDgxdujkfLYwoMYy/ctpyta1H2WovlasXmQ5lvydlAFDYXX94u8P74zQrnpwR9nnv/0L9PRc+eguB9jmCeX5MxqhvVhlVyNGIquUdYLG4T0v47i256nPcbmVVf/bf+my2KKHaSSPu+l6iJAC3VQptQ51FkTYVaPcU7YyKwI+BUkY0Tt9iBelSSejK/G6V63z+qqLCBy/uhKgLSeVfapu0nndLTiWlZsAVoQMiD5+Ji4mI/UTFQRa4tTOOcBaaWRF4Ty3Ex3qBGhUIrz7OO1dafU1Nq88VOIOdE8WXr09Lk3hBJGzOEs+yV2t3xIZppq7XRthiY/sQzrNtzOp8L5/8+NH5zwvnSgM9zPuf5d8+NpwI891/3t3/5hbXeI04B83Gsx0dl2MVNc1pTHRNC04SmDX2DozkvqNCqPlyrrDhpW0Wt1V3TvOaX0pj12GBtctZoW1y71lqs/KwtBNNut01IzdZGoVQBV1qUybbrPptWY1THCeIdFPPFnFaiE1QsoKTO/GDjDzphfTv9ZcPRIS5s+3ZinciCFy52I6+vLjYS6Oo8PnqG1bMsM/PtgbosDN6T5oWSM5OAH2LzvVt/0WZKO+dbvhjmfEttNa3TGJHWmPdit7f6TbEgWC653XtPGKxTuFSD9e2LLRw/3Rxa17JTxPa5OMj5+M0I5zmS5vzf/v5z0ycPHeOhvx/yH5/7/uXXBlqMYtGHgRBH5lRaoXHBu7H5MhaKH4J1vfJOztoGmUCGEAgxbARVpwMYWJxacCFYcEesNjSXjE9CGFqbgdC7h1mOT5wgLpp5HEY6CVcIfjt2LQV6Rc0Qe1EbSIAyGypIaot6tdNp0WknLdVSGiSvtECXanNUTw10QbdO21oTW3imnvqf1KJcTgOlWlNcxW2Ul6VUYozUCjfXt4zjyBAjl5eXbV/CcV7aQmad1DpLvogyXY7NR7fFchqHjcQsrQWjaFGOh6M1fpJKLa3WUwSRXv6nG0WoKncIqvt4TkB/0S5jTyXqnzNDH0qNPCfAj53ziwADT2jJ+wvJc0OaJtBq5mxquFFrL3cCE/QJur2ceYCbDypu80PlLEjvNq1qCX1pNCLGWNdOYCtOptu8dh3V/MtuXlpzoHaN1UxN8zU9PgYj6RomGi87xmFkYHWzUnvNlLYtenTZrABtYR8zs22braeosrXl0/NTbQbidv9SwRHMspDGSdSCZejdSd9Jyzb11W+a9F4tAc25ma9KJFrbRQVDA9lJpLRSat3yzCE4SjGTebs+Z8ctla1w3fLr9+fDy6y7r95l7Et++5yv+KkR2ocu/CXR2ec06OcM5xylWmHyfJxxymbO+S6McDJjpbX0c+Z3mat42rZPCNOElgbpFI/iHdJylSpNwLrzBCZsaqgiLeYTUivScoi1mPbqZd+IoBIIww4/GB61yQGCmHAmoSZF1G2+Zq+y6f6omcJKpWl5ba4rfe3Qrbua+QFi4qxmAVStlFxY5wWNDtGKVGWZZ/KajV2PZi2JCZClVgy87ru7EE6R2t64qUe4cUItrfRM2uJTC/M8m7+JLRXjOFCyULMaKii4dr7OSKeLskH99BTjeEihPDa+ChPCp2jR5zTm/e+eE76nzNqHorOPndNDAnnf1/ySUWshF+OeyVmJXfuJNF+zlUE510izfDccNw3i7fljbHyt47I4S2PUSnbKbhpawMj6kJwLZ4fVWYvBlufzAs40VakFAUPvlAK1V4cYhYn4iATLiyoe5wdCnIDW6LdU+hKjGEi+NCaDDlPs/TnBb3628evWfqO2FIsEbx2zVcmq1GpMg7UKx+PKsljifwi+sRh4lnzW5cw7cimUeaa8rewv9ux3O/aXO66vb4ygbBg5HA5Nu/Z+fq1Y3bExuocQ2O/25FK4/nDNbrdrTAuOb9+8omplzYXDMTXgfcG7xepnz+beuZD+Ij7nS83fT9WYz0Vjn/NFz/99iYA9pTFfuo+nRi2V4k0rqZhWEOnmEFgsxxjJLS5y0qhmPrVrtb01IqtqUVO1z3N2uGayBu/RRjLtGgGYc94ABLWTgYG42DABetJkLRBkQVUHrgmnN+BCL+XSbPQlW1/RBjo1tviAamnN9zgz707PzAJj5e5zbJFjE1IDkJcqW7UIWKF6ypl5XUg1Gc8tlRgHUi6IpKa97Z6mNbGGleANgGC1tIZuCiHQGburqrkSjg6S3IRTnBi7tpjJ28Eh3ju02MJznGfm2RgUtqbEZym7p1yz++NnDwg9N6FfYq4+9/lLV6Lz83mpFv1amhOsyHdr7Npwsc2SapagYlP5NCmMSd1aG9yfwEql1A4hA1RIJeG1YXdDADUTVxDEecQHJIQtOGIatU2DagTOYpXNRrHprbVgUAfekDyINMpMRatp1lqr9W7Z9oOBHBSknjVaaumH82vpHc96AK/3GK2bFtXmx2kDQji0WkBtLZlcLRBUaiXEiFuWZn6akKNQct4EdF0z3kcLluXcAkgZba3oO05W62nR2FojYvfHOysgcAg98pxz4XicTUCXtZWfneITz7lc98evFq196uQe04z9N+dplM5I/tg+P1VjflG65AXHKS0g5CWcKks4oYBiawDrXA8WNUSNNh/G+cZS1ytSBC8WCVTYUhMqrfktLZLbAOriszXOdb7lOz0SejhImh8cm8AGwjjhfATxTQhLS4+UFkHN5LUJKtn4gFK2yGmjj4TTPbVn5rdndc4er2qF0lpM4AuG4y0qLFm5XVbmXFmKAdqn3Y43zpHevWdON9zcHnHjjpzzdlznHK7FvfK6MguEEHn9zevtnIZhILiASOV4nPHS0D5ZGYZxK5o4Ho/UWtiNAxd7byTaC1xfX5MyzIv167S2gLWRsD0eH+mEZo+NX4UJ4TFBO//uJYGex7RrHy+JxH4qFO8l+39q4TEUjDVcdeIYQ2QcAlN7dXOrC6Y7e5DdoHXSO2nRAkW9+7QJpbTorY/RzFo1NvJawdVGh+IMeSOuQiktqqmGitCet3QMY8KHwfKJtWu0ZvtuuB6LDndiZ6kW4BGMqrM2Tc5mst7lXjpPM5S+AGihiqfUSqpwWAu388qSC0uurFVIpTC3FgwG6igsxyOl5yCdp+SeglFwxl+b0sq6rlu7iVoLPgaGEChJzVfWQlHdrtCoToqhpYKz9JBWqpp2nZeFdx+OvH1/w3G2es4+F56as0+Nz2ZC+FyBfcpUPX//0EU8JYyPXez9oNBLxpcuRue/f+i8KhZBVDU2uTGElt/stYDNTzy7Xu/cmbBylko5E94W8HHBIpJuaNHaqmgyM1i3PKMg6pCqVrWmrfqksb6jlareUiu1krV14lbbH775ySIGemi+oHfNjNYmcC0itcHy7AadkWdzZqafNKkhl+x4qSjzmljWxJorqSrLmllyZm5aujMG5rS2hbY9e04WSweop5RI62rtCEPYjmectP03zQ1RRRrkUbAcp3cW7VbtFoMwL4kPNwdujzNr3ppm3xn358JzQvrZZu1LJL+Pc4f4/u/PP7+Pi/2UVz/O/WM8hp99CP3zGCLoaw0RNrIrKakVPzuupoHLKbIbQxM6+y80YfXtGgfnCd5Bhd5JWpr5ayFZ19AuAecCMQyNch2GoVWXNPoQ07QgNMR6VQOFU5HQgj9xh/eTmbS5ULNCMUB4XY3yo1YTZFs8eklY07DacouYRu+5Si0tgNT8t7Y2tLSHtvcGql9y5pgyN/NitCrec7GbWPM1tRTWZUG1uQXBMS+JnCqldHKRLuSWhy0JVoU5HNFaGXdWpXNTMreHA+/fHXj16pIYR25uDhtuFjHLAC2UnLlde4rHzNn31wd+fHeNGwa0WH+aHjd4qaa8P7647Xwfz0VsnwvsdNPsJebtU5r1Jef2uZr0y818e5i5VAbp/LXWhn0YmuC1Okho2NIGLXNn1+Z7Z+amMbuWkdoa6TYtIi2X2E6+tVFoYeHWLMkZct62bV+JdxbMGXaoGuIlugLByqpCjI3Z3My9krOlUqrRkdQmgLXWZiXUBhQwjiIjNmuABAE65LAqPalSVVhyZc7Gx3tMCSGgpbLeHlGFGAYudo7DupCz2xbjXDI5VzQYmilq19B+09IpGeBdWksJMIs+bMTVdo+yAXfxomYBFKXklbyy9T99l1c+3B5JjZqkVrvfAh/Nz6fm7/3xycL5OX7W/W2eM1sf2+YhM/j+sT9HcJ7zTb9k3DdxtU1WCUIInt0UGaMJqXenNIJw6pnpfDNna2u14H3zO+0+1Bbt3HIVZjua1WBHbogh+857A26L9K5kLTDkjDFBWrpF4kgphmwSBZETD1Kt3V3ox6yU2iyShpk1zartfZcQWh9PtkUFuvXbMUOmZXMrfi4VKytr7eaXZE1xnXOMcWDNeUPn9MqXjjSyOtG2IIi34K0a0qiUQk5583m76Z1Lb+dnDYy0GrVod7O1mJlsEeTKzfFoGrtY9Pz+tHlICF+iTT9ZOF8iCJ8CXnhOI75Ua/ZtH0uDPAYyOA9MPGfOfhUzt02MMEQudwN/890rrvaRKbqtoLq7cqbZfBNGC9k7Z0zuMQxAL/eqm8/W6TYVI9jyjR/XOd8aFVmToNy6WYtY+sSJw4WRbDataVO1/N9mqtYG2pO791acM6YFPK40OpjNd2taPFgdpKCWpimuqx6gbr1HVcQ4eFGyNAB/CFxd7fnw/oYlJ45rglZONowDYZ035FSMgTVXRJVUKk5ya0DsaVEs8xPFhFCXpUV2beFMKVmwSGzxnOcZEbiYBgIgKnis5tbaARqr4XFJrLlY/lr8R4HOx8bP4nN+6gHva79uxj7mZz702UtM2sf8y/7vQ37pFoB4Qpi/xugBlVoL0Q9MQ+ByGriIgaEJ4DBYQfZuGpmmaRM2ESvb6v1H4jiZFiprA113HKeA8+DuVvgHu9gWRhKUvGkP8Z4gnuAtCmuRSciNXNpeCVonaQM/nCKsnbrDBNchzgReS4scA+JbgyZteFvXulE3RgQtreU7ltPNtTKvK4clszaunh71ndcVEdfAGjYPpnHC+YAPK87N+LBwnJNRedbKMI5m6qJUx+YWgC1iIt3Tb8Eew2TZoqe1BZA83tvitqaFqplKKxqn2TsdvvjAs3/M8ntsvFhzPjRZP9XJfUjwzt8/9tlzAvzUeEgbPid4P4dgnu0cVBuxtK3A0RmjnohVSYRgL7cJpttM0E4+5X0wqKpXamqt1Z2ntKip1UbqlgbQqmd+/eZe2qRpUdqSEtV1wRMzIxt8r5ZMb/NukU0z+zpOV2uvJmmC2qKlVtcpxmbQ+4q2czTbHQTfAkam7dZcWHIhZQO5r0VZeya2U684iwBbsbRDxKA7MUTGwdIgKRW0ynZfa0kNE2yCTj2bQ7Zm4VotXTeTzQWwKHDcXyBU5jWx5kQq3Xy3AJZ0UAcvE76v5nM+Fwx5yYT+lCDPfQ37mO/50PFfGol97pzv37ivkmIRW51jE0wBE8jWZSsOkRAjIZj2E+m67qzYuvmHPlhb91Vr688ZkAYWUC0WdNnM9hYQcSaWXaPVliKo62qM7C7ifesMVtg6fRVNJngCiNV3dhWhCloKWgo1FXr/UasbtYiyEwzJg2lG2jVttCktUDanzO2SmFNuyfzCmitzSex2EzGG1ijJ+I3WdWWYRvJSmZcFH0aGOFh6Y7Y28s55htFKzDqoPa3W+bp6A3X0Z2tNjTpAQAjOqD0P1zdc7L5hzSvvfrRcpq1BsvmnyGkhvT+HPlWRwWdozscO8pzwfqpgvsQPPT+37m8+JHxPCeTPnT45H67x+3gn1lvDGy2Jb0TLYwh4tZZ/XXuiYhUbmyYyCJ56a+unzbRTbeZlsMoPg8+d+lyGcYfzBgWqJRm0r/UJ8d66WDsVskqbXK0h0BgwIWxNgBocLjeh3fKStZqA1lMKIYST/1tr637m7DjatKfr1J5OoQWinA+4quQlnUg+VEkpg3NcXl5wmK2J0jzPxHHYGOaXZDUvpdZWI2v7G8cRwbEsK7eH2w2VJCKUFkHuLgQb6MAZWovAOAzc3B5ZUyLlyjynDrJsTAxsxe6qz8vJY3GT8/HiztZP7eS5pHv//EvzmE/t/zHB+llN1M8cIsZTG5w18gmtmLdXprh+36X7qTYJetWlmoN5AuW2CKp4t1F9KDScrE1O8UYubU6vmbz9tz4MaKPadLoFe9vUa/f7LAKMmuaVdl5nG6C0fKCT1ml7+wqL9Nrp9qoxvJVsqYihmaQvDgZ0t0bAgqBG4IVAaxtYasV5T2pF1j0K2xsJOXHtPRu43ntP9MFKfGif+7BFiUvJLUioRPW4YIVzIRrjQ67VSs5EqAXTxtXOF+nR9vvP++PA5UvGs8J5LqAPjYcABg99dx8D+7ka8/7FPeRPfqkWvH9NX0vA7Zy6KWutFYzF3QRz8MIYrclrqZmqsWklEwKDCBhovnGeYP6l9RFxwVOa6dnP3qpDPC7E1iazmFC1oA/O4+K0adjeiKhrwB6ppdV/AptmRGRLgZhESYMOGhODSvN5a0+j2KLiEKvpFNs+19owFCcu235s57wRcErleDACafGew7xsbsCyrK0hERiyySKyzrmNbULXleBC+421l08psSyLMUcUaSZ3br1GK9TQMNAQoiPVQqUShwHnEiln1txQUzwvdA99/8U+51O+11OT+EuE8TEz9jk/87HxmFb9Jc3aompt5kPk6mLP1eWei91klRTBzNSbtOCrx1frGmaBFkAtpeDVekh++PC2NQUKTNOuaUdPXWd6c9gYAhKivSRQ1yOaV8gLPdHZo5O0guairS8IShgGAxSgaNYtFaMtqGICJDgXqJ5G7aFbIyPXCo076WXXmLbAYJZBi8JqsR4oTi1AVry1lChNOXcfPC2Z25sDMYbNEjscD5TSW1q41mW7uwBm4q5rIrd6LxExq0Jao16tlLSSVzVyNd8Cbyh1XVBRUIvKFsVa1/tAEZjLSuq0B4+Mh+bycyYtfEWE0EtO7rHXy6KxfXW2YQnsj62Il+Q2f+6Uyf2xXQudVNra8Q1ejHJSLHVQVEnV6gsDUNbTQ5cqrDdHnJsJ7pbdGBliYDdG8NYCIDihdn9OTUB881Ot4U6i5tWgMM0fRYRa85beENdSJFXpnOWdwaBrs3ZR7dmJaVQnKEan2VMrTuLGhG7MAtBtXBE2ChSw8xVVgneUCsFZPeq8FNZinapDcIwy4uJw6vfZyvDMfzUT2XvrdXJ7OxMaBxAtsixCg+EpXl1bAOuWWjEMbjdRreqm13qWM+Gs7f52c/q5Z3///VOf9fGLC+dDnz3mJHfTSbZzkdOz5LSCb6v5PU3a/30qz3n++c8lqN0zc2LtEobBt16O4GiQr2IrswgEhYhjJdEROVKFeV1Mq9XKt1d7dmMklxE/7hklGqOBnu5NVWNMoFWx1JKoxXhYnYubz9qF00mr98RyiKrGxaBUqshmvrWHY35la6Dkmi/YUwuobi3gLXpcT+k/MWih+Xndj7WvNuGsRjBWjitryg2MYP1kdt5K3npASNv5GHDdFkBPZV0WXAxba8DuxzvnjElPm0CvK95bqV5KK9r9ecq2sKhqy8Ge6kpLqa372PN+5ueMzxLOx0zLh8zfTzFtz7e7//7R0aMXPC1Yv5bWbAcCMU25j47Xu5EYIkWFd8dM8WlrnVBLRRZFJKM+GM5UxIS0VVaMMbK8fc8UI68vdmjYc1Ede/EExKKeTnDDgAwDChze/0hZjyY0IUIwBj/BghrUQtYKpVLVYHxh6HBDWNdkz5NTVNKKqEyzOgfijK/VZWdplWIgca35LLDUopnOAi2UxuG77dvhnBK8sB8HfvxwQy0ZH3fG3oeZmMt6NPhdzgzDQKkNcCRiJV+lcHk1cVgX6qJGqo2Z8ClZ1rSWQs1Wg0q0udCLApzAFC0GoLVynDMSDNWUsRxsreBwxjrIx8qhLwh9Dp9/Bs8L8GcJ50uis/1EPkc4t383ctUe4eg+0tlNeOL8n9KIv5Sf2YcIW/rECczLwk3D17phbIx6WM+PvNpkE2+lWc4iqqEB4P1S8HnlcmcooqUUYqnEUhCprc2eh2hRWEszLC1l0TzA2sgtW2CpFCXnyppWStOYPtkzrLVwc33DOJg5OURjODAmvLXlYB1Omz5sz65oaULoNyyvBYhawKmZhlb/2Zv+tL4vzhakGCIxAt6RitVJOlesqLtVv5jJXqyNgp5cnp5eKbWXutU7bpBi2j00pnjVym43YfZvQXDGMK+eJVX8MKBZycvCkqz5kT7TIPchs/ZcWJ8an4UQekggHwsG9fefKpjdjG0fPHy8e0K6RRcfELqHcp5fazy1AmozVS1C2zSLwJJWbmdHCAPjlPHetNi8ZuYls6ZKRYxQy3tirAxDNPxtLYSyErynIIaqSYmwenCtLbx41PlWpmUIIO86l61pK9cEqSLkqqypclwSqZj55lJpEc/M+/c3XF1dMo2C8xEp1cizGuic1nFMmh/Zn0cHO1j9qmxmN6pbB7P+oWirrpHOd2tBraGoNUuq5Sxl0moplQ3sbhUyjQmCljWqlZzvmp/352bvp6ko4zA0qKJdgWvPxQqzrW1gzoY+MvKuemdfDz//p+fHY+OTEUKP7fCx1aB/fh/p85iAdh/zlAx4fJxiCV2QFd1KmR72Oe/8/isJ6VNmSg92OWeU/sMQiMPA7VJIdaGox8exNWS1Ff44r8xrtm5ajbZEZGEcjZ4kABfR0iPTxZ41J+pN5ni4wdWVy8s9F5cX+LyHmtGSUHFoAyHktJKT9aEMMbAk41lNGY5r4bCszGtizsVoHnPmw4cP/NX3haurC944R54PSC0EKl7FhMKczc2EtUqYYKby2giv7Bt7dsYQTafPBEW0ILUgtRKpXASPlsqHZbZmQb5HoiMpZ5a0bvdoGCLrOpOrpVOcH0AXM12b6ezPEEH3FY5zULVYA14sOJRL3Yi0D/PK9e3Kh/cH6zeq+pTS/Gh+PKQgPls4+8R6TOBeIqSfZtaea8vTmiT9f+1wD92Sx7Tlp2jKL3HiP44un38HWwjfTgznPMGbiegbkkXE4HaXbyZijIQ4tGY7hXletq7Q0Tte7Scud6PlRa0PAupci5g6arWqC6lWoSGdB6ix2Zl/qaxV+XCzkDPkItzOicO6MK8rN0tqC8XK4Xjk7e2B3TTy+mrP777/jikGojiCYuegBuHTJqSd/0ja8QzT2qLI3qNaoDGi2zNqwHgxUMY4OC5x1jc0OrIuLGvXnpWkSl4zrrEZ1FJPxedVmedlw/P2OWAR1tJIveoGTrDvrBQsNtih1sy6JoL3xDhSD4mcTWCdGEifFmQ6n15fK5D6IoTQpx7sfiCo//u81my/v78/TgK6pVDOX3r+188ffX1snK4VPtL8IlsOzXvjDtqNA5e7kav9jug7JUhmGgd208gwjMyrtbY7OiPvMvPYsRsCg3dIqTjPBgPsBcXafEJRi7e61v5PW0rETD4rOTsuK6lpz5vjwnFdWdLKcUlcHxfmJqRrqRyWlTVndvsL8jgyBs/gwWk1qsxmQmsjag7ed5rnLTpbqQbhw4QMcdsD7kANMAjj1PzkpVbGkNGqLPXkKliGzRKoFndrvPKNWY+z2Mf5vDBN6TaBPQGdTh3fVI1lsCDEwfKl/XWakP3KHh/nGvOxzMRD40UIofMD3P/+oe8eMofPEUIftek7M2Xv7ekjgd3EUE4pA9q/jwV+HhqfG7F9KoJ9+up+2sgaEQ1DZDeOXOx2vN7v+eZi4m/eXPF3v/sdg/d41ebv2I+8FxYfSYMjt56PXcNEH/A1c/zwjm++fUUMwbCs1RMbqqaWjFO1fGIYtokkOLQYqHxJhTUra6ksa+X6cDCunpKNNwgPTqmSKXhWdRwy/PGna3bjwn4YuJgCQZQgxq+T1mTlZnllHEaGEJhiPLE5SKVimNxSi/nVDlRdo5O0exjGqTX1daw5cxsMMpdFActnTuMOF0aD+rlC8C2fWyywBrYgIqFFnFtzpbM5uCyLCaWjwSitV43SmAClUmpmKZWlFFLJG1j/XujjwTn1nEv42PgqPudzAvyUttS2+ui5YG6H0vM/Ph4vWLXOz+uxf186nhLMeye1/duXnarKNAxcXez59s03fHe552qKXE4DpCMWg1D0bPsfbhaSmpZDLLLrnSM4z7KayXVzeyRVZb+b2E8jl/udsabnDNlZmgLBO+MnUjUAeclmTjoXGEaHukols5tGQwaukI+L+YBacMCyJpY1c5wTx8PMbhi43E/sBs8QPGP0XO531CpUdeTqSEshrEoahDEa8F9coFQDjmsLcOVSSaVYGujc8mgtF4IqO+8getDK5eUr5mXl+ubI9XxrbPPd5xXz8U0orXB8QNB6ML9TrGkUQJEGs5Xe/gLGIAzBEYbAshaWlPjp7ZHbg1XKhBAs/fSCFN5j4yVz72cHITwolHeCP2e0DvLxpT52BpspuwnoA0vYo797+Xjp9qd7pafL4/SvqPXU2E0DF/sd+2lkiIZUWebVgkGlsqzFkubes/qR29kY5o7LbPT/TszXU2sE6wUkHFlTMSZz59AYoHrGISDNBNRSrGaydhiabnlB7z2hCjUo+2kkeCtp02pt2EcveFFSNoRMVag5kwSOs7AuyjhEpjFa+kcLaKGkjMdaRliZZyQERwgtoKBWMmZ3Tbfoa4cfdpNT1c5jP7VUztBQUd7YCOaUmrvjWHIxLYic/MIWle4EZL3vb1MNzaqz+6nteGBCG7yQi3EJrWsmZ33AY3lcOT03t75KtPb+549pyYdSLh8LZ9coZ4IKLwnQPjBaiLxBrJ7Kaz719+cOW2seMWmb/9IDQbsxcrmbuLrYMUWPR1nXxFySpTHWzA/vbhjGkd3lJX/zP/0PXP/wnh/ef+Cff/+OeTniRHk1jfz11QW7GNlHz5pvuR5nLqcjVZXL3dBe09ahrLbEe1EDmW/CibErmN9ofqzWQCmZ3RBIaSXlzGFJrNkEdEmVNWcUyClxsywM48CujBzW0ljsK5oXgjiCONYQSKU0jl5vQVdtPjJQ23MsHUzbQBel8dHG4BmH0aLOTrhdEjGYf33MBb9mXMpcH2YLGIqlcbSc2r4bQwNYYXbZFvbOQysYGD755oYEIURPVHA+MqcjS6qIhI/iCvcBBqf58RJr6+Hx2ZrzJf7m+d93tOamIZsZ90gg6P44j7htec72uu9zfor/+bnjdKkfOR1mFZy9nCiv9iPfXu14PY34oixL4sPNyu2SQK3F3266YLi45OKbb/kf/+//Dz6E3/NT/QF3MzMNgbLM/PjuBokXvPIRFyd0PXK7Jn66PnC9ZN683vHtqz1XF5eW6hBh2O02ztqUlDVZmqSoopoouZBza6tAaySkMMXAFD1TDOiG27U8aIezraVQEArCuq6sa2JNiWVZmwnpuZwG5pQYvGMaPBdTJDirZ6U3C/KB47q2e2snYD0uG7FZr5xBmEKA0abOmis3hxkOC947crb8a0rWalGcMI4RIdJzvM1X2GhHe6Cuth4yOcNNWYkhkCsUldZECbQRST80vx4Khp5/fx6Yek5Af3GEEGKmlD3lLzWb74eJntjyAT/zS4T1ITP27EuzCzbhtKqKq/3Iq93ILjjmVJoWMia54ITBO/bDyO5yz8XVntEJu+jZjQZwr9WTsrCiSIiGABom6pIatWTldkm4WyO06poRJ0g04AA1t9ylBYRSI6kq+ZRW6NFTq0hp7RRUmrnYOnB329A5KoO1gBfHvA7czkecSGMeaPC/YgCDXKtRSJZqZXLBETczU85iEHqHrLqz4Pdn7YDoHGM0X3dpzBLjaPlPkhBiNDhee9a9xUUvTXPdqukLTrsHjh7xNuxwrkZsfTc78PCceOmc+uI850OS/9Dn59+d//Y8Envua0ozZ3vIZPvNA/s53/dHectmlpyL5ktuztcQynPhvP+9zbPTdTlnYPfX+4k3FxO7IByq8eWkogzBMXrHPnreXIxcvdpxeTkR1iN7l3k1Cq92kVIda3HoGJimkWHa4cYdUhZcBV+FVOF2zni/UrQRIzjBTxMsGYqSK6yptABP4nhcW6u+yhCNpkTENf800wNzvXW9+MAQLRfpg7feKz6gzjMXGA+RmzAjLjDPa2s4ZJo2lcqslWVJDMEWnv0YGrZAAXdqoKt1S6u4FijqQHkntkgMwVvwpvWX2Y0Dy7yyuszgB0QMfqi1GhMDbP1NnVh6q6ojN8RTaogn543eRLFFZs2ncznlYz9OhdwPnJ5bmJ8aw3mafW/DttqNu7Pze5HSh6K5D5uyzdd87JAvdq5NJC0Q0N6fHf9TAQhfY9yxFLYPbRJ9czHxZj/x3cWO715fsczv8Bq4HC4ouRBEGZxwGZULSezyLeGnP/B/C4Xffef4D8MVw/CGqsrhduWonoQnVQfFczFe8vpiYBgjJa+IVm5vrhlfXzBME2EcqVmNrDllbo+J47xwOC7cHOdNs1xMQvAGIFhzYlnXxuN6Qsvsx4nL/cQQlVghViV6K3W7iBPD5Z5Xu4nvvrniOK9c3x7559//CTATdzcOHHJiSYnjklimFijy1rnb2gm2fGOjDxmGoQktOO29TwzCFxqAv9bK4fbIECL+MnJ9WPAxUNVa/Zlgm37u5vYQA2McLH20JnLJXOxG9tPA1W4glcz1ceaH90tr8tviG9t8/3gun8/hp0AxX6Y57xz4nqaQHus6+6x/tWkXQE69P2yTryQom7rsps4Dm/zsQnm2ON379+wkAPPdxsFYD3yruBiCxztlPqygFS8wTYEQQMjk+QYnjp0T9m9es7vY47ynFPjp3QfD4aZKycp+hFd7x3QxkpORfHlvpl0YRqPsqLWxoVuN5Foh4Y20uWmrUsrmcizJyrVSLszrijrTYEtdmZ0jlsgYIS4wescYCvud9UoZfaMEcSNDcOT0LXOD8ClQizEupGKs8ENo7Pcx4PrirhDCCUDQn7eBB0rrSdoYCxtJWk6JqlaknVJqmOVuvblmsVvkPHhHdEKQym4/El/tuZgmptFYKnbDwHGeeRcHPtysHI8Losqx91f9jGzGV8tz6oMHP0HQ7hqk0HqHn2/atu5OhZ7J8WcGbPR0mO619iDFQ6mUXxoldD6kXbMgTEMgBtcig7CbjBR6Gh0H7xswuzIMoU3IQlmPuDAQfeTq1Sv2l1eEYbDUh1pLumVJpBKYRsd+57i4HMjJm08XPHEYCMNgwlmKtUWoZtoWDFrknTHtSS1oqeTGfrCmtJl785LQEJDGTF/VE9QzF4dbV0aByWfAMY7BopzeCMKGGFB1XN/eMK9rA9cb4KAUWzBSdIwacAKhNaa1oJo7tZzQ7sM7RDoJkVjbCu/bddTNXSilsDUmhtYIyvKZ0xAZvCN6YYyOV/s9ry4v+N23r/FOLW1F4HA4svOB65uZ2+PcAlDaKEjhIbfmoffn46XW3GeRSj8eyjn7tKt2kU2aeoh728knH/gEVdAmpNq6WHVf5CGT4WuYt5+b8xUgOuG7/Z6raWQ/RkvW72wCTpPjzW5HzmUDFjgxKF+MjhCtbGkfHE4rNWXWpTBMVwzjlQVn/sdv0TKjZeHV5SvykiipMIwD+/2eYZwM02r9EohhYIhKGBxhGMjjSJ6PpOVArtkAISKmVVwgBg8u8MP7W3bjBf/L//q/8u3f/g1zqvz47oZ//i//mXR7A8uRN9dHXu0Cl2Pg1T4yTSPeBy5Gj3cXLGliXBI3xyPLmphnmI8HsipZIcYBnCf6LqAOVdcE84Qys54q9lpyItVMdcq4nyjzSqEwuQByiowG5xhj5HI38moXeXO556+/ecXffP+tkXgPkRggpYW0JuZD5vUw8d3+kis/8Lvffcc//PCe//d//Vd+en+zdQv43PFFZu3jCIDHtOoDP/3SgOz9Q+sj2vCRa3wov/mz+KFy7gTonc9d8Ly62rHfja0mMjIGoyDxwBA8QSytMA5+88pzzmi1wExJmVyOLaii7C4uDYuryrxoKz0bSW1J906YpvFUq5irRYRDYDdWpqPRTnqn/Lv/8D+T5luO1+843H4gJTN9Ux6oLuDCwN+9es3/5ITh8pLv/u7fsfv+e/787pblxwPv5oSoEOLEf/7pHUELk4O/f7Pnr799xcVuQnzEqS1UuyEgjHbdXhqbpwEsSq6k9oynGNEWFVY9ET0DrVeJ0ZfkWtv5Zqt99QGvYqnMBrgXMQb83TDwzdUlf/fdJd+9uuSvvnnFNxcXxBjwwbEkA9cfD5n5WBmmiSSwpMLr3cTr/bw1llJ50Fj7auNps/aRzx+Uy/upvrPt9N4Gn5LOuJMCeeAYD23/lCP+9cZLAlaYcDrXKkii4TadJwZADZQenFBxlpAXa1NgDV9bdFSNIaGWdatRHMMVznlLgxTjnvUhsi4HQq1Ex0aCJShaspl03jTyGMwvcw6+/933lOWCwz5w/Q6ONweWeaVMEfETYZx4/d13DBcTYb8jvn6Nv7ri3SGz5srtmtgPkXE38k9/+jPL8YivBaeGYc25st+1dgniGJxDxtg6nGGdpHtTXz21fLivAPrydyfXjYHTcyl3Okkbn5DeER7VivfC68sdf/XmNd++uuDNqyv2YcBFBw4O68yalDUpVQPqR1CHC5Gr/cjFdNxY558aDwU270dvv0hzPpY6eXB38vGfeu/DT0HpPCRc3Emj3P37U5BBnyqkj4XH27f3Amf3T8B8nFe7kdj4V52YD9opJ0NjJ3DVNbPO/K0hBgQP4lHMXwrBcTVGLsYI4lgF9uOI80ItwofrA1eDY5oaa3zXMOuCqnVm9iLsgqU2/Oi4ugqE11eUNwPHbyJ//v2fuH57w9V3v2O8+BbnIuv7a8J8xHsl6JVxBeXEfLjlMB/5+7/79/w//5f/wNt31/z+x3e8uznyf75NvJ/f8t3+hr///hVvXl8ZIyCOaYjW98V7vnn9Cq3Z6i6PcxM8GrSz5RuxqhxD4kmLLjuiD6y5sKZiwauUKaUVY1cT4qqWvxxj4NXFxL/7/hV/+/237IeBoVemqFWVHtZKyoKTkb/67lvifg9S+e5y4lgzfz6WLcj5KXnN8/nz0t+8yOd8bmcP5j37/19obr7s2KeM5ikGpHc/f0Ar/zya8xSR3gJT2zdn0ekWqNp5QWpGc8aNaikDQIvgNSBeiAFCjFbxIEKMsVXfO0via8V5xzgOeG+t+bxWi4ZWy1uuxwWJk9WJilixdVXIK5QCpeJqYfBG4uyCsB5ucNNADJ4jlf1+h0NI64H3tzeUXNE1M+1GYrpgCBHF4dcD3+wC337zirfv/sz/63/7Mz/89EdqKlwNjr+9uuKVV6ZgDA+HeWEcivUtyeZPDsGjteARQoj4qfVU2ZojteoPsc8NOC94Hyj0TtW5sRJY/0wwmpbgoBQhoITdxN9894a//f4bvn3zjaVjciJXx1xWwn6PDxP7iz1RBjQLY7ywrIQaK6BHCE4ZxIrDX6pcntrmizUnPB0QeQox8dT2j+3/QQ17Fl4/Cb4JpV3kExfyBeNprXl+jj0g3d8AW/gKBmdFx6JqJFx0+FtLqiM4762SolFWem+aBRw1ZVSltbNzZxUYFSfGAJHTCrm09nXhBIhowaDaCZZrsdbprb40p5Xc2g7kbKTNPg6s64F1PpJXQyA5p6h3yM0N1QdkWbkahO8v9xznW+bDDRdDZCcOr/DNFNm5ytAmeC4Fnw2mKLUiHoLzxhIoVpgdEIo79c6EboGdFjvBIq892ls2biC73+IMbO/akukE9uPAm6s9ry92RO+sckeV4irHtVhpW3XEcUCKUWuKiJnarXWDmd2Kly5Un2eBdaH8Ivje+XjJSvAYougl+3vW9+SUQpGmrpTzm6QPCv1D5/c5psj5+27OiJwqakTaAtGgiXePpYwOPDYxJx8opZKq1QYmVRRb6VXCZiSL2PbOCbQ0g3OCR9G8omICI1KoeWWdDwwiDCEShxEXomkIzeaX5UxJrcM0jULSefJamDWxroXbOVNWpdbGXxQcTi1HWqWS00p9/5a6HHF4vgsg333Dkl+RSkX/auX6pz8z33xgH3RD7nQ4YOk9PrUaCB1p3EimmYiVlA3/m1PDTItpTodvlSNm0tbGEJFLbVBZq/2KccCF2NpYKF7gYjfyagpMrpKPt+TmPqgTA2HEkTBUpstIvU2klCj1SHAG4jce4URJCU93qV4+hz4n2v9V+3M+Nek/5eSe8jfv+J3nKKF7puunCv+njPsC+tAK2o83eMc+eKYgjD4SCOhq1I8+eIKAj8Ga3A7Runt1IixVC5Tg2A2R2poLWWt03bTL4XDLcZ5J88LVYFC4kgtpXVufTIsM9+JmVduPc1YWVXNibdpHU0VTRpNNxFNjXY8PwUzukinHmaoOV4UrcVztbTFY379jf7nj2BaMYRqsM9gQG3ug6TfxLTcZglGyeGuDWEpjCaxii4h3d+5pxXxm2l3vWhdoDAXeyJ9LNr7bXAjR82o3MnqPU2WdF6ITDG/RmO3zyvLhJ4JO1GWGWhnGvZG+tEXk3e2RtzczN4vhob9k/rxk/CzNcx8a9yNVT2330PsHtnx05XouQPRYoOtLxrlZq82cVFWicw0JZA1+OtbTe9f6bDp8tN4iLoZGjCwbOtIqWhxDDFQH4h0hREpOm3DOR8vLaSkMu9EqLaoZg9qJj6uixhtp193SAQZJq2gDdpsBqQ3iBkVMu1iZVAuCOI/30YQZ4+my31nmcRcDfj9RSmDaT8QhGjJK7Fi1Nq4f7/GtV0wIFsVOktDqqUU3Fnbl1OJ+c2vao3UNMdSDcnEYwFvPF6mFwUX2gzExWAWMNuDDqTXitBtxKKWspFlA7fn44PDVCHFzLrw/HHl3OHJY8xch3c4rUz4/z/mVx2Mn8pRAbn93TfKR5ry77XMa9P72nyugd7VnPxaW79Q+0a2ifjcE0zreahFTTQQGa/s3Rlyw4mp6P8tWgdGRMSLCMA4QY6Pt8BxvbqnzynxcuL05UGuxqowhWAIf8Bh3rJZKTa0HimLHE4xlTgRXy5a2CMHyg1LBEY00S40xwcr7zB/10wVRwa+ZWhdKTtS0mraMnmG4wAXP/nJPHAK+GqMCtbR2gHavcI4QwhnLYAR11GKg9iIOFWftGAxvYnMAE8zODNGDcBcXF1RnywROufKRqyFyOQ7WQa1UsoMlVXo/zde7HZpXSppZjgfGOBBa3tMXyFo5rCu/f3vNH9/fcD2vL47HPDeHvkpA6Hx8jon6bMDnuf1wVzAfWnke83lfIqifOvqxTYDOjt98JMGq8Ic4sJ8mkIj12lRCCI0DSVvnL0yjqZVCOcy3DNGfOlyHgIbQEDNKXlaWw8zhduZ4mPGoQf+cI8RoBMjiDUOjhbQkaq7gHSGOBioXhxdP6NUWItQ4Er2nlkJeVvusKNHvWHKiYG0dyvHW+q2IMO18S1soo9/hWrXKtL9Ay4pQmcbRyshKZj0emmltOFzXuHm9M8if6kzOmd00kIprXcOMrUDaXDBzW4jezGIXAkjieDxCsJrPvGTGq5Hd4InOzjtj7RBluGAcJ4Y4kOYFp8baMO52jOOAE8/xcGA/wpxm/o9/+hf+87/+nj++e2e9ROvD7sxT86XPkfOA0FfXnC8V2i8Whm43dcE8JVCeFNKXjpcuMvcXloc0vXS0iIBoQ4/UalQXrZFOZ26rqo2iUijVqEU6ZrgX/7pmzloXa2supMUEreTMentgOR5Z10QtleDsYQbncOIQWretVlOZc6Vanz3EW9Mj2+pEdOWcs25nLQCEYoyyRQl+gNFaO+AcRXx/EpR6egaiTeN4TxwHSiqgQohu024iEEI0c9Rqv1o/E9fcg1NJF1paEUiru7QlzY6FMRb0V0+zlFaH6jHc7DR4hmgtIsQ5hnHHxeUl4zASY4QEogGHMowDPka0Kre3N8QwcZsW/s9//SN/+PM7rq8PW3/TL13qn7PcvqrmfMzHu79CPKU5t31vZixNSO+btC8/319ibD4nJ3+x1IoXJXr7vDTGuxR7CwIjLlYXcM7SKb5X/DuHE0uj9PxdrSulFNZ5Zr65YTkcrS1BqeaXihC9N8SNtgBQrtTcIp9bsbHHB4dT2kSTTTiJ0SKi2rtjB2pVnATTuCHgQiC3hcV831aQjVolTPOnBag+WDMgOfmNCMQhNqZ1OTUDFmfxr7NMca3F/E/nW3OhtkC2iIxzsnUL987hPK0/SzXWhRiMgGzwpFXxMbLbX/Lq1SuGIRK8Q1cxIjMqPkZEHOuauL7+wG4vfDge+f/947/yxz+/ZV4zQmtS/AkW5C8Wrf2SVMTL93MWrlZLwHOmOfv4FJTG5yA6XjIe2qe0CReDAcet+3KhtoCINpSJE2mRU0/wHvA4P5hfFxylWv4yrQslraQ1cby95frDe66PMx+OC6Uak3lH3aAmzCUZKCEtyYQ0Bhye6oat/6R10TIt5ZzDNTpKnDAOO9KaSCkzzws+OvwQGfZ7JCu+FGpq2N1q19bxr5ZfrXi3o1ZrFrQuq7WBcI5xGvHOI6qknDeyaW3RV+/DZo6oVmqB3tu7k36VVrA+z2sj38oWGFPLn765uuDV5QVX+4GrvafWSow7ri6u2E+RoQWqGM3dQKzJU86ZJWdu15l//mPin/78jt//eGDJ1hbxa+DFvzjP+aVRzc8WhHsRue2zM9/x/vvnTNtzwfyaUdr7Y7MUAMRtvlTZeI9a/rInyhtSCLCuz94Dhv4puVBqotRMyYmcjA92TYmlZJZqyfrBB3bROHHjYBhWVaGmTMk2aWnBE9cZ2ntSXzxI3bpT+xDww4CEAKEgfsUHa0WoPjTtVgx6p47qvYHA/Ukzam0ClbNFcFvvQCfOSLZ8NJNdupkrjXhL7lhJ5/eU1mQXlGLhntY68fRMjZTb+IaCd43hMBJjZIwB1BaGvK64aqVpMUSEVmzgIAwD87Lil0J1gf/2hx/5hz/9yJISGTEg/hcbtC8bXwW+9zXHKTrbbjr9Vnwc1HlJuuSrntMT330k8IoJm3M430HYNulO/qRsgqxC06AN11JKa9aTqQ13WrPxzeZaWNVKrFQxnqEYmcaROIxo8zdra5FXSoaGePEC3iIsqNHkNdfezt85Z1p7GNBgE720CHJunedrKfhgQHHxrVJEPUbfcSKM1sY+gFYE2cxY53QjmO5NiExABaqe1eue4gyq1eg1MVIy6K0dOr2loZ1U2UzrabQcawiBIQw4SdamIq9IqXgcwQ/tfFo/m2mi4vAxkSXwTz+85R//8GdSLVi2+ISkfukSf3/+PMaUcH/8oqmUh8ZD6n3TMJwuTO99/1Lh+6UWlo8fAC2Y4xo+s6UkxAIxHgv6odaUZwgDwcfWSRmoWHu9VqfuxVNcMPZ19RQ8PoxcXY781Tjyer/jYrcnDhM55cZ63npkaiFT8AU0VTgoVceNJUG3azAUT1VD4/jgkCHjXTCi6dxMyVrwWrZFs5bG0VOVmhezGERwMZo7oopXxcVgZqrUHhraUka1YrnZXLf+Lv2+dnieiPVh6f08swqptZTw3krk9tlylGP0hKDEIMQgjLtg3bqTojkhdcX7K8b9a6gLnop3yrjbkzXgYuJmzfyXf/2Bf/j9n+ng+/OZ+Kg788K58kXR2ucm9nMn8tkCpPqxtnwkOvvY359y/J9rGD1UpTEqtyQ+bA+442edlYlZ/WZhq3MpBUdrqiMWSZXiSPUIBSLCNAYuppFhNFO0N+epOVNTtnbvVa3TF7kByg3XKmJAe1Ogph0dzjSY0oIuVuTsgzcIXa1IOWky1PxdFbEeKD60aGqbfM6mmKDGtNA6XxvAwOLFSSqqmVIzVRs9Zxf2atHglOtH6bSMsfrlYuz13gm7aUSkleHlbFhYb+ZrXo2wLJe1PYLeNVwRZwtGoXJMKx8OM3/+cORmVdZTvqs9t/7Px/P/U+bcF0drPwfw/iXjtM8moJtgfuSKPCiYD53b1wpgferwcncyGTDnLs1Lf6+1bhT/p6TDSbtIS8SnAkvr0RAd7IO3Au4YEeeaOdmb054isaqtsVHjpXXRwAxaSxPMFhASbxq9NLWuNN+5pXmKORo5l4Ykak1/aOkgmnmLIuKbjwY9kCfVIHcWNOoLQcv91WrCeSagPX+atu5l7bkDWZXUCq61XWeMHmlleFKNs9fqZyMlrag2mF+jx6yl4Eu7FieknLm+veWn9x/48/sbjrlS1KGUbfI9WSL4gvHSmMezZu1LJuqXBFge9RntjSUmtEP1nl8ofm1t2YegxJbrzKlSc92CHq5VqGgp1JTJKg0ZZNUkbRoT/dj6fQhJ4Md373l/fcuH99fsXWUXAhfRM4zR8LbBUZI1fvXB8KxVHCV7NFdSWQHFaUFW09gpBsK4M7KrEBlDNP94XSC29EoLgkitqGtNgOpK7xLmBIqzq/ZxoDdvFAnWglNbXrcaa520XHAtxvBQW+tAawdYKCWTctoi3J31wOaFPd9Os7mm0kjCms+sxmI4es9F8OyHgf04Me73LCWjWSmS8XGP5sry9kcr59tFnI+8f3vDf/pP/8D/97/+I//5n/6Jw3J8tnv1nef+gCy8BCjz0PgqPudzUdKXbPfRNmem7Om7yrm2fCxK+2vkQR97KMtqLfZqLRZ1LTbh1LvTA1dDvFgrO0O3dEb1Tvz8w4cb3h+OLCkRnHKxn7gYR3YXe4bd3lBBMRjgoEPkzvx1pd1S1PKruZLWjHMr0Q84F3AYNYqEBggoiguhnRfUlhh1OHxQNJcWAfXmRwdHDJ5SE1ULwU/W2SsbWbUPkZpN+HJOTTNWSkqWz6yVnIqlfVrBdKm9nYJdyWbSqpKzWq2pdv/es9zeUmNrd6iVEANhiM0AiPgo7C5GI7o+HpE84y48pXgU5b/94x/4j//xv/If/9vv+dPbdyxrerGP+JK58ZSg3h8/e0DouYt5THPe+6A9lC8/3i81uvmUslVHmPawNINpg8bRup2vpTK6EPVcUq2VeU28u77hZkloLYxOGMfRoGbTjjhN+BhxMSK5UtWaxlo0yfzGk+HRjlPVkEbzSojJunuFSKiVoC09YsaimZ4NkmhWqCLOIw1cIdJQSS0VVCmtgZK7Y+uIeMRZrrBsfmVtjIDlrD5Tt/tV691/tWnhWmksB2eLeY/c9vyxWOWPc441ZUqxc4gxsK4LtSYkzQzDSEpWUndze+DPb9/xx5/ecjsvrcTt/Bq+Xhrui3zOn3M8qW1hW+61WxRnyKGTefvbMmX76OeTSmFZV5a0kMF8qwrrYiB1cUIoxpgONvlrYQuoqBj1xu288PbDDTfzSnBw+Wpit79gf3HJdHnBsN/h4oDEAc0K/haVA6FUUl0RKfSKEhFraIsqacmscyFXYVeU6gJxpwSx1ESlBUtabqPDCEst1inbBQiKlm6uipnEPQYmPedppV5OmoksVjViQmeVNdbivbDmYjQjFXITyNwWqJNZaxFlE+J237IFe6ZojA4heIYYGYYBcY6b6wMlm5/rfeD6/Y/4mglUxjFwnA/czEfqdMXbpfDHDzfMKbW0zpd6mR+Pl1Ro/WrC+ZCJcNek5Y5Zu0Vs7de0SAXwOID41xRaBUqpjZvGUZ1nyYUlGwPc6eGYBrAAhXJWUW7at5lwVTyHXAmi5NoCKs6B86gL1DAg4w4ZA46AJ6LzikqiL2Ku4U+nGFmXpfHYVg4lY815YL+biEFQ7/AxGmNAtQ7R1RtFZnD+9GxqBd9JuSo5peaROJLmlu41jHBek/UNbWVY1t9FKbXc9TEb7w+Yv2oWSIcetHVa7I04sWZDUpHG1TsES6VMw4CWzLLMXH84WF7TiRWQY70251x4+69/tML3WrkumT9fH3h/XM6istst/EXHr5rnfJShrJl0559tnzxi4j7nD5wL+XOmyaf6yY8eczP5PFpNWA3Cdwps9GNJe7+hi9raoy3hG1rAqKhyXPIGLlA1U9AVS3E40S3CmYv5dN1n82KE0ME7I5NWo/JYFWou5HWlrAslBqr3BgAXqwbpkd9+ricT2RmQoTEc1LNr6ZdRVdFcKQ1IQSmtrYFu2rBbC926MNy99U0prfGRWkStRXrNPHfOgmhgnc56D5V+nblkNFnqZxxia56kaGkM+ApLqaylclwT//jjWz7cHim9tf29ufhLjs9qZPRzjDspkR7C75+dvc5E9kXpki9JqbxkPCTo22diRFTBBWpuk6waKAD1J+1nG1sk1wuNlA/UkDRBhH0MjCGwpMTb25nD4cg4DAbyXla8Orx6siTSPLMsM2nNFmBpZNKhMc77RpupHnIVbpMRVpV1JR0PRG+dn/1oUEBa+kdhQ/5Iy1PinJmubbnZzGdOz7QUY2UoKVnuVgvUk7btWlKcIMVaSZRivmmubLy0+Iai0o6usgBaaJSizlWopdGvGAXLui74Yu9fvdozRUcgMx8TRQVNVteaj5XrJfG//6f/wtsP14ZoaosN95TBS4EGz6Uhf/WA0KeMc7PWUoRnq+s9E/e06cdC+tCi8uuZuJYDzEU3E21OC2M0uFksBhZwoeBK6eAg0woxgphQXUyRqyVSS+bHDwd+/4cfWJcFBYbdjhBHfDiwLivzcWaZFw63B0rOtihoZS2Cz7BmIcTB6kWdI+hKKoXjYWbZHw1mh1JwxGlnXEStjrS2lUMax4mIZy2racVi6KaqFlnP2TDBNRcr9u6gCJpmz5llWYyvp1gFzfFonbyXbGan7cv8SwNbNURRi5ppI9vq4Au0sT7oaZH3IlwMkTdXE94Jy1yRaY+XhK+O29sjf3z7gf/rDz/wv//DP7NmtcLss2d4X46es9S+RuDok4Tzc3mAHt6g7bO/72bTfT/0gf1qfzCP+az3xtcyUz9n5FKYc2JOibVYTi634EcumZQzXq1VgKP2DGFjCtBTLtE5dsNALsq8Zj4sGb0+IvEDb15DiAUXEsu8MM8L87Jyc3u0Xie1sKTCmm0/F7uRi9bz83I3oVXJqbCWTFbHBq5Tq1qppYEMNhNcNm0qLZcraswEON8ABEaEXUrd4H2tYaixDvbvqpJTuye5GuFZyY0kuqWDpGNnjerFtfpYxVFxaDWoYinWVbuetegb48A0RoYQmn9bSVnJOCt708oP797z+x/f8i8/vuPY6k/PydueG+eplk8dnx8Q+tR5/InnJmfmq2CViz2VcK5F7bP7QvlpgvlLlIs99HDWnDkuC4e0suRsApodqRRCLsSUEdcMKLF7snWwEkvH5GpVI9M4omJt/95/eM98s5D1PdEHQsyI9yzLwrwkjmvi/e2xLQiF26Vwfcw45/jmUvl28ry+UGIcKKmyrpk5Z4oEVAJIKylrfi14YxCQViDdMUwKWupGBNZxgZWG02343g5o39A9pTbyZ6s1Tbmylkyq2Rattnj1VInzFmWW1kPFNcEUpBGXNc3Z+HxVFXGO3bRjNw0EWmlatYbFyVs0eE2Zf/3hJ/7xTz/yLz+8JavDoVuns8ee62Nz4WumWp5pAfjACXylA9/f9yZ8D/mI22ddMOvZxw9r0J+zLOxTxs28ED3cLis3c2KMgeg9+0kYcZbk944qQiqVaT9Ra2vrXmFeVo7HlXnJOHFMHr7ZR47LxLwm/vXtNdV7dsPIGAdDzSgs2fGn68JP796TcubbN6/4H/72b9gNo2npPKMI85JI88KcMgkYLq+QwZO1Ug43+BjxIeLjZMEhB1Kt9EtLseBOAxDYy9rGK1Yb7XpeVdrC2/O8rY1ErUYglrSy5MRaC0vNrLW0Ok/rFDZNrfZSWyoHAcuoboGziuKbsGpVYghcXlyw343ktDI3Rr7DnHGT4zBn3r5/z//nH/6Zf/nhHT9+uME12s2XappPARX0bV6qJD7Z53zq8Heiqs8MQ6o84DPajk6vB35551gvCAR9zvhaWjaXypoLVnJlHZKzQgEKVuHRWfmM1lFa271KUZjXypwraxWqVlIpHJbESiULZISfDgu7rOyipW7UBUoVJq18u58Q7/ju++94dXlJcB7NmVqN5KsURV0gjEZTOe72xACeaifZzFNxrQ2BKkhDNHXcbjNZN5xwe3Wz18ALRrpVGkN7zpbfNLB/w882kHsvvK5aG9wRojRCFQFx7qwFH4YGai/BrOetU3VaWL0Vns9rsrYNa2ZJN/z49i3/9Ic/89PNzJwKqMM10MbPubh/JWztSyao3Hn3IsHsAZ976ZLzAND55+ffn5u8nwulesnvvtQM7r+t1fpdIiZ0qVQjyQJKVXLJhBgs0CGOVCBly+vlosypsORKUseSMmvO3K6LAb6B6jw3SyZVIRUQCY3lQJiccHG5Z5gG3rx5zRAGYx7QSq49RSK4YTTe3GlgmnZEV611RCmthrJSnS0w6s6Es7EEbq0TFPNTtYWb9U5UZUur5HKGmS3lZJbW2ho1tXVZmxbriU3jMDEOo7KFKjifSdK2rQrLmjgcj2jNaMkc5pU1V9YM79PK7398yz/88Qc+HBfW3BaCjqZ6wbM9He/T5+JLtv+kLmNfupacn1DdbqjeuR16tu1dITx/3d3nczfoV0UQtYLMLJlDmhlXoegluSipKLlYI9talTUV5oMxmOdcmVNhXlMT6MDxuLCsK4fVaibFeTNlMyzVED+7weHSEa9w+fo1l/uJ3TRytZ9sQSwVCQ6H1ZqGOHD1zV8RpkjcRV5dvabmhboeSXU2f7NCZUG0gjf2OrSe8rEYiXNNuXEB2ec1F0o6cQzdqZBpLQ6898zLYumSTShpZGdGvt2JwHK2qG2pbYO2WPf8cakVFyPT/oIYI7//6Zqb48w4eMbomefWDLgK//r+mv/jn/6V/+0//TczrZUTE+LPPF6a3vsk4Tz/Wx7Z6nFD9M7Z2T5UTw/4I/+y/3meSjl99rnjFxPUtmDEEJimifHiAh+CIYVKoahN16pCUqGmStKV23k1+g0MYl6HgCiUtZK1tWiP8ZRDjQN7Fxve1JoEuWq5QGJkqQopcSWtV+cQGKbB/EHviDEw7A0076On5iNacss1Gr2JCBYYAqQaA7pu6B6D7tVSqNnY7bprUlO2NEopZq42c92uzfzqombO1nvP1jlhcKGZ+600rfm8xgnY6z3rnYBQUT1b4CFXkGzcs/NaWtfrymFZSSk3lBIN0OBeLDgfP+7Pk+yfBVv7WVP8zO7tVTh3EBj3zNW7EVp4KPiznc+93z6GPvrFRjuUd84EJsTG7B5bW/cmnFg1vwVElNuU6VRmlYoLRrZVBaoo4rBJi+BCMBqOYWiT0wSIasn56hxZ1VjLAYl2Ll48wRvPTmjds50XnIea1w2QrtWOp2Adynp0VjJaTj1EtZm2WoppIWisCFYKpqWB21U307WbuKUadrajmE7Pj7vCor0G9GxCt0WidneIxivUz70hmFSErOafZ4VUq3EC5Upn1/9thA/vjp8NhHD/gjex2CBRnAWEuBNI+Dj6ant4TrZeAt978fl/sSCfa3o43Fb+5m8u2O8ipVpwpSIsRSlrYVV7vzRAeKmFD++uGaeBMESiH1rrO89uGIyYyhl0Lo5NGIvj+vqGUi0HKN4bsVUMFAcyBFwciGFAqukvKQXn6SWblNyKnktBe9BSOzUIIAYuQE9tI1Stc1mtxUjJWv7SSdjyj2lNqJPWibpsQrlmA7vn3sNF2HiTvITTnADLa+rJ0FLVVlSuOO8ZxLHOC2uIeLG86BADIQaqCBIiPiXq8cDN8cBhTVRxZqL3INaZJnss7vCl8Yj++18eIdQF71y3nheUnAUOTr+57192oa33BFYfvImfGxj6kt+/7BgGQrg9zvzjH/7E334zso875nlBv39FFbjNlSKGC83CCWyeHXEaqSgpJcjV+onEyBBHxnEwNvgQKDUb4LwmLvcjLgyIj6gfiM4RxHGzJlyB4pSjLoxOrHMWBqR3pRpU0G6I3RfnTi6IYOVgqqR1ARr8UDxg4Hgrni5bQCfr2gK+dUt01Gr5xpyt0e2yJtaUTWDV0EPB++YXC0HCFkRKxci9TtrRTOxxiPiim8ksYITevpN9mYXinKNkJS0zN9fXLPMRaQCPTst5X2Aei2d8DQF9bvwi8D1jQNczf/KuIPbxfHrkM479M4EPXnJcaNHakrk5HlnWlZQDuRQDi4uQiuKHCa3VYGzLumkF74xGxPpDVsZxZAiRaZgMh+rclj/s3Zut/V8kjBPqB+MPqpV5TsQlGWOfE6oTghMGb9FNB7hqcDiHRWN7/xThzKQECxKBRVBcXzTriZO3Sou6WlF5Pz9Vt1kFuVgeM+VseONNOCEGMerNdnzXzGGVus0B6Sa21aZt5q4T6fkbQxQ5gMbS504kXSkVcjZrYGNS4eFI7K81Xo4QeuF5brUIeucDpNesNs15R0M+evCPX/d9yJemRc5/c/7vLzE6Uua4LBxXa6PnY4DgSSnx5q9/x4fDkR9/+JEf/vRHxmBUl6+GkV7sHAWupolpv2e/v+Ld9XuWlFjWbN25khE3OxyT9+ymiTDumI8L67xwWBJZr4lhYBh3HDQxDJ7Li6kJgvH51No55k0AvNj9M9rKuvHz1B7YaSD42jCt0JngTV8G3/OpBVW3Af+XdWVNmSVl87lLJddMdBBbkyfvTTuXajlL1+k8UZzlosi5sNaW30W2QmvvHMMYDcebM/OSGUbrfer9SNZAqbZYOP1YED91Xt0fX2N+vRwhpA++fXjc28Bgok3AzgSzqYg7Zu22i+2rpwNALxm/aioF0JZ8P8wrKe343bevCCEyDgM+jPzDf/6v3M4rt8eFd2+vGbxniQPDrnARA/sQuIwjOwJ+LdT1Hd94z81auPnxz/xULR0VHLya9ubL50p2GUQI48i3f7XjYr/De+sWdnPzgaUk1vfviXHAe3tOrmLcto3BTrsbIiZ0HUdbSjZNKRD8YMXRBQMCeBP2nBJryaj24um0+ZtLTqw5kzHInRePq8IYHGMMVtZ2ZvWIWAAMbTnWbAGjEELLF9et9byVkXnGGMlpaQD8Qg214XcrSxUKDnHBFO2ZpfNrz5c+nhXOh07z4fVC7/xz52Phwe/OdSI8pAkf13KPRWd/rfH0KgpL0xKlFKY2ybzzTNMO3l4jxdgRhhDxKmhWDrczYRwIA5QQKWs24fGOGBz7EHk17kjzgoiZg7txJDqP1sp6nFtqQYjBIroiBW21oWDY3UKD4lVrYZ9F8A4Ibqud7NFV1VZd04ufnVClEZp43zSqbq8esFGhCWltXbZPpiwCwXtcCIzBak4tMHQ3UrtFZBsgXruBJu38ehF6N29VScnIwkqtuOysbjMZwKM2QT5/dC8N1nzqfHhM4L+IGvNrjKeEq/3xWefwORf82O9/zgCRqnKYF5YlUXJh8o6arfnQq6tX7MefEBGGAqrWuq4uiQ/vDzAV6ljx6tAC0zhydbkniidMO4bvA/7deyoVHzyvLy4o4lmrcnNza5PXOXK04uwQAsMwYB87RB2lgwjW1YoPpFV/+MkmqwidHFq11Wdm08pefGuGG/AxUDCyrqyGYNLO8yMOVUun5GRM9LkUCgZQjzEwxsjgrLlw59e949S0Y1uhOQ14UABP79rtg2s8vKAls6bEmlZbWLzjuBau55W12uLi73XO3grePyPo+Dnz8bNBCF9rPJpr7LbrC3730N//VkaplXe3CzdL4pALh1JZa2UtiZwOfHN1wdQ066uLifl25nhz4F9+uuGfr69Z01vWvBKHgcuLPX//u7/m33//hv0QGRy8ivutz0qsgd00ISHgxZG1GlNdrazLgZwctYwMw8AQA36KZGet2JfDLdGDE4/3Ae+F7M3vdLUFiRrBc1UxXy0pYYqWs22MfxuZWdeeTcOKGCl2BSR4SsnMy8xut7NGwoNVj+RsEdmtbrOdf86lacfAUlaKGute6dAeZWsF6MRAC7txRER4f7jhxx8+cD0Xfjwot4vVsMJJeM6F6Dx6+2vNu59FOO+EeDbL5FMu8NzY/TKh/C0IdKe6LDiWCu+PC9+sKxfZuHtibH5TLgQHPjrCGPj+9RU/ciSXmZv5QF0Kt6niholp2vFqUi5iQKRamZNTlJmpOIZJuBomEkpGrVYzG0ghiFjtaIWSCzhlmWeWZWEIjuCVgDBUQ/Q4lMHRenx187Y2VI+iaTVHVc6v+aTtauMJmtfEvK4c5+PGauecx7UAa2eeN6E04L0Je0+p1bavdg4YCJ5q+/EBYvTNLFacFwaJFplOK0u+5WZOvL9ZNkG/7xaddxN/acDx2ef/mfv4WTXnvYDto99/7vgSHtF6j/LwS8dzJk3FkVSYU+XtzcxfvzYGALRaZNJZoXAUJQQYxoD/9hXaooo/vL/huCaWqsj7Gy4uX3OsjteTI2jGVyuXWtdEzQZZu3xzZXWLokT1pNU0kbQJmHNmWWe0JGMJXFZq9cRopGSpVnJaoVb2MTB4q0qpBs1p6ByBtOBUEG/N7k/35CRcKWeO87y9aAEf3zS8E0vZdBytqKCFlp7pNb1s3EiqaoCWFhlx3hFFiNH6uogozgkxRqp3hHVkVcdhzby7OViNrOodQTxnKLxv0j5k4v7ccY6fFSGkZ+/voIUejM6ea8qf6Zzu+Zi/pFZ1VP75D39iPd4yOeXv//obkhqkTJxsSBwHFlGNjjkv/P333/B3b17xxsGfb665SZYz/Zd317zLyjfVMWgyFnctjEd4fVi5Ghde3c4QPQSHjxZ0Cd7hgpA1Q06UdeF4uDUtKMJahEq2OsllYZ1nKxOZRpgGY6+LHtQIos13bmB0LcTYwr44cs2mnRvwoIoi0TNc7Ix2RCECUxCic4gWEN8Iw8RYB9t5xTgYS4MUkma8d3c6hdNABiEEgrd0kBVrO+vhmZXrtfJhLlwfZiumdrZoeu/vCOp94XypEH5tzq3PDgg9ecL60ZvHDvDJx34IYvW545eK8PajHJbEcc0W9CiWBM+lIuIJwfp8BARN1tTndjlwUa1V3ffjSNTKbUq8S5njMrMovE2Vi9EKkX0wLYGPrOI4zIl0bTxCoomr/cQ0RMYp4iKoVKI4EobBLWpwBFXIqXBzc7Cosli0OXiHekd0Pc91ukBpPLzSrVs1rG9tOUoL3Bi4IAZBWsRVRIjBEdzWuHpb2DvrfVXDw+Zat+izc40ITdkaGTkHk/d4MUDE7TGzqnJYE398e83bDwdu52R0pR2HjHUXP58P5wL6XEDy55xDnw98/4RVYcuk3Et/wMtN289dhX5Nh/50EvbPmqy3hxcL8a8pkUomDB7vbdV3tUHUamXJK2NjoX01DAwClzEyrit/Wgvz8chxzfirV+g0MsSAhgg+ksRxuySOHw6sxyN5vuGvXl9yuZu4upgYdw4XTYtqbgRZCj50n7KwLslImYNjLYVYCmDmc6tJ3lItvUN3k0xjck9pu5beR3NrNd+fSSMwc81EFSf0nkEKrYj6RI9Zay82NKhEVYyZrzHOj95DQyrNa+JmSbw/zvzw03ve3xw4zglUTi0enGzla9vjesS0/aXHJ2nOT1olVB/1Ne88HH0YIWSH+thMuB9Z+5ybdp5ofihS93MNxZrvvL1d+ONP7wnB8/2bV3yzm1ACIVeOb296Np9Xr69wc6Em5XKa+GbaI0CRyr++f8dPh5kfbm5IGqgE3DgSZEfOlWUtLMeZ67e3XH+45o9/+lf+/s0bvr+44G+/uWLYefBKpbJogeCRGLhMgFi9bdKEfx2IITTTMLfIqGfXWheKs8oVF6yyhapQEpoWDu/f46YdBG+tARsgwTsHoYWXRPFeti7ffhisl2e1zmEhRDNf58SSWm1rxbiUcmFJVlB9MU1choHoBVVHwpM188d3N8as9/sfuD6mLcLrwglU/xCe1jn38QP8lGf9FYT5kzTnkwc8F6aXnpg8vL3lj88hEPb+IS34OZrxFwcsnF3GnAr/7YdrrvY7vjmuXB+OXL6+womxlBMNL1udMIzBengUcHFgL5EgAlIJKvzusvA//1VlDSMMIzJ6cqikVu1xLUocHHGKLNNIKoWfbg/MaeViH60axfIPxHFgmGB2ic7TFUcPuZAxdnjNQh084zSicWiF1S1ZotXKxSpWeaJ1q0KR2jp8N5vX9ZrPVgInzsiyU65IXVq6xDdfsGlLsdrXXI0pQpupfWjA+SkmtEagkqqyVsXHkfdz5sebhcNaqZw4grX5qaYh+9y+Gws5VwBfkuf83PGiYusXTWXFGtycuSIv/i10ieRESahNQC3y1m/oQxrz10YHvXSo2sT68WY2trmUub498H1KDCFYt2snqBcQh4+O5AR1lhf0EohYGsTHEfWYQDpPcZ7iPasYT9GiyhiE3RS40JHw+tJKyRRrpNuoU6D1DFWHx2/dtkUby7xWq90shYwSRKHlDu33BlCo2G+0WklYrqfPOnDeNRKg3mSIbRdmZuaqaM0Gw1czcUszuXvta1WzPopWw+Wm3NIwhmpSDKe75MpaHNfHlevjSqpdGO+m10/QvbsUOGCLSPdHHxq/+WjteUSWe4J5/v1T3uXDMMGXac6vMX4p4a5qE+dmXhmHkVqVf/rjn/jdd1foMOLU2M7FGZ+Q94KLrWzLQ6YafC9lWBJhCIT9wOUYkRiQ4Kg5kX0hB1hjpOwD1AvcX7/heFhYS2UVYbkayWKMf2uxVnlxjMTBU0WprkJQvGsEWz5Q8gJqTAzO9VKxSqkZ6cJUCsd15bguZIXYTMQYfYPyWXS1pqaNRPHB/EcRWpokm6CI8S6tpRoO1kc0KUtaOC7rhqd9dXHB64sdlxcjReF2Sbw7rvx0m/jTu1ve3850rl1V7gSA9LRGAfZd9zeHYWCeZ1R1M3N/Sd/zRZrzaQ16drIij8ignqVTPt7g/JOPTYiHRfdzxmNm8c81PvJlYFvl/+mnDywl89evR3IWslOoiZyTJeJFiEHIwQqg0zoT9leMcSCGS/L1oe3T2vxJM9qCt6S+9x6pgowewRFC5EIcRSCjpMEZA2A1jeiDMSJMg1DV+GNv1tma4jpBfKAmzxC80Z241tOkAQQ6aKBWq48MMRIHjDjMe4YhtAi1cR1p06wqjVRLa2s0bEGknkIxbela9Uq1bm3eE4YB1wJN3715vUWsr49Hfvhwyx/eXvMf//lP3M5GKVpV24LCnfrNXjPcH5U7wx3nnD/Khf6S49N8zgc+OxedO6bmczvr9gUfi9/DN+K01ZfcpC+5yZ+dWrq3j5QLP10fGIPj26uR45IRhNh8NNufa5UZULRwXGfSODJGj4SRsDPT0oeARKwmUWidpVsTHjxUKwVzzjhygxMry3JKaemO4sE5a4I0BUAcWT0Fx4r5vy54VCC2ErDun2kTIuOD6iReBiX0XluHMaut1HrquaItEGiIH+Ec9tfpMVXcxjOUSzNjc26gwJY/F2E3jVZQXSvvb2fe3cy8uzny/voA4tuzOUVfuxnbEUInE/fhAOR9bqGXjK8R6X1Gc77ACX7pke5taPGjky7dyL7692eh7I+v7dNv1KP43q80XprzKqVye5z5008fmGLg3/M9P7y75s3Vnm8ud1ShwfEwNnaBQ87k25m9c0itBOfZXV4Qx5G425FLouSVWlbcxRUy/P/be7MnyZE0se/n7jgiIrOy+ppjeUikkaLpMMlWMpnpn9eL3qQXyUjZ2orkcnZnp4/qOrLyiAOAX3r43AEHApGZ1V09Ow/t1tURGQAcgPt3n5V03mo2+JMl9BZ76ghauoupxmBwROdx3ko3MWdxw0A/OOqN9FFpKy0uEQVKa0xjJI2MlPycdE2jpe2PQkoNaRPQQbpfZ4PPuDSjJVRKYlrimH0SE8cMMRX/CmEsyNU70c+ddyitGKz4No1SbJoa7xzHruf7D/f8ePfIx/1pZlTMYukEC5GCrYwwttzHKll1cwnPTyXQPwfWftEIIRjdXnMOe65OjoiqiuvXgT0WZ336y/9TBzOXzzFYx+3DgZurmroyvLq+QjUNUtNGfII3r6/Rdcsf7S0/KE8Xeip6Kt1SNRvM9QYTd1L9LnjM118TDgOxs6hK46LHYrF1wEVpahQODqUCIXpCsDRedEuzadhtNlR1JYWuO1CDZYiCiFVdJT8lYyqYUkrKnMDINSNJLNUabUAbcG6gHwa6wXI4DthklPIxjClsWimMqQUUQsD2g9TtTX1enPNEBW3ToHTEKEVTiTvn/nDih3d3/N1377k/dpwGK2GayRii1BRsYIwpKtRnSSVz1wmmShH3L87P+TmGmMwZkXF8RcXo41QLufapZZhz058n3j517HMGPK/da3CeY9+zP50Y3CsxzIRIXSURKkrQOUjr9M2uxbrIQ3C8747EusbVFdiBxtRkohWcl85dpxNGNfRDh3WWzll89Ckdy2KMWIar2rBpm8T9AsbElNmhqbSmNlrcI0phlEpRPJNImClvSCxP9Dkpg6mNkgCDVM7Sp4yW3rrUtTrFzWrpWqaVxlQpN5NkrBqkhUIIQdoWIiK/0pGmNlxvGo6njg8Pe374+MDDsaOzdoq/XSHkpV2jRMq0+6N7RRX1S/7idc6fMmbIuDDnzjXUxNFAkDYvZD5jdLHkv1fu9YLF+yUp4dqc5aaWSHoaeh6Phrv9ER/ApgY7yjSQ+lMaHDEKQnx5c8X9w5FH6+j2jwxK8QWRUFe82uzQUaOCIjw+8vD4wOFwoHGN5E/GwMH2SE6m9MeslWZTN2yutry6uULFQPCO4Hpkn4Qz1aYCHXBKjTV4Qup3EtOeoZM7xUkQv3dSI0jXFVVlJNTOO/FR+tSSIvgxeZsoOqvWqV5vnNo2dN3A4CT0b7vdSERQkFZ/TW24ud7w/dsPfPvuln94e8thsIkbCgGRIHhdrH08C0JRyoyEZlKnsuvnn4Zrwl9Kf84cwLAA4qyLokofZ2azgX+iNfssw/rIaXDc7TseTz3bU0d7OmKBmkgDOCM63sZobnYtm6bl4djx9uMDtjtxp2Cv4eZ0QCfONRiNSxUX7D0pmTjSDz2btqFtDJu25WrX0DQ1200rIm4qIu1jJPqIToEEykj1PpQaA81jKImn9EnxTmrTaqWSQSdQ15qIwnux0HZdz6nrOQ0ShqR0CuczOrk4Ig+PR5wSS7JqWpqoMam6gg8Sj2ydh+A5nTre2IH//f/8D9yfHL2XrJRs8DFmrVcrqVi2cFWlpDP2WtSYfBcxGGAYhl8YKubjGeS8pPO9fLzEETIXdZcTJKQtrLv/FONzibnjxkcJSHg89dwfe656y40LNE5EW11pmrqm1tK7c1NVRFOhTcW+swStOaH4YB23xx5SG766bQleOkib2tDqmsoYmtaw2zW0TU3biGujriuU1lNCtMo6oxhkpPlQytuMJKOIiKwxhDGAQPqI5u+keRSkZOkQPJ210hTXCldVWlOhyd2pfZBWhYONVO0GZQyPj48obUZ9dHC5t2nAOTh1Pd0wcOg9Pk5NdeURzi2v5cjctPxXphGKxJMLbbK49s8j4j4TWzv/W2UOd37mkzcp6FB2hqT5ChEz416BoOPXbKr/GQj6OcXZTxWf13MDxcH+eOy5O3bcdJbeRnYNqFp8iW1T0xhNpRQbU4kVtap5PPU8uMiAoree/cOe6MXC+0UE3IAKlle6pVEGU1e0VcurV1upfqAUdWNSkyDGtu9S20OPe6SMJno7pmV5F8a2CjmaS4/B7oKMo40hIWoI0pTp2A+cBulY7XzAoKai1QjXHAbPabDsmgYdDQ+PB7a7LU1To1BY6+kHRz9Ip7DHfcf7+wccBmWgUhrnHGphyFn6zjMyZoNPRra1NMZStL3kavmlxi8s1j5lbZ0vVnlFXJ6ZOGd2tzyFo7+0de1zzRtjwDqpe7MfPPvBcbKWrypD1ba0mwaFTXqfGSuYv9rW/Fe//YI/fXjk4djxcDrx6mpH225o2lZib4cO5Qe+3Da8vrnmarfhatOMtYOcc2CSyBml9EiuBB1JvS8V1E2N6wPBOQ7Ho0TpMPn9YpB42hEZjJYGuF5yLnEnXOfpOsu7hwP7Y4/zEoCgjR5TyXJDJx8ju92O27sHjv3A1dUV2+TP7Y4dtw8H7g8n7h6O3N49SiRSb4viYRZg5ICX3GclYuYQvYxoOUMlByh4f+6zXGax/FLjEwPfLx97+bOOvhNKf8psbjX9nil0qQ/ERJ7Le36OwIJl2tDPmXftHss0JIAYIv/4pzfsmoZ/+fvfsb1+RbttqRtDFVJDuoiIncFSac2XrzZSe0d7rqvA9mpH1bZUdYtSoENFFT3XjeFqt6FtKik8kJz3wIiAMU5lR6QNQ9LHPBAU1jqCk05j0qRISq7EKAgdo1QhUMln4mOUanxKauD2g+d4Grh/PDA4QZo6BVc4L7Gxzgfxt5iKfTdIF+9Ny+vX14C08rt9PPDu7oH7/ZH7hwP7U491UmbTVCYFO0yIdinjZG1v1mBArLVmhLE8158zjvvzcs655Xp1iK6e9JSVnmsxHZ/barPkVCLpn08F/ZxceAkIEXj3/iO//+YrrI+oukHXNaoyYuRxUh82qgAhYHTFpm34YlvRqobrWrO53qGrGlVJ97FK1dQKtpWirkwyComldiSKaelzdmREWjP41LMkEoku4r3kUpIC5WMyDJH+xSClLVVqbhsRXRUlhqDBiqi6P0kn7SqF8uU8T6mkF1CVwERnHaYyNE3DbruVqoXW8eH+wO39nofDif3hwJCqtUelxcVT5IlOoXmXXVnPWdaztTZfu+SWv7RICz8bOZdK6VPHi4NqQjAZsq3TusTxI+uZ5/J+/luR29B/yvhLCUSIUeqnHvuB27s7fnjzBv/lDby6oqnNWBxLK6hUJdbr3nJd11zXNUZr2qtrSaeKSOexSktfy+jw1hKDtG4fQm49iPS2TXph1VR4r/AOrMu+PeGmNiU5+wiDtbgQcUESxokBFaK0DzRG+rwY2Y0Y4XTqOXQD+9PAseto6xZd1TTNhvv7O6rK8Or1Db2TxOhTb9Fac7XZsNm2eB94//GR79/d8jf/5VuOfSftG7yX3E+jhbulJ86W1xy8HmMcq8bDFCu7lgqWP7NlFqSdRJ5XKTWb63PXoFobf0ZXylOIkH1MC26Y9Mx1NpnFj+e7j10avyTlu2RAyPfNYlhVVThrubra8cUXr2naBlPVoAwn69B2wASPUZqmbqgqKVu5S5E6Rim0kTZhUWnq7ZW09NOK4Aac6aXzV5A+JCpGgpcYVWU0pq5Qxkh0j4/01hGDFJjO/TRF59dYZ6VUSIiE6KTlgZZrrXP0TlouWOex1nM4DRxOQ4rW0dRGIoy8s1xtpMj1vut4PEoz4KqquL7aoZSm7y0f3t/zxx/e8e7jA72VCvERCWuc9m/ilsBYDwim0LucVVKKpWsImn/TOiPz0sI7GZKeI+yfIw77L8PPOTMOTXi49Kyce1nWHfyf5Yk+t+uEcvOlqFRVVdS1hKs1bctmu2W3u6LZbDB1jesd+IiJgS2CRFpXgtjGSPOhJEIqo9Gmomk30gfUgLPipkA7gnPSxiBKsebgQ+oRkgwzPgWcBxFjgw8pJFDW3VQSlhdjGNOvlBJjULb4Oh8JQWGdF8trN3DqpSeKUlIkyIfAqe/Z1QYb4yi2tm1L09Q0dU3XW/ange/f3vLjh3vuHg9SJwh5XmMqcjOlOP5vQrQ198jcZnGOdPPvc8hbzllmtfyS4+l2DAsZe+WMxd8//WGVKhYw/TDOnqy0JYvMi1xSz6ef9Xz8OcXaObesaZpGymVoaVFX1zVRGX7zu9/zareh0Yr9e4dVPSEadHuFqVu0MfjoJadSfBW4EDFGOEXVbqnqWkQ+3aArRxU82g7EYSA6h47S+VobjdYV79/fAQqtDFq3WAeDH/CpgoFSUsfHjKVJKsliIaKj6KEKUDoynHq63nLqLHePex6PHYNzaK0ZgscOA/vjgd9/9SW9tXx8PPH65jWvX13zarel6wfe3z3yw/uP/M3ff8++t1iXaufWDUZLCppPfT+D9yI5pP0sDUJlyldZJHpJyJe/5WihkkMuGcGfQy16Med8mjP9nIfM8xa6AIz9O8uQvhIhlwHsS7/iSwLcLxkKLiH6U3Ndsvrmv7POItyywZhqJEgKxd39nj/8w3f8T//Dv6OxGlLkTK0NVYwYJUnXMXp0YcRRiWuGKFFAVYTDfo+zAwppt+6j9EOxTtwYEc1mdyUxtEahm4quG+iHDm00GENdXSE2qByPO1Alri3iohT7UjHiVU79CnTWcX/oeDycuNsfGZzExZIQN8ZIWxseu4HtZsO//pdfsd1ssIPj7v7AH757w4+399w+Hjn1Vji8YuyEdrYnizW31s7Wfc2tMrqCEtKeZ6yUM5/vc8k1f0kEfYZzrut5sFQB19wjLxlq5fv69eeIWYi/Z66WX96S9pJRikJZhDUmpXNR6DzA8Xji7bsPvPvwHsIXxM0WQgbKVGXOOzTi78zLHZOIGZH1sLbHOTv6E21Oak4iZUj+zEYZKQKtkERqZXExSNSOliJCShui7fF4GCsEJPtAul+MKbXLSfbIsbdj1NNpcKl2bEAZJRxQQVMb2qbiarvh9atrTl3P3eOed7d3fPv2lrv9kX03JAOxcOWy4NZSpCw54hIJMyKW1tYSsZbc9BJyLrlmFm3n17wMJl46PlHnXNMNS6vpT6Ei5cOWXGuaL4u55TNMiCnf1zjnp4zPTQHLTTTG0LZb6rqemfwzkfEu8Ph4wNuBv/nbv+Xf/tf/in/+u7+iCpGrqkVrhY2RbhiIBqq2TUitJlt1Kg15eHyQ5rlNzX5/kMLMiM/OjTmJgSp4ghffpTIVylRgKlRV46OSygF1hXeD9CmxlqAiVVBAndZb9NPOCsc8dpbbQ8f7xyP3+44ADL00x9XZgpzW5fdfv+Zqd0XTbPjDH7/jD9/+wD98/5YPR5+qsUNdV1SF9TQj2RgoAKOIC4zZNGVq2FrX6iXxNoVYPH2WDCDOLL9ZCspNlX4p7vmZDUJLZfq5hy4RMeNfIeYmL3nWaSAvlmQdrBpxXzieMhD83JGRsq5r0QOrirbdTLVSyZxAfL0xBlDionj37pZvvviSL29esatbDoNjQNryWSy+0lJ/iAg54yI5/72X8iJORfCO9/f3EpzQNLTaiM4aY/InWnx3wjpH1w90/YAdHME0dH2P9Z7tlaEfLHaQRGyrpM/K4BJRSb1UHg4D+1PPw+HEm9sHKa7lAqeuZ7vbUDctmsirXcuubbjetljr+dP373hz+8j/9R/+I/u+p/dBunEbjY7MInfynpWWWZWMYRm5fAgjwpbccJmXWVpwc9RUuW8hEYcYJ56Q9dk8MoGo63qm25aw9XPHCwPfL4maa+dO1Obl3HTODWW27CxXo/6Z7/lT3v05K93PHaWJPnNLEWNNAp55Iu/8Gk0k4H3kcBg4nga63lJrAzqiVcpvDGACqTpAasGgFFFLl6+opMGsjwE3SG+SRkkdnohUYUCBNoa+67HDwDD00gLeeqwLEr/qUou/YeDh4Z7hdKTC44z0zqydcF8JVPd8fBR3yMPhxP3+KFxcSVs/0RcVV23D6+srqkpjQ+TNh4+8/7jnu7cf+XjoE7GpJrBJYy1UbpQ8AGKc6ZDEOIYTLiOFShG2FEmX1thzEVfNkHT5LEsd9nONn5CV8vw504ssf1++NKwhb+a/k8yaRZF1EXbt+7NP/RkQc82Ns3STCNXWs03LVDu/otaa4KXN3f5g2e97DseOxmh0WxONJiiNdRrlofcePQRMum3QNaZqME1L0zac+p6u7zidTgSlcSHSDRLuhlbUbUu3PzKkXii55YFH4Xo7OvrtsePd+w90h0e+uNpSVRXGaIzWOCf1Yo+d5cP9icdjz/7UcewHafnQ1Nxc7aQnqIp8dbPj5uaKwQbefLjjb//hB358f8+bD/dQtzRJypDmTtMa5xaASqWGuBSENrG2GddKi3rJGLS0zGZumPXTpe6a4aq03Ja/LRHzc0phv0wLwJFzLn//hPjEbHGYTZWrpE2bVIo4y034cxqG8kY1TZOA2CTDj4wQ5uUVy3+gxP2h4X6/5z/9/R/5eP+Rf/ev/yX/4p/9HvXqiu7Y00RofCTcH3nV1pjUO0/VChPFsrutw9gASCFVCYbB8ph6bypg/4AgppWWfM1mR1SGgOLxcS9pYTHicJjtKxpd8fb2PW1KMYsoDocD/WDpBsfj0eK8cLLf/+5rfEqkNpXir37zJVebFnTF9x8eeXv7wH/+xx/4/u0tgwtUmw0g+zgMwznnijnZYarCXuqckMpZFvsgdY8EmS/phCVSlYhVxudO4vDlUMB83i+hd74QOdcA/Dm98tMMROrsHoXAD6givO+ncsvy2k+55rkxdreq6pFbzsv5T2LRWlACiDGjrgwqwvFw4kMM/Hh9xWa3FYPMqeOmrqUrtoEqcbAYoala0V09qMFK52hPyoXUhCihd229Qae0qt46BusZIlSmIqJxPtL3/ch9ojJYa+l7ifTZn3piFI1/sFbC+oIYjpo6QUnwbGpDnaJ9QoS7Q8fDceBPP95y+3Dg48NBqraPxDpbfiddMO9P6SrJuZoXh1KkKGK5Vkn0VLxg3V3uQbkvc7haD6Jf2i1KRH3KtfbS8YtwzulZ5ohw6SEVRXcqyMF8xRkR4prcv04APtXI89T5zx0DEpeUwILsv8zPWQLB2vc8tNbUxqCJ2N7yYC3v3t+yu76SEDpr0dstvqqwRvIxjVbEEHm12RECGB/w3ZCiewIYQyRF7ziHNqID6wi9C/Q+4JUm6EpcNdHPuj1HpTidOo6Ho+Rj9oNUQ4iSxylESALZdSo+rUKgrRquti3XV1ve3T5w+3jk+w8P/OP37zh0w8iZ0yqxhJMlZ8zrc0lszCqQymsbcz/P1JdFC0HK85f7VyJWea+5gecyIV8agUoXy/KcT0XSzxv4/sSYAefiytGXlQwXy5yUGKVwMol7yjSBM+vBeP55gvNzyPqp3Lg0qe92u2QhNKvXlYaG0WiQqGxVCbJUWmOUpq0M0Xti8Lx/e4cxNX1v+bf/5l9hh0GSiR28+fsfMUqx3ez4Zghsd1va7ZZg3dgRxAVH97iXygNVjcXgVUVsFF1QDEFDVXPsU3idMnz5m99xGiyHY8c//vE7Hu4/MnQnaauXAg2GwfLV11+waRqaqmK/f6RtNty82vHl9ZbjsWN/PPF3377j23d3fHg48O7jw9i1Oov9S5Fyorlz3TL7ia21o4ibTBFyjZpXMDBVhY4Ra+3Y1QwmX+nSCnxJmpoI81zXXNvbjNA6EYJ8j58znkHOT538nJPNXiYtaEbGLLSIAWhC3PL/MX3JupmafX+6IPCzT7vCFZe/XUK08/jYSR+ar8cc0fNniJHopVDV1WabulurBEwaFQ3WDvz4wzvu7+7ph45//rvf8Gq3o60aHjqPtwP6QdoAvnp9w81rj/Kw2bQ0dUNQir4b6K0jYFGtpY4IRzUN1nZ0hxPmNFDVNdpU/Pjt96nNQUQRaeuKihajgnDqKO0LW6MxCnSM/O7rL0dd9Nt3d9w/HHjYH3lzK8nRp8GitcGkkiMhxGTBjqmeD+PeKqVmlQzyyJE8E/ec3G8SZjsXgTPhHA1GK/tZWnGXeyzHJ05dctOXwEhG0iWh/xTu+dnE2umml2+uFKmxDbNz1YrGeTbLqJjne4mPcI3jleNTqNdLuGte+Ez954EFMHHzc9fSDEGz6BXi1HFapR4pqUizGyyP93vu76XX9KZpAE3YGva9pzt2uKGXrlooYt2gPFg0GwyRyHHwdL0jALq3NGhMFFHWBng8nKRdQhupa/jxzY+MGSLbLbptiJXG4FNkUsTWFaYy4r6JkbqpsT5w7C3fvbvj7uHAw/7E7cMJ61NCdBKBIRt0dAL+AnYKxFzqfVnUzUbAsmxlyd3KvSoDPl6y5+cEPu/nZQPjU9z00v1eiqA/GTlVYTUtH+rSQ6jiHDWdNDtWjoIuFTocrKWIfapR6KVjTT/JwQUSuC6bn/WZyRCkZkA3t8xOgGO0lt4jxohYqxUGnbJNYHd1hVKG3g68f7vn/z7+R3a7li+/eI0xFbbvODzecwqKodrA1nI8HHE/fiCGIH01U6zpZrfFmZbagtaW3sO+c7x5f8f1V99wXctzGwWbGnat5uubBhUrCQO0jtPQ4b2n1oovvrrhMDh+uN3z//77vxu57d3+QN87rPOjqKx1TF2u3SiiZk40AvIKQpbrb62dIW02IsFcAiv3KlfVQ+uZG2ZpXV1KNaURSDi6SsRgnpa2DKZfis/lO5Zw9NLxTGzti+dZpR5QaIUjx8xK44R0a4g+e4jZQiryIuXrLokly/FTkLdccAEqkwLXTQFIoXiXaePLjlWljhVjxBjJb2zqaqRECiWZIjKrpHkpJWliHvaPHYdDz8Pjic12C1FE29eDo+8GDvsj79+9G587A6dSEoiQOViMEaUN3emIJjA8fqR3R+pNw7/4ase2rWmbhm1T8Xg4cRoG9ifL/fHEw+HEj7d3ktIWFZ2LPDyc8F4CE1xqblvui7x/RQ6Q8j6gVOaaEsaviv1ZK1O5rgvOkUFEYkMmjrP9M2ZiBmpeaS9XgJ/roiUMyd+lBb4Ud5e/Te9szvTbTxk/W6w9F0gXxzPQruBFxslV3IzFWWp5YC7irm/c2rN8uhU3f0qkTzWlTSk90o1zkX6ue88pp3xmzmm0EQNYQa2jYgLWJOpqbej7AR8s3dDTDY7KKCotFHzoe/b7A3boZV5jCKnsgdKa4Aa6g3DRGAKb7ZYqem42kk+6wdEEeH3d0rYtVV1hB8fx1HO3P3H72PFw6rk/nHjzcY+Pipg4o7dSz1bSt3SqFZYJcGGhTmJsrvQ+J7qTLhdTtb/l2pUIOUfeSV8t96DEB63UxeqNJYe7JOYuOe2a0XE5lpLAp47P50rJnFGpOYzmr7PvaeNmx+aW17EKyYoIu7SoPiVOrz7qE8hbHi+55uQmKUPD8gaU1HM+XxZ9Q6rzqgFtpM2BlNlQEBkB0lqfqh3o2Rx1pXFOkp9P3Ylj98Cmrfnq1Y5KRY6HPYfjkX/+9Y2UvzSGEMNorYzecjwcpPAzcN18xdXVhuvffIMySizEzrPb1uimxaP4/t1b/tO37/n+/T3fvX8gpI5dSjdSdT0RTq2lNonUHhIxM0Yp/JXFyVxeMyOlBA4Ih4uTWDVbwJKbTvuRahohXFfrvBeTFAPyey6oXYqrGfnHyhAl8dB6Zi2Yu1Oyd2AOY3lvlwhbitYxxlXr7XMI+5OQ80yEZeKMsQwWiEvOOpprUWPX6jzD4vvMnnt+/+cQdO38T3m/UhzNhp/SQJDPE+6gV+conycbgdCKpqqkazQQvbRQz0St5MzGaLx3RCZEIHGISlc0lRSG7k8naXKrFOarDa3RbJoKY2q2m0aKfCmozJdCIFRMrivQ+DGHk7ZicIHHxxMf9h3/x//zX7g/9nTWU7Vb+mEQIHM5fhVBtCAFwbTRiYAFgpIK8m7Vqrko4JxrwxaNhch66Mqa5ioIGVFVctGUIXj5+NL/GNPzlvOGOEUhZbF/DYakP8ykZ6411M3ulCWOlJFHLx0/wyBUiGqlYkkp1Kni/xTwNW3ShdmL+0zEdA0py98/18gLX1plMyKWAJa5fc57nT/C3GInYl1MCJ8odIxAbuKjRnFUMVVbjjH3rQQfgxSAHnU1KQnivadShiYhs4oeowKNMWxqQ1MbVAxstq045fG4QYIVJE+zkn4naPbdwA8fD3x/+8i7+wO9k4rvOrVMGDkE0/ecbTNJFDFxi4nbiC6e1ywuFitr2eNinVvvF2uZJZdyfqkskZoqEYlxHg877q1SqKLWUHms5ITz+57D11NMYI2LrjGTp+D22TIlTxlblkg3kvb0InqGnIXoohjl1tKAstQT5OHPf3tqrCHspyBuSYGzVXHdJJ8Rc37f7I8Twq9HINJJ/DVaU2lD9HFE0Lo21JWhqSq00kkvy9UFYupRonBOeoXEEJIf1POwP/LbVy1tXXOzaxn6AVtXxLrC1BWVkiJg/WBp21ZaubuAs1KjNjpHXUWijjgibz488Dd//4Y//HBL76f+KMGm901EJ4fE5WifLGIOgx2RxntXAOZin2bR7clNAqicv1lws0vWztzpTKnJYBejJwSpvjCvpBfGfaybZuTSZX5oabi7RPDL51kyi/K3JXctk76fct+U45M4Z/lQMKcl+XvSlBir9M9nSP9X0sqc+XyZO83vORldLumTay+7du5zSFoipHDLyS1ScoesZ84p7RQ4PZ03vbNWStwmWqOihujRKlIZhYoiKroQqSpJ/wqAdVaqpztJ4+rtgPcOozSmkiJX3eDI9l3vI733tLVn0wQ2dQQ0Rtdc7Sq6TsqEVFVF31tBTu8JGA5Dx8fjwL//wxt+uN1zGMR6OQwDIUbqqpFW8zGXjIwj4RFdU5K3S46/5BiZY8YYZj1NlCpkKdlsSATgEvAKIk1W2RA8zsmludFtmatZJmFnzl/CxRony3Ag8weUmgfRrzGutSyVEknzfeZ9QdfHs8h5cXHy/5PecUlQXb96iSQZkEskk99LKvaUKPCUqPsSsTdzyEnnK4Fq+swcUatM4TNVnMqnTM8ytzCOXDitW6bUGWB9BKWlB2UgpjKUIZUBkdZ2CunXKQAt/yojvTSV1gQPg490g2fXpmRupHFsP7hkeBJ3hnQLU3TWc3/s+fHjkbf3B/bdMCYuZxFTpTZ/ImbLtXMxf763IzwUemJ+b5LgPr8sXVeItJdEwfJYJg6Q6gGl37WaWivkHdSl2A0riCZFtPNeneuel0Xc8jnPRWLGOeHlNW8/WefMguvywdaQsjCJzA9mXeEMc1d47QpinhmkFoi4PO85LpopWw7Fm86RZ5o4e8kNMleNSJ3TzEnKHMJk0ZWLxwggAVIJOqiMIVg7uQ5MICCNE6z3uCA6pbPDeK+mbohaEbxUi6iNZIHUlaEPMNjIoXNcbyMuFZvue0vX24kIePEuRgWnwfL+8cR3tw+8vz9JGcrEwSaxTMTq4ENCzuk9l8avNYNhjBGlJ6hYN+CVx899iKWhpXwu77PBzROTiyqqqZO1TkQwG4VK6+q0XyG5gAJVJdULs9g8R7ilbaF4zwWCLnNASwaQfeDz7KX5+KTSmBMVKnTJiTHIQsxmyJac6Zo1vfIp1p6Pr1nQltdfEnvzsbWRI37ywp23IV/qTEkcV5P+lcU8mJdOmYtI+VnBKI1ScbSwqqoek62D82MD2cE7Bu9x0RO1WGjryrDZbhm8S079QFNV3OxaXl/vcLcH9ocTt/ePEjtrB653G5rkt4wx4pwXBEfjYuDv33zk+9s939/uU4s9PwLwuC7e4528Z2UMQU1B/CMAlnuZCXbBpZYcY84Z578plSNx5Peq0qN7abLWzvc/E4EQY2oTkZ5RTbGupciZdgmJOsvENKRoJrHOtq00Upr35lTpuvUqCKUoW/6WiUWp2z7FRZ9GzvkKjBxgjqLLUYgKavFzyWGLBZ3fZl2nfIl1a+26S0hdWmTLaJ+5GXzyYQrSTbp2br+eblRQy4XohYjBRhuJL1WFTopKU6jUHDZRf3QKRJj0Vp0turnjmFJ4FDpKbqW1lugt15uawVkG5zn0ns1pABRXGzHeqMThexwexRDgT+/u+fBw4nAa5mwhJh1xrKkjgDTnPHHksuP+qGSZLvahWBSIcfQplmslnDoj7Hwds3spT7EK1BmxvZeAg+I9So7JuIvnnPApRiFMYrLO53crYazUtdfmW3LVn26tXaDOnHusvczlG2UGG7O+BTPMfCrS6FP0x3KRLinvefFKV0k+p9Q3hfiq8Z7zuN4ioiVOlJcCoUQfFVG2KnTZ8n0T/I+W2RhDEj+yO2WKfjEprSwfyUa3Uz/QDzXR17zabOmGms56ehc49TZFIuWAekHQwTuGqDjayPfvH9l3AzZM+6TS22S9ORt/JvF9QfgKBCXGUXc8A1rZABHnEpfLUsiIXOrcOj4BuxC7kgvNpLqE5HlhSwKR29HPr8lvWsLG9M6lJTefW8LApbFEzmw4LNfiufFizlkyCtEXnxcl5875hdXu+WdbzLV+vzXu+BQiZwSZQvDEmJMjSkodQL7m557k97zQJZLnZ5B3jgmyA5WqUmC7ST/H0adJTBXzXEhFuwJaiQgZEqcK0RODiEQGQKdcUAVKRzCeb9994GZX8frqt1xd7UQfNdBZj1JivRysldxRJYadfe+43ff86XbP/QA+GpSKUox6RJIEUFn3LhBo7E2SGgeNXDYjZomsxbrn68eeJmccUIigUozRP3JZJgLTnqsCLvLzlI7+8vhcBxQkFeSb52yWiBljZBj6pPo0THrp3IVTnl9aZUu1QGtN3/fz4Av1mXTOl485So8ctjAGrJ35OcZTHLVEpLm7o+xwXLRaTsg4p7jTU08IO59fQtKSZTPVDarrWnpIJivl6HKPuTdJ8hcGUCa9R4woDdEn6yhIsILWqGQMGqLn4HvUYOg90piIyPWmJnDNvh9oK0NtNE1dCcAQCVFxGhx3hxM/3j4UAB1nnCeXiBRarMZlWQvmzitxVk+n4Jbre1J2mIsF4M/91GV1BJEa5mpOnj2EMElmZIY+37Mc/idrHpirMueipuiLNkUjZcJy7kef69AT580wt5z3Ofz6dGvtkxMujiU9U46c8WGeEguW41N0zdUnW+iY0+/zqmuTqDqnokJt14IkinvMBMLJkmu0iLSGHLsp/S5zqKPEnJZziXirSI7rGEeOO8bqRmkNaEPAaoNPSKRVZNfWKFOjNNQpV7QyZowycsFx7C37U8/joRv1sxnCFSJqernxnIt7kXTJfN54mVJncJPXV9b7/HZrElJ5YqlS5HssETWv5bg7C/2yvI9Sed2nY5lOCUKL1TxXvMjBMdP55wEpa/pofvaXjH/iLmNz7vOL3aVAzCVyriFcvmbNmijfSxG6cJQXOX+oJOLGFPYWlPQ/UUiNmzFGM+tJ2Vo4mi1xzon7IgphMJWRglUxEp3HBMWVbvjmescuWWP11YabXcsrXaGUNDyqq5pN2+JCZN8N3B3veftxz8fHIz4EmrYleKm0ngtijVbr0cA1T9PLa7T8zP0xfdavmJDlnENN0lQp0eS1WdM51/apTMeTOTLX8qv6YQ5IkLpH1chRp6WXe5W2iOz6CGFq+Ku1VMLI1t6l9bWEn7X6u88xnM+OnKr4ksCaJS0rn3GklGeRQQuqyTNUe3FuniP/K4MLJlGmrGCwvliXqO3635lyp4oGTTVWfc+lKjWgdQoOiAqvApLSEYjRjyJXLKNpghcFOFlopOeJT/qa4thb3t7v+cd3Ff/sNzds6gq0odEKoyPGRJq2QvtAPHnefbzj3d0jjydxD4iOe27omXGnQrce94JJr8u7VdaBzWu9NLRNBFHE2rU+JuW6L8XFrGbkZzMp7jefe26cy7ATxs/SwFTCy3JfS5grA91LEChD8y4ZLD8VMeEnIKe4rme3XXmQT5tx9dcVBHjuhZZW3fy51DWn32ESd34aB18anzInHHXNFAY4ArFKkSp5Q312t4j1NZR9J5PvlCgW1mydjXGKaY0ROuc59AP3x04s0EYMXI3RKeMloLTCu0jvAw/HnmNvpVFuTG0MSv2u4EJjalVh0IlFW4K0gmdgsFQTJmvnEkHPATdfN7Y/mKjngjtlv+R0bUlAlgi/JDzl813a2/L88nc1SjrnZTfn503XLfXRz65zfuqY7v/zgH8pu6+JEXK/6YXLnhkl9Z0v2HTtMn52rnueP8/8PNksrSUXU/qjbJHskYwwRtoTKNAm4lWK8tEakyyhzosYmxE9G6JMEhkrY7CDZfBeWsLHiO0dx6Hm5GMK5VNoFblqG07ejo1w746W93vLx5On9+ADo/+v1AszV6zrmmhd4k5mJGKjBTfKh9ZTQAZMyF52mc7lW+YIynisFEuNmdY1pDDCEMIYbJ91+bwnZXt4qcgAkHqexkkcj4Wld81KukTUp5FTjH7W+jHIPgcdLFPJSthb3ucpBP3ECKF8oCCUceW3s1GKtnORoJx/+eCfOtaQLxZWwGWGgJybEVBRVfO0KDlXxE8RRc8p8gS4JZXOvjqdoniiuFKUSB4RMJhxXUrL73jvhCBaa0icmBAJpKTlgsO5IA10nY8c+56mNmzbhlevrtiEwOADD73lP/zdt3z77p73d3spJZJ6tGQrM0y6kVIKa1NtpNHllIiGLMxIuLTORBCpp5SQQ67xxTvOreQl0OZg9XzebA9TfPF5zLPcZ7runFPl8inlbyU3L8XR2fovzp/gaT0UdJltsrTQltdlmHluvLg0ZomYs/EkUs7nmp79MvJdEhGeG3PEXG5gXqDpPcqp16hYuZiZ6q6JX8vrjDGpY7SeBRqEIHmbUeeWAW58BpXC+eRJYyIQ6VgRhKC0/Iv5d+TBQiRFBPXsTz03VxtpImQaGBzdaeDNh3t++HDH+7s9p8FO7pmU6pXHPHwxjkQmr0lMi1hGL+U1Hp+7QHZVAM5Sd5uv9ST2q+J3VvZmPtR0nVKpHpBc41KywBrSjvMvZ1sce+rc5TuszXWJU7+ECT2JnKWRZk2vOP/h/GY/hQk+haCXxNwSUXRyXcjezgsWnz+PIkaPGGhKwInp2Pp7XRp1XVOZmsqk2kBKQUZOUhpSbXCnAZ+4itYaHSNqpkvFzIBGRBTRyRC1S4HZItbGCMd+4P39ntvHPb/9+obNroVmR/dwYn/f8Td/94bv3t3zeOql61iaPIvh2VBSru2kp0+BB5M4XzrbwxgkLogwrf+UWifNj1QSz7PIXhKDqhJDWiRKhYgkbi99muPOjXuuEwefyoKEEDgcDqO4uYybXsJP/r1E4mXzqfKe+belBFCu33MI+NzxF3POSJQ8xDWOxEu558vG2kM/zVHnVFr0qDgDrCWCTeKU1JzJwDI34y+QZSHurD1XVVVU2kiYXbFpIQScdygM1DWVaTEYNBZSQHmIBuWyXhbG8h9KKepNM7oJvHe8fnVD1w/c3n3EoDh1nh/DiYeTZJ/0XccPb+/5228/8scf7/nD2zt6H5M4GsXtopXkj8ZsWJk38JmvH2QjziTGyj/nJpVHEHOSXkq9PweR5/cAsVyLmyIRVqNFR87J3EWY3hIR8tpLLSbSs7jx2oyo5X4tv+e/l6Lpmui6xr1LBC3HWBIluWBynnCu8veStLF/Mj/nS0TWNS65dn0Wa5YkYrlwl+45Ie/SaTynRWuK/DRnitU1JqWFzY0CMUoQgRJ+KtUQiBA8DjeaSmTu9E5kMVG4Z0j3NVVN27ajL1EBURtiqnB+f+hQbx/4hw97/vjmju9v9+y7ASeKJlpJ1+h8L/H7rQHlmhg/DznLa59DICkMPktkmut7C2IbE+EoEtczIpffl2tacvm8bnmsReWU168h4CWOd8mgUx5bwkQJfxlRS/i6LKrLeHlWSvGXunTST7PjnI2luPHc8RIocpW78fHOFuCcz6skekaWTuRJ1yyNCEsAgJQzqA2VThX64tzimO+T7yXXGTAmBbLH4rGS+weV/J3p2WLAaEPbNtRNgxkskSh9OqsK02xAa97eH/nxruO/vH3ku9tHPu47Tv0wFtLSWlO3U61WrU0SS9UCwLNoPwfEZSpU5qhLIF1DzOmaAjlDkHjcFKM7N8iVsc5zf2KeK0af9tyc3XMZFJA52ppB5inivSYWl8fLz3Ku/Dx5rfNvP9sgpFjD7HTTZ6f+aeMpSvcUJ82/556Y65w2/1ZWLEhcTk3HLlGZNeADsWZWVU1TN7R1SyYUbdvS9z3DMDAMA9EYFMmFYRQo4YaolCuSdFOf9K0QgnR8VikO1AcqU7FtN0KJYyoOZhRGK9ro+e7NHY6ak1O83584dL34M8NkAMoAUwI7MHKfSYLI3HCy4pbJwnO9dFrnvPal5XcpdUj0TrGvSUzJFeqXiCxr44vfJsu7WGQnEXINccpnK/8tAwfWRN78zn3fz7jrkmhP7xZmcy/nL4nGU9zzkwLfPxNjvDieQszyuyzGvCZLOoOYQt3K8y9xz5iNPWpRzyb9/pQoMz1HAnSVmhDleVJol3NuBF6Jh00RPrlmrdFoYzARqgCgCdGPDWjHvM7UKBeSa0Nr6qqiaRoJyEZDVLx7GPA64qJOZU8MxkTqWoGeAG0Cjqlk5KQe5HfmDLieWtenxLU5cVwgaoxjcMUS0OXabNgLoxieHycTiOm8EjHHb7N9XI6SECy/l38vAxwuqVtrBGk5PrvOuYbjM+5afH2JTlmOpZy+dnwu7mRfoho3LlP8ldkv3i8/9pTc/HTu6Pi3mt5cJ+QUzXUKUC//TZsZxvo8QpXNiJzai+4WQsQlVwek+rLZx4caK/lVpqKtW06hl7XAcHuwKAMY6ZlpjCZSpersasxsCcHOONy4FiNxmv5eF2XL85e637oasJR8JjE/V/Bb03GnPcyEN/+eLcSTtbmMj036Ours+5Lont/rfCwRd+342pzl2pTX/0UbhJaj3Mzly5diQj5XPicjxTq3nEQipZhxiFEUi5GIJ5dtkOOQ9deLlj+lRqTUAKm8RQweZSQSqDsdxBocxTWAUgQlgdNsGqpKdNTgHP1g6fuevu/x0RMVuBjE6qsVVdtg6galDS6EpNMarq6uyZk1dVVxtD0bZaTTtE6xvCiM0lIUehjO0qTmgDlZt0UfLaSDwiCzFGXz3kg7xHOfZgieEBL5WhF98zzL8h2T5bgsc5n13PxvCpCYnulcz81WZmM0w9CfvfuE9GEGi0uicklnLddjOUqCtfaea+OT69YuX+Spa5966EvKc3lOadqeJzRnQ0tE60lUkjmm74knjvdYKw0RU+yqnHNuoV1aJkmRL7mXoVYpo986ovV0EWLraNqWdrPBKRE3M0LnZ3HOoTHSekFpdLLj5qmJk76jtVhhjZFyJ5XSoodqpDPZWJW+oq4U26alqio+Pj7iiWJsSecoVcSsLvZiKdKt6ZJrkk1p4AjBlUfI6kGMMZu3zpAgFvpsCQ/zhHaVEqMnN1kpkeRnmAP7ZPybYCtX2JtE+DWRfbk2a9JC+X2mP3OuDiy5af7+k5Oty0k/9ZxL1OMpcbc8XtapycfmCA2ZCmeEnMSXPN/8eSYq62dIeP5M04UlwMj9UygbmXshJSaDJFdbwGiojMboLaTGPuPmJFeKZJbIMY0e/aJaK3KhdNFlp0CArERkYSGroVIpXtw4bdXQpvaEg7V4ImhFRa7PM9VhXQOcch+WnOcSgpY61hI5ZU8UZ0W58pyL58j7eQ4mE8FdzlU++/mYEFTeQ/TXkohfgtXl35+iqr1kzku/5fGzxNqnJn4JUi+pUUlRx4DsdGxW5S1GaeRKGZyeudpy7sw9y2ifyYBQHl/qI+U8AjRF2pmXOFcfItEna2gIVEbhfZXKWTqUqqW4V1WLyJspqjK4qBkcaGXQVUXTNlS9wVmfdFeTop3E1TEMA0FpfCoqHWJEG+G+tZGK8V9/8Zqqqke91jmHC4EYe7a73axmUrnGWifDlBaC4UNA6XlqVeY88jlPUBdOpsa1zWtWZpbEadHHa/LeTmucj+XeJHJPpSar8Dx167L+l1WZLD2VRO7SdZfgdknIyrGE3eWzPYXoTyH8L1Cm5OlxidWXkRNLxFw+T+aAcG71Og82nl+b12Kpk0yIvTQALT9l0eu6QkWIzo01Z7WS9gW50WtdN1S1Rinp6Rm8I0bROTeblrrSbOsW30d61NiANoQo3FiJ+CYZLi1Zgu+jok4iePSRq+2Wpqpo6wajK5z3dEOPTXmggnDTmiy5ZrvZUDcNTbvli69/Q7PZYKqawXaoEPF24P7uIw8fPzD0Pc65MSwuJ1cLIkpToRJscsSOynuwAlPTnmVEnPTeiSN7skFoCs2cjFBLRM23mmwSGfZkj5ei6FKsLuedw8N5db1l0Ht+p3x+HkvDW3ne2viFDUKil2WBDuY63RLgJ8SMs/OWIq38fS76lPL/tNlq3Kjl+ROlXNNRy/MozpFRmQpCYMj9OrJuFcQwZK1kdZjKo42haWqcBe9zpoeIo3VliFY0zpARM3GZDNBKidgLYtV02aATxQWx22xpm4amFo7Z9T2H7kQgjgH4y7jZUZc3mq+++YbNdke72bF7/SXtdkvVNHg3oELEDgMYgx06RF+WcMOSc07IPsUmX6Lta1UBMuIs9b9pr8s0uvUxR5AM/HP9tlyD8t5LGFube4nM6/f9fEztZ7UAfE4GVysdc+eIGUeK671P7dsnZLp071yIaymGllQsZ7vPxdtylEYHOS7Ucqn3rNwHaIzBg8TLFkDjE3cMIWBtT7PZUBvF9faK4+GIdwK8UldIjboiSjpPex9SmplYKFUK4g8uFaWK0vE6KKldW2nF16+/YLPZYuqGP333HR/vH3g47GcShqz5vH6r1pq6qfkf//p/5vrmC6qm5d3tRykUVlU09Q1Gabzz1Jst0Q5i9e06aagUpzWf9kalfc2fk4665pxfQ4oSNkpxcS46nuvJpbsn75QxVbrGzgIfyuddGnWWHLR8jqU4Wh5fvkd+njW7yc8Wa58b08Os32AmJhbPrZCojlyPJXMLrSfjSa7KlhGjBLJyEUqRZizXmIowLTcjP1Mp0uak3YxQ3k96a/ajTt/Ti8QoLg8votaYPTFG3Mh9u/6ESrrhVmvqWmNMLS37Ukcxn8S+XLc2j/wthoCzjs53iG05EgmYumLbNFxvtzSp9KZG3CW9tdjgUWYe+laOCRArbh8OeF2z2QTe/vAtp+MeHxzf/Oa3vP7ya9p2x83NDdf/7X/P+7dveLi/H3XJLAmUDx7T/L4IQo/FXl1yH2SDW+agKqkJREmLy+HyGa4Uc0DPc5RI5ZwfiWBZNrPMwV0aH/M8a+F6awRlKeYupZNyD35R5Fxa9iZrWCz+Tuemuq/598yJJvHVJ0Be6n2TSHJ+v3LO+Si55fK69TU4t+SpqdnojHuPRCI9Y9YLFYqwWAJZ8IAdBrTp5C7GUBkpJiXFnRkR2TkvHcWcpJGF1J7dJGNQrmgXkvistaKtDNum4WqzgRDpug4bO47dEetTgEFcF+Xzuuyurvjd7/+KzXaLTp2w3dBx3N/TdSeqStO04pZpmy3WG7SRqKQh+Uvnhg+mWOBE7BKmjQhbiqpro0QEnSKu4oI4jyoS5yVz5txqCkzImSsl4q+tSz5WrtOajaREsiVilnOW+uslY9Kl8bNaAE7fC+gsRNkpzGpyeYQQpT+k8yPHyHrf8qWNqYpFO3+ZuR6Q54ojgi3FjfwsEwE511HPu1RP81dGuJ0GvJNMEq01wTtSiNHsefqhxxMZnHTt2m131KkaXgyChD4ohn6g6zqO3YnBOULS5ypTUdU1VVVLkeZUDL6uDLt2y/Vmy/X2itPxxP3pxMfjnvvDPS5I7dZcLAygLBmS//7mN9/w1//LX0N7hQ+B3g5oDXboOD7eA56rq2vatqVpWu4f9+y7jt1ulzhnLumZqYBAf4xzFwlk7pQNOvM9vKTvzTjNmQ+zvH6ScrKEI/WAHeI2S6EYBWyVSLgmquYxGaSmwI015F67Lr93fpflvZ8bn2CtnYBeJQc8zPhO8cOS+0ipD2sdzgXskEWh0hgzGRRKUTLrj3nO8sXKFxbJMpClt6XRIeuxU3flc+PIEkiWVLGqKmpTYZRmUAMOi0tiXZn4PGU+aLz1ECxWnbBKQ/ColIWB1gRj8MGjtBaOJKHuGG344vWXY1MhiOy2GzZ1w9V2x6t2S13V+KgYlKKPnt4PkCKFQImfc7SkTmVAtNbSSDfC7cePmK2jqgyKQOg7DIa62mC7wHDs8F3P1W82uJvXEvQQHMf/9P8Rg6JuW7qumyk2a5xmWs/SoDet13Kv5PxJqtJKQg9DlBxPU2VdMje/FcIqLjaZIxOBGOMYUL+Wdjbd91x8XYqd0/3WJLq5RTaLziWcPWenKceLOOd0/ySOqIUT+uzkc/nbWo+zYcwgKA0tc71uXYydONv58VKsKscl69qSgpa/r4k0ipQRETPXLbhv+ioxs0uRB2ntjhi7hqGHNJ9KUoGLMDiL9Q6XROW6aWibVrh4dBADldFsm5bdZsvN1TW7ZkMEeu95OOzZHw+cuk7SypCq8KU/s1yP7LY6dSdub295/dsNOhUG86kma4jCuY2u0NoU9XMZxezlepZrulzbOVBm4j0h6XyuEnEyrKR9TxutRIYm66k5kiqLrqV6tUTET9H7yjH3x66LtUuEXoOpl44Xi7XjnGriQjKWBhc9O18ANDL0rkg2nfTJCZjPFe1SlD037MzFhvxw04YyO7606k33KPSbCwuXxTTSv5AASprw5OMi2lWJWmotLefynN457NBLqBpQt5KN4byIk70VBCVGmrpht9sxZmIQaaqKXbPherPjZndN3TT01jL0PbcP9xxOB06DlMZU2mCYqhCUvuOMNIMdOBwOvPvwnuuvfzeuQUx2AbShajdUTYs2FcMwYIcBawfhQjN1ZVq30SL7Ak6R9zsnepf7dH5tcQ4ZSTO8SaxqVZkZjC33cO3vlyDLmuhbHnsKbkqD5VMi/Np4XqzN6VS6pFxzbjqeW14HOOfpeyulHAc3PlhVmZVrphfKx9Z0jGWy7JwqPU3V8igXe1nRbU2h10pxvd3R1g0KabkXkj6DAqWNrENIVeIS9crl+yMR5x3apQRq46ESMdP6wKHr6J0DrXn9+jVtu6UyNf3pxHbTsN20fHVzw6baoLXhYX+EqseFQO9FRw1MVlBnc0XytQr3BccInuAdxoAyGtW0/Hf/6/9Gf+rojifevftA1W4ZXODUD9zd3fN4/5HbH99gXRKZU0BCJgR9388igeb3FUNXlpjyvkw66Jooeb4vpWSSEQCmgtYZFnJvk7zPa4S6HOW9SyOOqE1hhlxl4PoyCKJkOmu/l0arn24QGvMc18XCieMxWuREBIwp3MyNgDJ/4DnnnBb+spJ9joRLP+a6Re2SSHPpPkvKqFOETVM3Y5C7Ro0BALqIWMnGsIkI1WPnskorNrUECmzqWrqJhUhvHb21Y+nHum6kjyewaRpe7a64vt7xm6++YRg8g3WcbIcbAs4HrLdTuRKtR7GmNGSU75LfUaVPby3H/aPE+3ov52hFs2358uuvQSmiFjdEdzxy3O85Hg4ToJP2PoULZsIU9Vol90kfPIcn+Vfu53TtHEGXeyhIIhKTFA9Ts/uN77xCoNeC+9cI9XOIXF77lMSQ9f/y3EvjmUoIybmulg9YGmXSiwAqJDEvRLzz2EEMQNkie157puBY422eZvmlOL3+XnMzfSn+ruup80VWKudOgEISqGsjVQ6IpPjZgHcanTI+TAb6tGYocZXU9ZTPWRnFtm1p64amakBJAMPgpEcJIK0CC4twu9nw6uqKm6trXl2/4v7xQGcdnbMMgxijrE++RKbY0ZJbLjN7yhF8wA2Wx/s7KarlPNWmlaD9SnPz+obDqcM5h7UDp9OB0/FI33eoJJ5TAHJev7VyInlv8iUl95t0yjXAnnOgSxLQ3CYxV43W6PFSqlpDqEuqVPl3ee3a863d9ymkL8eznFOocMmR4KIom87z0Y/cM4sAE2AUPislFjjRw+YheaqY95IinzfjXBTl7Pw1aghzUShzdBAxvqoqdtsd23bDq92rZBQCg+bj3Ufx9TmHrnL3MFBjknTqMGYqqsqwaWrapqE2FY1pOAwdIVoG69ld36BSRQQdI5XWtHXDb7/6ktfX19R1zdvbO06dpbcW56N8OocLUoNWkELWuUkpY7lshyCXHXMtAWKAoesZup7j8cTNl1/w5Te/4d/8u/+GqEQS0AaO+wf2Dw9ge+7fvxOu6T1VEkenfM3z6J8ljJSlRaZ9m6Sm/FuWrqZz5/dY2g9KcXPSr7PYKxFga5bTPKdOksFS7M1VLErGkq99KkChPG9NvH0qnrYcLzQInWP3KsarCUnLc6YHm1vnFDmJdql7CucJucKByr8wup1Vcf5TIsTyOfLnkmqWLyHZGYZtu+Gq3bBpN7R1jTEbKlOxqzfUqpJW71FcPcH7hLwpuTpKLE9dCXI2TU2MCh9hPziOneU0OGwIbJpaNkyBCoGmrtluWrabLRHN4ALOR6ydulsZbYgmEBArZaUU2kzuhb6XZOIyKqZcF11wqqE7cffecjw80B0fqZuWqq6pm5a72ztOhyOuO3I6HrHOEr2TVhJRYwpgn+rx5JYI57VfSx0uj2WpzQwnOfpoqbeRISHDimKccwrtk3YMzllyQMQSHpdzVlV1FpxeIlz52xoszZ9vXSx+jrOW42cHvqvVv9Ro5j4TGWcL8lQolCYGCzFTUZX/g6hHVF3Ktucc8rLYMF8omU+nCnp1VYmOaCpqrVExoDEYJTGtIqLWKZ1Lgt29syNihhikIFeVEqSNoU9t9gYf6KyItD6kDH2t0v1TFkrTSLACKT0tTMAnPT8l+Vil99BKqi9MIZGTTr4qbhV/e+dwTsTWruvYbLa0bUvdNBwPR+Gwp9M8eDyJOWMTpFWda4rQWSOQ5X4vbQUA3qtRLF0C+iQdyR6XnDCL9hOHPjf0rcHC0rCzNBYuxyXkWtOJn5rn0vhl8jljHNOozs8tEJFz0USK75rkilBjKFsMYpGMiMipU4Kzd3Z2n3MFv3yG+XklFcyxvnVds6lFN9xVDSZEfNfxeNgnhPMMveX16y/Yba9ot6+Ei2XgZDJQ2MEK0nrPcbC4kIp8RcXgIlYqcAmCxggENpuWzaal3bRERHqQCnwBrSNVlGCHRkNUgc5bMlJn/+MakC2LGpd7ok09cpf+0GE7y0Gp1EE7WZWto6nrcd2MMfIuea5xvoyQuabTtBcT0s0LRS9hJO9hrmywFDfz/BPnnMI+s4jqnB+fJ4u7y5Fh7zyhXr7n0jRLTr/kgpdUpqVd48+KnGsjEdEzarUcIv6eb8zcSJSCm1X6nq7RRnqLhAIAl5/z73MjAZzrDJkrfPX6S3SA6AND1+ODw3tH5wXRQgjgHL2ztM0j2+0jm82Gqqqpayn2bEyFqTRBKaLTRO8xXqcWAx6so2oqolHoBEh1pWmaik3bSpZKQnSjpHot3hP9gLcWHzzOdvR9x+N+j0OnEplmNPEvxfWlPpQ/M0GSmrVa9Fe5IwSQJGcR+ZTWo1XXVNWIkGtVFab7zPXD5fMsAVfm8yMCXgbwrCadZ8Xk9/LezRrgriHTEvGm55v3F31OXC059/JZnzMsXRqfUFT6pSNlTjyBmFmseun843l5Q7WG5GN8SlyZA0cxnzo3DIhlVnG92WH7gdNwwvU9zjtc8HRuwAdPDAETAiF2DM5jnWewg0T1tBuigsoEjKmE42mdymYqPDYZjIJE5CjJp+ytw4SIioamqmlqsQ6PLpoQCN4JYrohRRt1DEMvnFkZVJwq2C05UgmESyNFuSZAau/LqDPnHXgycDsu9zvZreP0fckhl5LLhIT5mtJYtCYqTnu6huAlPKwRgeXazH9fR6ryWdaQb011W5vj0h4sxzPWWlmAF2H6KL7M1cCLLwhzjGHSQ8trSxSO6ZIsOj5HAGQR5G7TguS2fqUOJzV4GlNzs7vmY3/H8dhx7EXPCjEkMUkAJiCO/sF5usFSnY7UdU3TtFyddlRVI0Wmm1a4al2jgsF6RySmWNokwpuK/fv3qKBpjWJT17y+uuFqd5UMOx3eW1x/YuiPEqnjHYfjHhsjpq5RyhDi+aaXlN9aOxMXl4Hw5R7MpZBJNM7X53kzkrmsxsSl3zDPOYeFJXL61FmbGMamRXJMM7W7n3NF4apTT8wljK6JsqXR6pJ/s6zksOTI2fq9rJCw/F6K55cQdUlI1sZnF2unui9riHnZ6jX9RroWMtWdFP70QqiZSFtefz6eV+a1El/mpm2xg+XY9xyGAV03bKs69T9RDEOHdQNDLxUBopKK7T6CDpJ3+Xj/iKmkLMlXX32VDEmgUofrmNdIpftWIspu6pqb6yv+2W9/n6rWK5zthVPaju504HQ60NuBITi64Ihao02FNrW4VQpD0NNrPCHvskL+dC3EoEbnfkkMyzIlgmQpMJ3L3HWJLGeAGkU/zba/mL5ksbR02YjRy6N1LjR9rgOWSHTJ+DS7P+fwsyaqr63rWkL1JWR8at7leAFyrk9waeLIZLl7etrnxNoL1yfWGZcs+meMzE2NlgwRH6RBbS56VSUEDcHhgz/j+BmYQgxEHwtuNeCaRriU0kj+akjXi0FrGAYqpaiNlCzZpGwRaUIb8c6mdg69xOA6Sx8dLungOfKt5EZrRKu0XsJlySNLGqDQZtLvzq7LakEZKTTq8ufAvgTecoxPoZZ2iMnuILQ6zZGCLJbbsCbaXjq2JBZLXXY5xxpil0RuXTxeH5d00eX4xHzOCwdmYuwlnFHnfy1edDoS11FTFR/PGJxWL1+I6aMog5SgNNpMIlbxXFqlIPKl3pU3LINmCBARC2cMHI9H6kpC9VCSwuW8pIepGHBWCklvKk2da9BWlaTWeY9W0gC27zu6fuDUD3TeMeiAripMMtDkqn51XY+PtowMmgUgRKmbm8W80tGe10e4IdKst5CEZlJRCKTuJeMx56YghGXH7xHAkx6etnH2OVvfQq0p722MoalrcsJ+ef8lAo7PWsyfRfpSJF4adHLwwyWistQtl7pz+S5rhPA5tQyeRc5P45pKKakad4nrzU++KF5MVHJOMadHyo7u9fu8BGnjYk4JsTNYN3G3sc2CmpBPcgzjzP57iWj5FJgQvKOzA8fTkd5ZKUcSA5rIpta0KUc0+Mh+f5wIRlXT9Zb9qYOmxriWTWy4blswCpdcHDFyFq2jtR6rAObfSmRZAm/mrCHkTJpk0Cm442hQYgKuUi/NYmhZvPop0ZAkzvrUXYyCE6k0qw9h4s5ZT0wqRZ5nHuW1HmBQIs+S25XX5e95DfMoid0y2L3sQboGY5fE4vKctfH5XSnJt/UcgjyJ4CvonXURMi0tYKKkyuP5F+T91XuSdRQzOtUnDlsapKKkhq3OMX/OiaOq0V8phaSzWCiRT3rMYVUQFc46qroay2wqU1E3G6rdBlO1DNYyeAn7c8ELJ1ZmBngT0OTu0tOazDiYmhrZTpXUDWTVhHNgX9uvLB2qrG6MomEc71+G4QGjAWlc4ekhp8mKY1mEHslAmHrjlBxzzVCz1AGX77OElfK8pQ/0qfV4CcK9ROzN45mUsacvzop8OV6CmMDoI1tFokSxx+/5gsJ2G1dReO0u62MOqLkZkR67eyWUPROD13SLpfY8ctScebNybYxynlZZw5P/O+8xlQGtsT6gTU273VHvGraN5XQ68fbjeykwlsTKqpoAqOQiZTmQtbXO4qxw+AgEmqYurKfzGNRLHCB3ppY3ycStBGA1Q86QdPrMPcU1dhn587vNDEoqI9AcCct3XIrsef2XQQ3luyx/u7R+y+8lhy7zZtfmW+q7l4b6VL3t1/Hr+HX8ecbLwuN/Hb+OX8efffyKnL+OX8df6PgVOX8dv46/0PErcv46fh1/oeNX5Px1/Dr+QsevyPnr+HX8hY7/HwgiQ8sLmXNgAAAAAElFTkSuQmCC\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
       "       0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)"
Mirko Birbaumer's avatar
Mirko Birbaumer committed
     "execution_count": 8,
Mirko Birbaumer's avatar
Mirko Birbaumer committed
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# These are the class names; this defines the ordering of the classes\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "class_names = [\"brad pitt\", \"johnny depp\", \"leonardo dicaprio\", \"robert de niro\",\n",
    "           \"angelina jolie\", \"sandra bullock\", \"catherine deneuve\", \"marion cotillard\"]\n",
    "\n",
    "\n",
    "# Class ImageDataGenerator() returns an iterator holding one batch of images\n",
    "# the constructor takes arguments defining the different image transformations\n",
    "# for augmentation purposes (rotation, x-/y-shift, intensity scaling - here 1./255 \n",
    "# to scale range to [0, 1], shear, zoom, flip, ... )\n",
    "train_datagen = ImageDataGenerator(\n",
    "        rotation_range=10,\n",
    "        width_shift_range=0.2,\n",
    "        height_shift_range=0.2,\n",
    "        rescale=1./255,\n",
    "        shear_range=0.2,\n",
    "        zoom_range=0.2,\n",
    "        horizontal_flip=True,\n",
    "        fill_mode='nearest')\n",
    "\n",
    "\n",
    "dir_iter = train_datagen.flow_from_directory('./train/', \n",
    "                                         target_size=(image_size, image_size),\n",
    "                                         classes=class_names,\n",
    "                                         batch_size=25, class_mode='sparse', shuffle=False)\n",
    "\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "plot_img(dir_iter[0][0][1,...])\n",
    "dir_iter[0][1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "V2fYccc8GhJF"
   },
   "source": [
    "Before you continue, you need to split the downloaded images into a `train` folder and into a `validation` folder."
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {
    "colab_type": "raw",
    "id": "VamXG4FoGhJH"
   },
   "source": [
    "./\n",
    "├── train\n",
    "│   ├── brad pitt\n",
    "│   └── johnny deep\n",
    "|   ├── leonardo di caprio\n",
    "|   └── ...\n",
    "│       \n",
    "└── validation\n",
    "    ├── brad pitt\n",
    "    ├── johnny deep\n",
    "    ├── leonardo di caprio\n",
    "    └── ..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "9322su6vGhJJ"
   },
   "source": [
Simon van Hemert's avatar
Simon van Hemert committed
    "If you want to use the example of this jupyter notebook, you can use the images provided in the ./train and ./validation folders."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "xPqJWgeAGhJL"
   },
   "source": [
    "## Define a ConvNet Model"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": 9,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "UuJV4JBKGhJO"
   },
   "outputs": [],
   "source": [
    "batch_size = 20\n",
    "num_train_images = 480\n",
    "num_valid_images = 80\n",
    "num_classes = 8\n",
    "\n",
    "model_scratch = Sequential()\n",
    "model_scratch.add(Conv2D(32, (3, 3), input_shape=(image_size, image_size, 3)))\n",
    "model_scratch.add(Activation('relu'))\n",
    "model_scratch.add(MaxPooling2D(pool_size=(2, 2)))\n",
    "\n",
    "model_scratch.add(Conv2D(32, (3, 3)))\n",
    "model_scratch.add(Activation('relu'))\n",
    "model_scratch.add(MaxPooling2D(pool_size=(2, 2)))\n",
    "\n",
    "model_scratch.add(Conv2D(64, (3, 3)))\n",
    "model_scratch.add(Activation('relu'))\n",
    "model_scratch.add(MaxPooling2D(pool_size=(2, 2)))\n",
    "\n",
    "# this converts our 3D feature maps to 1D feature vectors\n",
    "model_scratch.add(Flatten())  \n",
    "model_scratch.add(Dense(64))\n",
    "model_scratch.add(Activation('relu'))\n",
    "model_scratch.add(Dropout(0.5))\n",
    "model_scratch.add(Dense(num_classes))\n",
    "model_scratch.add(Activation('softmax'))\n",
    "\n",
    "model_scratch.compile(loss='categorical_crossentropy',\n",
    "              optimizer='adam',\n",
    "              metrics=['accuracy'])\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": 10,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "JFdkIokMGhJT",
    "outputId": "63e7d032-4083-4fe0-d970-c10bf0c39a94"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 480 images belonging to 8 classes.\n",
      "Found 80 images belonging to 8 classes.\n"
     ]
    }
   ],
   "source": [
    "# This is the augmentation configuration we will use for training\n",
    "train_datagen = ImageDataGenerator(\n",
    "        rescale=1./255,\n",
    "        shear_range=0.2,\n",
    "        zoom_range=0.2,\n",
    "        horizontal_flip=True)\n",
    "\n",
    "# This is the augmentation configuration we will use for validation:\n",
    "# only rescaling\n",
    "validation_datagen = ImageDataGenerator(rescale=1./255)\n",
    "\n",
    "# This is a generator that will read pictures found in\n",
    "# subfolers of './train', and indefinitely generate\n",
    "# batches of augmented image data\n",
    "train_generator = train_datagen.flow_from_directory(\n",
    "        './train',  # this is the target directory\n",
    "        target_size=(image_size, image_size),  # all images will be resized to 150x150\n",
    "        classes=class_names,\n",
    "        batch_size=batch_size)  \n",
    "\n",
    "# This is a similar generator, for validation data\n",
    "validation_generator = validation_datagen.flow_from_directory(\n",
    "        './validation',\n",
    "        target_size = (image_size, image_size),\n",
    "        classes = class_names,\n",
    "        batch_size = batch_size)"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": 12,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "cytHiQUTGhJb"
   },
   "outputs": [],
   "source": [
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "logdir = os.path.join(\"logs\", datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\"))\n",
    "tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "C7dCbyXPGhJg",
    "outputId": "98b4085e-ed6d-43e2-831f-aec32161583f"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/20\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
      " 2/24 [=>............................] - ETA: 34s - loss: 2.1133 - accuracy: 0.0500    "
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.7/site-packages/PIL/Image.py:952: UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images\n",
      "  \"Palette images with Transparency expressed in bytes should be \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
Mirko Birbaumer's avatar
Mirko Birbaumer committed
      "24/24 [==============================] - 33s 1s/step - loss: 2.0931 - accuracy: 0.1250 - val_loss: 2.0772 - val_accuracy: 0.1500\n",
      "Epoch 2/20\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
      "18/24 [=====================>........] - ETA: 6s - loss: 2.0769 - accuracy: 0.1333"
     ]
    }
   ],
   "source": [
    "history = model_scratch.fit(\n",
Simon van Hemert's avatar
Simon van Hemert committed
    "    train_generator,\n",
    "    steps_per_epoch = num_train_images // batch_size,\n",
    "    epochs = 20,\n",
    "    validation_data = validation_generator,\n",
    "    validation_steps = num_valid_images // batch_size,\n",
    "    callbacks = [tensorboard_callback])"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "wt_ONw5PGhJm",
    "outputId": "e75d8a73-da49-4dbe-ffcf-7cb316be39a2"
   },
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "plt.plot(history.history['accuracy'])\n",
    "plt.plot(history.history['val_accuracy'])\n",
    "plt.title('model accuracy')\n",
    "plt.ylabel('accuracy')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'valid'], loc='lower right')\n",
    "plt.show()\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'valid'], loc='upper right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tensorboard"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "# Load the TensorBoard notebook extension\n",
    "%load_ext tensorboard\n",
    "\n",
    "os.makedirs(logdir, exist_ok=True)\n",
    "%tensorboard --logdir logs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Y8oAT4oUGhJs"
   },
   "source": [
    "# Part II : Transfer Learning\n",
    "\n",
    "\n",
    "Having to train an image-classification model using very little data is a common situation,\n",
    "which you’ll likely encounter in practice if you ever do computer vision in a\n",
    "professional context. A “few” samples can mean anywhere from a few hundred to a\n",
    "few tens of thousands of images. As a practical example, we’ll focus on classifying\n",
    "560 images belongig to 8 actors. We’ll use 480 pictures for training, and 80 for validation.\n",
    "\n",
    "## 2.1 Feature Extraction with a Pretrained Model\n",
    "Feature extraction consists of using the representations learned by a previously\n",
    "trained model to extract interesting features from new samples. These features are\n",
    "then run through a new classifier, which is trained from scratch.\n",
    "As you saw previously, ConvNets used for image classification comprise two parts:\n",
    "they start with a series of pooling and convolution layers, and they end with a densely\n",
    "connected classifier. The first part is called the _convolutional base_ of the model. In the\n",
    "case of convnets, feature extraction consists of taking the convolutional base of a previously\n",
    "trained network, running the new data through it, and training a new classifier\n",
    "on top of the output.\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "from IPython.display import Image\n",
    "Image(\"./Images/feature_extraction.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Why only reuse the convolutional base? Could we reuse the densely connected\n",
    "classifier as well? In general, doing so should be avoided. The reason is that the representations\n",
    "learned by the convolutional base are likely to be more generic and, therefore,\n",
    "more reusable: the feature maps of a ConvNet are presence maps of generic\n",
    "concepts over a picture, which are likely to be useful regardless of the computer vision\n",
    "problem at hand. But the representations learned by the classifier will necessarily be\n",
    "specific to the set of classes on which the model was trained—they will only contain\n",
    "information about the presence probability of this or that class in the entire picture.\n",
    "Additionally, representations found in densely connected layers no longer contain any information about where objects are located in the input image; these layers get rid of\n",
    "the notion of space, whereas the object location is still described by convolutional feature\n",
    "maps. For problems where object location matters, densely connected features\n",
    "are largely useless.\n",
    "\n",
    "\n",
    "Note that the level of generality (and therefore reusability) of the representations\n",
    "extracted by specific convolution layers depends on the depth of the layer in the\n",
    "model. Layers that come earlier in the model extract local, highly generic feature\n",
    "maps (such as visual edges, colors, and textures), whereas layers that are higher up\n",
    "extract more-abstract concepts (such as “cat ear” or “dog eye”). So if your new dataset\n",
    "differs a lot from the dataset on which the original model was trained, you may be better\n",
    "off using only the first few layers of the model to do feature extraction, rather than\n",
    "using the entire convolutional base.\n",
    "\n",
    "\n",
    "\n",
    "In this case, because the ImageNet class set does not contain images of actors, we’ll \n",
    "choose not to use the densely connected layers, in order to cover\n",
    "the more general case where the class set of the new problem doesn’t overlap the\n",
    "class set of the original model. Let’s put this into practice by using the convolutional\n",
    "base of the VGG16 network, trained on ImageNet, to extract interesting features\n",
    "from actors, and then train a classifier for the 8 actors on top of\n",
    "these features.\n",
    "\n",
    "The VGG16 model, among others, comes prepackaged with Keras. You can import\n",
    "it from the `keras.applications` module. Many other image-classification models (all\n",
    "pretrained on the ImageNet dataset) are available as part of `keras.applications`:\n",
    "\n",
    "\n",
    "-  Xception\n",
    "-  ResNet\n",
    "-  MobileNet\n",
    "-  EfficientNet\n",
    "-  DenseNet\n",
    "-  etc.\n",
    "\n",
    "Let's instantiate the VGG16 model."
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "4Luec7pbGhJv",
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# General imports\n",
    "import sys\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import confusion_matrix\n",
    "import tensorflow as tf\n",
    "from tensorflow import keras\n",
    "from tensorflow.keras import layers\n",
    "\n",
    "# Shortcuts to keras if (however from tensorflow)\n",
    "from tensorflow.keras import applications\n",
    "from tensorflow.keras import optimizers\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Conv2D, MaxPool2D\n",
    "from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense\n",
    "from tensorflow.keras.callbacks import TensorBoard \n",
    "\n",
    "# Shortcut for displaying images\n",
    "def plot_img(img):\n",
    "    plt.imshow(img, cmap='gray')\n",
    "    plt.axis(\"off\")\n",
    "    plt.show()\n",
    "    \n",
    "# The target image size can be fixed here (quadratic)\n",
    "# The ImageDataGenerator() automatically scales the images accordingly (aspect ratio is changed)\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "image_size = 150"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "eRes_n9BGhJ0"
   },
   "outputs": [],
   "source": [
    "conv_base = keras.applications.vgg16.VGG16(weights=\"imagenet\",\n",
    "                                           include_top=False,\n",
    "                                           input_shape=(image_size, image_size, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "vEIWLeqSGhJ5"
   },
   "source": [
    "You pass three arguments to the constructor:\n",
    "\n",
    "- `weights` specifies the weight checkpoint from which to initialize the model.\n",
    "\n",
    "- `include_top` refers to including (or not) the densely connected classifier on\n",
    "top of the network. By default, this densely connected classifier corresponds to\n",
    "the 1'000 classes from ImageNet. Because we intend to use our own densely\n",
    "connected classifier (with 8 classes of actors), we don’t need to\n",
    "include it.\n",
    "- `input_shape` is the shape of the image tensors that we’ll feed to the network.\n",
    "This argument is purely optional: if we don’t pass it, the network will be able to\n",
    "process inputs of any size. Here we pass it so that we can visualize (in the following\n",
    "summary) how the size of the feature maps shrinks with each new convolution\n",
    "and pooling layer."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here’s the detail of the architecture of the VGG16 convolutional base. It’s similar to\n",
    "the simple convnets you’re already familiar with:"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "M7Bk7t1MGhJ6"
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "conv_base.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "DBSrhVORGhKH"
   },
   "source": [
    "\n",
    "The final feature map (output volume) has shape $(5, 5, 512)$. That's the feature on top of which we will stick a densely connected classifier.\n",
    "\n",
    "At this point, there are two ways how we could proceed:\n",
    "\n",
    "- __Approach 1__: Run the convolutional base over our dataset, record its output to a NumPy array\n",
    "on disk, and then use this data as input to a standalone, densely connected classifier\n",
    "similar to those you saw in Block 4 of this course. This solution is fast and\n",
    "cheap to run, because it only requires running the convolutional base once for\n",
    "every input image, and the convolutional base is by far the most expensive part\n",
    "of the pipeline. But for the same reason, this technique won’t allow us to use\n",
    "data augmentation.\n",
    "\n",
    "- __Approach 2__: Extend the model we have (`conv_base`) by adding `Dense` layers on top, and run\n",
    "the whole thing from end to end on the input data. This will allow us to use\n",
    "data augmentation, because every input image goes through the convolutional\n",
    "base every time it’s seen by the model. But for the same reason, this technique is\n",
    "far more expensive than the first.\n",
    "We’ll cover both techniques. Let’s walk through the code required to set up the first\n",
    "one: recording the output of `conv_base` on our data and using these outputs as inputs\n",
    "to a new model."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "mlpIDmSCGhKI"
   },
   "source": [
    "### 1. Approach : Fast feature extraction without data augmentation\n",
    "We’ll start by extracting features as NumPy arrays by calling the `predict()` method of\n",
    "the `conv_base` model on our training, and validation datasets.\n",
    "Let’s iterate over our datasets to extract the VGG16 features."
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "from tensorflow.keras.utils import image_dataset_from_directory\n",
    "train_dataset = image_dataset_from_directory(\n",
    "    './train',\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "    image_size=(150, 150),\n",
    "    batch_size=32,\n",
    "    label_mode=\"categorical\")\n",
    "validation_dataset = image_dataset_from_directory(\n",
    "    './validation',\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "    image_size=(150, 150),\n",
    "    batch_size=32,\n",
    "    label_mode=\"categorical\")"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "def get_features_and_labels(dataset):\n",
    "    all_features = []\n",
    "    all_labels = []\n",
    "    for images, labels in dataset:\n",
    "        preprocessed_images = keras.applications.vgg16.preprocess_input(images)\n",
    "        features = conv_base.predict(preprocessed_images)\n",
    "        all_features.append(features)\n",
    "        all_labels.append(labels)\n",
    "    return np.concatenate(all_features), np.concatenate(all_labels)\n",
    "train_features, train_labels = get_features_and_labels(train_dataset)\n",
    "val_features, val_labels = get_features_and_labels(validation_dataset)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Importantly, `predict()` only expects images, not labels, but our current dataset yields\n",
    "batches that contain both images and their labels. Moreover, the VGG16 model expects\n",
    "inputs that are preprocessed with the function `keras.applications.vgg16.preprocess_input`, which scales pixel values to an appropriate range.\n",
    "The extracted features are currently of shape `(samples, 5, 5, 512)`:"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "train_features.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And the labels are now referring to the order of the folders"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "train_labels.shape"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "print(val_features.shape)\n",
    "print(val_labels.shape)"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "inputs = keras.Input(shape=(4, 4, 512))\n",
    "# Note the use of the Flatten\n",
    "# layer before passing the\n",
    "# features to a Dense layer\n",
    "x = layers.Flatten()(inputs)\n",
    "x = layers.Dense(256)(x)\n",
    "x = layers.Dropout(0.7)(x)\n",
    "outputs = layers.Dense(8, activation=\"softmax\")(x)\n",
    "model = keras.Model(inputs, outputs)"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "model.compile(loss=\"categorical_crossentropy\",\n",
    "    optimizer=\"rmsprop\",\n",
    "    metrics=[\"accuracy\"])\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "\n",
    "logdir = os.path.join(\"logs\", datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\"))\n",
    "\n",
    "\n",
    "callbacks = [\n",
    "    keras.callbacks.ModelCheckpoint(filepath=\"feature_extraction.keras\", save_best_only=True, monitor=\"val_loss\"),\n",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
    "    tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)\n",
    "]\n",
    "\n",
    "history = model.fit(\n",
    "train_features, train_labels,\n",
    "epochs=30,\n",
    "validation_data=(val_features, val_labels),\n",
    "callbacks=callbacks\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that we’ll also use a `ModelCheckpoint` callback to save the model after each\n",
    "epoch. We’ll configure it with the path specifying where to save the file, as well as the\n",
    "arguments `save_best_only=True` and `monitor=\"val_loss\"`: they tell the callback to\n",
    "only save a new file (overwriting any previous one) when the current value of the\n",
    "`val_loss` metric is lower than at any previous time during training. This guarantees\n",
    "that your saved file will always contain the state of the model corresponding to its bestperforming\n",
    "training epoch, in terms of its performance on the validation data. As a\n",
    "result, we won’t have to retrain a new model for a lower number of epochs if we start\n",
    "overfitting: we can just reload our saved file."
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let’s look at the loss and accuracy curves during training:"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "plt.plot(history.history['accuracy'])\n",
    "plt.plot(history.history['val_accuracy'])\n",
    "plt.title('model accuracy')\n",
    "plt.ylabel('accuracy')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'valid'], loc='lower right')\n",
    "plt.show()\n",
    "plt.plot(history.history['loss'])\n",
    "plt.plot(history.history['val_loss'])\n",
    "plt.title('model loss')\n",
    "plt.ylabel('loss')\n",
    "plt.xlabel('epoch')\n",
    "plt.legend(['train', 'valid'], loc='upper right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We reach a validation accuracy of about 32% — much worse than we achieved in the\n",
    "previous section with the small model trained from scratch. \n",
    "\n",
    "The learning curves indicate that we’re overfitting almost from the start—\n",
    "despite using dropout with a fairly large rate. That’s because this technique doesn’t\n",
    "use data augmentation, which is essential for preventing overfitting with small image\n",
    "datasets."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Tensorboard"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import datetime, os\n",
    "\n",
    "# Load the TensorBoard notebook extension\n",
    "%load_ext tensorboard\n",
    "\n",
    "%tensorboard --logdir logs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "DJT-DgHvGhKu"
   },
   "source": [
    "### 2. Approach : Feature Extraction with Data Augmentation\n",
    "\n",
    "\n",
    "Now let’s review the second technique we mentioned for doing feature extraction,\n",
    "which is much slower and more expensive, but which allows us to use data augmentation\n",
    "during training: creating a model that chains the `conv_base` with a new dense\n",
    "classifier, and training it end to end on the inputs.\n",
    "In order to do this, we will first freeze the convolutional base. Freezing a layer or set of\n",
    "layers means preventing their weights from being updated during training. If we don’t\n",
    "do this, the representations that were previously learned by the convolutional base will\n",
    "be modified during training. Because the Dense layers on top are randomly initialized,\n",
    "very large weight updates would be propagated through the network, effectively\n",
    "destroying the representations previously learned.\n",
    "\n",
    "In Keras, we freeze a layer or model by setting its trainable attribute to `False`. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "50DF9pH1GhKw"
   },
   "source": [
    "#### Instantiating and freezing the VGG16 convolutional base"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "conv_base = keras.applications.vgg16.VGG16(weights=\"imagenet\", include_top=False)\n",
    "conv_base.trainable = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Setting trainable to `False` empties the list of trainable weights of the layer or model."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Printing the list of trainable weights before and after freezing"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "conv_base.trainable = True"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "outputs": [],
   "source": [
    "print(\"This is the number of trainable weights before freezing the conv base:\", len(conv_base.trainable_weights))"
   ]
  },
  {
   "cell_type": "code",
Mirko Birbaumer's avatar
Mirko Birbaumer committed
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "conv_base.trainable = False"