{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1a0c2996-af15-4641-8f01-e6dfadb5f2fe",
   "metadata": {
    "id": "4e860ae3"
   },
   "source": [
    "# Lecture 19 - Generalization, Continued\n",
    "## Hyperparameter Tuning and Regularization"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df91baf8-f15a-474c-93fd-5f9c9bd98783",
   "metadata": {},
   "source": [
    "### Announcements\n",
    "\n",
    "* New seats, new friends, as of Monday:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "10911f61-893c-4067-ad26-6726344412f7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Malik', 'Josh', 'Alli', 'Erika']\n",
      "['Marcus', 'Keira', 'Maven', 'Dylan', 'Zach']\n",
      "['Narina', 'Finnley', 'Haden', 'Sebastian']\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "random.seed(518)\n",
    "datafolk = \"Alli Keira Malik Erika Narina Sebastian Josh Dylan Haden Zach Maven Marcus Finnley\".split()\n",
    "random.shuffle(datafolk)\n",
    "print(datafolk[:4])\n",
    "print(datafolk[4:9])\n",
    "print(datafolk[9:])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd07fa8e-5df2-46f7-9ac4-f28bd13c0ac2",
   "metadata": {
    "id": "a21c895c"
   },
   "source": [
    "### Goals\n",
    "* Know why and how to subdivide datasets into **training**, **validation**, and **test** sets\n",
    "* Understand what **hyperparameters** are and how to tune them using a validation set\n",
    "* Know how cross-validation works and why you might want to use it."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77c8c90d-d3f9-43c5-bcad-35de97eaec94",
   "metadata": {},
   "source": [
    "### Notes\n",
    "Lecture notes for today's content:\n",
    "  * See the notebook from last lecture (L18)\n",
    "  * See the whiteboard notes from L18 and today (L19)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32dd0f34-3d86-46cc-af0e-878f9fddad1c",
   "metadata": {},
   "source": [
    "### Warm-up\n",
    "Questions 1--3 on today's worksheet\n",
    "\n",
    "### Whiteboard:\n",
    "* MLBot 1.0 - Triain/val/**test** splits\n",
    "* Cross-validation\n",
    "* Hyperparameters and Regularization"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "562d22c8-0785-48ac-a46f-982a38953ead",
   "metadata": {},
   "source": [
    "## Hyperparameter Tuning and Regularization: Activity"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5444ebc1-7192-4075-a033-eaba86591a85",
   "metadata": {},
   "source": [
    "### 0. Imports and Data Splits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4c8421b4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train: 507\n",
      "  Val: 169\n",
      " Test: 170\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.datasets import fetch_openml\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "data = fetch_openml('vehicle', version=1, as_frame=False, parser='auto')\n",
    "X, y = data.data, data.target\n",
    "\n",
    "# This converts features to z-scores:\n",
    "X = StandardScaler().fit_transform(X)\n",
    "\n",
    "train_frac = 0.6\n",
    "\n",
    "X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=1-train_frac, random_state=311)\n",
    "X_val,   X_test, y_val,   y_test  = train_test_split(X_temp, y_temp, test_size=0.5, random_state=311)\n",
    "\n",
    "print(f\"Train: {len(X_train)}\\n  Val: {len(X_val)}\\n Test: {len(X_test)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42e3095d",
   "metadata": {},
   "source": [
    "### 1. Train a family of models with different values of $C$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d076ef5c",
   "metadata": {},
   "outputs": [],
   "source": [
    "C_values = [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "\n",
    "train_accs, val_accs = [], []\n",
    "\n",
    "for C in C_values:\n",
    "    svm = SVC(kernel='linear', C=C) # make the classifier\n",
    "    svm.fit(X_train, y_train) # train the classifier\n",
    "    train_accs.append(svm.score(X_train, y_train)) # evaluate on the training set\n",
    "    val_accs.append(  svm.score(X_val,   y_val))   # evaluate on the validation set\n",
    "\n",
    "best_C = C_values[np.argmax(val_accs)]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ba8ec9c",
   "metadata": {},
   "source": [
    "### 2. Plot the training and validation accuracy for each model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "56e4d6ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3kAAAHpCAYAAAA/CfW/AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYYJJREFUeJzt3Qd4VfX9x/HPzc1iJew9RTYIAqKoqAxBsDhqrdaK1bqoWmuptlL/VdG2Thy11YqbunBPpojKUBmiLNnITAhhJIGQff/P91wSMm4ggSTnjvfreY6595w7fjknwfvJb3w9Pp/PJwAAAABAWIhyuwEAAAAAgKpDyAMAAACAMELIAwAAAIAwQsgDAAAAgDBCyAMAAACAMELIAwAAAIAwQsgDAAAAgDBCyAMAAACAMELIAwAAAIAwQsgDAAAR495775XH49FPP/3kdlMAoNoQ8gCgGqSkpOjPf/6zevbsqXr16ikxMVGdOnXS5Zdfrvfee895zMqVK50PmxdddNERX+uNN95wHnf33Xc7919++WXnvm2PPvpowOd8//33RY+5+uqrj9pe+8Brjx07dmy5j7HvpX379kd9LYRO2Pnggw9q9D2L/+webTvnnHNqtG0AEE6i3W4AAISbrVu36pRTTlFGRoZ+/etf63e/+52zf/369fr000+1f/9+/fznP1ePHj102mmnOft27typZs2aBXy9F1980fnQe80115TYHx8fr5deekm33357mee88MILzvGsrKxq+i4R6iZMmKDf/OY3R/0jQ1U666yz9L///a/EvkmTJmnu3Ll6/PHH1bhx46L95f0+HK//+7//05133qm4uLhqeX0ACAaEPACoYo888ogT2j766CONHj26xDH7ILtt27ai+9dee62++eYbvfrqq/rTn/5U5rW2bNmizz//XEOGDFGHDh1KHLv44oudXr6FCxdqwIABRfuzs7P1+uuvO0HSvkaivLw85efn1/gH+YKCAuf816pVS5HM/pBRt27dMvtPOOEEZyvus88+c0Kehc2a6CmOjo52NgAIZwzXBIAqtnbtWufr4MGDAx5v3bp10e3LLrtMderUcXrryhveZsHBwmBpo0aNcno7rDevuA8//FB79uwp0/NX1S688EKn7WlpaWWOLV261Ol9vOuuu0oMB7UhghZMTzrpJKensU2bNs4w1Nzc3DKvkZSU5PSCtm3bVrGxsWrZsqVuuOEGZyhsoDlWNvx13Lhxzvm1cPf11187xwuHrFqYsJ7T2rVrO+ft1ltvdcJIcTt27HDCdp8+fdSgQQOnjd27d9dDDz3khMZAQw/tde+//3517NjRed8pU6Y4x2fOnOlcXws1Fvrq16+v4cOH68svvyzzvdrQRAs4dp4svNtj7f2t3dZG+xn45z//6QR9e4+TTz7ZCUal+Xw+PfPMM+rXr5/zfdpQYfs5nDNnTtFjvvjiC6fd5pVXXikaHlk6YNn3ceaZZzqvYa916qmn6p133inznoXnd/bs2c7jLdz97Gc/U3XNm7N2lh7KWdiGefPmadCgQU57rVfwuuuuK3ONA7124b7Vq1c7w6xbtWrlnOfevXtr6tSpZdpgPeSFj7OfEXuc/Vwz3w9AsOBPWQBQxQp7Kp577jnddtttRR+oA7EP0L/85S+doPbtt986H6SLf2C3IGEf+O2Df2nWG3HllVfq+eef12OPPVbUe2SB0UKABZXKsg+vqampAY+VDjkWuKy30j7clp7LZ8NF7fsuHU4//vhjPfHEE7r55pvVvHlz5/kWkOwD9+TJk0v0YA4cOFA5OTnOa1iA2rBhg55++mknsCxevNiZ51icDY210Gkhzd67RYsWRce+++47J6Bcf/31uuqqq5zXeOqpp7Rs2TKnpzQqyv83T7tv89SsF9QClb3/tGnTnOF9Gzdu1LPPPlvmvNhwWes5tNdOSEhQly5dnP127fbt2+eEbWvL9u3bnWs1dOhQ5/0tjBR34MABJ5DZ9uCDD2rJkiXO4w8ePOgEFuux/f3vf+8EYpuLecEFF2jz5s3OexYaM2aMcz1+8YtfOO9rvYqvvfaazj33XGcuqD2nW7duzpBJe6y1wa6jKd7zZkMa//GPf+i8885zro/X69X777+vSy+9VP/+97+d61ecXQ97fQtVNgTUDTYP1f7w8Nvf/tb5vbAwaz+Hdm1tSGhFWNst3N1xxx3OtbefVethtD/cFA/B9jtrP8vnn3++Ro4c6fxxwP4gYT+nABAUfACAKrVhwwZfQkKCz/6JbdOmje+KK67wPf74477FixcHfPy8efOcx954440l9n/++efO/ptvvrnE/pdeesnZ/8Ybb/hWrFjh3H7ttdecY1u3bvVFRUX5nnrqKd+uXbucY7/5zW+O2uZNmzY5jz3a1q5du6Ln5Ofn+9q2bevr169fidc6ePCgr0GDBr4hQ4aUeX1r25IlS4r2FxQU+C666CLnmJ2HQqNHj/Y1btzY+X6KW7Rokc/r9fruueeeon12254/ePBgX15eXpnvrbDt77//fon9t956q7P/1VdfLdqXmZnptKm0K6+80mn7jh07ylyHLl26OM8rbf/+/WX2JScn+xo1auQbOXJkif1nn32281oTJ04ssf+SSy7xeTwe3ymnnOLLzc0t2v/hhx86j3/mmWeK9r377rvOvv/+978lXsOeZ9eoffv2Jb638n427OfUjt15551ljl144YW+evXq+dLT00u8jm2zZ8/2HQtrgz3ffkZKX9Pi+wrZz6Cdr+LssXaevv766xL7R40a5YuOjvZlZGQc8bUL951//vklztHChQvLnItp06Y5+6666qoS77V06VLnZ6S8dgNATWK4JgBUQ0/eDz/8oJtuuskZZmfz4v74xz+qf//+zjBF66Ep7owzzlDXrl315ptvOr02hQqHcAYaqlnIFm+x+XiFQzZt+F1MTIyuuOKKY2q7DbObNWtWwK30cD7rIbFeE/t+7PstZD06e/fudXp1SrMepb59+xbdtx43G/ZmrKfIWO+XLUZjbbGhcNazWLhZG0488URnKGRpf/jDH5wep0Csd630AiPWO1f8fY31hhb2vFpPjg17tfcdMWKEcy2tx6o068EJNAfPehUL2ZDB3bt3O+2z3lrrtS3NjpXuIbOfDcswN954Y4l5ZIW9gLaYTyHrsbP3tO+z+Dmz82lzQ623dN26dTqawnmc1uNZ/HVss55AW1CocChsIes1tnmjbrKeXxuOW5y1yXpZK1ouwX6Give82wJK1tte/LzZcGhTesEjOwc2HBcAggHDNQGgGlgY+c9//uNsNrfMPhRbALPhiRZebP5Yw4YNix5vYcnCzrvvvusMNUtPT3fCkg27tO1IbFieBUobumdDBG3Imr12ecMuj8TmGA0bNizgMQsQpec3WZCz4Xw2LO5f//qXs89u2/vbkMfSbKhgaTbnzdhwTGND4yxQ2fdiWyClF+8wVqKiPIHe14ZQ2lDYwvc1FghsqKQNHbUA5e8kOszCa0Xf117X5iTOmDHDCVrFBRrCa+0pvVCMzcszpQN24X4LjoV+/PFHZ8inDYMtjy0I1Llz53KPF75O8etS3utU9NzXlEA/E40aNSpznir7GvazXPz5mzZtcq5foPNof6yZPn16JVsOAFWPkAcA1cw+vFvgsc162GzOlC3mYGGukPWa/PWvf3V65Gy/9eplZmY64e9ofvWrXzkLjticMAsmNmeqplgotAVgbHXQhx9+2Am0Nt/M5o4FWtnySPMTC48VBiv7vsr7/gP1nNliG0d77dLsvYofsx5XO3+2YIoFtKZNmzo9ozan7y9/+YsTPivyvtbbZb1tdg1tXmavXr2cHiHr/XzggQeceYClldcLeaRjxUOo3bZAUrjwS3m1Do+m8DXtZ9S+9/J6kCt67o/FkX5OLIgHcqTzVzqsH+95Pt73AYDqRsgDgBoeUmYhzxbhKM5We7QePhsKZkPLbKimhSRbTORobAESW5jFhtnZapU2JLIm2cIdtgiFDXtctWqV80E30FBNY8fL21fYi2LDMe1Dvi0aUl6vYmUFel8LpLYyaPHeGwurVsvNQnZxxYdFVoSFOHt9u46lVzm1RU2qg/UsrVmzxhliWHpRmsq+jvVG2SqlFk7dUNjLbcNli/di2sJAdl7tZ8Qt9vNiP+N2rm34dXG2DwCCAXPyAKCKWU9W8bl1hawXyMJQeUPhbO6dfXi0YZs2Z8t6/gqH5R2N9TLdc889Ti9U4UqRNcV68ixc2gqGNrzS5giWFw5sbp/1ihWy79d6AE3hCqI2xM5e0wLv/Pnzy7yGPWfXrl2VaqN9+LZVM4uzsgjF37ewJ6d0b4wNgbT6hpVR2CNU+rVsLmGg+XhVwVbLtPcbP358wB6l0kMsbTXNQMNPC3uYrWc5UK9Z6RIW1aFwKKSVpyjOrkOg3tSaZPMSja1wWnp1z0BzRQHADfTkAUAVmzhxohNOrGfO6pVZr0pycrIz384WKbEl8m3p9dJsKXarBff2228fdcGV0qxHoXSvQk2xUGlttRphxurelcfqidliGLbAiA1jtSBnH+QtoNgiI4Ws1pvVXLNzZcdssRb7cG9lDOw5Nry18P0qwkKnhRcb0mrzxyyIW0mFs88+2xkWWshKD1iZBBuuab2IFoysN65wbldFWdttbpyVc7CeWesVsxBgpQusLcuXL1dVKyybYOfO3ssWW7HSC9u2bXPmhFpvpJ2/QrYAjJ37Rx55xAnpNufSnmM9gRMmTHD+aGCLiVi5APu5tB40+/m1YZy2KE11snNv89vsZ8nmw1k5C6uB98033zjfk5vs99T+CGHX0noaC0soWHkPmz9r5+hIw00BoCYQ8gCgitlwPAtqX331lfOXffsgaB+gbfEPC4AWcAL1tlnvj9XpsjlbNkTN7dUKK8NCni3AYqthXn755UfsBbGVLu17tN41m/P2t7/9zdmKs9BhH5att81Cna0cWVg83YKIBY/KsJBotQRtnt1///tfp7bcLbfc4hQYL34t7DE2d+6tt95y3tfez4ajWvCpzNBRW9DFFlyxXlmrx2c9Yhb4LSDZwjTVEfKMBVILxtaraufYwpiFTfv+7X5xtiiQLdhz3333OQvqtGvXzjm3xsKVtdcW07FacdabadfK5vQ9+eSTqm72u2Dn3wrW2/mLjY0tKiRf/I8BbrE/ENjPrA2RtqBsgdTOuYVQ+7kNNGcUAGqSx+oo1Og7AgDCjvVUWiCyHjYLMaVZb5b1xljvUGV64KqC9apYeC5vpU6gqljvvfUS2+q4R1oIBgCqG3PyAADHzYaqWW+V1XMDwl2gObdLly51FqwZOnQoAQ+A6xiuCQA4ZrYK5ZYtW5x5XTaczhZdAcKdDXG1UGdDqm1orq3e+txzzzkr4tqwZQBwGyEPAHDMbNESmytnNeFsPhgQCazMxoIFC5w/blihewt6I0aMcIYj2+JCAOA25uQBAAAAQBhhTh4AAAAAhJGIHK5ptZaspo0tk00tGwAAAAChwAojZGRkOPVLA5VjiuiQZwHPlvoGAAAAgFCzdetWtW7dutzjERnyrAev8ORYQVwAAAAACHZWh9M6qwrzTHkiMuQVDtG0gEfIAwAAABBKjjbljIVXAAAAACCMEPIAAAAAIIwQ8gAAAAAgjBDyAAAAACCMEPIAAAAAIIwQ8gAAAAAgjBDyAAAAACCMEPIAAAAAIIwQ8gAAAAAgjBDyAAAAACCMEPIAAAAAIIwQ8gAAAAAgjBDyAAAAACCMEPIAAAAAIIxEu90AAAAAAKgpPp9PWbkFysjKVXpWnvM1w/la/Lb/WN24aN0+okvIXRxCHgAAAICQCWiZOfklglh5IS3DvmYHPp5X4KvQ+7VMjCfkAQAAAEB5Ae2AE9BK9pYFDGflHN+fnaf8Cga0o4nySPXiY1QvPrroa0J8tNN7V3i/cd04hSJ68gAAAAAcUUGBBbTCwHU4dKUfqRetxPFcJ6BVUT6TN8pzKJxFq17c4aBmIa1esdB2+Gvx4/59tWO98ng8YXnlCXkAAABAmAe0/TmBg1jJ4Y6BAps/qFlA81VRQIsuCmglA5i/J63svuK9bIW3a8WEb0CrCoQ8AAAAIEjZ0MT9pXrE/HPNyvaW7S8nqFnAq6qAFuO1gBYTsBetdBArrxctPiaKgFbNCHkAAABANcjLL3B6wI42rPFIvWk2h62qxEZHlQphJeefHW24o/WyxUUT0EIBIQ8AAAAIENACzSsLtHJjeYuH2CqQVcXCVeAQduRhjcUfFxft5TpHCEIeAAAAwkpuUUCr/OIghfsO5lZdQLPhiQF7y+KOvjhI4T7rhQMqipAHAACAoJGdl19uYeoS88yKzUsrPdzRCl1XFVvgozKLg5Q87v8a4yWgoWYR8gAAAFAlsnIPF6mu0FL7xRYPKQxyOXlVF9BsifwjDmd05qMFOu7/WpeAhhBFyAMAAIhwVqQ6O6/gmBcHKbydk191Ac2/IEhFessCD3u050fTg4YIRcgDAAAI8YBm88cCha4jDXcs3YuWm19Fa+xLAXrIKr44iN22gGbFrgEcG0IeAACAiwHNVmAsGcQq2JuWfXhuWl5B1QQ0qy1tASvwnLOKLbVfNzZaUQQ0wFWEPAAAgGMIZzY00Rb4yMwpOaesvBUcAy4ekp3nFLuuCparitc8q+ziILbVIaABYYGQBwAAQp4FJVv0w9nyCg7fzi1QtrPPf7toX/H7efnKLjp2aL9z/PBjbL5a6eO+qhvd6AS0Iw9nPPpwxzqxXnmsKw5AxCPkAQCAauvlyi4nNBUPY0WPCRDG/AGs/OOFAa4q55NVVnSUp9xhjdZbdngBkfJrodkqkAQ0AFWFkAcAQAT0cpXouSoVvLLLC1hB0stVWbHeKMXFRCk+xusUoY6P9h6+HeNVnHP/CMftdnRU0Vf/sWLPOfR853hMlPN+BDQAwYSQBwBADYq0Xi4bPVgYigrDUlxRcCoZmoqOBwhexcNYXDnPc4JXtJdVGQFEPEIeAABVoKDAp++27NXU5cn6MSndWdI+aHu5CnupyunN8vdgHeU4vVwAELQIeQAAHMcwyEU/7dG05UmatiJZKRnZlXo+vVwAgOpAyAMAoBLy8gv0zcY9mroiSTNXJit1f06JAtDDujfTmSc2dhbTYC4XAMANhDwAAI4iJ69ACzakatryZM1clay9mblFxxJrxejc7s00qldznXFiY2dOGAAAbiLkAQAQgK1GOW9dqjPHbtaqZKeIdaGGdWI1okczjezZQgM7NlKMN4pzCAAIGoQ8AAAOscVRvlizS9NXJOmzH1O0P/twsGtcN07n9WymUT1baECHhoom2AEAghQhDwAQ0TJz8jRn9S5njt2c1SnKzMkvOtYsIc7prRvZs7n6t2/I0vwAgJBAyAMARJyMrFx9vjrFmWP3xdoUp7RBoVb1azmhbmSv5jq5TQNFRXlcbSsAAJVFyAMARIS0g7ma/eNOZ47dV+t2OYupFGrbsLYT6mwo5kmtE+Wx2gYAAIQoQh4AIGztPZCjWat2atqKJM1bn6rc/MNVyE9oXMcJdjYcs0fLBIIdACBsEPIAAGEldX+2Zq70B7sFG3Y7BcsLdW5W1wl1o3q1cG7TYwcACEeEPABAyEtJz9KMlcnOUMxvN+1WsVynbi0SNOrQHLsTm9Zzs5kAANQIQh4AICQlpR3U9BXJzuIpizbvka9YsOvVKrFoKGaHxnXcbCYAADWOkAcACBlb92Q6wc7KHSzdsq/EsZPb1vevitmzhdo0rO1aGwEAcBshDwAQ1H5KPaBp1mO3IknLtqUV7bcFMPu3a+CEuvN6NlfL+rVcbScAAMGCkAcACDobdu3XtOVJzhy7VUnpRfutZN2ADg2dhVNG9GiuZgnxrrYTAIBgRMgDALjO5/NpXcp+TV2e5MyxW7Mzo+iYN8qjgSc0cubYDe/eXE3qxbnaVgAAgh0hDwDgWrCzXjoLdTbHbuOuA0XHoqM8OrNTY2eO3bndm6thnViuEgAAFUTIAwDUaLBbvj3NGYZpc+w2784sOhbrjdJZnS3YtdCwbs2UWDuGKwMAQKiGvKefflqPPPKIkpKS1KNHDz3xxBMaNGhQuY9/7bXX9PDDD2vdunVKTEzUeeedp0cffVSNGjWq0XYDAI6uoMCn77ftK5pjt33fwaJjcdFROqdLE2eO3ZCuTVUvnmAHAEDIh7wpU6botttuc4LeGWecoWeffVYjR47UqlWr1LZt2zKPnzdvnq666io9/vjjGj16tLZv366xY8fquuuu0/vvv+/K9wAAKCm/wKclm/c6vXVW8iApLavoWK0YrxPobI7d4C5NVSfO9f8VAQAQVjw+GzvjolNPPVV9+/bVM888U7SvW7duuuiii/TAAw+Uebz12NljN2zYULTvqaeecnr2tm7dGvA9srOzna1Qenq62rRpo7S0NCUkJFT59wQAkSgvv0ALf9rjzLGbvjJZuzIO/7tbNy5aQ7s1dYZint25iWrFel1tKwAAochyjI1kPFqOcfXPpzk5OVqyZInuvPPOEvuHDx+uBQsWBHzO6aefrrvuuktTp051evxSUlL0zjvv6Pzzzy/3fSwsTpgwocrbDwCRLje/QN9s3O0Mw5y5Mlm7D+QUHasXH61zuzfTqJ4tnEVU4mMIdgAA1ARXQ15qaqry8/PVrFmzEvvtfnJycrkhz+bkXXbZZcrKylJeXp4uuOACpzevPOPHj9e4cePK9OQBACovJ69A8zekOnPsZq7aqX2ZuUXH6teO0fDuzTSyVwud0bGxYqOjOMUAANSwoJgI4fF4Sty3EaSl9xWyuXq33nqr7r77bo0YMcJZrOWOO+5w5uW98MILAZ8TFxfnbACAY5OVm6+561KdOXazVu1URlZe0bFGdWI1omdzp8fu1BMaKsZLsAMAIGJDXuPGjeX1esv02tkQzNK9e4Vs6KUt0GLBzpx00kmqU6eOsxrn3//+d7Vo0aJG2g4A4e5gTr6+XJviDMWc/eNOHcjJLzpmBcmthp3NsRvQoaFTsBwAAAQHV0NebGys+vXrp1mzZuniiy8u2m/3L7zwwoDPyczMVHR0yWZbUDQuryEDACHvQHae5qxJcRZP+Xx1ig7mHg52LRLjdZ712PVqoX5tGyiKYAcAQFByfbimzZUbM2aM+vfvr4EDB2rSpEnasmWLM/yycD6dlUmYPHmyc9/KJlx//fXOCpuFwzWtBMOAAQPUsmVLl78bAAg9GVm5TqCbujxJX6zZpey8gqJjrRvU8vfY9WqhPq3rE+wAAAgBroc8W0Bl9+7duu+++5zA1rNnT2flzHbt2jnHbZ+FvkJXX321MjIy9O9//1t/+tOfVL9+fQ0ZMkQPPfSQi98FAISWtMxczfpxp7N4is21y8k/HOzaNart9NbZHLuerRLKnSMNAACCk+t18oK5vgQAhJM9B3I0a1WyM8du/vpU5RUc/uf/hCZ1dH6vFs4cu24t6hHsAAAIQiFRJw8AUL2sIPnMVcnOHLuvN+5WfrFg16VZPY3s5Z9j16lpXYIdUJ78PCnvoJSbFfirxyvVanB4i6llS4dzPgG4hpAHAGFmZ3qWZqy0HrskLdy0R8VynXq0THBCnS2g0rFJXTebCRwbG4CUl33k0OV8zZJyDx7j11KvV3C4ZEiFeONKhr6irf6R98UlEA4BVAlCHgCEgR37DmraCuuxS9KSLXudz8GFerdOdBZOsQVU2jWq42YzEYm9XOUFsMqErNLPlYszTSzAxcRL0bUOf/XlSwf3SQf3+ANhfra0P9m/VYbTIxgoCB5li0+UovwrjQOAIeQBQIjauifTKU5uc+y+37qvxLG+bes7PXYjejRXm4a1XWsjalgo9HJVJU9UybBV4mu8f9hkVX61LSrqyOc/54B0cG8Ftn0l79u5tLCYudu/VZYFvUqHw/pSdOxxXQIAwYmQBwAhZFPqASfY2Ry75dvTivbb9J9T2jd0eutsKGaLxFquthOHFOQfR5gKk16uI36tYLAq7zW8McE1vNHaElfXv9VvU7nn2vUtHfwqEhJzMvzPz0rzb3t/qtz7xtY9wlDSI2x2fQAELUIeAAS59SkZTqibuiJZPyalF+23WuSnndDIGYo5okczNa0X72o7IzrI7Voj7fhO2r7Ev+35ScrNlApy3WtXsPVy4cjsPNqW0KJyZyo/t5Lh8NBmgdD+IJCz37+lba3c+9r1Lt4jeMR5h8W2uHrBFcyBMEXIA4AgY5Vt1uzMcIZh2hy7dSn7i455ozw6vWMjZyjm8O7N1KhunKttjTg2HC9t2+Ewt/07Kel7/4fkCvdyVTZkVaZnLIh7uVA97DrXbeLfKvvHCQt6gYaOOiHwCMHRhuhar3FGkn+rjNIrkR51OxQamXcIVAohDwCCJNit3JFeNBRzY+qBomMxXo8GdWriDMM8t1szNajDHJoaYx9oLcg526FgdyAl8JC3lidLrfpKrfpJTbpJsXXo5ULwsoVaajf0b5XhzDvcX/k5h5l7/AvSOPMOU/1bpXiObd6hhUQLwkCEIeQBgIvBbtm2NE09FOy27MksOhYbHaWzOzfRqF7NNaRrMyXW4kNKtbM5bcnLi/XS2bDLDWUfFxUtNevhD3OFW+POrG6IyODMO6zn3+q3PYZ5h3uPYd6h9ZT7/L2Ltu3dVLn3ja13DPMO6zPvECGNkAcANaigwKelW/c5wzCt5MH2fQeLjsXHRGlwl6bOHLshXZuqbhz/RFffhciXUteWHHa5c0XglSIbdjzcQ2db8158+AOOa95hy8o9Ly/nyMNHjzjvUP7FaWxL23Ls8w6Lh796LaSGJxze6jRhaDSCDp8gAKAGgt3izXud4uTTVyQrOd1WQPSrHet1Ap3NsTunSxPVjuWf5Spnw8vSt5cMdDuWBp5HZx/WWvU/FOj6+odgVnY4G4CqZWUe6jb1b8c877CCw0oLNxtWWtF5hzZcu2GHksGvcKvbnAWJ4Ao+TQBANQ7H/GLNLj00fbVWJx9a5lxSvbhoDevezJljZ0My42MoYlyl7AOahbjCQGdf9+8s+7iYOiXn0dmW2Jq/yAPh4njmHWZnlBMK90hp26U9G6U9m/yrktofjGyot22l2SJIRQHw0NcGh77avzcUsUc1IeQBQDVYumWvHpy2Wt9u2lMU7Eb0bO7MsTvjxMaKiybYVek8uuLlC3avD7yiX+l5dE268AELQIB/L2yRlwT/1qDdkc9QXra0d/Oh0Fdq27fFX8MyZZV/K80bK9VvF6AHsIN/viMLxuA4EPIAoApt2LVfj85Y48y3K1xA5Zoz2uums09UYm0WTzkuBQWl5tEtkXauDFyLzj4oFQ90zKMDUB2i46Qmnf1boBqGFvSsx89Cny0YUxgArWh9fo60e51/C/SHKQt6gYaAWvC09wWOgJAHAFUgJT1LT8xepymLtiq/wOcUKv9Fv9a6bVhntaxfi3N8TPPodpQMdDusHt3hYa9FajeWWhefR9eXeXQA3Gc9cY06+rdA8wVtrnCJ3r9iIdDmA1ootG3D7FJP9kiJbQLPA2zQXoqtXVPfIYKYx2eTRiJMenq6EhMTlZaWpoSEBLebAyCEpWfl6tkvN+iFeZuUlVvg7BvWrZn+fF4XdW5Wz+3mhQ5b/KDMPDp/b2gJMbUDzKNrwzw6AOE1asH+/Qs0BNSCYKBFo4qr1/JQ6GtfKgB28A9BRUTkGHryAOAYZOfl639fb9a/56zXvkz/cMF+7RrozpFddUp7VmM86jw6K1dQfLXL8oYrFc2jOxTqGneRvPyvC0AYi4ryl5mwrf2ZJY9Z38yBXeX0AG7wryaascO/bZ4XeAXhQHMA7auViEDY4P+UAFAJNhTzw++3a+LMtUU17k5sWld/Oa+rhnVrKo9N2EfJv0hbgCs+7DJ5ReB5dPZX5tLz6Bh2BACH2f9jCstJtD2t7JnJ3FNy2GfxLTPVHxBt2/pt2edayAs0B9C22o0YMRFiCHkAcIzlEJonxGvcuZ31876tFO2N4jyaQPPostMDz6MrHuisp456dABwfApLRrTuV/aY9fKVCIDFbtvwUCsRUfhvd2lxCeXMAewg1WtOAAxChDwAqGQ5hIT4aN00+ERdfXr7yK5xVziPzilfcGgeXaCiwTaPrkWfkvPobNU4ej0BoObEJ0ot+/i30nIOBO4BtFVA07b5/1iX9IN/C/RvvFP7L0AITGhFMXiXEPIAoByUQyhVC8qGWRbvpSt3Hl33kr10zKMDgOAWW0dq3tO/BZpHve8ItQBzM6WUlf6tNG+cf8XP0vP/nGLwbZhjXY0IeQBQSsSXQ3Dm0a0vNY9ueTnz6NqXmkd3EvPoACCcxMRLTbr4t9LycqS0rYEDoBWJz8+WUtf4t9KiosspBn+Cf7RHdGyNfHvhipAHAJFeDiE9qdQ8uqXlzKNrVDLQWT26Oo3caDEAIBhYECuvFmB+npS+LfAcQLttAdBWBLWtNE+UlNi6nGLw7aUY6s8eDXXyqJMHRLzCcgj/mbNee8O9HIJNvC9dj+6o8+gOzaWzv7gyjw4AUBUjRuz/PYHqANrX3ANHfr7N9Ss9/LNwIZi4umF9fSpaJ4+QR8gDIlZ55RD+PKKLzu3eLPTLIdg8Oqce3aEwZ1vq2sB/MW3ao+TCKE26MlcCAFDzrBbg/pRyisFvDDzSpLi6zQLPAbQAWKu+Qh3F0AEgksoh2F9FbchL6Xl0+TllH2s9csWHXbaweXR13Gg1AAAl2R9Y6zXzb+0Glg2ATi3AcgLgwT3S/p3+bcvXgacdlO75K6oF2DCsRqswJw9ARAmbcgiF8+ic8gUW6mweXVrZx9VqWLYeXZ3GbrQYAIDjYyHM5oLb1uaUwKV99pZXC3CnlLnbv21bVPa5cYmBy0DYZsXnQywAEvIARISQLoeQlV5sHt2huXQZO8o+LrqWv/5RYZhjHh0AIJLYcMxaJ0stTy57LHt/qQBYLASmb/f/oTTpe/9WOvzduVmhhpAHIKyFXDkEW47amUdXbGEUZx6dL8A8uu6l5tF1Yx4dAACB2IIszXv5t9JyD/oLvwcaAlqnScj14hlCHoCwFBLlEJx5dBtLzaNbVs48ural5tH1Zh4dAABVIaaW1LSbfwv0/+oQRMgDEFaCuhxCRnLJlS5tPp2VNDjiPLq+/np0dZu40WIAACJbVAguxkbIAxAugrYcQuo6adHz0o8f+8f8lxYdf6geXbF5dFboNQSHhgAAgOBATx6A0C+HsHaXHpoWROUQCvKltTOkhZOkjXNKzqOzeXPF59HZ0BBvkC/8AgAAQgohD0DICrpyCFa757vJ0qIXpLQth3Z6pC4jpX7XSO1O90/8BgAAqEaEPADhUQ7h9Pb63TkdVb92bM03yMobLHxeWvGOlJfl31ergdT3Kqn/b/3DLwEAAGoIIQ9AyAiqcgh52dKqD/1DMosXVbVVLwfcIPW8xL9aFwAAQA0j5AEIekFVDiFtu7TkJWnJy9KBXf59UTFSj4v94a51fxZNAQAAriLkAQhaQVMOweeTNs/399r9+Inky/fvr9fSPxyz32+kuk1rrj0AAABHQMgDEHSCphxC9n5p+VvSwueklFWH97c7UxpwvdT1fFbGBAAAQYeQByDoyyH88dxOuqRv65orh5C63l/b7vvXpOx0/76Y2lLvy6VTrpeada+ZdgAAABwDQh6AoOB6OQSrbbduln9I5obZh/c37Ojvtev9K6lW/epvBwAAwHEi5AGI7HIIVttu6av+nrt9mw/t9EidR/jD3QlDpCgXCqoDAAAcI0IegMgsh5D0g7/Xbnmx2nbx9aW+Y6T+10oNO1R/GwAAAKoBIQ9A5JRDyMuRfvzIH+62fnt4f/Ne0oAb/bXtYmtXbxsAAACqGSEPQPiXQ0hP8te2W/ySdCDFvy8qWup+kb+2XZsB1LYDAABhg5AHIDzLITi17RZIi56TfvxYKsjz76/b/HBtu3rNq+e9AQAAXETIAxBe5RByDkjLCmvbrTy8v90Z0inXSd1GU9sOAACENUIegPAoh7B7g7ToBf9Kmdlph2vbnfRLf2275j2r530BAACCDCEPQOiWQygokNZ/5l9IZf2sw/sbdPCXP+hzhVSrQdW/LwAAQBAj5AEIvXIIB/dKS1/zz7fb+9OhnR6p03D/QiodqW0HAAAiFyEPwHGVQ5j05UanHMLB3PzqL4eQvNzfa7fsbSnPv4iL4hOlk8dIp1htuxOq/j0BAABCDCEPQHCXQ8jPPVTb7jlpy9eH9zez2nbXS70upbYdAABAMYQ8AMFZDiEjWVrysr+23f7kw7Xtul3gH5LZ9jRq2wEAAARAyAMQPOUQrLbdlm/8QzKt966otl2zQ7Xtrqa2HQAAwFEQ8gAc0fdb9+nBaT/qm43VWA4hJ1Na/rZ/SObO5Yf3tx3oH5LZdbQUXQ2rcwIAAIQhQh4A98oh7Nl4qLbd/6SsQ7XtomtJJ13qr23X4iSuDgAAQCUR8gActRyCDcn847lVVA7BatttmO3vtVs308Zo+vc3aC+dcp3U59dS7SpevAUAACCCEPIA1Ew5hIP7pO+ttt3z/h68Qiee6x+SeeIwKaqKhn8CAABEMEIeEOGqvRxC8gp/0fJlb0m5mf59cVbb7kp/bbtGHY//PQAAAFCEkAdEqGoth2C17VZ/4h+SuXn+4f1Ne/h77U76pRRbpwq+CwAAAJRGyAMiTLWWQ8jYKX33irT4RSkjyb/P45W6X+BfSKXd6dS2AwAAqGaEPCDCyyH87hx/OYRasd5jr223daG/tt2qD6UC/5BP1Wkq9b/GX9suoWUVfhcAAAAI+pD39NNP65FHHlFSUpJ69OihJ554QoMGDQr42KuvvlqvvPJKmf3du3fXypUra6C1QOiplnIIuQel5e/4w13yssP725wqDbhB6nYBte0AAAAiMeRNmTJFt912mxP0zjjjDD377LMaOXKkVq1apbZt25Z5/JNPPqkHH3yw6H5eXp569+6tSy+9tIZbDkRoOYS9Px2ubXdwr39fdLzU6xf+IZkt+1Tp9wAAAIDK8fhsgo6LTj31VPXt21fPPPNM0b5u3brpoosu0gMPPHDU53/wwQf6+c9/rk2bNqldu3YVes/09HQlJiYqLS1NCQkJx9V+ICLKIVhtu42fSwufl9ZOP1zbrn5bf7CzlTKpbQcAAFCtKppjXO3Jy8nJ0ZIlS3TnnXeW2D98+HAtWLCgQq/xwgsvaNiwYUcMeNnZ2c5W/OQA4ajKyyFkpUnfv+5fJXPPhsP7Ow71D8nsdC617QAAAIKMqyEvNTVV+fn5atasWYn9dj852T936EhsDt+0adP0+uuvH/Fx1iM4YcKE424vEDHlEHau8te2+2GKlHvAvy8uQerza+mU66TGJ1bDdwEAAICwmJNnSn8AtRGkFflQ+vLLL6t+/frO0M4jGT9+vMaNG1eiJ69NmzbH0WIgDMsh5OdJaz7199r9NPfw/qbd/cHupMukuLrV8F0AAAAgbEJe48aN5fV6y/TapaSklOndC/Th9sUXX9SYMWMUG3vk1QHj4uKcDQgnVVYOYX+KtOQVaclLUvr2w7Xtuv3MPySz3RnUtgMAAAghroY8C2f9+vXTrFmzdPHFFxftt/sXXnjhEZ/75Zdfav369br22mtroKVAmJVDsPWWti32lz9Y+X6x2nZN/HXt+l0jJbaqxu8CAAAAYTtc04ZRWm9c//79NXDgQE2aNElbtmzR2LFji4Zabt++XZMnTy6z4IqtzNmzZ0+XWg6EYDkEq2234j1/uEv6/vD+1qf4e+26XyhF0+sNAAAQylwPeZdddpl2796t++67z1lIxULb1KlTi1bLtH0W+oqzJUPfffddp2YeEJnlEJrqjhFd1aV5Bcsh7N0sLX5R+m6ydNA/vFPeOKnXpdKA66SWJ1fjdwAAAICIqpPnBurkISLKIdiv9sY5/oVUrLadr8C/P9Fq210rnTxGqtOomr8LAAAARFSdPADVUA4hK1364Q1/uNu97vD+Ewb7h2R2HkFtOwAAgDBGyAPCpRxCyupDte3elHL2+/fF1pNOLqxt16kGvgsAAAC4jZAHBGE5hHrx0bqpIuUQrLbd2mn+hVQ2fXV4f5Ou0oDrD9W2q+C8PQAAAIQFQh7goo1WDmHmGk1dXslyCPt3Sd+9Ii222nbb/Ps8UVLX8/1DMtsPorYdAABAhCLkAS6tmPngtNWVL4ewbcmh2nbvSfk5/n21Gx2ubVe/TY19DwAAAAhOhDzABePfXa5PlydVrBxCbpa/YLmFux3fHd7fqr9/SGb3i6SY+BpqOQAAAIIdIQ+oYcu3pTkBzxbJnPzbARrUqUngB+7beqi23StS5u7Dte16XuKvbdeqX422GwAAAKGBkAfUMJuDZy7u06pswLPadpu+9Jc/WDO1WG27NlL/30p9r5LqNOaaAQAAoFyEPKAGfbtxt75cu0vRUR7dNqzz4QPZGf7SBxbuUv0h0NHh7EO17c6TvPy6AgAA4Oj41AjUYB28wl68ywe0UdtGtaVda/217b5/Q8rx18ZTbF2pzxX+2nZNunB9AAAAUCmEPKCGfLFmlxb9tFdx0VG6rW+MNPlCaeMXhx/QuLO/185q28UncF0AAABwTAh5QA0oKPDpkRn+XryrB7ZT4xk3S9sX+2vbdRnlXyXThmbaaiwAAADAcSDkATVg6ookrUpKV724aP2+5Wpp0WIpprY0dp7UqCPXAAAAAFWGkAdUs7z8Aj02c61z+4ZBbVV33hj/gYG3EPAAAABQ5aKq/iUBFPfed9u1MfWAGtaJ1fX1vpZ2r5NqN5JO/z0nCgAAAFWOnjygGmXn5euJz/y9eL8f1FLx8w4Fu7PuYHEVAAAAVAt68oBq9No3W7QjLUstEuN1pWe6lJEk1W/rL2wOAAAAVANCHlBNDmTn6T9z1ju3bx/UVDELnvQfGPx/UnQc5x0AAADVgpAHVJOX5m/S7gM56tC4ji468KaUnSY16yn1upRzDgAAgGpDyAOqwb7MHD371Ubn9vgz6sm78Dn/gWH3SlH82gEAAKD68GkTqAYW8DKy8tS1eT2du/MFKT9baj9IOnEY5xsAAADVipAHVLGUjCxnqKa597QoeX5443AvnsfD+QYAAEC1IuQBVezfn69XVm6B+ratr1M3/VvyFUjdLpBa9+dcAwAAoNoR8oAqtHVPpt5YuMW5fd/JGfKsmSZ5vNLQuznPAAAAqBGEPKAKPfHZOuXm+zToxEbquepx/86+Y6TGnTjPAAAAqBGEPKCKrNuZofeXbnNu399tq7T1Gym6lnT2nZxjAAAABG/Ie/fdd1VQUFA9rQFC2GOz1qrAJ43s3kTtv3/Uv/O030kJLdxuGgAAACJIpUPepZdeqnbt2ukf//iHUlJSqqdVQIhZtm2fpq1IdhbPvLfdMmnXaim+vnTGH9xuGgAAACJMpUPeF198oYEDB2rChAlq27atxowZo2+++aZ6WgeEiEdmrHG+/rJ3YzVb8ph/51m3S7Xqu9swAAAARJxKh7yzzjpLb731ljZv3qw///nPmj17ts444wz169dPL7/8srKzs6unpUCQ+nrDbs1dl6oYr0fjG8+T0rdLCa2lU653u2kAAACIQMe88EqLFi103333acuWLXr11VcVFRWla6+9Vq1bt9b48eOVlJRUtS0FgpDP59OjM/29eNf0baD6i//lPzD4r1JMvLuNAwAAQEQ67tU1N23apG+//Vbr1q2T1+tVr1699OSTT6pz5876+OOPq6aVQJCasyZFSzbvVXxMlP4Q/6mUtU9q0k3qfbnbTQMAAECEijrW3ouPPvpII0aMULdu3fT666/rlltu0U8//aTPP//c+XrOOefoj3/8Y9W3GAgSBQU+PTJjrXP7lv51VGfp8/4Dw+6RorzuNg4AAAARK7qyT3jooYf03//+15mT17t3bz333HO64oorFBcXV/SYpk2b6o477tDgwYOrur1A0Ph0eZJ+TEpXvbhoXZ//lpR3UGo7UOp8nttNAwAAQASrdMj7v//7P11wwQXOIitnn312uY/r2LGj7r777uNtHxCUcvMLnLp45i/9oxT33Wv+A8MmyKmjAAAAAIRKyFu/fr1TJ+9oWrVqpXvuuedY2wUEtXeXbNOm1ANqVCdWl+9/WfIVSF3Ol9qe6nbTAAAAEOEqPSevZcuWOnDgQMBjtj83N7cq2gUErazcfD05e51z+96+mYpe84nkiZKG0nMNAACAEAx5119/va677rqAx2644Qb97ne/q4p2AUHrtW+3KCktSy0T4nT+zv/6d/a5Qmra1e2mAQAAAJUPeXPmzHHm5AUyevRopzg6EK72Z+fp6TnrndsP9k5W1JYFkjdOOme8200DAAAAji3k7dy50ymEHkjz5s2VnJxc2ZcEQsZL8zZp94EcdWwUr0Gb/+PfeeqNUmJrt5sGAAAAHFvIq1+/vrP4SiC2v169epV9SSAk7D2Qo0lfbXRuP9p1rTwpq6T4ROlM6kECAAAghEOe1b574IEHtGfPnhL77f6DDz6oIUOGVGX7gKDx3682KCM7Tyc1r6U+6w/14lnAq93Q7aYBAAAAx15C4d5779Upp5yiTp066bLLLnNKJWzbtk1vv/22s7LmhAkTKvuSQNDbmZ6lVxb85Nye2GGRPEu3SvVaSANudLtpAAAAwPGFvC5dumju3LkaN26cnnvuOeXn58vr9TqF0R977DHnOBBu/v35emXlFuisNrE6cfWhFTVtsZXY2m43DQAAADi+kGd69+7trKJ58OBB7d27Vw0bNlR8fPyxvBQQ9LbsztQbC7c4tx9o/oU8y/dIjTtLfX7tdtMAAACAqgl5hWrVquVsQDh7YvZa5RX4NLqjV61Wv+jfaYXPvcf16wMAAABUi2P6lGpDNKdNm6Yff/zR6c0rzuPx6G9/+1tVtQ9w1dqdGXp/6Xbn9r0Jn0jbM6XWp0hdf8aVAQAAQHiEvN27d2vQoEFavXq1E+h8Pp+z324XIuQhXEycuUb2I35V5zw1Wv26f+ewCfYD73bTAAAAgKopoXDXXXc58+82b97sBLxvv/1W69atcxZi6dy5s7Zs8c9dAkLdD1v3acbKnYrySHfEvC358qVOI6T2Z7jdNAAAAKDqQp4tuGKBrmXLlv4XiIpSx44d9cgjj2jYsGG6/fbbK/uSQFB6dOYa5+ut3far3oaPrb9aGnaP280CAAAAqjbkWU289u3bO2UTLOAdOHCg6Njo0aM1a9asyr4kEHQWbEjV3HWpivFKY3Mm+3f2vlxq1sPtpgEAAABVG/IaN26stLQ057b15q1YsaLo2J49e5SXl1fZlwSCig1DfmSGvxfvb12TFb9tnuSNlQb/1e2mAQAAAFW/8Eq/fv20cuVKnX/++Ro1apTuu+8+JSQkKDY2Vn/961912mmnVfYlgaAy+8cULd2yT7VipF9lvOTfecr1Uv22bjcNAAAAqPqevFtuuUWJiYnO7fvvv1/NmzfXVVddpcsvv9wZwvnkk09W9iWBoFFQ4Cuai/dQl/WKSVkuxSVIg/7kdtMAAACA6unJs8VVbDNNmjTR0qVLnSGbVkKha9euio6mQDRC18fLdmh1coYaxEvnpx4qfH7GrVKdRm43DQAAAKj6njwrfH7GGWfos88+K9pn4a5Xr17q2bMnAQ8hLTe/QI/PWuvcfvLE7+Xd95NUt5l02k1uNw0AAAConpBXq1YtLV++nDCHsPTOkm36aXem2tbJ16Adh+binf0XKbaO200DAAAAqm9O3sCBA7Vw4cLKPg0Ialm5+Xrys3XO7SfbzZcnc5fUsKPU9yq3mwYAAABUSqUn0E2cOFEXXnihs+DKz3/+c9WtW7eyLwEEnVe/2azk9Cz1SMhSn22v+ncO/ZvkjXG7aQAAAECleHxWFKwS6tWrp5ycnKJ6eLVr13bm5RW9oMdTVEcvWKWnpzsrhFo7rfwDIltGVq7OeniO9mbmalbXT9Tpp9ellidL18+xH2i3mwcAAABUKsdUuifvkksuKRHqgFD34ryfnIB3RqMMnbjlbf/OYRMIeAAAAAhJlQ55L7/8cvW0BHDB3gM5em7uRuf2ww0/lmdrrtRxqHTC2VwPAAAARMbCK0A4+e+XG7Q/O0+jm+5Sq62f+HcOu8ftZgEAAAA115M3efLkoz7mqqsqtyLh008/rUceeURJSUnq0aOHnnjiCQ0aNKjcx2dnZ+u+++7Tq6++quTkZLVu3Vp33XWXfvvb31bqfRHZktOy9PKCn5zb99Z+R0qX1OtSqUVvt5sGAAAA1FzIu/rqqwPuLz5PrzIhb8qUKbrtttucoGeF1p999lmNHDlSq1atUtu2bQM+55e//KV27typF154QSeeeKJSUlKKFoIBKuqpz9cpO69A17TYrEbJc6WoGGnwXZxAAAAARNbqmps3by6zLzU1VR9++KET2N58802dfPLJFX69U089VX379tUzzzxTtK9bt2666KKL9MADD5R5/PTp03X55Zdr48aNatiwYYXew3r+bCu+Kk2bNm1YXTOCbd59QEMnfqm8ggKtaPWQ6u5eJg24URr1sNtNAwAAAI5rdc1Kz8lr165dma1fv37O8Emrm/fkk09W+LWsFMOSJUs0fPjwEvvt/oIFCwI+56OPPlL//v318MMPq1WrVurcubNuv/12HTx4sNz3sbBoJ6Nws4CHyPbEZ+uUV+DT7a1/9Ae82LrSWXe43SwAAACg5odrHsnQoUOdoZQVZT2A+fn5atasWYn9dt/m2gViPXjz5s1TfHy83n//fec1brrpJu3Zs0cvvvhiwOeMHz9e48aNK9OTh8i0JjlDH3y/XdHK0/U5r/l3nv57qW4Tt5sGAAAABFfIs6GcXq+30s8rXXfPRpCWV4uvoKDAOfbaa685vXLmscce0y9+8Qv95z//Ua1atco8Jy4uztkAM3HmGtkg5fvbLFXcrk1S7cbSwJs5OQAAAIjMkPfVV1+V2Wfz3ZYtW+YMi7TevIpq3LixEwpL99rZQiqle/cKtWjRwhmmWRjwCufwWTDctm2bOnXqVKnvB5Fl6Za9mrlqp+p4snTpgUO9eGf/RYqr53bTAAAAAHdC3jnnnBOw580MGzZMTz31VIVfKzY21pnPN2vWLF188cVF++3+hRdeGPA5tgLn22+/rf3796tu3brOvrVr1yoqKsoppQAcyaMz1/i/tlmg6JQUqUF7qV/gFWMBAACAiAh5c+bMKbPP5se1b9++3N63I7G5cmPGjHEWUxk4cKAmTZqkLVu2aOzYsUXz6bZv315Un++KK67Q/fffr2uuuUYTJkxw5uTdcccdTo28QEM1gULz16dq/vrdaurN0Ih9U/w7h/xNio7lJAEAACByQ97ZZ59dpQ247LLLtHv3bmd1TiuG3rNnT02dOtVZtdPYPgt9haz3znr6fv/73zvBsFGjRs5iL3//+9+rtF0IL9bb/MgMfy/ek60+V1RKhtT8JKnHz91uGgAAAOBunTwbGmnBK1DY+/LLL9WyZcugnxdX0foSCB+zVu3U9ZMXq2PMHn0WO06e/BzpyvekEys+hxQAAAAIyzp5NrzSCp8H8vHHH+tPf/pTZV8SqFYFBT49WtiL13yqP+B1OFvqOIQzDwAAgLBT6ZC3aNEinXXWWQGPWe+eHQeCyUc/7NCanRnqF79dPXZN8+8cdq/V7nC7aQAAAID7Ic+6BgtXtSzNFj7Zu3dvVbQLqBK5+QV6bNZa5/bEhh/KI5/U42KpVV/OMAAAAMJSpUOe1ahbuHBhwGO23+rYAcHircVbtWVPps6ts17t98yToqL9K2oCAAAAYarSIe+iiy7Sgw8+WKaUwhdffKGHHnqoRL07wE1Zufn61+x1tram/lH3Hf/Ovr+RGnXkwgAAACBsVbqEwt13360ZM2Y4hc87d+7sFCDftm2bs+pm9+7dde+991ZPS4FK+t/Xm7UzPVu/qrdMTdOWSTG1pbP/wnkEAABAWKt0T54t2fnNN984Ya5hw4bavHmz89UKk3/99deUJEBQyMjK1dNfrJdX+Rof95Z/58CbpXrN3G4aAAAAEFx18sIBdfLC3+Oz1urJ2ev0+8T5+lP2f6RaDaU//CDFUxcRAAAAoana6uTt2rXLGZoZiO1PTU2t7EsCVWrPgRw9P3ej4pWtm6IOzcU76w4CHgAAACJCpefk3XzzzU56fO6558ocmzhxopMu33jjjapqH1Bpz3yxXgdy8nVPwy9VK3OnlNhWOuVaziQAAAAiQqV78ubPn68RI0YEPGb7582bVxXtAo5JUtpBvfL1ZiVqv67Mfc+/c8hdUnQcZxQAAAARodI9eTYcs1GjRgGPNWjQwBnOCbjlqc/XKyevQI80mqmYA+lS0x5Sr0u5IAAAAIgYle7Ja9asmZYvXx7wmO0vLwAC1e2n1AN6a9FWtdBujT74kX/nsHulKC8nHwAAABGj0iHvvPPO0z/+8Y8yi6+sW7dODzzwgEaNGlWV7QMq7PHP1iqvwKeHGn2qqIIcqd0ZUqdzOYMAAACIKJUuobBjxw71799fe/bs0eDBg4uKoc+ZM8fpxVu0aJFatmypYEYJhfDzY1K6Rv1rrjpqm2bF3ymPr0C69jOpzSluNw0AAAAI7hIKFuAWL16sX//611q2bJleeeUV5+uVV17p7I+JiTnetgOVNnHmWtmfKyY2/NAf8LqNJuABAAAgIlV64ZXCoPfCCy8U3S8oKND06dN1yy236JNPPlF2dnZVthE4ou+27NVnP+7UAO9a9T4wX/JESUPu5qwBAAAgIh1TyCu0YcMGvfjii05vXlJSkmJjY3XJJZdUXeuACnh0xhpJPj2U+J6UKenkMVKTzpw7AAAARKRKh7ysrCy9/fbbTk/e3LlzZVP6PB6Pxo0bpzvvvJPVNVGj5q9P1YINuzUi+nt1yFwmRcdL59zJVQAAAEDEqvCcPFtQZezYsWrevLmuvvpqfffdd85XG55pQW/06NEEPNQo+7l7eMYaRalA99d9x7/ztN9JCcG98A8AAADgek/eSSedpJUrVzq3Bw4cqN/+9re67LLLVKdOHWdlF8ANM1ft1A9b9+mK2PlqmrVJiq8vnXEbFwMAAAARrUIhb8WKFc6QzPPPP18PPvigunfvXv0tA44gv8CniTPXKE45ujP+PSlH0qA/SbXqc94AAAAQ0So0XPOJJ55wevNsaGavXr2c3rznn39eGRkZ1d9CIICPftiutTv364b4z5WQs1NKaCUNuIFzBQAAgIhXoZB36623aunSpVq4cKFuuOEGrV692vnaokUL56v18tkG1IScvAI9PmudEnRAN0d/6N85+K9STDwXAAAAABGvUsXQ+/fvr2eeecYpl2BlE+z+O++84yyAce2112rixInavXt3xJ9UVK+3Fm/Vlj2Z+mPtaYrPS5OadJV6/4rTDgAAAEjy+CyhHWetPCunMHnyZO3YsUPx8fHKzLRiZcErPT1diYmJzqIxCQkJbjcHlXAwJ19nPzJHykjWgtp/UnRBlnT5G1LXUZxHAAAAhLWK5phK9eQF0rFjR/3zn//Uli1b9NFHH+m888473pcEyjX565+UkpGtu+p86A94bU6TuozkjAEAAADHWgy9PFFRUfrZz37mbEB1SM/K1TNfbtAJnh0aXTDbv3PYvRLzQQEAAICqD3lAdXt+7ibty8zVv+q+p6i8fKnLKKndQE48AAAAUJXDNYGasHt/tl6Yu1F9POt1Vt4CyRMlDb2bkw8AAACUQshDSHjmiw06kJOn++u87d/R+wqpaTe3mwUAAAAEHUIegt6OfQc1+ZvNOifqB/XKWy5546TB491uFgAAABCUCHkIek99vk65eXmaUPtQL96pN0iJrd1uFgAAABCUCHkIaptSD+itxdt0YdQCtcvbJMUlSmeOc7tZAAAAQNAi5CGoPT5rrbwFObqr9nv+HWfeJtVu6HazAAAAgKBFyEPQWrUjXR/9sEO/9n6mJnnJUr0W0qlj3W4WAAAAENQIeQhaj81ao7rK1Lj4j/w7zrlTiq3tdrMAAACAoEbIQ1BasnmPPvsxRTfGTFW9/DSpUSepz5VuNwsAAAAIeoQ8BB2fz6eHp69RE+3TjdFT/Tut8Lk32u2mAQAAAEGPkIegM299qr7dtEe3xXygWF+W1Kq/1G20280CAAAAQgIhD0HXi/fIjDVq50nW5d7Z/p3nTpA8HrebBgAAAIQExr8hqMxYuVPLtqXp6bi35VW+1Gm41P5Mt5sFAAAAhAx68hA08gt8mjhzjXp6NmqU52tJHmnoPW43CwAAAAgp9OQhaHywdLvWpezXG/FT/DtOukxq3tPtZgEAAAAhhZ48BIWcvAI9/tlanRm1XAO1XPLGSoP/6nazAAAAgJBDTx6CwpRFW7R97wE9V9iLd8p1UoN2bjcLAAAACDn05MF1B3Py9a/P1+tnUd+omzZKsfWkQbe73SwAAAAgJBHy4LpXvv5J+zIO6C9x7/h3nPEHqU4jt5sFAAAAhCRCHlyVnpWrZ77YoMu9n6u1L1mq01QaeBNXBQAAADhGhDy46rmvNir3YIbGxb7v33HOX6TYOlwVAAAA4BgR8uCa1P3ZemHeJl3nnaoGvjSp4QlS399wRQAAAIDjQMiDa56es0G1cvZobOyn/h1D/iZ5Y7giAAAAwHEg5MEV2/cd1KvfbNYt0R+otu+g1KKP1P0irgYAAABwnAh5cMVTs9epWUGSxkTP9u84d4IUxY8jAAAAcLz4VI0at3HXfr29ZJvGRb+jaOVJJwyWTjiHKwEAAABUAUIeatxjs9aqi2+TLvbO9+8Ydi9XAQAAAKgi0VX1QkBFrNyRpk+WJenlmCn+HT1/IbXsw8kDAAAAqgg9eahRE2eu1cColTrH+4MUFS0NuYsrAAAAAFQhevJQYxb/tEefr96pD2Pf9O/o/1t/bTwAAAAAVYaePNQIn8+nh2es0cioheodtUGKqSOddQdnHwAAAKhi9OShRsxdl6rvNqVoZtxb/h2n/16q25SzDwAAAFQxevJQI714j8xYo196v9QJniSpdmPp9Fs48wAAAEC4hrynn35aHTp0UHx8vPr166e5c+eW+9gvvvhCHo+nzLZ69eoabTMqbvqKZK3fvlO3Rb/n33H2n6W4epxCAAAAIBxD3pQpU3Tbbbfprrvu0tKlSzVo0CCNHDlSW7ZsOeLz1qxZo6SkpKKtU6dONdZmVFx+gU+Pzlyja7zT1dSzV6rfTup3DacQAAAACNeQ99hjj+naa6/Vddddp27duumJJ55QmzZt9MwzzxzxeU2bNlXz5s2LNq/XW2NtRsW9v3S7du9K1u9iPvbvGPI3KTqWUwgAAACEY8jLycnRkiVLNHz48BL77f6CBQuO+NyTTz5ZLVq00NChQzVnzpwjPjY7O1vp6eklNlS/7Lx8PT5rrW6O/lD1dFBq3kvqeQmnHgAAAAjXkJeamqr8/Hw1a9asxH67n5ycHPA5FuwmTZqkd999V++99566dOniBL2vvvqq3Pd54IEHlJiYWLRZTyGq35RFW6V9W/Sb6Jn+HcPulaJc7zwGAAAAwlpQlFCwhVNKr8ZYel8hC3W2FRo4cKC2bt2qRx99VGeddVbA54wfP17jxo0rum89eQS96pWZk6d/zV6vO2PeVazypPaDpI5Dq/ldAQAAALjardK4cWNnLl3pXruUlJQyvXtHctppp2ndunXlHo+Li1NCQkKJDdXr5QU/qdGBdfq599BKqedOsDTPaQcAAADCOeTFxsY6JRNmzZpVYr/dP/300yv8OrYqpw3jRHBIO5ir/36xQXdET1GUfFL3i6RW/dxuFgAAABARXB+uacMox4wZo/79+ztDL22+nZVPGDt2bNFQy+3bt2vy5MnOfVt9s3379urRo4ezcMurr77qzM+zDcHhua82qkv2Cg2LWyqfxyuPragJAAAAIDJC3mWXXabdu3frvvvuc+rd9ezZU1OnTlW7du2c47aveM08C3a33367E/xq1arlhL1PP/1Uo0aNcvG7QKFdGdl6cf5G/S/mDee+p99vpMYncoIAAACAGuLx2SonEcYWXrFVNtPS0pifV8UmfLxS279+W5NiH5cvprY8ty6V6jWv6rcBAAAAIk56BXOM6z15CB/b9mbqzW826aPot5z7ntNuIuABAAAANYyiZagy/5q9TqP1hTpFbZdqNZTOuJWzCwAAANQwevJQJTbs2q+Pl2zU57GHFsA563YpPpGzCwAAANQwevJQJR6btVZXRc1QC88eKbGN1P9aziwAAADgAnrycNxWbE/T3GXrNDfuQ/+OwXdJMfGcWQAAAMAF9OThuE2cuUY3RX+sRE+m1LS7dNIvOasAAACASwh5OC6LftqjH9es1tXe6f4dw+6VorycVQAAAMAlhDwcMyux+PD01bot+l3Fe3KltqdLnYZzRgEAAAAXEfJwzL5cu0t7Ny/Xpd4v/TvOnSB5PJxRAAAAwEWEPByTggKfHpmxRndEvyWvxyd1/ZnUZgBnEwAAAHAZIQ/HZPrKZMUlLdYI72L5PFHS0Ls5kwAAAEAQIOSh0vLyCzRxxmr9JeZN577n5CulJl04kwAAAEAQIOSh0t5bul3t9szTqVGr5YuOl84Zz1kEAAAAggTF0FEp2Xn5emrWaj0XPcW57zl1rJTQkrMIAAAABAl68lApb3y7RQMyPlPXqK3yxSdKZ97GGQQAAACCCD15qLDMnDxN+nyV3op5x7nvGfQnqVYDziAAAAAQROjJQ4W9NP8njcz6VK09qfLZEM0BN3D2AAAAgCBDTx4qJC0zV699uVyfRn/o3Pec81cpphZnDwAAAAgy9OShQp79aoOuyHtfDTz75WvcRer9K84cAAAAEIToycNRpWRk6ZP532mGd5pz3zPsHsnLjw4AAAAQjOjJw1E9PWeDbvS9o1qeHPnanCp1GcVZAwAAAIIUIQ9HtG1vphZ8+7Uu885x7nuG3St5PJw1AAAAIEgR8nBET362Tn+ImqJoT4HU+Typ3emcMQAAACCIEfJQrvUp+7Vu6Rc637tQPnmkofdwtgAAAIAgR8hDuR6buVp/8b7p3Pb0uUJq1p2zBQAAAAQ5Qh4CWr4tTQdWzdRA7yoVeOOkc8ZzpgAAAIAQQMhDQBNn/Ki/RPt78aIGXC/Vb8OZAgAAAEIAIQ9lfLtxtxI3fKjuUZtVEFtPGvQnzhIAAAAQIgh5KMHn8+mJGct1e/Tb/h+QQX+UajfkLAEAAAAhgpCHEr5Yu0tdtr2rNlG7lF+nmXTq7zhDAAAAQAiJdrsBCB4FBT79e9pSTYp+37nvHTxeiq3tdrMAAAAAVAI9eSgydUWSzkp9U408Gcpv0FE6eQxnBwAAAAgx9OTBkZdfoJemL9Rk76fOfe+590hefjwAAACAUENPHhzvfbddF6S/qjqebOW36Ct1u4AzAwAAAIQgQh6UnZevt2d9qSu8nztnwzv8Psnj4cwAAAAAIYiQB73+7RaNOfiqYjz5yj9hqNRhEGcFAAAACFGEvAh3IDtPn82eoQu8X8snj7zDJ7jdJAAAAADHgZAX4V6av0k35r7q3Pb1ulRq3svtJgEAAAA4DoS8CLYvM0c/fPWBzvIuV4EnWlFD7nK7SQAAAACOEyEvgj375Xr9vuA157ZnwHVSg/ZuNwkAAADAcSLkRaiUjCwlf/2GTorapLzoOvKcdYfbTQIAAABQBQh5EeqZ2av1B01xbnvP/INUp7HbTQIAAABQBQh5EWjrnkwVLHlZ7aN2Kie+sTwDb3a7SQAAAACqCCEvAj098wfdEvWeczt2yJ1SXF23mwQAAACgihDyIsy6nRlqsuJ5NfGkKbteO6nf1W43CQAAAEAVIuRFmEnTF+oG7yfO7bgR90jeGLebBAAAAKAKEfIiyLJt+9Rt3STV9WQpq3EvqfvFbjcJAAAAQBUj5EWQl6d+qSu9s5zb8SPvl6K4/AAAAEC44VN+hPhm426duXWSYj35ympzltRxsNtNAgAAAFANCHkRwOfz6a1PpumiqPnO/fiR97ndJAAAAADVhJAXAeasSdHoXZMU5fEpq8uFUsuT3W4SAAAAgGpCyAtzBQU+Tf/kHQ32/qB8j1fxw+9xu0kAAAAAqhEhL8x9umyHrkh/wbmd2+c3UqOObjcJAAAAQDUi5IWxvPwCLZ7+ivpEbVBOVC3FDx3vdpMAAAAAVDNCXhh7d9FPuipzsv/OwFukuk3dbhIAAACAakbIC1NZufna9Nmz6hiVpIMxDRQ76Fa3mwQAAACgBhDywtSbC9bomtw3ndvRg/8sxSe43SQAAAAANYCQF4b2Z+dp/xdPqZlnn/bXaqWYAde63SQAAAAANYSQF4bemLNUVxW879yOH3G3FB3ndpMAAAAA1BBCXpjZl5mjmK+fUILnoNISuyr6pF+63SQAAAAANYiQF2Zemzlfv9J053a98/8uRXGJAQAAgEhCAggjO9Oz1OK7xxXnydPepqcqqtMwt5sEAAAAoIYR8sLIW5/O1EWer5zb9S/4p+TxuN0kAAAAAJEY8p5++ml16NBB8fHx6tevn+bOnVuh582fP1/R0dHq06ePIt2W3Znq/uPjivL4tLvtefK07u92kwAAAABEYsibMmWKbrvtNt11111aunSpBg0apJEjR2rLli1HfF5aWpquuuoqDR06tMbaGsw+/PgdDY36TvmKUqML/u52cwAAAABEash77LHHdO211+q6665Tt27d9MQTT6hNmzZ65plnjvi8G2+8UVdccYUGDhx41PfIzs5Wenp6iS2crE1O18CNTzm393X9ldS4k9tNAgAAABCJIS8nJ0dLlizR8OHDS+y3+wsWLCj3eS+99JI2bNige+65p0Lv88ADDygxMbFosxAZTj774CX1j1qrHE+cGo36m9vNAQAAABCpIS81NVX5+flq1qxZif12Pzk5OeBz1q1bpzvvvFOvvfaaMx+vIsaPH+8M7yzctm7dqnDxw+ZUDdvxrHN7/8k3SAkt3G4SAAAAABdVLCVVM0+pVSB9Pl+ZfcYCoQ3RnDBhgjp37lzh14+Li3O2cLTwg//o+qjtOuBNUMPhd7jdHAAAAACRHPIaN24sr9dbptcuJSWlTO+eycjI0OLFi50FWm655RZnX0FBgRMKrVdv5syZGjJkiCLFN2u26fw9L0seKWfgH1UnPtHtJgEAAACI5OGasbGxTsmEWbNmldhv908//fQyj09ISNDy5cv1/fffF21jx45Vly5dnNunnnqqIoUF2zUfTVRLzx7ti2mmBmff5HaTAAAAAAQB14drjhs3TmPGjFH//v2dlTInTZrklE+w8FY4n2779u2aPHmyoqKi1LNnzxLPb9q0qVNfr/T+cPfVsnW6aP+bTi9e1JC7pJh4t5sEAAAAIAi4HvIuu+wy7d69W/fdd5+SkpKcsDZ16lS1a9fOOW77jlYzL9IUFPiUPPVBJXoytatWRzU59Uq3mwQAAAAgSHh8Nu4vwlidPCulYCtt2hDQUDPj6yU6e/oIxXtytf/nr6nuST9zu0kAAAAAgiTHuF4MHZWTm1+g3NkPOAFvR0If1e11PqcQAAAAQBFCXoiZ+eVXGpn7mXO7wYUPWP0Jt5sEAAAAIIgQ8kJIVm6+6sz9p7wenzY3OUe1OpZdgRQAAABAZCPkhZCZMz7SOb5vla8oNb/4n243BwAAAEAQIuSFiP1ZuWq9+CHn9uY2FymuZQ+3mwQAAAAgCBHyQsTsj15VX/2obMWq7c/vc7s5AAAAAIIUIS8E7M04qG4rH3Nub+08RtEN2rjdJAAAAABBipAXAua9/7Q6e7Yow1NHJ1z4N7ebAwAAACCIEfKC3M49+9R3w9PO7ZSTblJUnQZuNwkAAABAECPkBbkl7zyqVp5U7Y5qpBPOH+d2cwAAAAAEOUJeENuyI0kDt7/k3E477Q55Ymu73SQAAAAAQY6QF8RWv/sPNfDs147oNjph6PVuNwcAAABACCDkBan1G9ZrUOoU53buOXdL3mi3mwQAAAAgBBDygtS2D+5VLU+ONsZ3V7szLnW7OQAAAABCBCEvCP244judmf6pczv2vPskj8ftJgEAAAAIEYS8IJT+6T2K9hRoVd2Bat3nXLebAwAAACCEEPKCzLJvPtepB79Sgc+jhhf+w+3mAAAAAAgxhLwg4isokGbf49xe1ug8Ne/Uz+0mAQAAAAgxhLwgsvSL93RS7jLl+KLV+pL73W4OAAAAgBBEyAsSBfn5SpjnH575Q8tfqnGrTm43CQAAAEAIIuQFie+mPq8TCzYqQ7XU5Rf3ut0cAAAAACGKkBckclPWKd/n0cr2v1VCo2ZuNwcAAABAiIp2uwHwG3jto9q8+tfq1eoETgkAAACAY0bICyLtup7sdhMAAAAAhDiGawIAAABAGCHkAQAAAEAYIeQBAAAAQBgh5AEAAABAGCHkAQAAAEAYIeQBAAAAQBgh5AEAAABAGCHkAQAAAEAYIeQBAAAAQBgh5AEAAABAGCHkAQAAAEAYIeQBAAAAQBgh5AEAAABAGCHkAQAAAEAYiVYE8vl8ztf09HS3mwIAAAAAFVKYXwrzTHkiMuRlZGQ4X9u0aeN2UwAAAACg0nkmMTGx3OMe39FiYBgqKCjQjh07VK9ePXk8niM+9pRTTtGiRYuq/Hig/ZbMLXhu3bpVCQkJChZH+x7deN3KPreijz+e612ZY8F6rQ3Xu2LngutdfT9D/H5Hzu92qP17zv+7g/N6H+9juN7Hd26P99pU9vGRfr19Pp8T8Fq2bKmoqPJn3kVkT56dkNatW1fosV6v94gX9ViPH+l5tj9YfpAq8j268bqVfW5FH3881/tYjgXbtTZc74qdC6539f0M8fsdOb/bofbvOf/vDs7rfbyP4Xof37k93mtT2cdzvXXEHrxCLLxyFDfffHO1HD/a84JJdbX1eF63ss+t6OOP53of67Fgw/Wu2LngelffzxC/35Hzux1q/57zb3lwXu/jfQzX+/jO7bGe92N9PNe7YiJyuGawsi5hS+ZpaWlB17uDqsW1jixc78jC9Y4sXO/IwvWOLOkh/NmcnrwgEhcXp3vuucf5ivDGtY4sXO/IwvWOLFzvyML1jixxIfzZnJ48AAAAAAgj9OQBAAAAQBgh5AEAAABAGCHkAQAAAEAYIeQBAAAAQBgh5AEAAABAGCHkhaCMjAydcsop6tOnj3r16qXnnnvO7SahGm3dulXnnHOOunfvrpNOOklvv/025zvMXXzxxWrQoIF+8YtfuN0UVINPPvlEXbp0UadOnfT8889zjsMcv8+Rgf9XR5aMEPgsTgmFEJSfn6/s7GzVrl1bmZmZ6tmzpxYtWqRGjRq53TRUg6SkJO3cudP5hyQlJUV9+/bVmjVrVKdOHc53mJozZ47279+vV155Re+8847bzUEVysvLc/5gY9fYCuva7/O3336rhg0bcp7DFL/PkYH/V0eW/BD4LE5PXgjyer3OD5XJyspyftB8Pp/bzUI1adGihRPwTNOmTZ0Pg3v27OF8h7HBgwerXr16bjcD1WDhwoXq0aOHWrVq5VzjUaNGacaMGZzrMMbvc2Tg/9WRxRsCn8UJedXgq6++0ujRo9WyZUt5PB598MEHZR7z9NNPq0OHDoqPj1e/fv00d+7cSr3Hvn371Lt3b7Vu3Vp//vOf1bhx4yr8DhBs17vQ4sWLVVBQoDZt2nCRIuB6I/yu/44dO5yAV8j+Dd++fXuNtR+Vw+975KjKa83/qyPjeu8L8s/ihLxqcODAAeei//vf/w54fMqUKbrtttt01113aenSpRo0aJBGjhypLVu2FD3Gfpis67f0Zh8QTP369fXDDz9o06ZNev31153hfAjf6212796tq666SpMmTaqR7wvuXm+E5/UP9Jde+4CB8P19R2Rda/5fHTnXu36wfxb3oVrZKX7//fdL7BswYIBv7NixJfZ17drVd+eddx7Te9hrvfXWW8fVTgT39c7KyvINGjTIN3nyZC5VhPx+z5kzx3fJJZdUSTsRPNd//vz5vosuuqjo2K233up77bXXuERh/vvO73NkXGv+Xx25/y8fG4SfxenJq2E5OTlasmSJhg8fXmK/3V+wYEGFXsP+UpCenu7ctq/W5WwrtSE8r7f9+3P11VdryJAhGjNmTDW1FMFyvRHe13/AgAFasWKFM0TTVmebOnWqRowY4VKLcTz4fY8cFbnW/L86sq73zhD4LB7tdgMiTWpqqjM5s1mzZiX22/3k5OQKvca2bdt07bXXOv+g2HbLLbc4S+sjPK/3/PnznWEDdo0Lx4z/73//c5bsRfhdb2Mf+r/77jtnOImN9X///fedpZoR+tc/OjpaEydOdBbjsPm1No8jmFZjQ9X/vvP7HBnXmv9XR9b13hYCn8UJeS4pPQfDfkAqOi/D5vN8//331dQyBNv1PvPMM50Pg4iM621YbTG8r/8FF1zgbIiM683vc2Rca/5fHVnXu18IfBZnuGYNs5V3bNnV0n/Vt/pnpf9igNDH9Y4sXO/IxvWPLFzvyMG1jiyNw+SzOiGvhsXGxjrpf9asWSX22/3TTz+9ppuDasb1jixc78jG9Y8sXO/IwbWOLLFh8lmd4ZrVYP/+/Vq/fn3RfVta1bp0rYh127ZtNW7cOGcBjf79+2vgwIHOkvi2JOvYsWOrozmoZlzvyML1jmxc/8jC9Y4cXOvIsj8SPqu7vbxnOLKlku3Ult5+85vfFD3mP//5j69du3a+2NhYX9++fX1ffvmlq23GseN6Rxaud2Tj+kcWrnfk4FpHljkR8FndY/9xO2gCAAAAAKoGc/IAAAAAIIwQ8gAAAAAgjBDyAAAAACCMEPIAAAAAIIwQ8gAAAAAgjBDyAAAAACCMEPIAAAAAIIwQ8gAAAAAgjBDyAAAAACCMEPIAAKgiy5Yt0zXXXKMOHTooPj5edevWVd++ffXwww9rz549nGcAQI3w+Hw+X828FQAA4eu5557TTTfdpC5dujhfu3fvrtzcXC1evNg51rt3b73//vtuNxMAEAEIeQAAHKevv/5agwYN0rnnnqsPPvhAcXFxJY7n5ORo+vTpuuCCCzjXAIBqR8gDAOA4jR492glxGzduVJs2bTifAABXEfIAADgO+fn5SkhIUK9evfTNN99wLgEArmPhFQAAjkNqaqoyMzOdxVYAAAgGhDwAAAAACCOEPAAAjkPjxo1Vu3Ztbdq0ifMIAAgKhDwAAI6D1+vV0KFDtWTJEm3bto1zCQBwHSEPAIDjNH78eFnZ2euvv94pl1Ca1cv7+OOPOc8AgBrB6poAAFRhMfSuXbvqd7/7nXr06OGEu6VLl2rSpEnq2bMnxdABADWCkAcAQBX54Ycf9Pjjj2vOnDlKTk5WTEyMOnfu7NTRu+WWW9SkSRPONQCg2hHyAAAAACCMMCcPAAAAAMIIIQ8AAAAAwgghDwAAAADCCCEPAAAAAMIIIQ8AAAAAwgghDwAAAADCCCEPAAAAAMIIIQ8AAAAAwgghDwAAAADCCCEPAAAAAMIIIQ8AAAAAFD7+H23ljzPXEIHKAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 900x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(9, 5))\n",
    "\n",
    "ax.plot(C_values, train_accs)\n",
    "ax.plot(C_values, val_accs)\n",
    "\n",
    "ax.set_xscale('log')\n",
    "ax.set_xlabel('C', fontsize=12)\n",
    "ax.set_ylabel('Accuracy', fontsize=12)\n",
    "ax.set_title('SVM Hyperparameter Tuning', fontsize=13)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebcccda8",
   "metadata": {},
   "source": [
    "### 3. Evaluate the best model on the held-out test set\n",
    "Use the best `C` chosen from the validation curve and compute the performance on the held-out **test set**.\n",
    "\n",
    "**Important**: we should run this **only** when we are finished tweaking our modeling assumptions and hyperparameters. After we evaluate on the test set, it's no longer unseen!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "e49e4f2b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Validation accuracy (C=10): 78.7%\n",
      "Test accuracy       (C=10): 83.5%\n"
     ]
    }
   ],
   "source": [
    "final_model = SVC(kernel='linear', C=best_C)\n",
    "final_model.fit(X_train, y_train)\n",
    "\n",
    "test_acc  = final_model.score(X_test, y_test)\n",
    "val_acc   = max(val_accs)\n",
    "\n",
    "print(f\"Validation accuracy (C={best_C}): {val_acc:.1%}\")\n",
    "print(f\"Test accuracy       (C={best_C}): {test_acc:.1%}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a40b02b8-62bd-4e44-8bfd-59023bcb22c7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
