{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "[Previous Page]() [Next Page]()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise: Some More Algorithms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook shows another class comparison between cuML and Scikit-learn: The `LogisticRegression`. The basic form of logistic regression is used to model the probability of a certain class or event happening based on a set of variables.\n", "\n", "We also use this as an example of how cuML can adapt to other GPU centric workflows, this time based on CuPy, a GPU centric NumPy like library for array manipulation: [CuPy](https://cupy.chainer.org)\n", "\n", "Thanks to the [CUDA Array Interface](https://numba.pydata.org/numba-doc/dev/cuda/cuda_array_interface.html) cuML is compatible with multiple GPU memory libraries that conform to the spec, and tehrefore can use objects from libraries such as CuPy or Pytorch without additional memory copies!\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Here is the list of exercises and modules in the lab:\n", "Logistic Regression
\n", "- Exercise 1
\n", "- Exercise 2
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Lets begin by importing our needed libraries:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "# Lets use cupy in a similar fashion to how we use numpy\n", "import cupy as cp\n", "\n", "from sklearn import metrics, datasets\n", "from sklearn.linear_model import LogisticRegression as skLogistic\n", "from sklearn.preprocessing import binarize\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.metrics import accuracy_score\n", "from sklearn.model_selection import GridSearchCV\n", "\n", "import matplotlib.pyplot as plt\n", "from matplotlib.colors import ListedColormap\n", "\n", "cm_bright = ListedColormap(['#FF0000', '#0000FF'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once again, lets use Scikit-learn to create a dataset to use:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "a = datasets.make_classification(10000, n_features=2, n_informative=2, n_redundant=0, \n", " n_clusters_per_class=1, class_sep=0.5, random_state=1485)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now lets create our `X` and `y` arrays in CuPy:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "X = cp.array(a[0], order='F') # the API of CuPy is almost identical to NumPy\n", "y = cp.array(a[1], order='F')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets see how the dataset works: " ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAB7bElEQVR4nO39aYxkWZodBp77nu2bm/m+xpb7UllV3dnV1WwKTVJNTc+gpwlqRoAWaDSSgIKAIWYESJCmWRhxBEEABQIShKGAmYJIaARQ0hCQSApsCs1qqIVmUb1UVnVl5Z4ZERkRvi+279u78+P4iWvu4RHhkeER7p5xD+AwN7O3XHvudu73vnu+8xlrLTw8PDw8Li+C8x6Ah4eHh8fTwRO5h4eHxyWHJ3IPDw+PSw5P5B4eHh6XHJ7IPTw8PC45Yudx0tnZWXvt2rXzOLWHh4fHpcVPfvKTA2vt3PHXz4XIr127hvfee+88Tu3h4eFxaWGMuXvS6z614uHh4XHJ4Yncw8PD45LDE7mHh4fHJYcncg8PD49LDk/kHh4eXw+Mx8BgAETReY/kueNcVCseHh4eZwZrgXIZqFT4PAiA2VmgWDzXYT1PeCL38PC43KjVgIMDIJ8HjGFEvrMDxONANnveo3su8KkVDw+PywtF47kcSRxgRJ5KAdXq+Y7tOcITuYeHx+WFtcyNB8eoLAyB4fB8xnQO8ETu4eFxeREETJ/0ekdf7/WYanlB8NREboxJGWP+xBjzvjHmI2PMf3gWA/Pw8PA4FebmGJV3OkC/D7RajMif1WLncAi020C3yzuCC4CzWOzsA/gL1tqWMSYO4EfGmP/JWvtHZ3BsDw8Pj0cjmQSuXQOaTRL59DRz5mF49uc6OGBO3hiSeCoFrKwAsfPVjTz12S2bfrYOn8YPfy7GNOXh4fFiIB4ngT9LtNvA/j5QKLiF1W4X2N0lmZ8jziRHbowJjTE/A7AH4IfW2j8+YZvvGWPeM8a8t7+/fxan9fDw8Hh+aDQY/YvEASCdJsGPRuc3LpwRkVtrx9babwFYBfAdY8zbJ2zzA2vtu9bad+fmHrDT9fDw8LjYsPYoiU++fs44U9WKtbYG4H8B8BtneVwPDw+P54IoeniJf6HAHPwkej0gk7n8OXJjzByAobW2ZoxJA/h1AP/JU4/Mw8PD41ljNGJlaK0G1OtcIE2nSdpzc0cJOpsFSiUWGgUBI/F4HFhYOK/R38dZTCNLAP6/xpgQjPD/rrX2H57BcT08PDyeDaylTPHOHf7e6bhc9/w8Cb3fB65cccVGxpC0p6b4XixG0j9ejHQOOAvVys8BfPsMxuLh4eHxeFhLtYjINJt9MjIdjYDNTSpQymWS9uYmJYsAX7txgwVF3e6Dfi2pFH8uELxploeHx+VBFAHr6yRhpTbyeUbO8fjpjlGp0O42DBldt9vA3h73TyRYXNRssvBnbs5F6rkcfyYnjV6PZK8K03PKlXsi9/DwuDwol4HPPnMpjW6XRJtIAGtrj9/fWubCMxlXodnrcYK4c4epk16PEXe/z+2KRZ6r2eTzlRU+n4zopWhZXeXYnjPOP7nj4eHxYqDfJ4m2Wox6nwRRxCj6o49cOiWdZoQcRYyoGw0+VqunM8ySY2K/z2NYy/2KRb6+v89t0mnqx/N55tJbLU4g5TJfy2a5XSIBbG+fixzRR+QeHh7PHgcH/FFaIggYvT4u1zwckpzv3WNK5O5dKkoODkiemQwj4lu3+HsiQSLd32eEfjw6NobplHqdBLy8zN+HQ0baIuUgIKEfL/NPJBjFx2JMxUzqyuNxRvODAYn/OcITuYeHx7NFt3u08QNA4tzaAq5fP7nIBnD58EaD5Dg7y+e3bwMzMzxGr0eCn54mQQuDAUvnr1598PgzM4zCm02+Nz8PfOMblBbG405LPjPz4JjGY0fgD4u8H/Z5niE8kXt4eDxbtFpfLXrtdEjWk9soN24MI+lUihPF8WrxRIJEPRo9uAgahrwb6Pf5/soKo3yAz8OQEXcqxefKf49GJHLZ4x4ckPB1l6HceiLxdNfrK8ATuYeHx7PFo6LXR2E4JKnWaiRlaxmdZzIk09GIUXip9ODxRb4PkyUaczSts7p6NL9tDPDOOzxfrcbnsRjTNZpUlpYY9Su/bgwnlElyf07wRO7h4fFskcs9GL32+yTEeJwR9XDobGFjMeah63Xmxttt7qMFTkXF8/Mk4HIZ+OQTHrNUYgpmOGSUfVor20yGaZ5+n4Qsc6x0msebTKkIhQLH1GyS0K1luigWI8lnMmd7HR8BT+QeHi8aooiE9KxzuVFEMlZEfXDAXHYYkhSLRRJwpXKUrPXYaAA//zkj74UFPkYR99XiZKcDvP8+CXd/n4uhqRTwq7/6YLrlcQiCk6WDYcifXo+fI4rcQmsQcPyJhIvURyNgY4NFRc9JV+6J3MPjRUG/z8ix1yOJl0ok1qdNA4xGrsBmMt+9s0MpYKPBqFsdfN56ixHuz3/uUhfFIgn4o494vFgMeOMNNoyo1Uj0pRILf6QF73aBTz8lYS8tkWC7XaZI1td5zHz+ZDLt93lMY0jIyaSTOAIP2tXu7VG/rpx7Lsdz5vOcVCbbyul8nY7LvT9jeCL38HgRMBoxTRGLOe11uczH+fmvftyDAxJnv88JYW6Okr7hkNFrp0PiFaneuQP8/u+TJHs95rgLBRL67i6PaQz3394moaqicmaGRN7rMVctFYtauo3HjI6N4b6Li3x+vOqzWuW5YjHXvLlQ4Filb08kGPEnEpwc/vRPeZeg3Hy9zmt39erJ18WYJ9fKPwU8kXt4vAhoNvmoiDkISI7VKqPyr5ICaDYZEU92sa9WnVZ7OCQJ5nIkzL09kqUKaVotepwsL/N9a3kckf/eHscl1crUFM8ZizHVEovxJ4p4N1CvcwzxuPt8KtxZXOR7gwGPKynkeExS/6f/lNH/3Bwjf6VHrl/nnUUYupx3IsF9Gw035sn8v7V8/hxz5L6y08PjRYBSH5NQnvyrRo7b265bfTbrFiNv3nTkNnn+wYDbx2IkudlZ7rOzQ8I1hiQ5GjHS7/VIlorQh0MS+LVr3C4I+LvuLDodHrvV4iIowHRNq+XGIT9xKWm2txm1J5M8ZqPB8SQSTqfe7z947eJxZ9q1uMg0TbvNMTSbvHt4jkVBPiL38HgRkE67iFXQoudpzaaOo1ZzEj5rSWwynFJUvrvLbaKIhBoEjHiDgO+3Wnxvc5OEuLTE4zUafJyd5R2DMSRTlc9L8nf1KieIL7/keOJxLjLKI3w8PkrCk4u8vR5/kkmOR4udrZYjfGs5Ue3vO5249lWuPBZj5N5uc1zZ7HN3R/RE7uHxIkBeIO02iWs8JhktLX31xc50mnn3ZNKRdKfDCDed5mLl/Dzw4Yc832DAR0XY+/vcrlhkSkPpjkKBEfVg4N4vFint+/BDEnYsRoJPpxmVX7vGKF5VnuOxs7tdXj465iDg+TUWRecq5NH4goCfbWaGKSP5xIxG/Pn2t11KKpE4l0IgwRO5h8eLgCDgAmG9zmg3HifJHvfaBkhqilYlFVQOOJUi0XW7JLN+nyTXarn0SbHIRc0vvyQJfutbfP32beCLL3hO+aVsb/O9uTkS9Wuvcf9ej4Q8GDidNuD04gCj9Rs3uOC5vMxzxWLA559zQgE4UU2mOMKQi5hKC7XbvDN47TXuE4Z8bTDg5CDp4UsvceJpNnk9FhefmyLlNPBE7uHxoiAMSY7T0w/fxlrmiBsNEne5TPJfWSGBpVIkx60tEuA77wA/+QlJ7eZNEp1SDN0uUx9LS5xEul3u32y6/He5DLz8stONf/AB8Mu/TKJVqXy57EyyslmnsqlWuV0UMUrP57mQWSzyfFoo3dwkKevOI51mKqTX4/GGQ+bs5dty9SqJezLCTqed9PEcvFQeh7Po2bkG4L8GsAggAvADa+1//rTH9fB4YSHTpjB8/qShikrJ8QYDEujeHieAnR1G1nq9VCJJNptMe1SrLtJtNhk9q/hnOGQUr6Kbmzf5+NlnjHCt5XF//GPg7bdJ7AcH3EaFN1qYLRR4rJ/+1BF3Msn9Gw3nIa6Jo9NxHYAAV7V5/borWkokmA4qFB5+3S8giQNnE5GPAPw71tqfGmPyAH5ijPmhtfbjMzi2h8eLA2tJVtUqiVwyu5PSH88KjQYJsddjykISQnmI7+1xnMvLHN/BAQmw0+HvirpHIxLoZ5+RJBcW+P5wyAmh2+XrjYabNKxlikWl9vE4J4SlJaZLpCLZ2HDKlnabxyoU+KN0i0g8FnPFQ7OzTL9MVm9q8bVUen7X+BngLHp2bgPYPvy9aYz5BMAKAE/kHh5PgkrFNTMIApLV+joj3ljMRZapFEnruNqk3eYkMBrx/amp03uNCEqndDquu3y7TfJVAU+nw4lGviR7e0y11GrcxlqnJx8MSMB/+qdMcVy54iSBaqeWz7vjbm0x1bK7y7G/+aaTTmpx8ic/cZF9peKi8XqddwsffMCc99ISz5PLAd/9Ls919y63f56T43PAmerIjTHXwEbMf3zCe98zxrxnjHlvf3//LE/r4XH5EUUkv8mekGpesL9PdcjBAUlNDRa06Adw3/V1ElwQcNuNjaNa7tMgkSCZJhKMYLtdZ2w1HvP4+Tzfz+dJztUqI+7XXyeRq0NPGLoKUskQl5a4j56PRvw8rZZbeHzjDeCVV5y/eKXijLQ+/ND16zw44DkKBZ5X2u+tLZL6xx/zOt27x0kmmXSeLMehCs9LijNb7DTG5AD89wD+bWtt4/j71tofAPgBALz77rvPvxeSh8dFRhQdrZAUlL5Q0Q3gUh/lMlMc4zHJabJxQy7HiLfVOqquGI/5E4s9eK5ul2qT4ZD561TK3Rmk03zdGOazNWFI+ZLPU5FSLB7tci9r18VFjmd/n/vdu8fxy/+l2eQC45tv8vO9/DKPffcuJ5Ivv+RxMxk+qtJybo7Hkb+5IvBGgxH+a69xfF984SJ/adeDwPm2lMu8LokEz/scqzLPAmdC5MaYOEjif8da+z+cxTE9PF4oSOY3HB5NmQwGJJ3jBSZKT6jP5ElqiliM5FYo8P1ymdGtXPympkiwIt/1dZ57YcE1ZtB7wyEnjWaTxDc/TwLWImK1SrKfm3M56ViMx1H5vJodS8cuq1mdY2+P43n7bUbtmQzz3e+/z/1zOb4fRc7fBXDkPB4z160GyZ0OP6tMsapV/h6LuWtVr3MBN5vlOIdDXoerV597Uc/T4CxUKwbA3wLwibX2P336IXl4vIBQpKv0iKRzkgyORkflcIqq1fAAcNWT8iOJxbi4p5y1emZWq3xvd9d5oczOumIcNVIolUi8qnYEXIrlyy+ZwhgOqTJR8c7Skmtq3O26SUPjn54mqWYyTpI4qVcHSMLpNPdT0+Nr13gMtX1LpZxTYaXimk0cHPA9OTyOx9znrbdce7crV1wRULnsSBzgGEYjXgP5s1wCnEVE/qsA/lUAHxhjfnb42l+11v6jMzi2h8eLg0zG2bYOBiThQoFkt7np0iHWOjUHwNcLBSo7ABJmpeKi76kpEtbCAsk7nXa5dkW66+sk2WKR2+3vM6Ld2eHzuTluowXMrS1G0HfvukKaRoOTifxSpqb4maQ/bzSYt19ddSZYtRo/TzzOz5NKcYyrq9xX41te5mfQXYI627/7LsddqbjPoEVjSR7X1ly3oLU1l2pSOuthPiqXCGehWvkRgIsprvTwuGxIJp1PiJDPMzpUlx01DJ7MfavJwb17JN/BgJFmIsFScpWWj8ckwa0tkrzsZu/e5e/Xr5O0V1dJiMUiX/vxj3nc8ZjKkI8/Jukqb67mEEtLJEI1knjlFX6mrS1ORtPTzp9Ei7eplDOdyud5/Habny+fB159lZNGEPD4Bwf8PG+9xZz6O+/wM/3RH7lConv3XKefN97gpLi6etQ3XMZe29t8roIjVadeIvjKTg+PiwpJ/GTcpCKYkxYqWy1GxkHg5HtBwMhU1Y6KaHs9l4MGGMlLIXPzJqPm//V/5XFWVoBbt3i827dJ5LUayVQyRKlPlO4JQ6ZlZCGbSvHnzTd57g8/5GShNE2hwP36ffcTj5NgDw44EV2/zkYU1pK0r17lQqYmDFnQykdFcsZsludYWztaEDR5zdThp9l0k4UUM5cEnsg9PC4i+n2S7XDI50HAqHwyopzEYECCVWQOOEXGwQEVIZ9+6jro9HrOKyUISJxhSBK7e5dpkG9+k8f99FNGu2HIO4FOhz/qsBMEJEHltcdjblevkyQLBb4nsi8WnVnXvXsuBTM3x1y9fFVKJU4A9+4xmk4k+J4WSCVJrFQ44UjeKG/zZNL5xhzXjUcRjzU3x2MpnWUtx/BVHSHPCZ7IPTwuGqwliQeBI+7xmAScSj1IMpMLn3IZvHWLj+oWr244hQIj9NGIEanSCvm8yzuryvGTT5iSqNW4QArweLu7PLZ6aKrVm/xVUqmjlZuJhCu/16TRanHRUVWdiYRbE+h0SKZq36ZJJpViVB2GLjVUKHC8nQ4fNzZcib3WEubmHlT0DIfOBiEM3cJmr+cWUS8RPJF7eFwEDIeut6W1JKZJcyv5rnQ67ra/0yEpDwYkrGKRqZRPPnHmVfLuvnUL+IVfcAZVN28yzy3lxt4eyXN5mceLx13bNKVgmk2+t73N90XMku2pBVom49QuyqFnMm6BdTgkIcstUU6MWniUTPGTT/j7jRvcP5vlJFKpkNSnp/m4t8dJQWsJkwU/Dyu/16LxcYzHly4aBzyRe3icPwYDFuKo8KbZJFnKQ3wSqtTs96nSUJSqBcW9PRJzo8GoN5UiAW5vM/3w9tskvEaDEe/2tuuqU6nQhCqVcr0pm01OLktL3G5nx3XykRYc4PlHI5LjaERClqnWzg5fGw75WWMx12w5m3WFO72emwjUHFlt0zY2OIFZ63zIMxmOpVx2pFwqubUEuSeehHic20niKAsArUdcMngi9/A4T1jLRcTNTZJLLOYMo/b2XMsylZArOpYWXNGjmiqrfD6TcUZS8/Mk0P19kmoUuYi90aBKJgjc4qR6VgKuq1A+76opNza4n3pxKrLOZJgeWVx0joiNBlUlsg2Ix13kXyqRvFdXXceft97iGL74ghNPMumi+Js3XZs4pU7UVWjSikDpkschl2P+vVrl+GZmqHDxEbmHh8cTodHg4uL0tIsKlebY3iaBqru7uroDrl8k4Bb0tCC6sUGSlhIDICEWCsAf/IHLc/f7Lo2hiHY4dOkaa90EAbiJ5NVXScqKzjWefJ6PWjicmuJnk+eKqiyXl51HyswMJ5qVFUem8ptR04p6nYu1KpBKpXh9AH7GZPLJ+2P2+7yDWVzkeEYjjq/bvXTl+YAncg+PZ4PxmOkK9XnUIt1xlMsktMmFN+mqV1acm6C8U1SgMxo5OaCMqg4OSIoq2pGJVKXiinzUsHh9ncdSZ3p1tZcaJZFwpfOdjpMKLi6SRFVN2WqR7LV/IkEiv3uXaZN43DU1Vt/N/X1OXKo6XVpiJCwbXBlyzc46vfho5O4yqlVndbuzw88kG4Js9nSe4fX60TsaVZZWKq6n6CWCJ3IPj7OG/Dqk+ZYp09ra0dt25ZNnZkhIYUgCMcaZP5VKR/PklQrTAV98Qf23imoWF0luX37pjrGxQfJbXWUEns06u9dikft+9pmrqlSDBTUibjRcPl0yw26XY221nDOiugmpGjKRYFRfKHARstt1vTJlRdvr0Y72V36F29+969Quw6HLkafTPI4qW6emeE7Z7MqLXB2HCgV+lseR+eQdjaAFUBlqXSJ4IvfwOGto8W2yAKXTYSSpNmXAUTXH3BxJWkVAKysk9kSCz0cjEtsXXwAffcRJYWHBRcv1Ogl7OCRpyykwnXZmXPIQabddvnp6muPa2nLVnwDHsrjoctLWOilhtcpjpFL8XRG9ovcw5O9BQNJXVJ5K8TGKOHmlUu46GcNJqN93ahSRvwp1Gg2OczTiXUWrxZSLVDzqBjQ19Xi/8VzOXQNBE++TerhfAHgi9/A4azQaDxJJOs3XJ4kcIIHfu+eiYkWKq6uMuG/f5sSwv89j9vskbi04Vqt8vdlk1Nrrkazn5xnNb23xp9OhMkapDXUCyuVIqgcHPLaaK/f7nBzGY1fqPzPD5/2+80rpdBjdyxRLTonjMcfW6XBCKJe5/7VrLl8+M8NJQhNMGPK48ntptZi//ugjfhb15FRZvRZyJxGLuYrOR0EpGqWRpKpZXb2w7dweBU/kHh5njVjMFekIJ5kzASQuGWXV63w+Pc0I9O5dvp7L8Wc8ZpVlMulSNjs7JKJcjgSrCF1FO60W0zyKaJW2UFWnyHey1D6ZdE2JpejIZjnpqCpUBT+ZDPfb2OD2QeD6eabT3F/5eqVeXn2V50wkOIFpPSGR4LH7fXcnodSTJofXXuM5u123+DkJtch7HMKQZf71Osk8m3WSyEsIT+QeHmeNmRmnOJmsMFxZObKZAtFmI4ZEdYxSGCGTtSRheY1PTzOC7vW402SDYRF8o+HSGq2W61cpmaGi3ShyDoVRhGEyiVGzB2t6MGGAZDqNQPvJoCud5ucIAldA1O0yGg8C5wOuH+WXRaay2Z2edo0mjGHELVdEe/iZFU1rUVSLr1HEazepJtG2ImHA+bIf91R5GGQRPFl4dUnhidzD46xRKDi1iDA/f6TQZDxmRmU8BpKDFgbVFu7Fp7CMNgqmw3xxuex01VtbJPF220XP7bZbZGxMNOWSfE8qkDB05luDAdDtojseAyYOpOIwYRKRtWjncsh2Kgh6Pdf2TCQr61s5Jk5Wmk5OHEq7yNhLC7Zzc66oaHnZLUoOBuyxqSbOMzN8/PnPSdzXr3MiW19nikZFQaMR36vXncQyHn9wQfkFgSdyD4+zhjGUzqmw5oQFtEaDb+VyAGoNxHIJxKp7KH+6jXzvE5jtbZbVf/EFSVJSPaVC5KmivpUyy2q1XP9LVUomk0csAOxwCIwtEFogmQDsCMYECCoV9DFGulhw3inVKslR49eipfp3Sr+udIyKmuS7ouKkqSlOZvPzfC+X47affuoaU2QydEjc2eH433qLk188zolsY8PdWUhvnss5z5d4/FLmt88Cnsg9PM4CyjnLpEoeJA9RQMgnCsB9Ao5VDzDa28No3ER8ZoYk+dlnnBTyeZLxwgKj03LZ+Zjs7pKww5CEKPJTeqRadUVDvR5GGsR4CAx6gAlgUkkgsABCl8ZR+b306ZP5dC1MKnctlYx6fErzrfTMyorL3b/yCvf75BOea3GR2+7vc/IqFt2+W1uM4K9d476K8NNpdzFPkxP/msNfAQ+Pp4WqHHVLH4+78vKHIJl0ASumpphn6bZh6xWEc0kS4vXrZPx+n+qVb3yDBHdwQIJTGkP+JceVI8kkyXA45M/hYmYwHAGw/On3D1MvPSCeAGCA/uFdhNIlkjdqgmg2uZ+KlfSBKhU+zswwipcC5tVXjxYYzc25qtJq1RUbNRp8VMm+FjkbDe4rNcsllAc+a5wJkRtj/jaA3wSwZ619+yyO6eFx4RFFjI4/+ogRaCLhbFi3txlJp9N8zGQcqRqDQj6OSsWQizMZROk0op99hJmNDxE00iSs2VlnqBWPHzV60uJhterUJuokr6gZcE2ao+i+rW2ICde/yAKxADAWpt+FUTGR9teEoAXbXs9ZBmhRU2kWmWktLPDzfuMbJGV1A3rpJb6uiaXT4YRUKnGM9TqP89ln3O/ePedjroVJT+In4qwi8v8KwN8E8F+f0fE8PJ4vRLKPcsw7DkXGhQJJdHeX6QJ5bpdKPO6XX/KY9+4xfRCLIbGygisrL2FvPI3WvSbSn3yCqUQbheIhGd+7RwJfX+ekkM1SV6589MsvM0qvVEiI0oUrHTJZuXioUrnfoxJAEsD9rpQ2AkwIxAxS48PmD4r0VZSk1IzMrcZjThLyh0kknOFXocC7DJliLS+7ZtLydlHLOE0EnQ4nqOVlnkPrC/U6P9tLLzGS9zgRZ0Lk1to/MMZcO4tjeXg8dzQaLDRR+fjUlGsb9jCo5VkuR7LZ33cLbYpef/pT6p4rFVeRKPVIuYzUnTu4AiBqtWHufQozNwukl6kfv32bRK7mEMOh63gP8PeDA7egKZKMxe7nwpFIuChaBH+IAEDaGIziMYytRdxECMIQCIOjjSoOq0IHQQydRBG9WAGxoI5sp4K0HTsd+PQ0P1cY8vPGYszj5/NOSx4EjLCnpjjmRIKvtdv8PMWiS61cueJati0tub+Nx4l4bjlyY8z3AHwPAK5cufK8Tuvh8Wh0uyTZbNbdttdqrsHxw6DUQyZztNmxVCMLC4xqb90iMQ8GjDKnp0liH3/M/dbWEBgD5A610IUC9719m1GqompNAtUqCa/ddtGwom2lVuSv3e8f9QwHnK4dAKxFzBjEjDmq/CgWSbCdDjAYYBSEaJgpjON5JNtlhOMBuuk8bL+JTK/novaFBfqdNxok7GKRTSGGQ046kw0zkkng136N7+3vOz14pcL3pYh56SUep9m8lB4ozwvPjcittT8A8AMAePfdd09ozeHhcQ6o1UhCk7lXRdmzsycTh6LxrS1XvKJClnKZUeTsrGupVqmQrOTPvbnJ53JHDALu9+qrJH6tgqrF2XjsPLmlzzbGFRzJuU+VkPJWUbedSVjrtpMRloh9stenjjMaoVtcxtjkkEgFCA46QCqOWCqJPgKk+mUEispXVlwvzW9+kyQehkwNqbT/7bdJ1Jub7m4jkeBnNoYTwNqaqywVqcfjnsQfAa9a8XixMRo9SBBa7JuMAHs9kmmrRdKVdvDuXZcuyeVc0Uql4jxXajVXdbm/z6i6XObjzo4ze9rfdxOK2qppYVEFOiJEa13ErabGgEvr6PnDPvOksZXy+epgr3J5AAhD9EcBgnELQbsLY0cwnQFsGMPYhhiVZpBIxZkKmZ93kfjyMifDbpeRusywOh2nprlzh2QvI65Mhu3oymXnsyLVzLGqWI+j8ETu8WKjUHB+JcJg4KoTAZL43bskPJW5HxyQXF57jc8//JCLnakUCfnOHUbl8v2Wb7gaOjQafJ7LHdbpN0l8pZLLM6uKc5KU1exYboZyKzwl+gCiw4g7BcBoIgtDkrCqRqPofmonFhvgIJhBKeohlkjBjkawwzGiqRJib68CsZATVjbLSSyXYyFTu01ylyOi0jCy2n3zTX6OTIb7xGK8DrLuVcPo1dXTl92/oDgr+eF/C+DPAZg1xmwA+GvW2r91Fsf28HimyOcdkcbjTjNdLFKBEoaMFtNp118SONp9p1rl87k51zvTGKYP7t1zlZd7eyRopRRyObcYGUX8fXraRefH0yKCCo+egMQtgN6x13oA4v0+YkrBqHgH4HU47PiTa++hGcbQiWeRCXsw8Qz6qQLy0ykE5QPq3d95h+P5/HOaUampRafD15aXef2UWnrrLU50YcjnapaxuMjH5WWXOvJ4LM5KtfIvncVxHoXx2DUYTyYf7EnrcXaoVsk51pLPpqcffb2lTFMDcvXhlVBB+17IFGcQMCcrHbMW2/p9XgQ5Ck5NOVe/Xo/R4uYmI06ZVlUqjrT39+kXApDAFPke/j6otzFOWcTafcT7bddWTXcHj9JLDwZP/DGPk7gwDGKIqdxf+XJVaR7axsb6bSyEe2jYIoZhGmEqgWKsi3SrCaQOrQiWl50mfH7eFTN9/jk/cyrFz6dq1Hqd2weBK9lvtZyR1t6e8yn3eCwuRWql16PNwmQacH7+8pmWyZxtkhQVVD1tlbFSiXIhPe7GOR67grxEwllMawzb2+ShzU3nzxRFvMZra/wZjVzXMn2/oohBp1xTAWd5YYxL166s8Jyzszy2xhGGHLf2U/8E2UTrc4lb1OB9UiJ9cOCa1BQKbuJR+lj211Hkei2oroUijgCjUQGm2kZ2GEfYs9j/qIrafoRsu4GZxm3kVooYZbbReekd9DYHiD7/AsF4gGDPotDaRmxhGsNBH2ZvD8lxF0azWjwOWAu7swuTzSBqd3CwM0Z3nENQ76M7yiKFOAqmheSgj0TUQTiqwQ6G6CMBG8aRGLfxVcpgxgAGYDTeRxxDxBDHCEkMMUmPURAgUFpFVrRyPIzHgXQaicBiFlUgHwCJw8XQdMZVlG5tkXwXF51UMJ93C7WDgVOmrK6StNfWmHpSBWcy6apjlULyEdupcOGJ3Fr+j8TjzsXSWgY8+mI/a/T7/L96XKB0EkSSt27xfzqXc+Pudh0htduH3420M4erVklQ6jUbj3M7wJHZeEzy/eADjm152Y2zViPBNhpUs6mBerFIu4s/82d43L//95nS3Nxkand6mtLdZNKp2d5+m9vevUviTqWYSQhDfn+NAXa3BihvD9DoWGQyMVRbKYxG5r5fkj6DrK3l+aTUqL67Ozu8Nofqt/vKO01SyaT7/Lu73C6dJh9ks7zGqvJWOjuXoygknWZQ8NlnrkdBoQAsTDWR6XSAcQbbOxZhPYmphMXydBGLmTcQ+8MmRpv72B3+BMMwiVQjiU5sHgtLIUpTVxBLxJEbloEoh+54Csl+H9lRCrFojAAD5Go7aG2GGDRKGEcBMoM6Uqiijhw2sYqktViwm7jW2UIaFTSwhD7ywDhAAj3MYRMGA9RRhEECRZSRRQ8GgAruAWCMEAMkESICYBEBqGIaLeQRQ4QQY6QwRApDhPEQ6bCHZEAN+iiTxyiIYMMQ/WofUb+DRlTEOF1AMugD3Q7irTQKxRjSs0VnnpXP859mbo5/4J0d/gH0T600UfqwYlX5fa0ByMtleZkf4lBFM0aI9uHNTir15P2VXyRceCLXF3iSsKW4Urep4dBVIYsk5ePzpI6W8t3X49aWW49Jpfh/WCgc3cfao3eAcvOsVEigt26RdBIJyocrFW5fKrlgZH3dFdI1m05YoGbmauQiqa/+7//n/5mN0Xs9ktjiIrf78Y95TXRtFCBKADEcushZxXrdrhNCSE48HLpoVkQLOIM7yamBw7AaAQADUksHwMmdWhTIPVt0cd9TBAAQB3BShNcFxz0HHMaqAaZhEcEe7puARR51zGIHfSSRwivIooPRXgwh+hghxF38KlooIIEBsugjjj4KaGAe+3gDnwIYo4MMOshhhBFy6GCMFDpIIsQQAQwWsIMSmhggiQJquIFbGCOGKr4LIMI6ruIAs3gFH+BtfIYGsjAIMI0qkuhjgAyyaGGEBCqYxjoWcRfX73+uLOqYQw3TqGJhuIfYMMI0Kui3s+hMX0EzPYP97QCdUYAtzCGEgelEMGCx0GvDm8h0LIphDnNTKaQbFQSZt9AI38a9mz3U1lsIbBHLGwdYLI6QaYeIojWYwlWYrU30wzR67QjROI1EaQkzQQyl/Bjj/ALq9TSS7QiFoIVhfhp3boX3MzEHB/xLzc3xOwi4Oqh8nq+fdVA3GjFIuAwTibHSkD5HvPvuu/a999471bb9PqPECStnALzAMkHb2HCS2E7HEa9skhcXH7xDkxhABWzWMkKTsVy1SsLVnWA8zn8ga2nElkqR4Pb3ec543EWcW1uMBNfXXYMVRcW1Gs/ZanFcd+64gKTd5nvb2/xMIjpF4mHIVG0mwzHXaq7/QBAMYHt9jHsjdJBEhBAsxH4WGIPEEEw8f1TeVk51FkAER/b9w+eJw9fGAEIAT5oXtYfHsmBsEoebWI4jxINk/rBtj2N4OM4hprEHixAdpNFH7vDcAwC5w/HreoQABljAFlqIIzr824yQwDwqCBAhhiHGiAGwiGOAl/EFQozRQwZtZJBGB/PYxx6mUcY0KphGHk3k0cRLuIsGcvhF/Ax5NFBEGS2UMEQcA8TwKd5EFykAAXYxhwam8Uv4Y6TQRQwRekjgAHNIo4c9TKGFEhawjQrmDieiJtrIIIkuGigiiQFSGCFCAuP0FPLJHszcLHZHs+h1gUQyQiocYWW8gVEYxyiIw8YTmJqyKAzryEU1hIU8bDyJ8cwcZq7kYefm0Npuo3wwwvpODPnZNJav5zAza+7ftSkoU23QwoJLnxlDIv/2t6lmnEz7PWxdRsHLw+6wOx3eoU7UTmFu7vzTucaYn1hr3z3++oWPyFUXoW5RgCPhTIakqXUUa12+dGrK5UI3Nki+WssRUSv/KhsI5XMl/e31eOztbS7E7+/zH0ge/h984AhWLRnV1EW37JUKo/BcznXHUgPyvT3uXy47F1KlFGo194+mhUN9djV5UQFiYPtIoYMIIbpIgKQyPHw8KUyJDt8P8WT/Aj0Axyf+JB5N4sKjyHJyfyk10mDSQM8TwImZ4slt9PxRof4j9NX3oSj+OAu427sKFuEmHW2XPDx+73AKjdBHDEAau7gOTjYBgBjS6AAIEEMXDUyDBrIRUuihjzRS6CKNLoZIYow4PsIb2MUKWsgAsDjAEvKoAYihjSz6SCOGCHk0MDhMr3SRQRdp9JHGCAm0kcAAcfwx3sUSthEhjhFiyKOJEBGaKGEP82ghiz5SiBBDCh2sYw1xDBAhxAAJjMG0h+0GSHQtujVNZCES6CCGMZIowCKOBIYIMMQYcSzEUsinZ2Eyaczk+kg3E+jcjuGzWgb9fhbNxhiRDTAaGUQRv8PFIr8PSpeVSkynNZuMkIPA3Z3u7AC/+ItMvW9skIiHQ74/N8dAS55mOzv8fhUKDKgmo3m1BJUCtdUiX9y+zZTk6urRPhrGcNvTrMsev3s/K1x4IjeGC2Wbm/zjKXpeWODv47FTTPV6rlJaeVPVWnS7rgL44IARfqXiCF3pBlk+qN2hzP83N3k8kfQXX3DfUon/TKoXiSL+4yg9YS2Pk8u5dooidBnIqahNbRg1oUjBNSlS6Hb5mdT+EAACjDFEDOP7ka5SGyfdbU0Sqgg9iQdJ6zgmM7GT6E+c72E4bcR7fJ8I7vPoIqSPbfcQid5XRgRghPAwrRKdOIGEJ7wmcPLsIwIYt2KAPvhVSyGOIVZwD3EMYdHHHMpIYowq5pBGFwV0cRc30EUS06hiDKCCaTQwhQR6mEYdY8QwQAwBQmxhCX2kUcYCruIOtrAGgzHSaKOLJKqYA2CRRA9D5NBFEjXMoIUCAhhMoYoWChjDIn54R9RDBkMkECLCPubQRB4JDDC4f7ehv3eE7rG7swGSGCBAFwMEsIghgRxaGCJEZZRFtRlDysaw3ZlCspvG/t4IjVEfQ6QAhPeLUgH+rzebLpjp9/m9jSJ+H7NZ1xb0iy8YMP3oR1zfKRYZ6EmBNTtLn7EwJImn03xfvZ6/8Q2mJLXIL15pNt32Mp68d48TQ6XiBBix2MnOxUqNjkYM2LpdbjM7e7bS+AtP5IDrT6tcrSJwXSRBvx+/pZLkVgox9bGtVvnH6fc5yxeLJNJej3+wdNrNtvqjtlr8gx0ccHvdmqXTTm2haHxvj6+n064YUFH71JTLhcuLX7eKUoAdz3pJCSI1hhAiwggBovtfMkw82onfH0aofTxIkMfxKMIM8fAoOPaI9x6FEU7+91T6Rb9/VQzhxpWA03cAQAxjjAAkEKCL6LHXRrCHY+NxmFQJESBCdDjJLmIHMYwQYACDMcqYwRz2kMAILWRRReEwFk9jB0kEGKOFLBIYooQWEhjAIoSFhUWALOqIoYYqstjFHF7H5zCw2MEc9rCIJPqwiKGGeSTRxywq2MIiNrGCHNpoII8xYjCwmEIV48O7jiS66CKDKkqHn4PpmaM4aUILD69EEmMMEDv83wwxQh8xDJHFeGARJuJolYEo4pR5/69y7N9MIpp6nd+9yWJWrWNJiFAqMRLf32fAlU6TOJeX+T394gumO69fJ2nv7PC73Wi4vtQzM+5uXoFfJuPWq+To+9lnPK6CyH6fk8v1687jbGfH2cnv7jKSn5riexsbZ1vndCmIHOAfc7L3KuC6TnW7rum2cmbqxwo47bnyYmpzKMuKeJzHUp59suGJqpbVNEWyPTmGTsoGFYED/ANpMlhY4K1aOs1oQdG4/tEWF11rxShyx54cbxS5Rd5JI7ggAOzYHC7M6Ys2ee922vs45a6/CiI8nLDjD3n9q2KAx086j8PxCU3RfgQSke4ExoeT48MmleOYzP8bWBgYADH0MIJBCgNM4wBZNBDHGGMEsLAYIg6DIerIIoXxYaafJJhEB3k0UMc02siggyxyaCGLJuKwKGEfI6SxjC3UUUATeViESGKMt/Ex2sjhDl6CRYABUrCgjHAdSxggCQuDHNroIYU9zCJCgCw6aGIJgMEYCdgjhG2BIwHDw64BAMQxxAAGaQwRIIMexgjQG0RIBRGsDRAPRhhHD1ckqFOeFvkBJ1eVy4B+6nXyQbF4tFlTs+m+Q9q21eL3ezQiuXe7LNJVYHb7trN5F3dITNFuH/UzA7hNs+nSsTK7zOcdD5TLrhse4NRUZ4FLQ+QPg+oQWi0+1+wp7bBM55QDSyRcQxUpLvp914lK+XhFvnNzrjWgZHnxuLPTkFvoaMT933zz6MKkFCdvvMEZenGRNRK9HvfRP5n+uLLN0D+gJpBYzEnvtLiq2b3fCZAaDdEHMDq8zQ0wQoSHf0EexNMsesfBL28cbtExiSdftJxEhMdPLmfdZEATjtJSw8OIMjphu5O+OiR/AAgwRAAghTaKqGOEEHk08SY+wi5m0UThMH0xQglltJBFETX0kUUAi8Kh4iaNDmIYoY0cRofnDBEhgz76CBEhwBTqCDHEInaRQA+7WEEDWeTQQxFVtJHCFq7DwmCM4DBjPkaIEWIYHy60AmPEEGKEHlIYIXv4OZVGGRx+5sdN9nq/B8AgABDBInE/1TJECIv4cIhUzKCRKCGIYhPqp6NQ0CRFl3o+K389ab6oTnhSRA0G/I60Wvw+6Vhy9c1knJX7lSvcRvn4mRneUQNOFCHRhGxhToIscHo9J9Do90nknQ5/ZF8vocJZ5MwvPZHH41yI1C3Wyy/zIiqFoWYlgloeyhp5b48XvFTidpkMCXt7m8eWXlkLkXq+sOAmC93uXb/OWV0SWYApIWtdwd547NQtOztOHaNiuHSaub5azTVPnyyesZZjkPdQrQb0+2nYPmCaDYTBCLu1NDpRGt1x+n5FucNkqmUSjyPFJEjSyonqOAGOfrlPUsqEcGkQRbt4yDiIGAYYIcDRCPCkxduT7gR0ricneoMRDCxCjDFGhCS6GKEAl1oaHr6XOeH4VHEHh5RrYbGMXbQRRx4dxDHECAbL2EYZfTSQRwZtzOMAFRQQxxhlJA6j9jFGiKGGDFLoI4XWYXyevf9p02gjjS5GCDGDCmKIkEEHX+JljJBEBIs0+lhABQdYRg8JJNFDgCEiRIgQIokWIgQYI40pNBAghgoKIHHr7mIMpyp6HJFbACMkMcAQSYwQIoEAMUSwiCFMBCiluxhFcSSn4ugMcsiGjtQmoe9dLOa+l9PT/E4ISm0oRz0769aVRJ6DgUuDymxSjr+tFl+fn3fRv9RuxSLJe3OT5Ku7/4k6rwcUMip2myTndNplADRhDQauE95Z4NITuTC5yCBCPgnpNMlVhTbScQ8G/GNdv84/0uIi/2FUeq5iG0XOMzMkVy1wFgrOxjmReFDuePUq93/rLebXDg74u7plpVLun+Wdd9xk1O26Wzo1Trl6lQT+ox/xkYqXNK5fTyOTinDnrsHP3jfY2+M/chAc5hmrCbT36+iPDIbjgP/QQYR+kEYs7hZRpXM/aqIXIAwSSJkuwnELI4ToIIPTpTkSIBH2EaKFJIboIAlG8BZOfqj/6hAjZJFDA3FYDBEggkUHeTxInvHD1/oI0EMJBxgjDXO4YFlDASOkD48/yRQnfYPiyKGCJBqIHS7mRYcpkT6SoCqjhTSGaCKLBopwUesAJXQOVSoGWXQOf8qYQh9zqKCBIrpII4cWvomfwSDCEClECDFEiJ/g2xghjgz6yKKJGorIoI013EMB7UORZxwBLK5gE2MAMUSIAKxiA12EaGAWU6jCwGIMgzjGSKCFBFpIIcIMyriHawAMDCIEiDCFGiKEiBDDDhYwQogYRvc/P+9PArj8f3zi+mltIYA5jL2zGCGTjCOeBPrdMQrxDqaKFtlYF1G+hJXVDMZjg1olwlTcBS3Kh+uu+rCoFHNzDNDefJNn/Kf/lP/Xsn9vNPh9W152thJra/x9c5PkPzvL/+21NX6HxmMGcdks95NgYX7e1UsUi3yezbqFykzGFaYeHLjgKopcLl5cJHIvFjmOXs8ZQfb7/B6fFS68jvx54WG3OHIMVTOTszqXim9SKZf2kYolCFxFowqJlCOfbELTaDirZ1VPKtKQC6o8oba3eQfwxecR+vUO5nI9lGZiiJeyWFyNIwicxr1Wo02IGtsoalla4pdiOOQ2Uv3kcs6GWgaBatO4seHUBsvL/FJurQ/RKve50JtOo1IP78svAVfpOeqNgF6PLR5jaQyj8BE2IwOs4RbGCBEhPEwdDDGNfdzEKxgiRAp9xDBGCg30kMEB5hAhwjTKKKKJIsooooUYumgjg+EhYRkAadQRxxhdZBGHRYAxasgiiw5KqGAZZQQYYYT4IYVGWMQe5nCAAlpYxxq6SCKHFlLoYA07qKGAz/Aq4ojQQQYf4Q0AY7yFjzGNGuKH1ZljxDGFKvqHEW4ODUQA4rBIo4chEoihiwz6GCOJHcxiB4uoYO5QeUMdzho20EQeu5jDZ3gFfeSRwhBDxDCFGloooo4pBAhRxAHqmDqcbGIIEWEKHfRjaezHV2DicUzlxiimuuh1LJKxCEExj67NYTZWxcKCRakYIp0Gwvo+EkmLq7NdrP3SMnqDAIlxH5VWDLc7y/ebGy0uOqVJu01CnJ93fTpmZtz3URXLqZSzqVle5v9Ns0nCVspTAVI6ze+W/m9VDVwu8y59bo7b9np8/e23H10ENGnzMGl5AXBsqkgHXOpXtjMzM+5u4knwMB25J/IXBP0+iV3+SGrAPjV19J9VC0JRxEhfEX02y3/Ybtf9A8s2QV5IKp2fbL7e7/OLcvs2H+NxFm3cuMHtpBiQ2iCZ5Bf6lVeAbjtCpWoQWXPEJyaR4BdZx9zcBILKFq7gHjIzObS7QGuvjuS4hyvdL1Ccj+Gl68CNTAUtZNBoWOzbGXxuX8bBh5sobX2MWByY795FLuwhnQkRH/XQGwKZ6jpmBrsYzywgqOyj3+6jiThGSCGDHjJoHC5eRmihgB4SGCOGAmrIo40usqgd3kkMkEQcbUyhhSECBAjQRgYHKKKHFEKMECGGHlKYOSzBz6GFGOi70kcSfSTQQwoVzOAqNlHCLixC7GMJQ1hk0EMSA6QxRB9ptJFBEwWkMzHMBxWYWIjeMEANOWwlb+AjvI36KINEKoHla0Bv/iV0TBrDSgfDeg/peA9TU0AqDrwyVwXSGezE1rBlltAIZ1BvGOSTHVx7JYP08gwsDJZLHfTXdzCMZRDGQ8S7daT27mH6rWXkVouYnRohOWphtLgGZLP3RQo3b5JkUyn+X66ukuzGY9fVTmnQ8Zh/+16P5JvLuYg+CEjmsZhbXJxUsh0P2ib7hAyHjN5PKiJ8Uih1IxcDqeCeBp7IPc4VUgtM3lUch5QB4aALs7frVrimpxnyH9tR9gGdSg+d9z+DaTWRnM4iEQeatTG6n95BePsLpJr7WFoA4gu8x7a1OgZXXgbiIaJPP0OlajC4s4nC3ufAeIRUZRujSh0mjCPWb8MM+kAcCJtNjKLoMOnAbvTKTU6qzQc4Kow8HniNJx7HOL6kS3IfwCCHLvIY3V+ZUIZ6B/NIYoQUeggwxhgWI6RhEGABVR6rULifFB4kM2jlFmHHEcxgABM3SMUskI7BlubQTM+ic+VNdEprSL1xA/FwjEzKIipXMO6PkCzlMG510N1roH/1NUSNNkZz85grRsisTsMmUxivXEEyG7tfhdwvNxFWD5AKR0ilDcJkDHY4grERx6Xw9xik1pKKzOMoLm1lp8fXA48icCEIgGDYBzbW+U3O5fit3t3lBqXSke216JTvNYH5LpBoAUWukE13djFY7ML0hkgMDpOth00cTLeL5PrNQytGg5XZEdAfoXfQxWh9G0G3jsR4BAQR0KzeXyhIHJYHEQ8PgB4XyIXgioEI/WjGLsIsWkdeSR15F0jCIHu4FIxDcWAMfQyQc8dSE+lMBonBACVbxwAW1oyRjCdgkgkglQDCMTKrWWBxCLR+TmOg+Xn+MRYWgDAJ1PaBcIDB67MYzsURTq0imQ5gmg0gb4BXrhzR4k1NAZjKAzbnFpiMgbH2yPOT8KTeSB6EJ3KPiwUlyydNzHM51wvz+ELF/j7viWs1Pr99G0gmYXo9JEcdYHkOKL7Ce3Ntp/v35WVG+uUyEARI2ghRowq0akAYB8YNYEy1ylkHh49S1j9KdBmAapURAsQRITicUIZIIRm3QJhyMo/Z2fse6SaKkMym3aKLtW7lXJ2M5Asube2XXwLf/S7zAp99hsTsFBKvrTolweyMW62/P3jdVoWuXFk4/tzjzOCvqsfFQr//4Jddui0lOtVhvdej9ECrYOrQfusWb9sV/bVaJJEvv+Trg4Gr8753j+/duQNz9y7MsAeMIsCO75M4cLJjzbPC40R+WbTQRAEjJBBiiBESiIIUckVzOAGNnShaVXMSN8/O8hrt77vUlfzC5UfebjtL2qkpXt9S6cEKOBVpAK5sulJxq4/z875F23PCmRC5MeY3APzn4F3jf2mt/etncVyPFxCSLUzeY0u+E4ZcGZXjkTRh6jaxvc339/b4+uoqif/LL4F/8k8YlRvjPH+lA7ty5b4wP51JYWwjDMYjYHyyV+KzxuPU72kABg10UMQQGSRiQCnZQTw/6wxBJI1QGXO/z7ud+Xleg2KR10fVLoMBo/OVFeCll4707LyvAbx1y70mYfTUFAclE6Ns1k22m5s85vNoGvCC46mJ3BgTAvgvAPxFABsAfmyM+R+ttR8/7bE9XkBMTTnnsMmecSsrruuEPIql0dzYIPlXq+419cjc3ubrGxs87uys01iWyyQ17XNo5hN2O0g/45W2RznQnEblmorHkcJh1Vkq5bwb1MAhnydRdzr3U0coFhkhhyFlQ3KJUtVLEDizkf19krm8LnI56k9VGi35iCQh1aojcYDXWNd5cfGprpXH43EWEfl3ANy01t4GAGPMfwfgLwHwRO7x5IjFGCGrIXIqRQJJp0nEMsQBXO789m2mSBIJRuLtNompXHZdCKKIKRbp08Zjl3Ixxlldqq/cM1ZzqRTquO3XqaTFWuWdLH1Ubjsed2b9xaITUW9u8vHKFb4+ae4NcLsvvwRef53XptNxqRE1hp6b44R6HLILPL5+oUjf45njLIh8BcD6xPMNAL98fCNjzPcAfA8Arly5cgan9fjaIhZj5Dw76xzCJh2PhGSSUaBs5tJpElgi4ZzJ5ueZBshmnb+x2k5JJG+tawXzHOW4p0rZKNIW1NZJEa9MR9TvUguWpRL3lWlPqUTDn9decyWR3a6L4mMx4Jd+iQL+MCShS5BtDCP1h3VVmDQ7mUyJDQbcz+OZ4yyI/KR70Ae+DdbaHwD4AUAd+Rmc1+Prim6XCpPtbRIODWWch+j16yRo2dMtLbkWT7u7jMRVfSRT60bDLYiOx27xVAt8D3NtOm9oItOCr6JwlcuWSiRY3VmoPFKeq/JJ/oVfYNeF0YjX4uZN5+aWyZCIp6edYYlwmrSIMc7ESOsZWkg9QSvucfY4CyLfALA28XwVwNZDtvXweDRaLfa/290lWX36qSMjFbncvcuFtStXXOePjz6i4bT8BNptknirRUKrVjkhTCpfhMkuHRcRahWlHn8AybJYZMQrP9ZEgr8vLjpzbalNXn8d+OQTTn4q8U2lXLpJZtlaR3hSZDI0MarXeT1nZ53DnMczx1lc5R8DeMUYcx3AJoB/EcC/fAbH9XgRsbnpFim3t11XEDmSBYFr+SK3/n/yT1x99XhMIlGuW/Z3cgCb7N81aUd3UTFpmq+WV+oOruj67l2+NzVFMn/zTeeT8M1vklw/+4zXdnbWGZKsrnKCmJ3lJCcfhq8KmaN4PHc8NZFba0fGmL8C4HdB5dTfttZ+9NQj83jxMBxy0VLKC4Ak3Gi4DtSbm3xcXiZp/fjHtMPb23NWlErBhCEjd2mkrXXRqPLMF30xLgxd0Y3SFfm8M72Rcb7SRbEYr08ux8h8cZHbqR2OOpUUCryDkTl/KsV9rl0770/s8RVwJvc91tp/BOAfncWxPF4AyCdUnQIELURK663eeLK6+/JLEpgqD60l8ZfLLnecTjPaHg75/uRC4WQ65bJALWq04Avw7kQLloOBU4skEiRotcu5csU1jJyZcS5SW1uMnCeLgnZ2mC/3Oe1LCZ/A8ni+qFYZJYtkMxnmcZNJ3v7v77tuHfv7JOnRiLf++/uuwEWvHxw4pYa6bQwGLvJWpHpZYS0nJRldy5gecCX4MqzXZxfRv/22c6C6csV1+pYt5XDoGlhKquidqi4lPJF7PD+oJXk+T8LZ32eUPTNDFcXmJgmmViMp7+05IhLU8WKy84bIvdNxXbal4rjMJD6JIKA6R4VOqk7VoyJvfd7r16lACQIS/k9+4uwiVa4va4NejymVszLc93ju8ETu8WzRbLr2L5WKk8rt7vJWf26O6ZHdXad5jiI+5vNMo3S73LbR4ASg6Fy5b8BJCRMJ5tNFWl8H6M5lNGLKRC3k220XoavV/J//865JraLrbJZtpz76iNdVZmFXrjAVpTsY74tyaeGJ3OPZoVZjBJ5Ok3A2N/kzM0OSnZpyNrWZDHO35TIj60lZ3GDAFMpwyGi0WnUkrYIZ5b9lFKWUxGWGFCsAP0uzyahcawu5nFO05HJ8zGaZYmm1+KMOwMUiFSz5PN8vl10xULdLT5Sv0rLG40LAE7nHs4FMrbJZks5wSNK5fZuRea9HAkmnXSXmJ5/wvXjcFbM0Gnyt0SAxqRX55HkmofNcdDXKo6BqU8ktZT0rfxmR9pUrvC7JJAn+1VcpPVxY4DXb3XVEDrg8ez7vTMOiyFdgfg3gidzj2UALjUqj7O0xhaKS73ye6ZF0mjncP/5jErtI+OCAed5mk+Qju9R2+0H/6+OYIPEhjppTTXbyuZCQLHI8dha0irS1SKnrooKe+XkS+NIS73IGAz6qr5/WGFIp/t7ruSaWgwHP+bBu5R6XAp7IPc4e/T4Jt9ViZCgHQkndZD+7uemaEKyvu3TB3p6zrB0MmFfXAqh0z6cZBmhKJR2GBduwxXFB//Hln6I8//Q0ybZYdL7hMzMkdS16Li8zEu92OeFJbrm4+OBdiTFcAJX1gc6pwiCPS4sL+f/scYlRqzECVxn8D3/oilZkG9tuk6zW1kjWn33GR5WhK1Lc3nZpl+1tJz+c1IY/ApMkjsPflTV/rv/4xhxNAWUyTAFN5vDTaScvzGRI4lHEaHswcCmotTWnB/+1XwO+8Q3uv7PjNODjMas9Z2cf7CCcSDAfPhhwTL455tcCnsg9zg5ajJQvda/n1CrDIcmj2XQVlvW6kxBay9/lgx2GJHBr3fu9niNE+WI/BLKIPf4PHgdbqT13KO8td8BJIyzZ0t5vQppn/ltrAmFIeeB3vsOIfH8feOstRt2Tk8R77wEvv8y7mliMx240Ti7yedoW8R4XCp7IPc4OIuV0muRycEAy6vUYnTebfE2yObn47e7yvW7XLWTKklWeIorC9SjPlEdUa06mVI5H5s8V8gwPQyeZTKedhlv9LZXTlhvhtWuMzN96i5H5yy/zuty8yeNJJ7+7y4hcTSOsdd2RDg58teYLAE/kHk+P0Yipj4MDV05fKh1NjUiF0Wg4ZcnurpMVymYW4Lb6PYocyU2mAB7jWGjATjtjHF3cPE7qzwUyvBJJK1pOpdyEpIlL3X3GY7cQnEzy+mgBVNp63cW02/wbrK5Sl9/t8prPz9/veuSLfb7e8ETucXpYy8i5ViOpTk2RdPb2SKwzM8yDqwioVmOEODPD14ZD15ZsOCSRy61QaRJpwkXak/nwJ2z6kAbQxdFUSoDTdeHpH9vvKymsJR2U8ZWaW5RKvB6Virt7icd5ndSV55132ORB6pRqlXc3qZTrx9lqcbIMAh5TOnAVVskN0ZP41x6eyD1Oj50d5rXTaUZ5W1sk8nabZPHppyy539tjiqRed3LD8ZiR4swMjwMcVaYALrWg9065qPkwGAAZMCpXvvw0lNZ9yGtPTOZSnkiNoy4+s4dNkjMZRszjsWuj9s47vD7yWjeG17NQ4OSYTLruSWqIoQ49Gxu8xvE4r2Ovx4VNj689PJF7nA7yNpnMt8bjrrz+1i3XuCGVYpSphrxTU67Cs1p1Ubc0zFK4qEpRvuJnhBCn144/qoyoB+CJ+sHL/6RYdE2ORbqylO12mQuXTe/eHie7RsP13pyaInFPTVFDnkzy+PE45YdKYa2ucr9ymRPD9eu+g/0LAk/kHqeDSHcSlQpz3F98wce9PZL1yopr3ru15UrNt7e5n6xU222XVuj3XR79nHA8nXIcT9yfUCkkOQ22WsB3v8vJr15nlL62xh81zJiZ4euFAqPp+Xn33muvORIXCgVOsppEez1G+nNzXlb4AsETucfpEIsdzVFLalguOwtVqS82Nkg+tRojQrX/qtedrLDff5C81Y39HGBxxrLESf+T4ZBReSbDO5KZGZK3Fi3DkIQ9M0NlSrvNKk3ASS7lkXIc6peZz/OuSH0yOx1G5zLG8vhawxO5x+kgMvjyS0aWW1skbFVrqpJTjRC2tkjYqlaMx0lc5bLr4C754QXomXkae60jXxaljzT2TMbp4wF3p6ES+8VFmlYlEsCf/bNMR+3ukqiVCnnpJRJ4s8nf+31ObLHYgx3qj2N/n+mrVIp/i3yek8furu/68wLgqYjcGPMvAPh/AngDwHeste+dxaA8LhikVd7bAz78kMZXWkyTXazy3B9/TAKKx123mk6HE0GnQ3KXGVSnc7JXyvFKyAuAERixjwCkjKGEMZnk5xgOXSu2IHDVkvJGT6WYFlEKRcqUep3pKS3sqmx+YYHHUn57OOR+D4usu11qy/N5V+ijBeh0msf2JfhfazxtRP4hgH8ewP/nDMbicVFRqfCnXic5z88z3x2G9LiemWGOvN9nNCmHvmqVqo163TVDaLVc7lYa8eOkfQ5EnsDJapUIVL+EACxi6COEtWNkZAErotairRYzAbeAm83ymqVSjJIBfvblZUbgGxvOtTCZZAS9ve0UP7EY1x0eRsb1ursjENJpTppqE+fxtcZTEbm19hMAMP4f5esHlcS32zS0SqWcH8rNmySH/X0+3r3rFkOVAtACnLzFrXWSO5Xq6zyCItPDKD0CyXUMygYThz/PCuHhuSahpVebzGEUyyAyAToji1TQ5HtaG1CpvRwLFZEvLgLf+haj5XichC4/9ViM0fRrr7F60xjnw37tmvNDeRwZj8ecMHd3XRUp4FQvXkf+tcdzy5EbY74H4HsAcOXKled1Wo+vAmtdAwdjqLKIxVxz5H7f9csUISsNMBjQ1dBaJ0FU8dBoxEjRGJL8cUwsdEYAakiijwxiGMJghDYCFND5asU5p0ACXPR0fYUCvpJMY5zJAlOzMP0xRgOLsTEIUjHnOChJ5eysK/x5+WVOXN/+NtMqvR5fq1SAO3c4Sa6sUCY4eReiReOTFjdPQj7PCWBpyd0ZaRKZnz/jq+RxEfFYIjfG/B6AxRPe+r619h+c9kTW2h8A+AEAvPvuuxcrAfoiQvntWOxoWzCAhF2tMrrc2SHBVCr8XQuV9+65dmNatEyluJ2sZuWDojREp+M69zwmfcIlRIsUWggQIcQYIyTQQhYptJ9Zmb3BYeFPLIZuPA0bRYiybEps+h3YIAUzM41Y+rC8XtLCdJqPhQJJ/OpVppxeeYU2s4CLlt9+m+R99y63jcd5LdptZ1n7JMjlOGF0Olw0VU796lWfVnlB8Fgit9b++vMYiMdzQhSRkJV/tZYksLzsCKTV4u+6VZeHdanEnLgaKNfrbhJoNl3z43jcRde6rZdKJZFwDSQeQeQjBIhjDIvxff12gDEM4hiBLobPFKMRErEROmEKkQ0QGAM7GmEUWORHFZhu9KB8cm2NKY5ikRPa2hqvz927JHg1TzaG5HvjhjMMCwLuOz395GMNAqfd73SOSh89Xgh4+eGLBpXNT7YAa7dJPHNzfK6WYqMRI0aARN/rcRulElotJ7ebn2e6pN12BKdu9tZy+17PtXh7DAJEGCGGAEdNrgKMT1Vm/5WhRcsgQGiA9FQGg24fo1gGscAgYbpIdw4/39wcibnZ5Ofe3ub1SCYZDReLzpp2MHAt1oR0mrnw0cgpeb4qgoDk7Rsov5B4WvnhXwbw/wIwB+B3jDE/s9b+b85kZB5nC/lyVKsPtvXKZEjCs7OuDdvnn1MLrpZg8gkplbjYqW73xSJJTHasyu9KVqioWy3cTpk2iAEYHnoVGnARso8MUug9u1ZtWmxNJO57mMSadcSsBQYdkmQQ8DpoMXPS13txkeqTWIzX7MoVkr1Ms2ZmTibrU3Y88vB4GJ5WtfL3APy9MxqLx7PAeMyFy0aD5LO1RcJ5lEe1CHc45GOrxSi7WmWaYDIlEo9zm2rVpVZOqs5UVH6SbvwEJAFEGKOPABFisAgRxxC5U5XufEWIZCX5UwPoKOJzdetptxlZp9PMgc/M8BosLHAyHI2c97hK7qURB5xMczx2+W2fy/Z4CvhQ4OuOvT2SiFIpMzOsznz9daeK6HSoKlEaZH+fqRRj2BR5c9M1QVBk3u8frc5UfvZxBT5PoA9PA0ghwhCDJzK++sqYLOyRVDIW4ySYy/EaTk5W2ay7AxmNuM/UlDuOrk8U8XOn0yTwzU3XGKJa5T7q9uPh8RXgifzrjNGIJBSPMweubun5PBfZpqfdYmc+T1KJIqf9/tM/dZFks8n31RyiXCbhyU+813t467WnKO4xeLba8QegfLWaMaTT7u6k1+Nz5bOXlpwbYTZLC9pSidt9/LGLzkcjRuuxGNU+mgAAHq9eJ5n7TvYeXxGeyC8jVKyjvPQkMUxCOfHJ3PR47CLH2VmSS6/HlEkYujL7ctk1PpC0Te56spvVIh9wtJHwZcBk9KvPnUq5vHepxJ+ZGV6vRsP1Ic3lqAf/7nepFqnXqeRJJDjxtVqUGP6ZP8PX1DhZ3XqO/63icV5fT+QeXxGeyC8brCVpqMpSxLC6+mABSRSRZMZjkvJ4THKq1xlNyhNkb4/kNByyoOTgAPjRj3i8mRlG75WKI3J1Bpos/Llg3ihHEIvxsysHPikZDALXVi2V4t1FLMZJ7soVknilwt+1KFwqAb/4i0yHrK2xMvPmTR7PGHa2v3HDLZ5KBqgGzMdxErl7eDwBPJFfNrRaJPFMxjkNjkYk9+PdYJTuuHXLqS22tkhWqj5UaXkm4/ptfv45yV053oUFbrO/7/TnktMNBkdbtV1EiLgnpX+AU6jE424STCRcw4fBgAucS0ssoZ+ZIYlvbPCa1+vAT3/K9MrVq65CM4p4rdQSTza1+TyvsxpUA85Yy8sGPZ4CnsgvCkQe7TYjwocVdNTrrpOMusxnsy6fm0q5RbrBgNG1rE1rNZff/uwzRpvr6yTn117j+b78kpNCqeRsWm/dchF9PM73teA3qRe/aK6FstDNZDjWyW45SnfI9EqpIkXjc3NUpCwt8Tq+9BKlllrU7Hb5e7/P6/nyyy5dc3DAa53LuTZ3m5vUjC8tPWiItbrq/tajEa+1UjnT024h2sPjIfBEfhGgdEm97rqp7+/zC348b9pqkTimpkgYsjDt9/ne8rIjB1VxFgokk2aT3XxiMUbdpRJJS7LCjz4igcRiTrWhVItIpVZz0jmA28r1T6+dF6Gr0bFSFVo7UKMFKW4UZb/2GvDJJyTZVMrJC0sl7rO4yNfHY/derUZCL5Wc7cDSEq/97Cy3nSRxgGOIx/m60jHS9Su9BfD5xgbfy2Tc3093Bh4eD4En8osANSqe1HaPRozcbtw4Go2p0UCj4Xy/+33uKwMntVJLpUj4tRqP1+m4hgjb2zxuu81z1+s8ZqXCfaRW0TFiMZKXzqsF1ESCP2qwoMrI59Hp57jRFOCeS7OuO4ZCgVH41BSj65UVFu+8/Tbwh3/IbaOI10XbybhqaYmffWeHx9XdhxpmJJMnF0BNQguqwkl3W9LrSyoahk5NVCr5knuPh8IT+UVAu/3gl1Q6ZJV8C4oo33+fr8uLemqKpFsuO6KfnWV+W00G4nFG1zK1kooiFmMkL+24CEot2SS96/UYjYs0h0OeR4QZj7vy/meNMCThThbsSCaoFJDy/1oTSKcZTb/xBq/L/Dwnt5dfdnc6167xOuiOZDh0EboxvH7VKq91FDnLglLJjUvt3Sb/pv2+2+Zh0ELrJDQhyMPGw+MEeCK/CAjDh6cijkd2uRwJfm3NPa9WXfpge5sEU6mQdItFktb775P0EwmnBa/V+DyT4S1/JsM7ABlg6diKJttttzgHONc+RajKmT+P1IqIXB4umnyUWgE40aVSrmtPJgP8yq8A/8w/w0j3gw94LVdWuO3GBj/3Sy/xekYRP28+z2NMTdGS9osvSNQq2ZdcUX+vxUWuPagydjjkOCb9bU6CFq4noevoy/g9HgH/33ERkMsx0ptsySVd8aSXB8Aoe32dv4ssul2Sx+Ymt19fd/4eGxskuJdfZi49lSKBK0erHPLGBo8xPe0WXBXpJhKcBFSx2Om491U4o0IaqTROWYp/IiTTe9RkoMpI5Znj8aP2APE4JzF5waj58eqqu0tR5x75d0/awc7MuLTS5ASVzVJe2G7zeiST3GfSQ0VmWI0Gt1GZ/uNMsXI5Hq/ddjnydpt/Ex+NezwCnsgvApJJ3s7v7joiymRcJ/VJJBL8Yu/vk2Tk7/3JJ3xfJDA766o69/bcgqUKXsKQxBFFjMATCR5DihktDKrJRLfLyDeRcJ1rZFc76ccNPH1xkCorH0XkWmCdNK7K5UjKyt2nUvw9k+FkNT3Nz3DzpuububTE3Ld8wZWqisU4sfX7D3bo0eT3KCQS/Bs86edeXT2qWllc5N/Zw+MR8ER+USCL08kGvidBXXeWl117r26Xz+/eJTHNzJAI19fZiUZRaK1Gorp925XbR5Ejqnabv1vrZI7r625hU42UJ9MnkzatMsbScQWRbhQ9ehE0m+UxwpDneRi0mKqmFuqNKfdFTUZBQFLUhBiG1HsnEnx/b4/XQvnvqSnmySXXFJmeNKE+K8icy6tUPJ4AnsgvEoLgqNZ5EsrXAnwcDkniipxbLRL11JQzsarXSYyJBBfl6nWmXw4O3GJqt+s6ukvuKEOsL7/ko1Imk/lbpT4m89Jh6JQzPdcw7b7Hi9I5k06ISt/E407KqEIn+bicdJ1U3KOJR3a7xSLvMKamXIPjYtFFu5PHuHYN+MlPXCpnPKZ2PJnkNcrned0eNql6eFwQeCK/DGg0XAGQtU5Nkkq5RhGVCl97/31GneUyib5UIimNRiT74ZAElUi4BTvllms1kqkmhW7XtQ07nvMWgWocksopklbVqAhfhlOqBNV6gPTnmpCmp52s8uCA+0qZAjj1jXL0an4Rj/NR/jH5PCPtZpPnVQ/NgwMu6OpO4sYNt6CpgirZEKysPMc/sofHV4cn8ouOToeacKUKRORbW0yXNJsuKpYRlrrWhCFTBEtLTpcOkNRyOUeq/b5bMGw0+LqqRoGTFy4VUSuyV8egft8tgCoXr3RKFDkdu7rDS3op18V0mu+pKlN3KJ2O06irSEr7pVL8PJpQ1tboMri87ApzEgm+trLictf9PlMYmQwnvuHQyQYXT2pT6+FxMfG0HYL+BoD/PYABgFsA/nVrbe0MxuUhVKskvMmmBwsLTJHs7bnS/ELBWaaqzHw04jZ7eyTMrS1G7r0eCVtViyLkIHBl6s3mo8elNMtkYZBy1YAz2FLOGjhqsKUf6a41SYnMFYWn027RVakYTQzZrFONrK2RfAcD3qVcvUrSnpnhNWy1GO1PtqkLApJ9MsmIXNdJ9gbqBOThccHxtBH5DwH8trV2ZIz5TwD8NoB//+mH5XEf6jYDuGi8UuHzSoURZyLBfLZasbVazAtPT/N1Rd3LyyTKXo/k1uu5FIMi5+GQ+4uUH6YcmSRoFRHp98kFTRGn5HOK1rVtOu320evjMUlYUkgV5XQ6jmALBXanVyee69dJ7DIKkwnV7ds8pySC8rApFrl9LOaUOZpEVCo/O/vkyhMPj3PAUxG5tfYfTzz9IwD/x6cbjscDyOddtaaqD4V4nEoVqUYm25N98glz5IpOm03uL6OouTnuo0XMXo8TQ7v94GLlcUiFIpWNdNiTNq2TKRXARdNKj4i843HnsphIOAWN0ipSyyivnk5z7Jo4XnmFpF4que708i+Rv4pSMVevus8s46tej8ftdI4W7KgZR7Hoi3E8LjzO8j/03wDw/zvD43kAzHs3GiRitW2rVBilTk/z940NEtq9e8CnnzppndIvn3zivEaaTZdKENndvetUJyrdn4QqN0XAQcDtJlUoSrWoclStzSbJXBLBIHCqFJWea1F1OORY+30+LxadJlwR+ews319Z4edutZhuWlsjoe/vc7vdXV4/taOTxLDZZKSuMdfrPNckketuRBOkh8cFxmP/Q40xvwfgpJWf71tr/8HhNt8HMALwdx5xnO8B+B4AXLly5SsN9oWA1CNqHDEzQ4JqtUjKSjvUai4qTqVcLliNfaVH7nT4+sEBt6nVHPHGYm5/KVomKzSVXhEBa9EQcHlkRc+qfpSplJQlUqooRaTFxGTSEex47LZJp0nGqiiVx3oyyUh8a4uvF4t8vrzMzyvLWdkBS3kiJU6p5BwO797lNRVxW8sUVKnkfMIF3/DB4xLgsURurf31R71vjPnXAPwmgH/W2oeX4llrfwDgBwDw7rvvXiDT6gsEFfHIm2M8ZpS9uEiSmZ9nFWIySeIT8WYy9P/Y3DyqHhkO3eIfwAi13eaxq1WSYa3mZHzdrit7P95RXuXqySSPL+12t+tIW5MA8KDOXGkR5bjDkJ8pmXSTi6SLaqc2NcXJZ2qKRCu5YhjybkTHevddXoNWi+O9epVR/cEBr8nUlJs8ymUnMxRkqHVwQILXWFTh6uFxwfG0qpXfABc3f81a+4hSPI9TodU6ulCnVMfBAaPOL79kpaYKVhTlbm+79EC/z/cmC2qkue52eVwRoOxou10SW6PhqjYVWcubXB2FAE4saiE3GvEYqsrU+YZDRs6K1LWv+oV2Ok7ml0y6uwnFAsvLnLiWl13+Wwu4Sq0sLAC//Ms8pqo9lfoBXDs7SQv7/ZNz3mHoyvFl31sschLx8LgEeNrk398EkATwQ0OZ1h9Za/+tpx7VZYW00CpweViV5sPQ7T5IMqMR8OGHbIgssiyXSTiqwmw0nO8KwPeaTaePVqWkqjwlU5RkUWoVEa/y3vIan5sjsSm9srLCJhSVijtes+mKdQCOR0VHOubsLKPtbJZpDRlVSTmytOQmo29+000umYz77JkMCXZ1lZWZqZQjaUX6gjE8ZzrNyW4wcCmcXs/9fXTdXnnFvfY4gysPjwuEp1WtvHxWA7n0GAxcdxdVQqrLjMhWlZSyRT2ORILbdTpcsNvfZxR+6xbJq99nfrdcZjNgRdhzc9xHJCbflXL5qM2sct/KU0vHLZKXWZQiY7VJU6MFRb0ylpJVgDTfvR73y+fdIqc08Drn2hq3nZnhcZWbf/11l5+emnKVoAsLPNc3vuE8UZT/TiaZLlJvTGt53JkZp/8eDplXVzpGHi3VqisWstYVUnl4XEL45fizwu4uHyeVD8pNq31aGDLHXauR0NSEQemIbJZqioMD55WiNmT1OvdV7rxe5z5XrpCw5WeysODy51HEcyvFovy5SL1ed26B+byzhO31+N6kLez2Nn8vFEh6Ikr1uwxDp6bRhCIZoHTcYejy6v0+8M47PK5sAtJpXpu5OV6LGzecX0ouR8Jtt/n5PvzQtZyTO6C1vHaJhHMnbDTcOAFH6GrRpnH6XLjHJYYn8rOA2qgdbxyQSJCYr1w5Sm6SENZqXNyUX8nsrKtmVEpEXdfLZedPopywSF25cuWrx2OmHtQWTqX56bSLmjMZ1wLNGJ5D/tyKcNVI4uCAz/N5kp+i/0LBTVaaEGSP22pxO3XnkR1ru83PubzMfXM512nIGPqhSA8fjzO6FslWKu5Oo9PhAu+NG+xwr7RPOs3tROQqepqE7oY0CXl4XHJ4Ij8LPKyMW/nh4xK2MGTz49HIqUF6PUbfrRZz0AsLjMABl/rY23Md4ZX/VXSuZg/ttmtXJnVGteo02JIGAnxMJJyVrXpvNpuuxZxyycMhCf7ePafNlrRvPHayRFVPVqsux66IN5Uioc/N8VENoatVl4oql7n9tWt8nJnhRAK4xV4tAg8GnAhLJdcxSWkcIZ3mZ590MJQqx0sLPb4m8ER+Fph0/lOeVQ0f8nmXpxbabZfqEEm3WkzPdDrcb2PDeZRvbJCQYjGS+/IyF+aUZlAXG/mEbG/zuDMzPJZMpGRUpcpG9eAsFt25RPTDoVOXKP0TBC5yj8dJ2LLHVRVlFPH95WWXb1f1JsCy+nSa51PaR/LA2Vleh9df54+uZybDzy0J4mTjjN1dTnDLy3yv1zvaG7NQcBNZKuUWOhcX/YKmx9cGnsjPCvPzJBotrCWTLuqs1dzCmtIIatwgMhsOnUSvWiXB7uxwH9nWptMksfl5p/TY3SXR9npusRJw3iTVKrev14+WpqtYR+SufP3CAsei/LncCqURV4s0pUrk1SLLWzV0lspFC6Zra9xmNOK+sRgXc+UXo/SJWpwpN59I8A5Fxl4zM/wMcnvc3XVpHIDHmSRyrSPomsbjTDtJ4unh8TWAJ/KzQq3mUiXDoevvqAhYRS+DAYmn1SLpDYeuYbKUGCI95ZBv3GBD4PV1Rp9yB6xU3EQxN+ei+nSa5C3STCaBt9/meeR6qKIjKVqyWe6/s+McB+X1LRJXemQ45PGtZfFNt0uC3dpiDnthgedKp11TZ8AZValYqVTitgCtBYpFp1H/7DMqVZT+mJ1lukV6eYCffW6OY1BVZjb7YKQdj/uuOx5fa3giPwtoMVILh4Aj6OvXSSAzMyTuDz5w7oJffskIt1TiMQoFR3CFgjODUgSqqH48Jokb4yL3Wo3njSIS5aefMn3R6/G9VMq9pxz39rbrrJNKkUi1yPj668CPf+zuBLpdfo6XXuK5r1/nsdWtJ5kk2apaU26GpZKLhF96iWNst5n3zmSche13v+si+oUFXq9JQk6lGJmXy1SspFI89swMCf9xHeo9PL7G8ER+WvT7JCBVKUrO1m5TPVGruXJytS6Tpap8RZTTHY0ogVtc5GtRRDXIG28wH37rluvkXq1ym6tXedxajYQoN8N2mz+djsthK+ctopUsL5VyE4AWIOt1Hkfvr6ww8jUG+Pa3OZZJFcv+PpUlv/Irrrx+c5Pn+rN/lmPc2OB4790jOcdiHPP1687WVp17goD7K83zxhskckkNBfm+qDGEKjA9iXt4eCI/FRoNl/s2hqQ3N0cS2tkh6UiX3W6TbOSTLflbEDCaVLQqRYs8t69d43bNJo83P89jzM3RvbBW4yQgWWI2S/KW81+lwtelOpmbI6mXSiQ6laaLJJUzHgwYGYvctdiqXLmaD8sbpVQi2S4ukpzVPWg0Olr0pDZqGxsc27Vr/LwLC66L0MICj6eenzMzfE1rCZNVrkozqTAKcFYAxxeTPTxeMHgifxxGI5K1Wq0BbpFROuxkkqSoYpdqlT+1mos8b9zgvpL+3b3r8r3dLotjCgXn6qfoWQVCk1Wj6ofZ6bjiGpW8JxLO/Krb5TFSKb4uF8BOh5OHFhnlWiiHwEQC+Na3mFpR9C/duop11LhZeu1k0i3WSkHT73OhcXubY5+ZcePY3nbXc3qan+/GDVdA1OsdbZYscy51RBI0KXgpoccLDE/kj4PK1SfztcpTy4QpmWQELR/sjz8mca2uctt6HXjvPZLiRx8xlaBUwf4+iemjj7i9NN2LiySuO3eYkogiTiijkSvCabWcAkX668VFdzeg0vlcjvK8ft+pV2REJddDRbaFAieF3V0e97XXnJtirUaC3dhwbdFWVxlFT5KrioWEUonErQKhMAR+8Rc5xk6H6ajpaR5bLdgWF48qS+SlPhmly4rXywg9XnB4Ip9Ep+O60QPOflWWppO370Hg8s+S9WUyJLhKhZGo8ujJJAn7zh0eTzrvZpP77e05yd70NKP5cpnHaTScTno45Fh2djjGXo9kViq58vt22zVOVrm8FjtVlalIutHg75mM6xp/9SrHkEzyUZNFrebGFotRWaPJ7Oc/5/65HLc57lmi7dXUWc0njkOyQzWfmESxyElITo1aGF1Z8WkVjxcensiFZpORphz3Dg5IQEtLJGEtSALOAEqNGuQjIpdBSffUjUft1cpl1wihXGbkq1Zs6jo/M0PpXbfrmkkMBnxNFYq1Gt9/5RUXCSuiTiYdgavUXaXx4zEnmNu3ndsh4DrZN5vc9s/9OeAP/9A1aa5UOF6lS6anuV+3y7sLkXMy6brXT0bkwmR15UnQ5HgSEgmOXe3o9NwbXXl4eCIHQALc32eOV4qKmRkS1WBAlcbt246k43FGggDfbzT4mqoQf//3mQNPJPh8dZXkOz/vGv9K/VKvu/yu0geJBI975QrHNRrxUeZU8j0JAhJvv8+ofDJKX14m6S0ucls1kpia4uMXX3AMqnAcjZhGkdRxZcUtutZq3F5yyFde4XjX1znGYpHjVf57f9+1kjstBgNnnfuw/ZJJN5l6eHjchydywHXISaVIhCISOQHOzpKMZ2edf7ZyvmqDls2StP/u36U+vF53zRH290lAhQKPWSqRWCVnHAxInI0GX9/dZcT8xhvAT35CctfioqR86+vOAAtwzoIqvR+NSLC5nOsCVKkwvaOcerlMIl9aooxP0frf//tuUVEThypKl5bc9dFC49aWuwuROka9OB+HwYD7K50Vj/O6PamXu4fHCwxP5IAzUFIRiyApHeCqH1Mppjt6vaP65YMD4Hd+hwuduRxJ9/PPSZZzcyTf/X0SXSbD9ESzybSKPEAODkjosZjrT1kskixrNZL03BzHdfUqCV+LhwCJV+Pt94E33+Tv9frRJg+7u65V2vQ0z3fzJiemgwPn37KwwOMVCm4RNpNxVrGlElMpMzMcdxDwM4YhyViT48MibGuZzgLctZSv+/XrXoni4XFKeCIHnJPg1pYrT1fz43yepKzydGtJqpLaCY0G0ykASW51lfveucPIemmJhHfvHo+jdEsuR0K/d4/klc+TBDc2jqpSrl1z6Qtp0199leSp5soLC47o19ddz8xSyeWn43GOXXl7eZTIB0U67nab5D4764555QonpJUVjk3aenmnSEuuuxhJFjU5HYcsCiYnRKWVul3vh+LhcUo8FZEbY/4jAH8JQARgD8D/2Vq7dRYDe+6YmnLFPlKopNPOzEo+HSqJV9ccOQY2m4xalU6QHnrSHzubJfk2m3wMQ0fiUmPIayWbBf7kT0i08k7RxFKp8PW33+b5bt5kA2IpSrSQWam4rjlSqKRS7jwrK9xGnudq0KAin3rdnXt6mlG+tOpzc3x9MHBVptK5Lyy4c3Q6TnVzHDrPSZBploeHx2PxtBH537DW/j8AwBjzfwXwHwD4t556VOcF+ZtIUjga8XVFk7u7JMtUihGryG9uzqlE5uZIXLGYi3Ln5pyKIwhctyDAeY5cverIS52AikWSYrF41LhKpfU3bjgfFKk5rlxxcsQ7dzhmFczEYiT0dJoRfhSRjKV0WVtjJL27y+NLy72wwAmjUCChq+u8TLpWVnjue/eci6EmtEzGdfI5nirRtvIHB3jto8jnyD08ngBPReTW2sbE0ywA+3TDuSBQTncyHaCCGOnFpeVWheKrr3KhsNUiAcqf5KWXWCUpour1nLlWtUrSLxRImOUyt2k2+frLLzOSVcpne9vJFqOI6phMxmnH19ZI0NUqyXw45PlFuNKzhyGPPx7z/VyOqR55dSulUanwGhwckODlG6P3NeZbt3isctl5fU+uN6gv5nHIMmBnh79r8pyd9a3XPDyeAE+dIzfG/McA/k8A6gD+/CO2+x6A7wHAlStXnva0zxeDAYl5MOBz6cXVik256b/8l4Hf/V1uu7REOd9gQGINAhKwusDfu8dqz1u3SGBTUyRhuSSqGlNNkCsVRsnFIqPobJbHODhwPibDoSun10QyM0NSV0cdWb2++irHsrjIfep1FvaoWYXy6N/5Ds8JcBJoNNxzqXXUxHlx0S0CSxGjgqOTcuQAj5VKcbKxlp97skrUw8PjsXgskRtjfg/A4glvfd9a+w+std8H8H1jzG8D+CsA/tpJx7HW/gDADwDg3XffvRyRu9qrVauuNH193fXnzOVIfPU6iXxhAfjN32TOWu3L1tZIiDKUWl4maf3Jn5CEGw2SoQqQ1Clnsrrx6lWeU34uUpYUi/y916NXC8DjiTh3dnhO5dSXlzmuTIZacHmK7+zwc6yt8f3BwHl4qzFyv8/n3a5Lk3Q6NPTSZBOPu76gsh6QfcGjoLy9h4fHV8Jjidxa++unPNZ/A+B38BAiv5So1Uhs0n93OkyfrK05W9rlZVfGPxiQ+OVoKI+WXM5JEuWkKFWMFCDDIVUvpRKj+VLJLURubrIgRyX68TiJcmHBkXGp5Co7VVVqDPD++xzfjRuuc9E77ziHROWkjeHEIG90uRdqMpEUURWikg6qu1A87ho/q7Hy2hrH771QPDyeKZ5WtfKKtfaLw6e/BeDTpx/SBUK1erT9mvzBpeZQ2mQwcGXxU1OuLZk01+pxaS3z3MqrT3qbdzqM9lVwpO7x6+uMeldWnKnU+rorxgG4f7l81C5XapdM5qjf+Ntvk7DlI16r8fNIVx5FbkHTWlfBCrhIPBbjRABwnNvbfC2RcH4vV654+aCHx3PC0+bI/7ox5jVQfngXl1mxchIUqUpvrWbDAH9XXlo5bHWClzJF+zebXGzc3OT7itzzeZJ1LEYCVO9L5dTX1nietTUSpjHAj37EiFta69df53jabVd8IxXMYMDXNIlMKlq2tkjSipibTddxB+Adw2jEcclDXRWoQeA+m4qb1KFIKRwdx8PD45njaVUr/4ezGsiFgpoNq9N7NuvsUqVoabVc+zTZv9665chwepryv/19Gl71enxtetpF9Orb2e2SiG/ccLn2fp9R9HjsiHhhgeoSRcTvvOO80QHXlajRcGmdICBpa2Lp9XjMVIp3D7orGA45gei1MGSBkppXyOdEC5GZjJNLqjOSCnyuX/fpFA+P5whf2Xkc3a7zUVHTBlVG7u0xJ93vsxR/NGK0HAQkz06H5N3pkOh6PaY5dnZIvLOzzjM8ilxH+vV1EvSbb5IUw5CE2Wg4e9h22/XFVLomlXLNG9TardlkXlwSvkqF45e/eblMolajC2P43u4ut1W16dqa06xPdqUXNJZy2XX4UdTvS+s9PJ4rPJFPYjCgpK/ZdKXrqth89VUSV6PhyuzX1kiEd+86zfdoRHL7+GNHloWC02HfvcvHpSWS3sICH/t9Thzr666qdLKYSGkXuQq+/jpf39oigRaLHNf2NicbSSMlW/zmN12kvLfHz6f8fyzGsauTUTp9OudCmYjJPEySRQ8Pj+cKT+STkE+I8uEAyalSIflevXqUtJtNFynv7pI4UymmKDY2eKxKxXW/UYR7cMBIW8dptRi1z8/z3FtbfHztNR43m3WeL2owMRq57j7LyxxvGPI8pZLLoas3pix4ARK1WsWl0051s7j45P7eXjro4XHu8EQOkNTqdeq/Nzdd4Y5y4smkW/zr913/zmaTOXCA28ViJPZYjBFyp8PjNZvcR00ZdIzFRdeOTb4nsoQtlZxlQKPBCH7SA0bd6EXwxrgOPeoAlE67VI1IXPnva9c4gTQarsHySc0gPDw8Ljw8kUsS2GqRyDY2nH/3/DzJMhZzJeRBwBRGr+dcDO/edc2OGw0Sfz7vmjYXCiT1ep0TRD7PFEY8TlIPApc/lxugGiIDnAjUGELmV8vLJP/FRZK/GlIEAV9fWiJhr6+7IqF+nz8zM64JxuOKdTw8PC48PJH3+yRx+ZfMzpLM63USsrThuRxfK5eBDz5wpe+5HB+//JJkr472akVWqzkf8nfeIQl/61tOb51OOzmfrHKlx06nebxymfl4VYcmk5x8RiMS9uqqU6NMT1Mlo3Zu2SydEZVbn5t70ILXw8PjUsMT+XDoFvaCgCZS8TiJcDwmYU82Vs7lmCtXv8rFRZKj2qX1+yTt27cZ7f7SL/H3XI4kvbjIhVPJ/WSRu7XlIupy2TWgkCpEnYREwrKqPThwaRTAdTmSRl2T0cyM9zDx8PiawhN5LHbUmU/66UKB0W4mQwK8c8f5dqsIZmeHaRaR9/XrJPtKhcfZ2qK65OWX+V6vRyKe7EgEOFWKzLa6Xb7fbrtmD0rxCMY4t8DRyEn+Gg2+PmlMNhhw0fTatWd7LT08PM4FnshTKWcFm8mQ1NttkmGtRlLWgqKIfG+PaRb5mUSRM4l64w1Xydluk/DTaR4rk3Ga7F7PVYkC3GYyYlYzYms5iYxGjviHQ04eOzs8bqvF88zPu5TQJJSqOckT3MPD49LDE7kxzhVQZeaAa+IQBFyoLJeZO89mGUF/9JErxpE1rKoq1eZtYcGZax0cOEMrLZQ+SiUyqcdW67dOh/sCJGU1bGi1OH7l0GVbK6ic3ldbenh8LeGJHCDZzs7yZzxmqb1avwFO7tfrucXJTIbbz89TJaLo+O5dknqpxHSLMSTsxUXn9S0zq9MSa6HAvPrSEieEu3ddLnx+3qld1IatWnW5cWtJ9PPzpyvy8fDwuHTwRH4cau/W65F4AbfAuLTE39VcYX6eJFkuMzpWMU4UOc23EIu5npiTsJb7qiHE1NTJRTmxmJscxmNOBnfvusg9DHmHMDvL9I8sZdVY+qQyew8Pj68FPJEfRyzmGkmoiKZWYyScz5NIp6ZI8h9+6IqAmk2S6UsvkTS3tpxq5GGQhl3ac2uZ415YeDjxynFwMHDOjMa4SD+KuO/CglsE9SkVD4+vNfw3/Dgmu7drYXB3l0S+vs4oeDh05ezxOIl4bg546y3nOyJr2kdBBUSFgtOQ5/NcTNWdwUlQoVIi4e4ExmNOMIOBSwvJn9zDw+NrDR+RH8dkQU+1SjVKPk+inppypfyZDPtZ5nIkd/mQq9uP1CyPQq/3YC9LpWMGg4f3uUylKCUslyl/HI1chyCZX3l4eLww8ER+HL0eI2/5bY/HJGk1jZifd1avo5EzjZIW3RinKJmUF54EeYSfhMfJBJNJkrZMtKLIR+AeHi8oPJFPYjx2zYmVH08kmMdeXCR5Km2SyzFaTySYj97acouMrRajd732MMVINkvCrtWYkhkOXQOJR+XWj0Nj9fDweCFxJuGbMebfNcZYY8zsWRzv3NDrkUhXV0m8KryxlgU36rMJMDpfWXHqkOlpknc+zxL+tTX+vr3N9Ee3e7SCFCCJT08zB1+ruQXMwYDn9fDw8DgFnjoiN8asAfiLAO49/XAuCMLQpU4k55P393DoGjfIsjafZ3T985+T1A8OuGCpfp4HB5wkcjlKGCfTH42Ga/hgDM+tvp2Li+d3DTw8PC4NziIi/88A/HsA7OM2vPBQD871dRJpPE7ytdYpSq5eJTnfvUsit5bbfvKJU6DIe3xvj6kX7dtqcbFUsJbbJRI8pvLiyaTrUOTh4eHxGDwVkRtjfgvAprX2/VNs+z1jzHvGmPf21YzhoiEMGVm3Wo5ko4ideuJxLl4mkyTobJbqkESCOXW5ECo9oy5D+/uuFF+eK4IkgselhoPBk+XIPTw8Xmg8NrVijPk9ACfd438fwF8F8M+d5kTW2h8A+AEAvPvuuxcvelfqpNdj1K30h1qktVrcxlqS+6SqRF13YjHup1J8gORdLLrtji96zs7SDjeT4f6Dgevp6eHh4XEKPJbIrbW/ftLrxphvALgO4H1DcloF8FNjzHestTtnOspnjWaTChNjGFm329RpqzRfBDzZLX6SlGMxkn0YOhtagDrvV15xevBu90GCzue5aKo8ejLpjLg8PDw8ToGvvNhprf0AwP0+YcaYOwDetdYenMG4nh9GI5K4fMITCdrGbmzQR9wYRuOzs3w/CBhhS0sulYne73RcIwc1JVaqRn04jyOfd+3dvLGVh4fHE8LryNW4WKmURILSwbt3GVFns8yNT0+7febmuE+97lq0qbNQu320hL/fp5IlHj9qTXsSPIl7eHh8BZwZkVtrr53VsZ47juu702lqyRcXXa/LSQQBJYizsyTyyVL64w6Hiso9PDw8nhF8RJ5Ou7J6LWCORiTrbPbRUXIQuE49gwFJe2bGK048PDyeK7wxRyxGv5Jez/mCDwZ87XF+J52Oc0NMJJimuXPHV2V6eHg8V7zYEXkUuWrNxUXX0DiVOl1vy4MDbqvcdzrN45XLnAg8PDw8ngNeXCIfjahM6fddR/tMhlLA0zgIWuvK7ieRTLq+mh4eHh7PAS9uauXggGSez5PA83lG05OVl4+CMa5X5iSUZvHw8PB4TngxiVx9Mo8X3RwvoX8cZKglMpdr4czMmQ3Vw8PD43F4MYlcOC47tPbJGjPkcpQpqlN9ELC831dlenh4PEe8mDlyY1hlWakczXF3u09uHZvLOYdEX9Dj4eFxDngxiRxgpWa/zxSLutEXiyeX0J8GnsQ9PDzOCS8ukQcBFSr9Phc9T1NC7+Hh4XEB8eISuZBM+kpMDw+PS40Xe7HTw8PD42sAT+QeHh4elxyeyD08PDwuOTyRe3h4eFxyeCL38PDwuOQw9nh14/M4qTH7AO5+hV1nAVyuVnKXb8yXbbyAH/PzwGUbL/D1HPNVa+3c8RfPhci/Kowx71lr3z3vcTwJLtuYL9t4AT/m54HLNl7gxRqzT614eHh4XHJ4Ivfw8PC45LhsRP6D8x7AV8BlG/NlGy/gx/w8cNnGC7xAY75UOXIPDw8Pjwdx2SJyDw8PD49j8ETu4eHhcclxaYncGPPvGmOsMWb2vMfyKBhj/iNjzM+NMT8zxvxjY8zyeY/pcTDG/A1jzKeH4/57xpjieY/pcTDG/AvGmI+MMZEx5sJKzowxv2GM+cwYc9MY838/7/E8DsaYv22M2TPGfHjeYzktjDFrxpjfN8Z8cvg/8X877zE9CsaYlDHmT4wx7x+O9z980mNcSiI3xqwB+IsA7p33WE6Bv2Gtfcda+y0A/xDAf3DO4zkNfgjgbWvtOwA+B/Db5zye0+BDAP88gD8474E8DMaYEMB/AeB/C+BNAP+SMebN8x3VY/FfAfiN8x7EE2IE4N+x1r4B4LsA/i8X/Dr3AfwFa+03AXwLwG8YY777JAe4lEQO4D8D8O8BuPArtdbaxsTTLC7HmP+xtXZ0+PSPAKye53hOA2vtJ9baz857HI/BdwDctNbettYOAPx3AP7SOY/pkbDW/gGAynmP40lgrd221v708PcmgE8ArJzvqB4OS7QOn8YPf56IJy4dkRtjfgvAprX2/fMey2lhjPmPjTHrAP4VXI6IfBL/BoD/6bwH8TXBCoD1iecbuMAE83WAMeYagG8D+ONzHsojYYwJjTE/A7AH4IfW2ica74XsEGSM+T0AJ3VB/j6Avwrgn3u+I3o0HjVea+0/sNZ+H8D3jTG/DeCvAPhrz3WAJ+BxYz7c5vvgberfeZ5jexhOM+YLjpMau174O7TLCmNMDsB/D+DfPnZnfOFgrR0D+NbhetTfM8a8ba099brEhSRya+2vn/S6MeYbAK4DeN+w2fEqgJ8aY75jrd15jkM8goeN9wT8NwB+BxeAyB83ZmPMvwbgNwH8s/aCFBs8wXW+qNgAsDbxfBXA1jmN5WsNY0wcJPG/Y639H857PKeFtbZmjPlfwHWJUxP5pUqtWGs/sNbOW2uvWWuvgV+MXzhPEn8cjDGvTDz9LQCfntdYTgtjzG8A+PcB/Ja1tnPe4/ka4ccAXjHGXDfGJAD8iwD+x3Me09cOhlHe3wLwibX2Pz3v8TwOxpg5KcOMMWkAv44n5IlLReSXFH/dGPOhMebnYEroQkuhDvE3AeQB/PBQNvn/Pu8BPQ7GmL9sjNkA8CsAfscY87vnPabjOFxA/isAfhdcgPu71tqPzndUj4Yx5r8F8IcAXjPGbBhj/s3zHtMp8KsA/lUAf+Hw//dnxpj/3XkP6hFYAvD7hxzxYzBH/g+f5AC+RN/Dw8PjksNH5B4eHh6XHJ7IPTw8PC45PJF7eHh4XHJ4Ivfw8PC45PBE7uHh4XHJ4Yncw8PD45LDE7mHh4fHJcf/H7/tE8sxfGcJAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.scatter(cp.asnumpy(X[:,0]), cp.asnumpy(X[:,1]), c=[cm_bright.colors[i] for i in cp.asnumpy(y)], \n", " alpha=0.1);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now lets divide our dataset into training and testing datasets in a simple manner:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "# Split the data into a training and test set using NumPy like syntax\n", "X_train = X[:8000, :].copy(order='F')\n", "X_test = X[-2000:, :].copy(order='F')\n", "y_train = y[:8000]\n", "y_test = y[8000:10000]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the resulting objects are still CuPy arrays in GPU: " ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "cupy.core.core.ndarray" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X_train.__class__" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise: Fit the cuML and Scikit-learn `LogisticRegression` objects and compare them when they use as similar parameters as possible\n", "\n", "* Hint 1: the **default values** of parameters in cuML are **the same** as the default values for Scikit-learn most of the time, so we recommend to leave all parameters except for `solver` as the default \n", "\n", "\n", "* Hint 2: Remember the **solver can differ significantly between the libraries**, so look into the solvers offered by both libraries to make them match \n", "\n", "\n", "* Hint 3: Even though Scikit-learn expects Numpy objects, it **cannot** accept CuPy objects for many of its methods since it expects the memory to be on CPU (host), not on GPU (device)\n", "\n", "For convenience, the notebook offers a few cells to organize your work." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 1. Fit Scikit-learn LogisticRegression and show its accuracy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Solution for Scikit-learn\n", "
\n",
    "\n",
    "clf = skLogistic()\n",
    "clf.fit(X_train.get(), y_train.get())\n",
    "clf.score(X_test.get(), y_test.get())\n",
    "
\n", "
\n", "\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "from sklearn.metrics import accuracy_score" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### 2. Fit cuML Regression and show its accuracy\n", "\n", "* Hint 1: Look at the data types expected by cuML methods: https://rapidsai.github.io/projects/cuml/en/stable/api.html#cuml.LogisticRegression.fit \n", " one or more of the input vectors might not be of the expected data type! You may need to typecast.\n", "\n", "\n", "\n", "* Hint 2: as mentioned above, cuML has native support for CuPy objects" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Solution for CuML\n", "
\n",
    "\n",
    "reg = LogisticRegression()\n",
    "reg.fit(X_train,y_train)\n",
    "\n",
    "print(\"Coefficients:\")\n",
    "print(reg.coef_)\n",
    "print(\"Intercept:\")\n",
    "print(reg.intercept_)\n",
    "\n",
    "preds = reg.predict(X_test)\n",
    "\n",
    "print(preds)\n",
    "\n",
    "print('Scikit-learn accuracy: ' + str(reg.score(X_test, y_test)))\n",
    "
\n", "
" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "from cuml import LogisticRegression\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Coefficients:\n", "[[-1.28726705]\n", " [ 2.75051631]]\n", "Intercept:\n", "[-0.812162]\n", "Scikit-learn accuracy: 0.8025000095367432\n" ] } ], "source": [ "# useful methods: cupy_array.astype(np_dtype) converts an array from one datatype to np_datatype, where np_datatype can be something like np.float32, np.float64, etc.\n", "# useful methods: cudf_seris.to_array() converts a cuDF Series to a numpy array\n", "# useful methods: cp.asnumpy(cupy_array) converts cupy to numpy\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Expected accuracies for apples to apples comparison: 0.8025 vs 0.8695**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Additional Exercise: Play with the different parameters, particularly the different Scikit-learn solvers to see how they differ in behavior even in the same library!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Licensing\n", " \n", "This material is released by OpenACC-Standard.org, in collaboration with NVIDIA Corporation, under the Creative Commons Attribution 4.0 International (CC BY 4.0)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[[1]]()\n", "[[2]]()\n", "[[3]]()\n", "[[4]]()\n", "[[5]]()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6.2" } }, "nbformat": 4, "nbformat_minor": 4 }