{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Compound\n", "This notebook explores the metadata and images associated with a set of compounds across all IDR studies.\n", "We aim at finding out the range of concentrations used across studies for each compound.\n", "We retrieve images associated to each of the compound and offer all the other metadata associated with those images as a CSV. Using a subset of these images, we further programmatically generate an OMERO.figure that can be viewed in any OMERO.server." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Install dependencies if required\n", "The cell below will install dependencies if you choose to run the notebook in [Google Colab](https://colab.research.google.com/notebooks/intro.ipynb#recent=true)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pip install idr-py" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Import libraries " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import csv\n", "import os\n", "import pandas as pd\n", "from tempfile import NamedTemporaryFile\n", "\n", "import scipy\n", "import numpy\n", "from skimage import filters\n", "import matplotlib.pyplot as plt\n", "from idr import connection\n", "\n", "import requests\n", "import json" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Set up where to query and session " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "code_folding": [ 3 ] }, "outputs": [], "source": [ "INDEX_PAGE = \"https://idr.openmicroscopy.org/webclient/?experimenter=-1\"\n", "\n", "# create http session\n", "with requests.Session() as session:\n", " request = requests.Request('GET', INDEX_PAGE)\n", " prepped = session.prepare_request(request)\n", " response = session.send(prepped)\n", " if response.status_code != 200:\n", " response.raise_for_status()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Compounds to query " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "compounds = ['loratadine', 'cycloheximide', 'ML9', 'ML-9']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Set up base URLS so can use shorter variable names later on" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "URL = \"https://idr.openmicroscopy.org/mapr/api/{key}/?value={value}&case_sensitive=false&orphaned=true\"\n", "SCREENS_PROJECTS_URL = \"https://idr.openmicroscopy.org/mapr/api/{key}/?value={value}&case_sensitive=false&id={compound_id}\"\n", "PLATES_URL = \"https://idr.openmicroscopy.org/mapr/api/{key}/plates/?value={value}&id={screen_id}&case_sensitive=false\"\n", "IMAGES_URL = \"https://idr.openmicroscopy.org/mapr/api/{key}/images/?value={value}&node={parent_type}&id={parent_id}&case_sensitive=false\"\n", "ATTRIBUTES_URL = \"https://idr.openmicroscopy.org/webclient/api/annotations/?type=map&image={image_id}\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Find images for each compound specified\n", "For each compound, search of images in plates then search for annotations associated with the images. The results are saved in a CSV file. " ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "code_folding": [ 1, 2 ] }, "outputs": [], "source": [ "TYPE = \"compound\"\n", "KEYS = {TYPE:\n", " (\"InChIKey\",\n", " \"PubChem InChIKey\",\n", " \"Compound Concentration (microMolar)\",\n", " \"Concentration (microMolar)\",\n", " \"Dose\",\n", " \"Compound MoA\",\n", " \"Compound Action\")\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Helper method\n", "Parse the output of the json and save it into the CSV file." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "code_folding": [ 0 ] }, "outputs": [], "source": [ "def parse_annotation(writer, json_data, name, data_type):\n", " plate_name = \"-\"\n", " screen_name = name\n", " for p in json_data[data_type]:\n", " parent_id = p['id']\n", " plate_name = p['name']\n", " qs3 = {'key': TYPE, 'value': compound,\n", " 'parent_type': data_type[:-1], 'parent_id': parent_id}\n", " url3 = IMAGES_URL.format(**qs3)\n", " c = compound.lower()\n", " if c.startswith(\"ml\"):\n", " c = 'ml9'\n", " for i in session.get(url3).json()['images']:\n", " image_id = i['id']\n", " url4 = ATTRIBUTES_URL.format(**{'image_id': image_id})\n", " row = {}\n", " inchikey = \"unknown\"\n", " concentration = \"unknown\"\n", " moa = \"unknown\"\n", " for a in session.get(url4).json()['annotations']:\n", " for v in a['values']:\n", " key = str(v[0])\n", " if key in KEYS[TYPE]:\n", " if key in ['InChIKey', 'PubChem InChIKey']:\n", " inchikey = v[1]\n", " elif key in ['Dose', 'Compound Concentration (microMolar)', 'Concentration (microMolar)']:\n", " concentration = float(v[1].replace(' micromolar', ''))\n", " elif key in ['Compound MoA', 'Compound Action']:\n", " moa = v[1]\n", " row.update({'Compound': c,\n", " 'Screen': screen_name,\n", " 'Plate': plate_name,\n", " 'Image': image_id,\n", " 'InChIKey': inchikey,\n", " 'Concentration (microMolar)': concentration,\n", " 'MoA': moa})\n", " writer.writerow(row)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Retrieve data \n", "A CSV file is first created in the ``home`` directory. The CSV file can then be downloaded to your local machine. To download it, click ``File > Open``, select the CSV file and open it, then click ``File > Download``.\n", "\n", "If you are running the notebook in [Google Colab](https://colab.research.google.com/notebooks/intro.ipynb#recent=true), click on the ``Files`` icon on the left-hand side. The files are saved under the ``root`` directory. " ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "code_folding": [ 2, 21 ] }, "outputs": [], "source": [ "home = os.path.expanduser(\"~\")\n", "csvfile = NamedTemporaryFile(\"w\", delete=False, newline='', dir=home, suffix=\".csv\")\n", "try:\n", " fieldnames = [\n", " 'Compound', 'Screen', 'Plate', 'Image',\n", " 'InChIKey', 'Concentration (microMolar)', 'MoA']\n", " writer = csv.DictWriter(csvfile, fieldnames=fieldnames)\n", " writer.writeheader()\n", " for compound in compounds:\n", " qs1 = {'key': TYPE, 'value': compound}\n", " url1 = URL.format(**qs1)\n", " json_data = session.get(url1).json()\n", " for m in json_data['maps']:\n", " qs2 = {'key': TYPE, 'value': compound, 'compound_id': m['id']}\n", " url2 = SCREENS_PROJECTS_URL.format(**qs2)\n", " json_data = session.get(url2).json()\n", " for s in json_data['screens']:\n", " compound = s['extra']['value']\n", " qs3 = {'key': TYPE, 'value': compound, 'screen_id': s['id']}\n", " url3 = PLATES_URL.format(**qs3)\n", " parse_annotation(writer, session.get(url3).json(), s['name'], 'plates')\n", "finally:\n", " csvfile.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Explore the data\n", "Read the generated CSV file into a dataframe." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>Compound</th>\n", " <th>Screen</th>\n", " <th>Plate</th>\n", " <th>Image</th>\n", " <th>InChIKey</th>\n", " <th>Concentration (microMolar)</th>\n", " <th>MoA</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>1940</th>\n", " <td>ml9</td>\n", " <td>idr0094-ellinger-sarscov2/screenB (216)</td>\n", " <td>ESP0025959</td>\n", " <td>10631902</td>\n", " <td>OZSMSRIUUDGTEP-UHFFFAOYSA-N</td>\n", " <td>0.00636</td>\n", " <td>unknown</td>\n", " </tr>\n", " <tr>\n", " <th>2056</th>\n", " <td>ml9</td>\n", " <td>idr0094-ellinger-sarscov2/screenB (216)</td>\n", " <td>ESP0025961</td>\n", " <td>10633852</td>\n", " <td>OZSMSRIUUDGTEP-UHFFFAOYSA-N</td>\n", " <td>0.00636</td>\n", " <td>unknown</td>\n", " </tr>\n", " <tr>\n", " <th>2007</th>\n", " <td>ml9</td>\n", " <td>idr0094-ellinger-sarscov2/screenB (216)</td>\n", " <td>ESP0025960</td>\n", " <td>10633344</td>\n", " <td>OZSMSRIUUDGTEP-UHFFFAOYSA-N</td>\n", " <td>0.00636</td>\n", " <td>unknown</td>\n", " </tr>\n", " <tr>\n", " <th>1991</th>\n", " <td>ml9</td>\n", " <td>idr0094-ellinger-sarscov2/screenB (216)</td>\n", " <td>ESP0025960</td>\n", " <td>10633350</td>\n", " <td>OZSMSRIUUDGTEP-UHFFFAOYSA-N</td>\n", " <td>0.00636</td>\n", " <td>unknown</td>\n", " </tr>\n", " <tr>\n", " <th>2044</th>\n", " <td>ml9</td>\n", " <td>idr0094-ellinger-sarscov2/screenB (216)</td>\n", " <td>ESP0025961</td>\n", " <td>10633848</td>\n", " <td>OZSMSRIUUDGTEP-UHFFFAOYSA-N</td>\n", " <td>0.00636</td>\n", " <td>unknown</td>\n", " </tr>\n", " <tr>\n", " <th>...</th>\n", " <td>...</td>\n", " <td>...</td>\n", " <td>...</td>\n", " <td>...</td>\n", " <td>...</td>\n", " <td>...</td>\n", " <td>...</td>\n", " </tr>\n", " <tr>\n", " <th>1871</th>\n", " <td>ml9</td>\n", " <td>idr0017-breinig-drugscreen/screenA (96)</td>\n", " <td>PTEN-/-_LOPAC_Plate_1_Replicate_2</td>\n", " <td>1741163</td>\n", " <td>unknown</td>\n", " <td>unknown</td>\n", " <td>Inhibitor</td>\n", " </tr>\n", " <tr>\n", " <th>1872</th>\n", " <td>ml9</td>\n", " <td>idr0017-breinig-drugscreen/screenA (96)</td>\n", " <td>PTEN-/-_LOPAC_Plate_1_Replicate_2</td>\n", " <td>1741162</td>\n", " <td>unknown</td>\n", " <td>unknown</td>\n", " <td>Inhibitor</td>\n", " </tr>\n", " <tr>\n", " <th>1873</th>\n", " <td>ml9</td>\n", " <td>idr0017-breinig-drugscreen/screenA (96)</td>\n", " <td>PTEN-/-_LOPAC_Plate_1_Replicate_2</td>\n", " <td>1741160</td>\n", " <td>unknown</td>\n", " <td>unknown</td>\n", " <td>Inhibitor</td>\n", " </tr>\n", " <tr>\n", " <th>1860</th>\n", " <td>ml9</td>\n", " <td>idr0017-breinig-drugscreen/screenA (96)</td>\n", " <td>PI3KCA_mt-/wt+_LOPAC_Plate_1_Replicate_1</td>\n", " <td>1752609</td>\n", " <td>unknown</td>\n", " <td>unknown</td>\n", " <td>Inhibitor</td>\n", " </tr>\n", " <tr>\n", " <th>716</th>\n", " <td>loratadine</td>\n", " <td>idr0094-ellinger-sarscov2/screenA (9)</td>\n", " <td>GUF0000027</td>\n", " <td>10536416</td>\n", " <td>JCCNYMKQOSZNPW-UHFFFAOYSA-N</td>\n", " <td>unknown</td>\n", " <td>unknown</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "<p>2099 rows × 7 columns</p>\n", "</div>" ], "text/plain": [ " Compound Screen \\\n", "1940 ml9 idr0094-ellinger-sarscov2/screenB (216) \n", "2056 ml9 idr0094-ellinger-sarscov2/screenB (216) \n", "2007 ml9 idr0094-ellinger-sarscov2/screenB (216) \n", "1991 ml9 idr0094-ellinger-sarscov2/screenB (216) \n", "2044 ml9 idr0094-ellinger-sarscov2/screenB (216) \n", "... ... ... \n", "1871 ml9 idr0017-breinig-drugscreen/screenA (96) \n", "1872 ml9 idr0017-breinig-drugscreen/screenA (96) \n", "1873 ml9 idr0017-breinig-drugscreen/screenA (96) \n", "1860 ml9 idr0017-breinig-drugscreen/screenA (96) \n", "716 loratadine idr0094-ellinger-sarscov2/screenA (9) \n", "\n", " Plate Image \\\n", "1940 ESP0025959 10631902 \n", "2056 ESP0025961 10633852 \n", "2007 ESP0025960 10633344 \n", "1991 ESP0025960 10633350 \n", "2044 ESP0025961 10633848 \n", "... ... ... \n", "1871 PTEN-/-_LOPAC_Plate_1_Replicate_2 1741163 \n", "1872 PTEN-/-_LOPAC_Plate_1_Replicate_2 1741162 \n", "1873 PTEN-/-_LOPAC_Plate_1_Replicate_2 1741160 \n", "1860 PI3KCA_mt-/wt+_LOPAC_Plate_1_Replicate_1 1752609 \n", "716 GUF0000027 10536416 \n", "\n", " InChIKey Concentration (microMolar) MoA \n", "1940 OZSMSRIUUDGTEP-UHFFFAOYSA-N 0.00636 unknown \n", "2056 OZSMSRIUUDGTEP-UHFFFAOYSA-N 0.00636 unknown \n", "2007 OZSMSRIUUDGTEP-UHFFFAOYSA-N 0.00636 unknown \n", "1991 OZSMSRIUUDGTEP-UHFFFAOYSA-N 0.00636 unknown \n", "2044 OZSMSRIUUDGTEP-UHFFFAOYSA-N 0.00636 unknown \n", "... ... ... ... \n", "1871 unknown unknown Inhibitor \n", "1872 unknown unknown Inhibitor \n", "1873 unknown unknown Inhibitor \n", "1860 unknown unknown Inhibitor \n", "716 JCCNYMKQOSZNPW-UHFFFAOYSA-N unknown unknown \n", "\n", "[2099 rows x 7 columns]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv(csvfile.name)\n", "df = df.sort_values(by=['Concentration (microMolar)'])\n", "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Determine the number of studies\n", "Parse the result returned to determine the number of studies\n", "Names like idrXXX/screenA and idrXXX/screenB are counted as one study." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "code_folding": [ 1 ] }, "outputs": [], "source": [ "curated = {\"Screen\":[]}\n", "for s in pd.unique(df[[\"Screen\"]].values.ravel()):\n", " curated[\"Screen\"].append(s.split(\"/\")[0])\n", "\n", "df_studies = pd.DataFrame(curated)\n", "studies = pd.unique(df_studies[[\"Screen\"]].values.ravel())\n", "print(len(studies))" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "The resuls consists of 6 studies and 2099 images." ], "text/plain": [ "<IPython.core.display.Markdown object>" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Markdown as md\n", "md(\"The resuls consists of {} images from {} studies.\".format(len(pd.unique(df[[\"Image\"]].values.ravel())), len(studies)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plot histogram\n", "Plot the concentration vs the number of images for each compound. \n", "A png file ``figure.png`` is created in the ``home`` directory. The file can then be downloaded to your local machine. To download it, select the file by ticking the checkbox on the left-hand side of the file. Then click ``Download``.\n", "\n", "If you are running the notebook in [Google Colab](https://colab.research.google.com/notebooks/intro.ipynb#recent=true), click on the ``Files`` icon on the left-hand side. The files are saved under the ``root`` directory. " ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "code_folding": [ 3, 4 ] }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAvwAAAKPCAYAAAAR7h7gAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABs30lEQVR4nO3deZgsVX3/8fcHEBRQBLkgi3BRcUFU0Bs0IVEUjZioGFdcUVESoxLjClEDaFSMJhH38FMRgxuLCcQFRfS6AyKrbILsgnDZFMWwfn9/VA00w8y9Pfd2TS/zfj1PP911quqcb3fP9Pl29alTqSokSZIkTabVhh2AJEmSpO6Y8EuSJEkTzIRfkiRJmmAm/JIkSdIEM+GXJEmSJpgJvyRJkjTBTPglIMnSJK/uY7vFSSrJGgNu/y+SnLuS+26R5PdJVp9l/X5JDl21CCVpMiW5KMlThh3HdEl2SnJZz/KZSXYaXkQaZyb80gioqh9W1UNXct9Lqmrdqrpt0HFJklZOvweS+lVVj6iqpYOqTwuLCb8kSdIcDPpXXqlrJvwaW0kekOSrSZYluSbJJ5Ncm+SRPdtslOSPSRa1y7smOTXJ75L8KskuM9S7WpJ3Jrk4yVVJPp9kvWmbvSTJJUmuTvKOafvu3dZ9TZLDkmzQrvtkkiN6tv1AkuPSmP7T7UVJ3prk9CR/SPKZJBsn+WaSG5J8J8n67bZ3GWaUZKsk32+3OxbYcNrze3ySnyS5Pslp/kQsSZBkrSQfTnJ5e/twkrXadTsluSzJ25P8Bjg4yfpJvtb2Qde1jzdvt38v8BfAx9ohlx9ryw9McmnbB/08yV/0tH+vJJ9r6zoL+JNp8d0x9KgdqnlY2z/d0A73WdKz7aZJjmxjuzDJXl2/fhptJvwaS+149a8BFwOLgc2ALwBfBl7as+mLgO9U1bIkOwCfB94K3Bd4AnDRDNW/or09CXggsC7wsWnb/DnwUGBn4J+TPLwt3wt4NvBEYFPgOuDj7bo3A49K8or2Q34PYPeqqlme5nOBpwIPAZ4JfBP4J5oEfrW2rZl8Efh5u917gN2nViTZDPg68C/ABsBbgCOnvhBJ0gL2DuDxwHbAo4EdgHf2rL8/zefmlsCeNJ/DB7fLWwB/pO0rquodwA+B17dDLl/f1vGztv4NaD6rD09yz3bdvsCD2tvT6PnsnsWzaPq8+wJHT7WdZDXgf4HTaPrGnYE3Jnla/y+FJk5VefM2djfgT4FlwBrTyh8HXAqs1i6fBLygffyfwH/MUt9S4NXt4+OAv+9Z91DgFmANmi8XBWzes/5EYLf28dnAzj3rNpnat13eAbiW5ovKi3q22wm4rGf5IuAlPctHAp/sWX4D8D/t46mY1qDpdG4F1unZ9ovAoe3jtwP/Ne25f4vmi8fQ31dv3rx5m+9b+3n7FOBXwF/1lD8NuKh9vBNwM3DP5dSzHXBdz/Id/cpy9rkOeHT7+AJgl551e87QLzylfbwfzcGsqXXbAH9sHz8OuGRaO/sABw/7tfY2vJtj0DSuHgBcXFW39hZW1QlJ/gA8MckVwINpjnxM7fONPurelCYhn3IxTTK9cU/Zb3oe30jzKwA0R3r+O8ntPetva/f9dVWdmOQCYCPgsBXEcWXP4z/OsLwud7cpTYfzh2nxP6AnvucneWbP+nsA31tBLJI06Wb67N+0Z3lZVf3f1EKStYH/AHYB1m+L751k9ZplEoUkbwZe3dZbwH24c9jlpjQHrHrbX57p/dA926GdWwKbJrm+Z/3qNL84aIFySI/G1aXAFpn5xKlDaIb1vAw4oucD+lKan0pX5HKaD8wpU0fNr5x587vF9fSqum/P7Z5V9WuAJK8D1mrbeFsf9c3VFcD6SdbpKdtiWnz/NS2+darqgA5ikaRxMtNn/+U9y9OHX76Z5hfgx1XVfWiGiQJkpu3boZxvB14ArF9V9wV+27P9Fdx5cGaq/ZVxKXDhtM/5e1fVX61kfZoAJvwaVyfSfDgekGSdJPdMsmO77r+Av6FJ+j/fs89ngFcm2bk9uXazJA+boe4vAf/Ynvy6LvA+4CvTf02YxaeA9ybZEiDJoiS7to8fQjN2furLyNuSbDfH571cVXUxzTCm/ZOsmeTPacb/TzkUeGaSpyVZvX3ddpo60UySFrAvAe9sP7c3BP6Z5jNzNvem+bX1+jSTM+w7bf2VNOeB9W5/K+1w1CT/THOEf8phwD7tycCb0wzdXBknAr9rTzC+V/tZv22SP1nhnppYJvwaS+3Ppc+kGbJzCXAZ8MJ23WXAyTRHV37Ys8+JwCtpfoL9LfB97no0Z8pnab40/AC4EPg/+v/gPZBmCNG3k9wAHA88rv0l4lDgA1V1WlWdR3MC7n9NzQIxQC+mGcN5LU0HdMeXnqq6FNi1bXsZzZGgt+JngST9C80Bk9OBM2j6kX9ZzvYfBu4FXE3zWX/MtPUHAs9rZ935CM35Ut8EfkkzXOf/uOsQnv3b8guBb9P0Q3PW0z9u19Z1NfBpYPpsc1pAUjXbBCHS+EryWeDyqnrnCjeWJEmaYJ60q4mTZDHwHGD7IYciSZI0dP6Mr4mS5D3AL4APVtWFw45HkiRp2BzSI0mSJE0wj/BLkiRJE8wx/K0NN9ywFi9ePOwwJKkvP//5z6+uqkXDjmPS2TdIGiez9Q0m/K3Fixdz0kknDTsMSepLkhVdhVMDYN8gaZzM1jc4pEeSJEmaYCb8kiRJ0gQz4ZckSZImmAm/JEmSNMFM+CVJkqQJZsIvSRpLST6b5Kokv5hh3VuSVJINe8r2SXJ+knOTPG1+o5Wk4THhlySNq88Bu0wvTPIA4KnAJT1l2wC7AY9o9/lEktXnJ0xJGi4TfknSWKqqHwDXzrDqP4C3AdVTtivw5aq6qaouBM4Hdug+SkkaPhN+SdLESPIs4NdVddq0VZsBl/YsX9aWSdLE80q7Goj3L/1IX9vts9NeHUfSn3GLtyv9vA6T/hrMhX83oy3J2sA7gL+cafUMZTVDGUn2BPYE2GKLLQYWn2Y3Cv9boxDDuPE1a4zD6+ARfknSpHgQsBVwWpKLgM2Bk5Pcn+aI/gN6tt0cuHymSqrqoKpaUlVLFi1a1HHIktQ9E35J0kSoqjOqaqOqWlxVi2mS/MdU1W+Ao4HdkqyVZCtga+DEIYYrSfPGhF+SNJaSfAn4KfDQJJcl2WO2bavqTOAw4CzgGOB1VXXb/EQqScM1Fgn/THMtJ9kgybFJzmvv1+9Z51zLkjThqupFVbVJVd2jqjavqs9MW7+4qq7uWX5vVT2oqh5aVd+c/4glaTjGIuFn5rmW9waOq6qtgePaZedaliRJknqMRcI/y1zLuwKHtI8PAZ7dU+5cy5IkSRJjkvDPYuOqugKgvd+oLXeuZUmSJKk1zgn/bOY013KSk5KctGzZso7DkiRJkubfOCf8VybZBKC9v6otd65lSZIkqTXOCf/RwO7t492Bo3rKnWtZkiRJAtYYdgD9aOda3gnYMMllwL7AAcBh7bzLlwDPh2au5SRTcy3finMtS5IkaQEbi4S/ql40y6qdZ9n+vcB7u4tIkiRJGg/jPKRHkiRJ0gqY8EuSJEkTzIRfkiRJmmAm/JIkSdIEM+GXJEmSJpgJvyRJkjTBTPglSZKkCWbCL0mSJE0wE35JkiRpgpnwS5IkSRPMhF+SJEmaYCb8kiRJ0gQz4ZckSZImmAm/JGksJflskquS/KKn7INJzklyepL/TnLfnnX7JDk/yblJnjaUoCVpCEz4JUnj6nPALtPKjgW2rapHAb8E9gFIsg2wG/CIdp9PJFl9/kKVpOEx4ZckjaWq+gFw7bSyb1fVre3i8cDm7eNdgS9X1U1VdSFwPrDDvAUrSUNkwi9JmlSvAr7ZPt4MuLRn3WVt2d0k2TPJSUlOWrZsWcchSlL3TPglSRMnyTuAW4EvTBXNsFnNtG9VHVRVS6pqyaJFi7oKUZLmzRrDDkCSpEFKsjvwDGDnqppK6i8DHtCz2ebA5fMdmyQNg0f4JUkTI8kuwNuBZ1XVjT2rjgZ2S7JWkq2ArYEThxGjJM03j/BLksZSki8BOwEbJrkM2JdmVp61gGOTABxfVX9XVWcmOQw4i2aoz+uq6rbhRC5J88uEX5I0lqrqRTMUf2Y5278XeG93EUnSaHJIjyRJkjTBTPglSZKkCdZXwp/k2UnemcYLk5yX5MQkj+46QEnSaLJvkKTx0O8R/ncBz2offwx4ELAE+LcugpIkjQX7BkkaA/0m/A8CTqeZxux+wPOAbwCP7SguSdLos2+QpDHQb8K/RnvblubKhN+juUT5mh3FJUkaffYNkjQG+p2W8xzgxcBzgPOr6rokW+BVCiVpIbNvkKQx0O8R/n2Aq4AbgbcmWRNYDHy9o7gkSaPPvkGSxkBfR/ir6lhg82nFjxh8OJKkcWHfIEnjoe95+JM8IckXk5yQZLMk/5xkhy6D6zOuf0xyZpJfJPlSknsm2SDJse0UcccmWX/YcUrSJBrVvkGSdKd+5+HfFfgusBvNlGtXAq8F3tZdaH3FtRmwF7CkqrYFVqeJcW/guKraGjiuXZYkDdCo9g2SpLvq9wj/PwPXAt8HqKpbgR8Bj+8orrlYA7hXkjWAtWlOFtsVOKRdfwjw7OGEJkkTbZT7BklSq9+E/6E0cyuf2lN2NbDBoAOai6r6NfAh4BLgCuC3VfVtYOOquqLd5gpgo5n2T7JnkpOSnLRs2bL5CluSJsVI9g2SpLvqN+G/guZErNUBkmwAPJVmvuWhacfm7wpsBWwKrJPkpf3uX1UHVdWSqlqyaNGirsKUpEk1kn2DJOmu+k34j6S5cuJr2+Vf0yTZR3QR1Bw8BbiwqpZV1S3AV4E/A65MsglAe3/VEGOUpEk1qn2DJKlHvwn//sBXaI7iBFgLOBx4b0dx9esS4PFJ1k4SYGfgbOBoYPd2m92Bo4YUnyRNslHtGyRJPfqdh/+PwIuSvIHmoioXVdXVXQbWj6o6IckRwMnArcApwEHAusBhSfag+VLw/OFFKUmTaVT7BkkaVe9f+pG+tttnp70G2m5fCX+SR/Us3gxsmmRT4CbggnY4zVBU1b7AvtOKb6I52i9J6sgo9w2SpDv1lfDTzMBQs6y7LcmngDf74S5JC8qp2DdI0sjr+0q7NOMzZ7qtAbwOeNPAo5MkjTr7Bkkacf0m/C8HLgAeA9wT2B74FfBqmllxrgBe1kWAkqSRNdS+Iclnk1yV5Bc9ZRskOTbJee39+j3r9klyfpJzkzytq7gkadT0m/C/H/hBVZ1aVTdX1WnAD4H9q+p44PM0J2xJkhaOYfcNnwN2mVa2N3BcVW0NHNcuk2QbYDea6wbsAnwiyeodxiZJI6PfMfxrArsluQA4B9gaeCFwQ7t+LZoTtiRJC8dQ+4aq+kGSxdOKdwV2ah8fAiwF3t6Wf7mqbgIuTHI+sAPw067ik6RR0W/C/5/AO2nmXJ4S4INJ1gZeQDMlpiRp4RjFvmHjqroCoKquSLJRW74ZcHzPdpe1ZXeTZE9gT4Atttiiw1AlaX70Ow//Pye5EHgJsCnN1RQPrapDkqwGbEszDZskaYEYs74hM5TNOMNQVR1Ec00XlixZMtssRJI0Nvo9wk9VHQwcPEP57cBvBxmUJGk8jGDfcGWSTdqj+5sAV7XllwEP6Nluc+DyeY9Okoag74Q/yQuAJwOLuPNISVXVc7sITJI0+kawbzga2B04oL0/qqf8i0n+nebXiK2BE4cSoSTNs36vtLsf8K7eovbenzolaYEadt+Q5Es0J+humOQymquuHwAclmQP4BLg+QBVdWaSw4CzgFuB11XVbfMRpyQNW79H+F8BXE8zv/JjgU+2ZZ/qIihJ0lh4BUPsG6rqRbOs2nmW7d8LvLe7iCRpNPWb8G9KM5/y74DHVtXrkqwHPKizyCRJo86+QZLGQL8J/43ALcA1AEleBjwMeHhHcUmSRp99gySNgX4T/guAB9Kc9BSaqxtCc6EVSdLCZN8gSWOg34T/bTQXKDkG+H80F1O5EvjbjuKSJI0++wZJGgP9XnjrOz2Lf4sf5pK04Nk3SNJ4mMs8/E8GtgfW6SmuqnrPwKOSJI0F+wZJGn39zsN/IPD66cU0cy37oS5JC5B9gySNh36P8L8cuAn4BnBDd+FIksaIfYMkjYF+E/4rgZ9W1Su7DEaSNFbsGyRpDPSb8L8aODzJ+4FfAndcjryqPt9FYJKkkWffIEljoN+E/0+BjWimYJvOD3VJWpjsGyRpDPSb8P8TzYlYFwPXdxaNJGmc2DdI0hjoN+G/Dvh6Vb20y2AkSWPFvkGSxkC/Cf8ngTcleRHNJdN7x2me3kVgkqSRZ98gSWOg34T/AzTzKh86rbzmUIckabLYN0jSGJjLB3L6LJMkLRz2DZI04vpK+Ktqta4DkSSNF/sGSRoPflhLkiRJE2y5R/iTXLuC/auq7jfAeCRJI86+QVKX3r/0I31tt89Oe3UcyeRY0ZCe+65gfQ0oDknS+LjvCtbbN0jSCFlRwv+keYliFSS5L/BpYFuaTuZVwLnAV4DFwEXAC6rquuFEKEkTZ+T7BknSnZab8FfV9+crkFVwIHBMVT0vyZrA2jRXfzyuqg5IsjewN/D2YQYpSZNiHPqGJP8IvJrmQNAZwCtp+gcPBklacMb6pN0k9wGeAHwGoKpurqrrgV2BQ9rNDgGePYz4JEnzL8lmwF7AkqraFlgd2I3m4M9xVbU1cFy7LEkTb6wTfuCBwDLg4CSnJPl0knWAjavqCoD2fqOZdk6yZ5KTkpy0bNmy+YtaktS1NYB7JVmD5sj+5XgwSNICNe4J/xrAY4BPVtX2wB+YwxGbqjqoqpZU1ZJFixZ1FaMkaR5V1a+BDwGXAFcAv62qb+PBIEkL1KwJf5J/TfKM9vHLkyyZv7D6dhlwWVWd0C4fQfMF4MokmwC091cNKT5Jmijj0DckWZ/maP5WwKbAOkle2u/+HgySNGmWd4T/LcDO7ePPAS/qPJo5qqrfAJcmeWhbtDNwFnA0sHtbtjtw1BDCk6RJNPJ9A/AU4MKqWlZVtwBfBf4MDwZJWqCWN0vPb4GXtEdKAJ7W83hKVdUe3YTWtzcAX2hn6LmAZiaG1YDDkuxB85Pu84cYnyRNknHoGy4BHp9kbeCPNF9QTqIZ9rk7cAAeDJK0gCwv4T8KeHl7K2Cb9targKEm/FV1KjDTT8o7z1AmSVo1I983VNUJSY4ATgZuBU4BDgLWxYNBkhag5SX8rwK+DjwUeDdwAnDMfAQlSRpZY9E3VNW+wL7Tim/Cg0GSFqBZE/6quh04HCDJ6sDxVfWt+QpMkjR67Bskafws90q7U6pq/yRbJfkXYEuaKxQeXFUXdBmcJGl02TdI0njoK+FPsgPNVQnXBtIWvzHJzlV1YlfBSZJGl32DJI2Hfi+8dQCwDs3JWgcA/9Muv7+bsCRJY8C+QZLGQF9H+IHtgCOr6o4ZDZIcjic/SdJCth32DZI08vo9wv9/wIbTyjZsyyVJC5N9gySNgX6P8P8YeE6S84BzgYcADwKO7CowSdLIs2+QpDHQb8L/FuCxNB/kD2rLLgLe1kFMkqTxYN8gSWOg32k5L06yLfDXwGKaD/SvV9WN3YUmSRpl9g2SNB76PcJP+wF+eIexSJLGjH2DJI2+fk/alSRJkjSGTPglSZKkCWbCL0mSJE2wFSb8SdZIclyS98xHQJKk0WffIEnjY4UJf1XdCjwMuH/34UiSxoF9gySNj36H9LwbeHaSJya5R5cBSZLGhn2DJI2Bfqfl/CRQwHcBkkyVV1X1PbWnJGmi2DdI0hiYywdy+iyTJC0c9g2SNOL6Tfi36jQKSdI4sm+QpDHQV8JfVRcDJHkI8OCq+kanUUmSRp59gySNh75O2k2yQZLvAGcDRydZnORWp2OTpIVrlPuGJPdNckSSc5KcneRP23iPTXJee7/+sOOUpPnQ7yw9HwSeDNwMpKouAo4HntFRXJKk0TfKfcOBwDFV9TDg0TRfSvYGjquqrYHj2mVJmnj9Jvy7AEuBT/WUnQU8cNABSZLGxkj2DUnuAzwB+AxAVd1cVdcDuwKHtJsdAjx7GPFJ0nzrN+G/F3DFtLINaY7qSJIWplHtGx4ILAMOTnJKkk8nWQfYuKquAGjvN5pp5yR7JjkpyUnLli2bv6glqSP9Jvyn0/xE+ziAJB8Engmc1lFckqTRN6p9wxrAY4BPVtX2wB+Yw/CdqjqoqpZU1ZJFixZ1FaMkzZt+E/53AmsBj6eZX/nNwO3Aft2EJUkaA6PaN1wGXFZVJ7TLR9B8AbgyySYA7f1VQ4pPkuZVv9Ny/ijJEuC1wJbARcBBVXV6h7FJkkbYqPYNVfWbJJcmeWhVnQvsTHNuwVnA7sAB7f1RQwxTkuZN31farapfJHkrsBnw66q6sbuwJEnjYIT7hjcAX0iyJnAB8EqaX7UPS7IHcAnw/CHGJ0nzpq+Ev52r+CDgOT1lXwX+tqqu7Sg2SdIIG+W+oapOBZbMsGrneQ5Fkoau3zH8nwGeSzNGc+r2HODTHcU1J0lWb2di+Fq77MVVJKl7I903SJIa/Sb8TwEuBLYD7glsD1zclo+Cf6C5qMoUL64iSd0b9b5BkkT/Cf+vgO9V1entBUxOA74HnN9daP1Jsjnw19z1iJIXV5Gk7o1s3yBJutOsY/iTPKFn8fPAvklOBc4BHk7zM+5+XQbXpw8DbwPu3VN2l4urJJn14irAngBbbLFFx2FK0vgbo75BktRa3km7S4GaVnZgz+MAH6JJuIciyTOAq6rq50l2muv+VXUQzQlnLFmyZPpzlSTd3VJGvG+QJN3V8hL+S7j7h/qo2RF4VpK/ohk/ep8kh9JeXKU9uu/FVSRpcMahb5Ak9Zg14a+qxfMYx0qpqn2AfQDaI/xvqaqXtpd39+IqkjRg49A3SJLuqu8LbwEkuR+wTm9ZVV0y0IgG4wC8uIokzYsx6hskaUHq98JbT6WZb3mzaauq3zq6VlVLacaWUlXX4MVVJKlT49A3SJL6/0D+FLD5DOUZYCySpPFi3yBJY6DfefjvB3wLuE9VrdZ76zA2SdJos2+QpDHQ7xH+j9JcLn2zJL+sKmdokDSj9y/9SF/b7bPTXhMdwwJh3yBJY6DfozBHApsCZwG3Jrmtvd3aXWiSpBFn3yBJY6DfI/xfANabodxxmpK0cNk3SNIY6Dfh3wL4GfA24PrOopEkjRP7BkkaA/0m/AcBOwA/raqbO4xHkjQ+7BskaQz0m/DvDGwLLEtyEXBbW15V9dguApMkjTz7BkkaA/0m/I9q7+8NPLKn3BkZJGnhsm+QpDHQb8L/yk6jkCSNI/sGSRoDfSX8VXVI14FIksaLfYMkjYe+Ev4kn51lVVXVHgOMR5I0Jka9b0iyOnAS8OuqekaSDYCvAIuBi4AXVNV1w4tQkuZHv0N6XkEzJnNqbuWpxwUM/UNdkjQUr2C0+4Z/AM4G7tMu7w0cV1UHJNm7XX77sIKTpPnSb8K/f8/j1WlOznoWMNvRHUnS5BvZviHJ5sBfA+8F3tQW7wrs1D4+BFiKCb+kBaDfMfz7Ty9LchCw2cAjkiSNhRHvGz5Mc0Gwe/eUbVxVVwBU1RVJNhpGYJI03/odw7/FtKL7AA8FHj3wiCRJY2FU+4YkzwCuqqqfJ9lpJfbfE9gTYIstpj9FSRo//Q7puXCW8jMGFYgkaeyMat+wI/CsJH8F3BO4T5JDgSuTbNIe3d8EuGqmnavqIJqrCLNkyRKvKSBp7K3W53aZdvsj8BOaE7YkSQvTSPYNVbVPVW1eVYuB3YDvVtVLgaOB3dvNdgeOGlKIkjSv+h3D3+8XA0nSAjGGfcMBwGFJ9gAuAZ4/5HgkaV70O6RHkqSxU1VLaWbjoaquAXYeZjySNAzLTfiT3LaC/auqFvSXhvcv/Uhf2+2z015z2rarGEah3nGLoSv9PLeVeV5d1Ttsk/y3MG7sGyRpvKzoAzkrWC9JWnjsGyRpjKwo4d9+2vK6wOuBF9B84J/aQUySpNFm3yBJY2S5J1xV1WlVdRpwLvAU4EjghcAvgOdV1WO7D1GSNErsGyRpvKxoDP9awGtpLj2+EXA28IaqOnweYpMkjSD7BkkaLysa0vMrYBOggMOArwC3J3nW1AZVdXR34UmSRpB9gySNkRUl/JvSfKCHZmzmC6atrz7qkCRNFvsGSRojK/pAvoTmg1uSpCn2DZI0Rpab8LeXJZck6Q72DZI0XsbtsuiSJEmS5sCEX5IkSZpgY53wJ3lAku8lOTvJmUn+oS3fIMmxSc5r79cfdqySJEnSMIx1wg/cCry5qh4OPB54XZJtgL2B46pqa+C4dlmSJElacMY64a+qK6rq5PbxDTQXf9kM2BU4pN3sEODZQwlQkiRJGrKJmSc5yWJge+AEYOOqugKaLwVJNpplnz2BPQG22GKLeYpUkjTp3r/0I31tt89Oe81p20HHMNc6u6x3kO13HcMoGObfzcrUOwom+bmtyFgf4Z+SZF3gSOCNVfW7fverqoOqaklVLVm0aFF3AUqSJElDMvYJf5J70CT7X6iqr7bFVybZpF2/CXDVsOKTJEmShmmsE/4kAT4DnF1V/96z6mhg9/bx7sBR8x2bJEmSNArGfQz/jsDLgDOSnNqW/RNwAHBYkj1oLgH//OGEJ0mSJA3XWCf8VfUjILOs3nk+Y5EkSZJG0VgP6ZEkSZK0fCb8kqSJ4lXYJemuTPglSZPGq7BLUg8TfknSRPEq7JJ0Vyb8kqSJtbyrsAOzXoU9yUlJTlq2bNm8xSpJXTHhlyRNJK/CLkkNE35J0sTxKuySdCcTfknSRPEq7JJ0V2N94S1JkmbgVdglqYcJvyRpongVdkm6K4f0SJIkSRPMhF+SJEmaYCb8kiRJ0gQz4ZckSZImmAm/JEmSNMFM+CVJkqQJ5rScktSB9y/9SF/b7bPTXh1HIkla6DzCL0mSJE0wj/BLK+CRWkmSNM48wi9JkiRNMBN+SZIkaYKZ8EuSJEkTzDH8kiRJHfE8MI0Cj/BLkiRJE8yEX5IkSZpgJvySJEnSBDPhlyRJkiaYCb8kSZI0wUz4JUmSpAlmwi9JkiRNsIlO+JPskuTcJOcn2XvY8UiShst+QdJCNLEJf5LVgY8DTwe2AV6UZJvhRiVJGhb7BUkL1cQm/MAOwPlVdUFV3Qx8Gdh1yDFJkobHfkHSgpSqGnYMnUjyPGCXqnp1u/wy4HFV9fqebfYE9mwXHwqcO8dmNgSuHkC4g6xr1OoZZF2TWs8g6xq1egZZ16TWs7J1bVlViwbU/oLQT7/Qlo9S3zDo+oxtNOozttGobxJjm7FvWGPV4xlZmaHsLt9uquog4KCVbiA5qaqWrOz+XdQ1avWMYkyjVs8oxuRzm796Bl2XlmuF/QKMVt8w6PqMbTTqM7bRqG8hxTbJQ3ouAx7Qs7w5cPmQYpEkDZ/9gqQFaZIT/p8BWyfZKsmawG7A0UOOSZI0PPYLkhakiR3SU1W3Jnk98C1gdeCzVXXmgJtZ6Z98O6xr1OoZZF2TWs8g6xq1egZZ16TWM+i6NIt56hdg8O/nKP+tLZTYBl2fsY1GfQsmtok9aVeSJEnSZA/pkSRJkhY8E35JkiRpgpnwS5IkSRPMhF+SJEmaYBM7S898SPL3VfWJYccxypJsUFXXDjuOUZNkY2Azmov+XF5VVw45pJGMqdco/C2N+muk0WDfsHJG4X98nIzy59EgY+vyea7q39wovwfTmfD3KcmbphcB+yS5J0BV/fsc6noYzR/ICVX1+57yXarqmDnUc39gX+B24J+BNwDPBc4G/qGqruiznkcC/6+N6ZvA26vqunbdiVW1Q5/17Ah8uo3nVcC/AA9Kcg/gBVX10zk8tx2AqqqfJdkG2AU4p6q+0W8d0+obiX/KJNsBnwLWA37dFm+e5Hrg76vq5DnW9zBgV3qeG3B0VZ09rJh66v1zYAfgF1X17TnuO8i/pQcBf0NzwaVbgfOAL1XVb+dQx3YM+DVKshbN/+tiej6Lq+rdc61LwzPIvqGtbyD9Q7vPQPqInvoG0le02w/sf7ynzoH2G22dI9F39BrFfqSL2Dp4noPsVwYaW0+93fULVeWtjxtwA/AVmg/NfdvbdVOP51DPXsC5wP8AFwG79qw7eY4xHUPzAb43cDrwdmCLtuyoOdTzI5oPxvsCbwHOBB7UrjtlDvWcCDwS+FPgauDP2/LHAD+eQz37AscDJwHvB77bvu4/AN4xx9dou7aus4HvtLdz2rLHrOLfxJ8DbwL+cg77nAo8bobyxwOnzbH9t7f17Q28tL3tPVU23zEBJ/Y8fk1b777Aj+cSz4D/lvYCjgXeCfwE+ATwXuAsYKdhvG89+x5D85nyNuDNU7dV+Zv0Nv83BtQ3tHUNrH9o9xlIH9FT30D6inb7gfyP99Q3sH6jrW87RqjvmLb/wD6PGFA/0lFsA/3cHeTfXBd9Qrt/Z/3CKlewUG7th+QRwAeAtduyC1ainjOAddvHi9sPp39ol0+ZY12n9Dy+ZNq6U+dQz6nTlp9EcxT08cyhk5kWz9nT1s2lnjNoLoqzNvA74D5t+b2A0+f4Gg3yw2eVE1rgvOWsO3+O8fwSuMcM5Wsur52uYpr2/v8MWNQ+Xgc4Y47PbaB/S+3jtYGl7eMt5vL/Nsj3rWe/X6zMft5G6zaovqHdb2D9w/R9VqWPmG2fle0rZohtpf/Hp712A+k3pp7rKPUd0+obuX6ko9gG+rk7yL+5LvqEdt/O+gWH9PSpqi4BnpdkV+DYJP+xklWtXu3PtFV1UZKdgCOSbEnzU/Bc9J50/fnlrFuRJFmv2iEOVfW9JM8FjgQ2WMl49pm2bs051HNrVd0G3JjkV1X1uzauPya5fQ71AKxTVSdML6yq45OsM8e67tHzeE/gqVW1LMmHaI76HNBHHd9M8nWa9+vStuwBwMtpvtnPxe3ApsDF08o3adf1a1AxrZZkfZq/g1TVMoCq+kOSW+dQDwzubwman0VvA9YC7t3GdEn7M26/Bvm+TflJkkdW1Rkrub9GwAD7Bhhs/wCD6yOmDKqvmN7+qv6Pw2D7DRi9vqPXKPYjXcQ26M/dQf7NddEnQIf9ggn/HFXVUUmOBfYHLluJKn6TZLuqOrWt7/dJngF8luanprk4Ksm6VfX7qnrnVGGSB9N8a+/XB4CH03zw0MZ1epKdgXfNoZ53JVm7qm6sqv/piedB3L2zWZ6bp+oBHttTz3rM/QNokP+Uq5zQVtVeSZ7OneMlQ/N39PGa+zjTNwLHJTmPO5/bFsCDgdf3W8kAY1oP+Hm7fyW5f1X9Jsm6zD1ZGdTf0qeBnyU5HngCzd86SRYBfZ+oNeD3bcqfA69IciFwU1tnVdWjVrI+DdEA+gYYbP8Ag+sjpgyqr4DB/Y9PGWS/ASPWd/QaxX6ki9g6+Nwd2N9cR30CdNgvpP0JQSshyf2q6po57rM5zZGI38ywbseq+vHAAhxTSdaqqptmKN8Q2GSu33xn+ac8eq7/lEkuouk4QnNi05/1JLQ/qqrt5lLfICRZjebE2N7n9rP2SNdISLI2sHFVXTik9h9Bk6T8oqrOGUYMM2mP2t5NVU0/0qYxszJ9Q7uf/cNKGnS/0e47sX1Hr3HoRxaKTvuFrsYKTdqN5ie3DdvHS4ALaMYuXgw8cSXq25jmRJHtaZKhlYnpcdx1nOL+wP/SHIVZb0DPe89h10NzpOG5wDbD/juYJb61ga1G5bUe8HNbpZiADYYdE7BGz+N12//fgcW1sq8R8G7gqTRDB4b+Xntb6fd/oH1DW88q9w9tPZ33ET1tDezzaxB1jXq/0cY4kL6jq/ehg+c7Un8joxhbl/2CF97q319X1dXt4w8CL6yqrWnemH/rt5Ik27XDC5YC/9rW9f0kxyfZfo4xfRa4sX18IM2Qig+0ZQfPsa7ZrMy40VWqJ8n32qMyJHkZ8A3g6cBXkrxhQPGQZM9B1FPNz4ODOHo9qNeaJF8bVFVzaLN3yMA2SX4J/DzJRUkeN6B45hrTK4Ark/yyPVp3Os3/yGlJXjTf8UxzEfAi4KQkJyb5t3YcuMbLQPoGGHj/APPTR0wZ2OfXytQ1X/1GW/+o9R29RrEfuaPKEa1r0PWtSl0X0VG/4JCePiU5B9i2qm5NcnxVPb5n3RlV1df4yiSnAn9b004GSvJ44D+r6tFziOnsqnp4+/jkqnpMbzs1h58JM6B5eAdRT5JfVNW27eOfAbtU1TXt0JDja0BjnJP8bVX95xy2fxRwEKt+vYKBzbO9nDY2qTnMsZ0BzF/d+zfYjn39WFV9s637w1X1Z3Oo63E0syj8Lsm9aKaJewzNdJrvqz7n0E9yBs1MIvcGTgO2r6pfpZlb+9i5/C1lAPP5z1Lv/YEX0ExzuH5V3XtV6tP8GlTf0G5/KgPqH9r9BtZH9Ow3yDnbB1nXvPQbbf1D6Tum1Tly/UjPfgO/HkJb70pf26XdfyD9Sk99nfQJbd0D7xc8wt+/jwPfSPJk4JgkH07yhCT700yx1a9Zz/ynmb5wLn6R5JXt49OSLAFI8hDgln4rSfJ24Ms030pPpJlSMcCXkuw93/UAtyTZrH38e+AP7eObaKZdG5Sb57j9J4D9aE6e+yXwo/YfHu46C8OskuwFHEUzD/Yvpn1zf98c45nVHJP9fYGPAJ9M8n7gYzRDX/ZO8o6VDGHTqvpmG8uJNMMJ5mJQRyZvq6qr26Nov6+qX7UxzeniOe379ingnsCf0DyfBwA/TTOTypwl+XSSnwCfpJlA4XnA+itTl4ZqUH0DDLZ/gAH1EVMG+Bk/0Lpa89VvwBD6jl6j2I/0xDaw/iTJiT2PX9PWdW9g35X8GxnYL15d9Altvd31C4MeIzTJN2AnmgsinEIz5+83gb9lhjlsl1PHR4CvAy8E/qy9vbAt+9gc41kP+BzwK+AEmg/wC4DvA4+eQz2Dms99UPXsRHNBl3fT/IP/hOYCKscCbxng+3nJHLc/ddrynOegZrDXYViPZvzwOcA17e3stuy+c6hnIPNXA9cDR9OMEV5GOyd5u25OcwvTM0fy9Nd2+vuwgnqOprkIz8doLsTzb8CONHNgf2uur1H7eKXn859W53+3/7cHA68AHrgqf8/ehncbRN/Q1jOw/qGtbyB9RE99A5uzfZB19bwHnfcbbVvz3ndM23/k+pFpsQ3qOjqn9DxepWu7tPsNpF/pfZ7t44H0Ce3+nfULTss5B1W1lGZs5arUMcgpq35LM33TvYEH0nwbvKzmfunvQc3DO5B6qmppkj8DXkzzbf7nNEdp3lBznGUlyemzraI5MW6O1a3yHNSDnGf7MJokdqdqZ/VofwbcHTicZgxxPwY1f/X0cYartTFtTHO0Yi5+keSVVXUw7ZHJqjppJY5MvhR4HfBbmp9vn0Yz//LFNB+mczGI+fzvUFV/A5Dk4W1c30uyelVtvjL1aXgG0Te09Qx0qr8B9hFTBjln+0Dnfx9kvwEj2Xf0GsV+ZMogr4cw0OlMGVy/MmWgfUK7f2f9ggn/HAxqvGE1Qx2+OcDQ1qb5Rr0ycw3D4ObhHVQ9Ux3VXJPEmWxM809z3bTy0BwBmotBzEE9yHm2F1fVB3oL2g/sDyR51RzqGcj81VX1/VnKr6QZ9jAXrwYOTHMi8NU0P5NeSvN39eo5xPQ7miP8U45sb3M1kPn8e7Xv+1+09a1P0+n+cGXq0nANcix6B/0DrHofMeWNDG7O9kHWBQy034DR6zt6jWI/MmWQ10NYj8Fd2wUG1K+0Bt4ntPt31i940m6f2vGGL6IZczh1UZXNgd2AL1fVXK+UN1Mbe1bVQXPYfjuaMWTrAb/uiel64O+r6uQ51DWQeXgHVc9y6p/ra/QZ4OCq+tEM675YVS8eRFxziGdg82wn+TbwHeCQqSN27dH0V9BcyfEpfdYz8PmrZ6hrTu9bz36DOjK5yjFlwPP5J/k48APgh1V1+arWp+GYj76hbWfO/0OD7CN66hzYZ3zX/UVPOyvz2o1U3zGt/ZHrR3rqm4/+ZJWu7TKofmXQfUJbZ2f9ggl/n9JMMfiIqrplWvmawJnVTMO2qm3M9cz/UxngjA7jYK6v0XxZ2YR2Fdtcn2aYyq40R6MKuJJm3PoHqmqljzIM2ii+b6MQU9ux/km7eGJVXTXMeDR389E3tPXN+e91IfYRMxmF//XZDKPvmNb+2PQjC0VX/YJDevo3sPGGy/n5d64fSLPO6JBkZWZ0GBkDfI3my6DnBF6hqrouycE0J6UdX9OmZmPul39fZZl9OrahvG9t0rUbcHlVfSfJi2lOhDybZpq8oUnyfOBDNGO/A3w0yVur6ohhxqU5G+hY9AF/9k1sHzGTMew3YAh9R69R7EcWsi77BY/w96n9w/8YzZn1dxtvWH3OezvIn3+TfAR4EPD5npgeALwcuLCqVmoc5LDN10/kg9RzItB8trkXzQmpZwPb0czScFS77i5zbs9TPPvSXOhmDZrO43E0H1pPoZkR573zGU8b0xfaeNamGcawLvBVYGeAqnrFfMfUE9tpND+ZX9UuLwK+s1COuk6KQfUNbV0D/eyb1D5iJuPYb8Bw+o5p7Y9UP7LQddkvmPDPwSDGGw7659/MPKPD0bWKF7gYpvn6iXyQklxSVVvMc5tnAH/anrC1GDgC+K+qOjDJKVW1MlfmXNV4tqOZseA3wOZ15wVOTqgBXvhmDjGdXlWPSrIGzRjmTavqtiQBThtGTD2x3eWiTO3ny2k1hws1aTQM8ByogX/2TWIfMZNx7DdgOH3HtPZHqh9Z6LrsFxzSMwdVdXuSC2kuulE0wwTmenLRoKci62JGh2Eb6Gs0KBnsNG2DMMip2QZhkNOxDcpqbYe/Ds1R/vVoZlBYi5W44M2AHZPkW8CX2uUXAhOVhC0UA+oboIPPvgntI2Yykv0GjGTf0WvU+pGFrrN+wYS/T9NmO7iM5h9h8yTXM7fZDt7IgKcimyXeoZ4ItIreyDy8RithkNO0DcIgp2YbhEFOxzYon6G5oMzqwDuAw5NcQHPBmy8PKSYAquqtaebi3pHmb+igqvrvYcakuRtg3wDz+Nk35n3ETN7IaPYbMHp9R69R60cWtC77BYf09GmQsx0M6uffFbQxsrMS9GM+XqOViGmkpmnLAKdmG1A8nU/HtjKSbApQVZcnuS/NOQWXVNWJy91R6sOgZ8KZr8++ce8jZjKK/UYb10j1HdPaH6l+RN0x4e9TkvNmGwOY5PyqevB8x9S2PbALvkiaP0meQ3Oxlo1okpPQzHB0n6EGpjkZ1b6hJwb7CGlMdNkvmPD3aRRnOxjXWQkkNckg8EwTr/E2in1DT2z2EdIY6bJfMOGfg1Gb7WBcZyWQBEl+XFU7DjsOrbpR6xt64rKPkMZIl/2CJ+3OwQjOdjCysxJIWqGTknwF+B/gjnMfquqrQ4tIK2UE+4Yp9hHSeOmsXzDhH4AhznbwRkZ3VgJJy3cf4EbgL3vKiubCYJoAIzATzhuxj5DGSWf9ggn/YAxlrtqqOibJQxjBWQkkrdCbq+ra3oIkWw0rGHViqPOY20dIY6ezfsEx/HPgbAeSBiXJj4GnT12gLMnDgcOratvhRqa5sm+QNAhd9gurrWoFC0U728GXaY6QnAj8rH38pSR7DzM2SWPpfcD/Jlk3yWNpLmn/0iHHpDmyb5A0QJ31Cx7h75OzHUgatCTPBt4G3Bt4TlWdN9yINFf2DZIGqat+wTH8/XO2A0mrLMlHaYZ9TLkPcAHwhiRU1V7DiUwryb5B0iqZj37BhL9/b8TZDiStupOmLf98KFFoUN6IfYOkVdN5v+CQnjlIshrOdiBJ6mHfIGnUmfBL0hAk2RHYD9iS5tfWAFVVDxxmXJKk4eiyXzDhl6QhSHIO8I80P93ecSS4qq4ZWlCSpKHpsl9wDL8kDcdvq+qbww5CkjQyOusXPMIvSUOQ5ABgdZpLpt80VV5VJw8tKEnS0HTZL5jwS9IQJPle+3DqQ3hqrOaThxSSJGmIuuwXHNIjScOxdIYyj8BI0sK1dIaygfQLJvySNBy/73l8T+AZwNlDikWSNHyd9QsO6ZGkEZBkLeDoqnrasGORJA3fIPuF1QYQjyRp1a0NOAe/JGnKwPoFh/RI0hAkOYM7x2auDiwC3j28iCRJw9Rlv+CQHkkagiRb9izeClxZVbcOKx5J0nB12S+Y8EuSJEkTzDH8kiRJ0gQz4ZckSZImmAm/JEmSNMFM+CVJkqQJZsIvSZIkTTATfkmSJGmCmfBLkiRJE8yEX5IkSZpgJvySJEnSBDPhlyRJkiaYCb8kSZI0wUz4JUmSpAlmwi9JkiRNMBN+SZIkaYKZ8EuSJEkTzIRfkiRJmmAm/JIkSdIEM+GXJEmSJpgJvzSLJNXeFnfczqvadvZYhTouauvYaXCRdSvJ4qnXeAB1fSHJLUm2HkRskjQT+4Vu2S90x4R/AUqyY5L/TXJNkv9L8qskH02y5rBj60eSndoPhIsGVN9+bX2fm7bqwPb2u0G0M0vbawD7AVcD/7UKVX2WJtbLBhDWjHpe90ryyyTpWfeZnnX7dRXDcvw7MPVaSpoj+4W71We/0Af7hfGxxrAD0PxKshtwKLA6cBrwM2Ax8HfAu4CbhxbcgCVZDaCqbl+Z/avqjQMNaGbPAB4AHFRVK/3aV9W7VyWIJGtU1a1z2GVrYGfgO0nWA3ZblfZX1lTcVfXzJOcBz0uyV1VdM4x4pHFkv9A/+4Xlsl8YYR7hX0CSrA18nOZD/VDgMVX1mqp6KvAw4MZ2u0clOSbJ1UmWtUd9HtpTz9TPhHsnOSXJH5J8I8n6Pds8Psm32/1/n+T4tn2SbJvk60muatcfmWSLnn2njgi8vj1icEOSQ5Os2f40+b120y17f/pLsrRd/kCSE2g6qS2SvCXJeW2cNyU5Lcnz2n32A/Zt69u93X/ptDgWt8uLknw6ySVJftc+p1164v5cu/2n2tfsxiSnJ9luOW/LM9r77/fU84q2ntOS/Hv7+p2VZPsk70ny2yQXJPnLGd6Tnabe6yT7JzknyR+TXJbkNdPi/M8kxya5GfjzJPdIsk+7zx+SnJ3kH6c6yB43AX8EXjv1ugFrA9dNf3JJ/ibJz9r38OIkH09y39lejCRfbGO9qd3nu0keOcPzfEeSM9tYpnwfWBN46nJeb0k97BfsF6bFab8wqarK2wK50fzBV3t76CzbbELzD1rA14Bvt4+vANZvt7moLbsROAS4pl1+T7v+EcD/tWU/AD4DnA/cF7g/cC3Nh+5X2zYKOBtYq91/KsZrgM/RfIgUsAfwYOCIdvl3wIeBD7f7LW3Lbwf+l+an0E1oOrOvtveHAbe28S0GdgGOb/c7q63v9dPiWEzz5fin7fLJbd23ALcBO7bbf65nn/8Gzmwf/3A578mJ7Tbb95S9oud5/JjmaFsB17ev07fa5ct69pl6T3Zql7/QLl9L87Pu0cAHZ4hzabv+McC/tmW/bt+zZe3yPu1+O/XEcXD7/DdrX7dfAUe16/drt396u3wTzd/JL9rlY9r1i6fi6HkeP25j/zjNB3UBZ8/wPG8Fvgwc3rPuTe26Dwz7f82bt3G5Yb9gv3D3OJdivzBxt6EH4G0e32x4Sc8/9D1n2eZt7frv9ZSd0pbt2S5P/XO9tV3ev13+Wrv8sXb5qJ46Vqf5cHwrd/0Q/TBwVVu2S7vtVIzPb5cPaZc/1i5PfcBcNC32pW3556eVrwO8HHgP8B80nVQBL27X79cuf27afr0f7Du0j28A1mnX/0db9sV2+XPt8tfb5Se1y79fzntyXrvNg3vKXtHT1r16nm8B2wD37lleNO092QnYsGd9b4dxj2lxfr9nXYDft+VPbMt2bZcvn/a6X9/zekx1/G8F/oe7frB/o13et13ekKYzKOAhzPzBvhnwBuAA4KM9z2PTac/z3TO8lq9u1x007P81b97G5Yb9gv3CXeO0X5jQm2P4F5areh5vCZw7wzaL2/uze8rOAbZr9+l1Snt/fXu/bnu/VXt//NSGVXUbNGfgt0UPb2+9Htxn/Svy46kHaU44Ox7YdobtFvVZH9z5ulxaVX9oH5/T3q/odVlnOfVObXPvGdZdVFV/THJ9T9m5VXVb7jwvah2aIy69pl7/m6tqKhaq6pZp2/2k5/Ginjin3vup57dJpp24V1UnJjmZ5ujgTTRHdnacVv/i3vqq6uokV9MczduSplO7Q5qZFE5m5vd5EXB5z/KPZ9jmPu399TOskzQz+4W7sl+4k/3CBHEM/8LyE+4cT/fO3jF4SbZMcg+ab8rQjN2cMjVO8+Jp9U2dzFPTyi9s7x/XU/9qaT6Npur/alVl6kbzE+tn+qz/tvZ+tr/f3vF729B8qN9Gc0LRajRHkaA5etFPffTE/YCpMafM/XWZyent/fROrjeuO0x1kCsw9fqv2TtONM3MD716X6dlwFSHNfXeTz2/K2rmE8c+2d4fXlVXz7D+ot76ktyP5mgO3P01A/hrmg/1M2h+5t+4Z12mbXsTdzf1Gp4ywzpJM7NfsF/oZb8woUz4F5D2CMQbaMYAvhQ4OclBSb4G/JLmm/yhwG+BJyU5OskxwPbAlTRjJPvxKZp/vF3bE6YOohm3uB7NOLzrgeck+VZ7gtB3gEu56z/y8lza3m/eniz19uVse3X7fFenmaLrWJoP+Jnqe3qaaeieO0M9JwEn0Hzw/DDJ52leywI+0WfcM/lae//EVajjLtoP2S+2i8elmRrtq8B7l7NPcecH9ReTfBr4dLv8sVl2+wLNkZy3zbL+4+39P6WZ2m4pzcxgx1bVL2fY/sr2fmuaqeS+PVu8s3gizRjgY+e4n7Rg2S/YLyxnH/uFCWLCv8BU1RdoxhB+A9iC5kz6hwP/D7ixqi5v13+b5qe4JcDXgSdV1bV9tvELmnF936E5ivISms7i5rb+J9J8oG1H08FsRvMhMNPRgJnqvwj4UFvnHsDLlrPtZTQfwFe27f6cu/5kCXA4zQlP6wCvp3n+0+u5HXgWzU+UGwF/Q3PE4FlV9aN+4p7F/9LMkfyc6T+PrqLX0IxNvZrm9d+B5gS55XkHzRR8NwIvpjmx663AB2bauKr+WFXfqaorZln/deAFNJ3682g69v8EXjhL+4fRHM27BXgK8P4VxHuHJI+l6RCOmOWokqRZ2C/YLyyH/cKESPMFTtKwJHkVzQfaa6rq0yvaXneX5FCaDmObqjpvRdtL0iizX1h19gt3ZcIvSZIkTTCH9EiSJEkTzIRfkiRJmmAm/JIkSdIEM+GXJEmSJpgJvyRJkjTBTPglSZKkCWbCL0mSJE0wE36pQ0kWJ6kkaww7FkmStDCZ8EvzKMlmSY5Kcm2Sy5L83bBjkiRJk82EX5pfhwIXAhsDfw28L8mThhuSJEmaZCb80kpIclGStyY5PckfknwmycZJvpnkhiTfSbL+tH3WBXYC3ltVt1TVacARwKuG8BQkSdICYcIvrbznAk8FHgI8E/gm8E/AhjT/W3tN2z7T7qceb9ttmJIkaSEz4ZdW3ker6sqq+jXwQ+CEqjqlqm4C/hvYvnfjqroB+DHwriT3TPIYmi8Na8934JIkaeEw4ZdW3pU9j/84w/K6M+zzEmAr4FLgk8AXgMu6ClCSJMmpAqV5VFUXA8+YWk7yReDE4UUkSZImnQm/NI+SPJzmiP5NwAuAvwQePtSgJEnSRHNIjzS/ngZcAFwH/B2wS1UtG25IkiRpkqWqhh2DJEmSpI54hF+SJEmaYCb8kiRJ0gQz4ZckSZImmAm/JEmSNMGclrO14YYb1uLFi4cdhiT15ec///nVVbVo2HFIkkafCX9r8eLFnHTSScMOQ5L6kuTiYccgSRoPDumRJEmSJpgJvyRJkjTBTPglSZKkCWbCL0mSJE0wE35JkiRpgpnwS5IkSRPMhF+SJEmaYCb8kiRJ0gQz4ZckSZImmFfalaQOvH/pR/rabp+d9uo4EknSQucRfkmSJGmCmfBLkiRJE8yEX5IkSZpgJvySJEnSBDPhlyRJkibYWCT8ST6b5Kokv+gp2yDJsUnOa+/X71m3T5Lzk5yb5GnDiVqSJEkavrFI+IHPAbtMK9sbOK6qtgaOa5dJsg2wG/CIdp9PJFl9/kKVJEmSRsdYJPxV9QPg2mnFuwKHtI8PAZ7dU/7lqrqpqi4Ezgd2mI84JUmSpFEzFgn/LDauqisA2vuN2vLNgEt7trusLZMkSZIWnHFO+GeTGcpqxg2TPZOclOSkZcuWdRyWJEmSNP/GOeG/MskmAO39VW35ZcADerbbHLh8pgqq6qCqWlJVSxYtWtRpsJIkSdIwjHPCfzSwe/t4d+ConvLdkqyVZCtga+DEIcQnSZIkDd0aww6gH0m+BOwEbJjkMmBf4ADgsCR7AJcAzweoqjOTHAacBdwKvK6qbhtK4JIkSdKQjUXCX1UvmmXVzrNs/17gvd1FJEmSJI2HcR7SI0mSJGkFTPglSZKkCWbCL0mSJE0wE35JkiRpgpnwS5IkSRPMhF+SJEmaYCb8kiRJ0gQz4ZckSZImmAm/JEmSNMFM+CVJkqQJZsIvSZIkTTATfkmSJGmCmfBLkiRJE8yEX5IkSZpgJvySJEnSBDPhlyRJkiaYCb8kSZI0wUz4JUmSpAlmwi9JkiRNMBN+SZIkaYKZ8EuSJEkTzIRfkiRJmmB9JfxJnp3knWm8MMl5SU5M8uiuA5QkSZK08vo9wv8u4Fnt448BDwKWAP/WRVCSJEmSBqPfhP9BwOnA1sD9gOcB3wAe21FckiRJkgag34R/jfa2LVDA94BLgTU7ikuSJEnSAKzR53bnAC8GngOcX1XXJdkCuLyzyCRpHrx/6Uf62m6fnfbqOBJJkrrR7xH+fYCrgBuBtyZZE1gMfL2juCRJkiQNQF9H+KvqWGDzacWPGHw4kiRJkgap73n4kzwhyReTnJBksyT/nGSHLoOTJEmStGr6OsKfZFfgSJovCAVcCbwWeBTNjD1Dk+QfgVe3cZ0BvBJYG/gKzbCji4AXVNV1QwpRkiRJGpp+j/D/M3At8H2AqroV+BHw+I7i6kuSzYC9gCVVtS2wOrAbsDdwXFVtDRzXLkuSJEkLTr8J/0Np5t0/tafsamCDQQe0EtYA7pVkDZoj+5cDuwKHtOsPAZ49nNAkSZKk4eo34b+C5iTd1QGSbAA8lWYu/qGpql8DHwIuoYnxt1X1bWDjqrqi3eYKYKPhRSlJkiQNT78J/5E0V9V9bbv8a2Ar4IgugupXkvVpjuZvBWwKrJPkpXPYf88kJyU5admyZV2FKUmSJA1Nvwn//jQnwa4OBFgLOBx4b0dx9espwIVVtayqbgG+CvwZcGWSTQDa+6tm2rmqDqqqJVW1ZNGiRfMWtCRJkjRf+kr4q+qPVfUimqExOwAbVdVuVXVjp9Gt2CXA45OsnSTAzsDZwNHA7u02uwNHDSk+SZIkaaj6nZbzUT2LNwObJtkUuAm4oD26Pu+q6oQkRwAnA7cCpwAHAesChyXZg+ZLwfOHEZ8kSZI0bH0l/DSz89Qs625L8ingzcNI/KtqX2DfacU30RztlyRJkha0vq+0SzN2f6bbGsDrgDcNPDpJkiRJq6TfhP/lwAXAY4B7AtsDv6K5wu2f0UyJ+bIuApQkSZK08vpN+N8P/KCqTq2qm6vqNOCHwP5VdTzweWBxRzFKkiRJWkn9juFfE9gtyQXAOcDWwAuBG9r1a9GczCtJkiRphPSb8P8n8E6a+finBPhgkrWBF9DMkCNJkiRphPSV8FfVPye5EHgJzRVtfw0cWlWHJFkN2JZmZhxJkiRJI6TfI/xU1cHAwTOU3w78dpBBSZIkSRqMvhP+JC8AngwsohnOA1BV9dwuApMkSZK06vq90u5+wLt6i9r72S7GJUmSJGkE9Dst5yuA64Gft8ufBP4IfHjgEUmSJEkamH6H9GxKM9f+74DHVtXrkqwHPKizyCRJkiStsn4T/huBW4BrAJK8DHgY8PCO4pIkSZI0AP0m/BcADwSOphm//7m2/JwOYpIkSZI0IP0m/G8DNgOOAf4fzYW2rgT+tqO4JEmSJA1Avxfe+k7P4t9ioi9JkiSNhbnMw/9kYHtgnZ7iqqr3DDwqSZIkSQPR7zz8BwKvn15MMw+/Cb8kSZI0ovo9wv9y4CbgG8AN3YUjSZIkaZD6TfivBH5aVa/sMhhJkiRJg9Vvwv9q4PAk7wd+Cdw2taKqPt9FYJIkSZJWXb8J/58CG9FMzzmdCb8kSZI0ovpN+P+J5iTdi4HrO4tGkiRJ0kD1m/BfB3y9ql7aZTCSJEmSBqvfhP+TwJuSvAg4h7uO4T+9i8AkSZIkrbp+E/4P0My5f+i08ppDHZIkSZLm2VyS9fRZJkmSJGlE9JXwV9VqXQciSZIkafBM5CVJkqQJttwj/EmuXcH+VVX3G2A8kiRJkgZoRUN67ruC9TWgOCRJkiR1YEUJ/5PmJQpJkiRJnVhuwl9V35+vQFZWkvsCnwa2pfnF4VXAucBXgMXARcALquq64UQoSZIkDc8knLR7IHBMVT0MeDRwNrA3cFxVbQ0c1y5LkiRJC85YJ/xJ7gM8AfgMQFXdXFXXA7sCh7SbHQI8exjxSZIkScM21gk/8EBgGXBwklOSfDrJOsDGVXUFQHu/0Uw7J9kzyUlJTlq2bNn8RS1JkiTNk1kT/iT/muQZ7eOXJ1kyf2H1bQ3gMcAnq2p74A/MYfhOVR1UVUuqasmiRYu6ilGSJEkamuUd4X8LsHP7+HPAizqPZu4uAy6rqhPa5SNovgBcmWQTgPb+qiHFJ0mSJA3V8mbp+S3wkiTrt8tP63k8papqj25CW7Gq+k2SS5M8tKrOpfmCclZ72x04oL0/algxSpIkScO0vIT/KODl7a2AbdpbrwKGlvC33gB8IcmawAXAK2l+uTgsyR7AJcDzhxifJEmSNDTLS/hfBXwdeCjwbuAE4Jj5CGouqupUYKbzC3aeoUySJElaUGZN+KvqduBwgCSrA8dX1bfmKzBJkiRJq265V9qdUlX7J9kqyb8AW9Jcvfbgqrqgy+AkSZIkrZq+Ev4kO9BcsXZtIG3xG5PsXFUndhWcJEmSpFXT74W3DgDWoTmR9wDgf9rl93cTliRJkqRB6OsIP7AdcGRV3THbTZLD8cRYSZIkaaT1e4T//4ANp5Vt2JZLkiRJGlH9HuH/MfCcJOcB5wIPAR4EHNlVYJIkSZJWXb8J/1uAx9Ik+Q9qyy4C3tZBTJIkSZIGpN9pOS9Osi3w18BimmT/61V1Y3ehSZIkSVpV/R7hp03uD+8wFkmSJEkD1u9Ju5IkSZLGkAm/JEmSNMFM+CVJkqQJtsKEP8kaSY5L8p75CEiSJEnS4Kww4a+qW4GHAffvPhxJkiRJg9TvkJ53A89O8sQk9+gyIEmSJEmD0++0nJ8ECvguQJKp8qqqvqf2lCRJkjS/5pKsp88ySZIkSSOi34R/q06jkCRJktSJvhL+qroYIMlDgAdX1Tc6jUqSJEnSQPR10m6SDZJ8BzgbODrJ4iS3OlWnJEmSNNr6naXng8CTgZuBVNVFwPHAMzqKS5IkSdIA9Jvw7wIsBT7VU3YW8MBBByRJkiRpcPpN+O8FXDGtbEOaI/6SJEmSRlS/Cf/pNMN3HgeQ5IPAM4HTOopLkiRJ0gD0m/C/E1gLeDzN3PtvBm4H9usmLEmSJEmD0O+0nD9KsgR4LbAlcBFwUFWd3mFskiRJklZR31farapfJHkrsBnw66q6sbuwJEmSJA1Cv/Pwr5/kcOAG4BzghiSHJ9mg0+gkSZIkrZJ+j/B/Bnj2tLLnAKu395IkSZJGUL8n7T4FuBDYDrgnsD1wcVs+dElWT3JKkq+1yxskOTbJee39+sOOUZIkSRqGfhP+XwHfq6rTq+rmqjoN+B5wfnehzck/AGf3LO8NHFdVWwPHtcuSJEnSgjPrkJ4kT+hZ/Dywb5JTacbwPxx4LiMwLWeSzYG/Bt4LvKkt3hXYqX18CM1Vgt8+37FJkiRJw7a8MfxLgZpWdmDP4wAfAj482JDm7MPA24B795RtXFVXAFTVFUk2mmnHJHsCewJsscUWHYcpSZIkzb/lJfyXcPeEf6QkeQZwVVX9PMlOc92/qg4CDgJYsmTJSD9XSZIkaWXMmvBX1eJ5jGNl7Qg8K8lf0ZxMfJ8khwJXJtmkPbq/CXDVUKOUJEmShqTfk3YBSHK/JFv03roKrB9VtU9Vbd5+OdkN+G5VvRQ4Gti93Wx34KghhShJkiQNVV/z8Cd5Ks1c/JtNW1X91jHPDgAOS7IHzdCk5w85HkmSJGko+k3WPwVsPkN5BhjLKqmqpTQnGlNV1wA7DzMeSZIkaRT0O6TnfsC3gPtU1Wq9tw5jkyRJkrSK+k3YPwpsAWyWZGSO6kuSJElavn4T/iOBTYGzgFuT3Nbebu0uNEmSJEmrqt8x/F8A1puh3KP9kiRJ0gjrN+HfAvgZzRVtr+8sGkmSJEkD1W/CfxCwA/DTqrq5w3gkSZIkDVC/Cf/OwLbAsiQXAbe15VVVj+0iMEmSJEmrrt+E/1Ht/b2BR/aU12DDkSRJkjRI/Sb8r+w0CkmSJEmd6Cvhr6pDug5EkiRJ0uD1lfAn+ewsq6qq9hhgPJIkSZIGqN8hPa+gGa8/Ne/+1OMCTPglSZKkEdVvwr9/z+PVaU7cfRYw25F/SZIkSSOg3zH8+08vS3IQsNnAI5IkSZI0MP2O4d9iWtF9gIcCjx54RJIkSZIGpt8hPRfOUn7GoAKRJEmSNHir9bldpt3+CPyE5mReSZIkSSOq3zH8/X4xkCRJkjRCTOQlSZKkCbbcI/xJblvB/lVV/Z4HIEmSJGmerShZzwrWL3jvX/qRvrbbZ6e9RqJeYxidGPqpt8vnNQoxjML7K0nSpFtRwr/9tOV1gdcDL6D5MnBqBzFJkiRJGpDljuGvqtOq6jTgXOApwJHAC4FfAM+rqsd2H6IkSZKklbWiMfxrAa8F3g5sBJwNvKGqDp+H2CRJkiStohUN6fkVsAlQwGHAV4DbkzxraoOqOrq78CRJkiStihUl/JvSJPuhGbf/gmnrq486JEmSJA3JipL1S2iSekmSJEljaLkJf1Utnqc4JEmSJHXAK+1KkiRJE8yEX5IkSZpgY53wJ3lAku8lOTvJmUn+oS3fIMmxSc5r79cfdqySJEnSMIx1wg/cCry5qh4OPB54XZJtgL2B46pqa+C4dlmSJElacMY64a+qK6rq5PbxDTQXBtsM2BU4pN3sEODZQwlQkiRJGrKxTvh7JVkMbA+cAGxcVVdA86WA5irBM+2zZ5KTkpy0bNmyeYtVkiRJmi8TkfAnWRc4EnhjVf2u3/2q6qCqWlJVSxYtWtRdgJIkSdKQjH3Cn+QeNMn+F6rqq23xlUk2addvAlw1rPgkSZKkYRrrhD9JgM8AZ1fVv/esOhrYvX28O3DUfMcmSZIkjYLlXml3DOwIvAw4I8mpbdk/AQcAhyXZA7gEeP5wwpMkSZKGa6wT/qr6EZBZVu88n7FIkiRJo2ish/RIkiRJWj4TfkmSJGmCmfBLkiRJE8yEX5IkSZpgJvySJEnSBDPhlyRJkiaYCb8kSZI0wUz4JUmSpAlmwi9JkiRNMBN+SZIkaYKZ8EuSJEkTzIRfkiRJmmAm/JIkSdIEM+GXJEmSJpgJvyRJkjTBTPglSZKkCWbCL0mSJE0wE35JkiRpgpnwS5IkSRPMhF+SJEmaYCb8kiRJ0gQz4ZckSZImmAm/JEmSNMFM+CVJkqQJZsIvSZIkTTATfkmSJGmCmfBLkiRJE8yEX5IkSZpgJvySJEnSBDPhlyRJkibYRCf8SXZJcm6S85PsPex4JEmSpPk2sQl/ktWBjwNPB7YBXpRkm+FGJUmSJM2viU34gR2A86vqgqq6GfgysOuQY5IkSZLmVapq2DF0IsnzgF2q6tXt8suAx1XV63u22RPYs118KHDuHJvZELh6AOGujGG17XNeGG37nEe/7S2ralEXwUiSJssaww6gQ5mh7C7fbqrqIOCglW4gOamqlqzs/qtiWG37nBdG2z7nhdO2JGnyTfKQnsuAB/Qsbw5cPqRYJEmSpKGY5IT/Z8DWSbZKsiawG3D0kGOSJEmS5tXEDumpqluTvB74FrA68NmqOnPAzaz0cKAxbtvnvDDa9jkvnLYlSRNuYk/alSRJkjTZQ3okSZKkBc+EX5IkSZpgJvySJEnSBDPhlyRJkiaYCb80QpJskeS+7ePFSZ6XZNshh9W5JPeYoWzDDtu7b1d1S5I0apylp09J/gb4flVdm2QR8G/A9sBZwJur6rKO238S8Fyai4ndCpwHfLqqzu+wzX8HjqyqH3fVxiztbgC8nuZCaZ8B/gn4U+Bs4H1VdV3H7T+N5kJtx1XVRT3lr6qqz3bY7t7A3wI3AR8C3gL8GHg88Jmq+vcO234YsCuwGc0VqS8Hjq6qs7tqs233ScB/AWsBpwB7Tr3mSU6uqsd01O6twFLgSzR/49d30c4KYliL5n96MT1TJFfVu+c7FknSZPMIf//eW1XXto8/RpOcPB34JnBwlw0nOQB4OXA8cAtwAfAr4PAkz++w6ZcBBya5OMm/Jtm+w7Z6HQqsAzwW+B5wf+ADwB+Bz3XZcJL3Ae8AHgkcl+QNPatf32XbNK/3NsCOwH8Af1FVewA7AK/qqtEkbwe+DAQ4keaidQG+1H4J6dK/Ak+rqkU0c9Efm+TxU6F12O7ZwIeBJwO/SnJUkt2S3KvDNqc7iuZL1q3AH3pukiQNlEf4+5Tk3Kp6aPv451X12J51p1bVdh22fUZVPbJ9vAbNLw07Jlkf+GFVdTLkI8kpVbV9kq1prlS8G81FzL4EfKmqftlRu6dW1XZJAlxWVZtNX9dFu239ZwDbtxduuy/wReDcqvrHqdejw7ZPr6pHJVkduAK4f1Xd3q77RYfv8y+BR1TVLdPK1wTOrKqtu2i3beO0qnp0z/IjgK8CewPv6vAI/x2/HrRJ/jNp/r6fCHyrql7cRbvTYujsPZUkqZdH+Pu3NMm72+RgaZJnwx1DEn7bcdu3t8NcADalSbpph7Z0eRS02nbOq6r3VNUjgBcA9wS+0WG7q7VfZh4ArJtkMUCS+wFrdtguwBpVdStAO8zjmcB9khw+D22fnOSLNAnvccAhSV6S5DM0Q8e6cjvN39V0m7TrunRLkvtPLbRXw94Z2Bfo7IsGPf83VfXHqjqsqp4DPJDm6tzz4SdJHjlPbUmSFrA1VryJWq+nGepxbrv8j0n+APwvzVCMLr0POCXJucDDgNcCtOcSnNZhu3f7MlFVpwOnA/t02O77gXPax68CPp2kaIa77N9hu9AM73hiVX0foKpuA/ZI8i8046279Grg+TRftI6gGcrzYpq/uY932O4baYYvnQdc2pZtATyY7ocx7Q1sDPxmqqCqLkuyE/C6Dtv9wkyFVfVb4JAO2+3158ArklxIc95GmhDqUfPUviRpgXBIz0pIsh7NkeBr5rHNDWiOPp4/XycYJlm3qn4/H23N0PbqNH+ft7bDmLYDfl1VV3Tc7r2gOeo7w7rNqurXXbY/LElWo/mCsRlN4nkZ8LP2C486kGTLmcqr6uL5jkWSNNkc0jMHSVZLslp7FPCGJI/pGWrTtetohvI8OcnfJHlcO8a9MzMl+0n+vss2e9q+bWpoDc0QottpTtrtut0/Aotmmhqz62Q/yX2SvD/JfyV58bR1n+iy7aq6vaqOr6ojq+qI9nHnyX6Sdduhcmcm+W2SZUmOT/KKrtteTkx7zlNTewAPAa6uqounbvPUtiRpATHh71M7Zv8K4NdJdgV+SDN14ulJntlx239JMw3nfsBfAX9NM7TlvHZdV+2+adrtzcC7p5Y7bPcTPY//nGb8+r8BZyT5q67abdvbG/g+cHySVwPH0MzG9JUun3PrYJqj60cCuyU5sp26EZqpOeddkq913MQXaGadehrN3/RHaIbIPamdMWkYOv0i3eMi4EXASUlOTPJv7WeLJEkD5ZCePiWZmobzXjTj5v+kqs5tf5Y/sqqWdNj22cDTe+eEb8u3Ar5RVQ/vqN0baE7OPZM7k6A30kxnSFV1Mp5+2gwq36O5zsHJSR4IHNbxa30msARYmyYhe2BVLUuyDnBCl7OqTJ+BKMk7aL7gPQs4tqsZa1YQ0yZdDqOaYZaen1XVn7RDjM6qqod11O5ewH9X1aUr3Lhj7UnLL6C57sL6VXXvIYckSZowHuGfg6r6TVVdCFxSVee2ZRfT/eu4Bs2Y6ul+DdztCqUD9AiaYUTrAB9sE/zrqmr/rpL9Gdynqk4GqKoL2ni6dFs7rOd6miFE17Rtz8f86Gu1iS5tm++lmZv+B8D95qH9u+n6nAngD+2vOLS/lF3btns73R5pfw9wQpIfJvn79gT4eZXk00l+AnyS5n/8ecD68x2HJGnyOUvPHLTj92+n5yJI7cmlXU/X+FngZ0m+zJ2zqDyAZt7wz3TVaFVdAjyvHWZwbJL/6KqtaR6W5HSahG9xkvWr6ro2Ge7yCw7cOTXmOtw5NeYxNBdo6nJqTGhmfHoy8J2pgqo6JMmVwEe7arQ9CX0f4NnAVOJ7Fc2FoQ7o+CTxv6OZhemhwBm0/1ttAt7lzEQX0FzY7SnAC4H9k/yc5hoTX62qGzpse8r9aL7AXk/zRefqnvNWJEkaGIf09CnJnwBnVNX/TStfDPx5VR3acfvb0Azt6J1F5eiq6joJnWp/bZox1o+rqid03Nb02UuuqKqbk2wIPKGqvtph22sw89SYlwAfn6cj/fMqybeA7wKHVNVv2rL7A7sDT6mqpw4zvi70Dhtrl+9BM2TvRTTPed6O+Cd5OM05DP8IrF5Vm89X25KkhcGEfxUkud98Ts2pyZfkYcCuNF/sCric5ovd2R22ecdVpOeyboDtP4zm+Z7QOzNUkl2q6piO2pz1qslJ7jXTtKwdxPAM4C+AJ9AM5fkpzZWzP9t125KkhcUx/H1KckB7hJkkS5JcQDMG+OIkT+y47fXa9s9Jck17O7stu2+H7d4/ySeTfDzJ/ZLsl+T0JIcl2aTDdofyfNu2h/Kc27bfDnyZ5hecE4GftY+/1M4e1JWLk7wtycY9sWzcxtPpSa3tybNHAW8AfjFtlpouZ+l54Wwr5iPZbz0dOBl4blU9rKpeabIvSeqCCX///rqqrm4ffxB4YVU9GHgqzZSRXTqMZh7+narqflV1P+BJNGN/D++w3c/RjFu/FPgezUmsz6CZkvRTHbY72/O9jm6fLwzvOUMzL/ufVNUBVXVoezuAZljRHh22+0Ka8eTfT3JdkmuBpcAGNLPHdOk1wGOr6tnATsC7kvxDu66zk3ar6pdd1T2HGF5H8zo/Jskzkmw05JAkSRPKIT19SnIOsG175dfjq+rxPevOqKpHdtj2UIZc9A57SHJJVW3Rs+4uU0gOuN2hDTEZ1nNu6z8HeNr0iy+15zR8u+Pn/TBgc+D4+RpW09Z/VlVt07O8Ls25E2cBT+7y9R62JM+nuZbHUpovN38BvLWqjhhmXJKkyeMR/v59HPhGkicDxyT5cJInJNkfOLXjtoc15KL37+Pzy1k3aEMbYsLwnjM01zg4Lsk3kxzU3o6hmS3oH5a/68rrGVbzeuZ3WA3Ab5JsN7XQftl4BrAh0NmX6BHxTppfdHavqpfT/JLzriHHJEmaQE7L2aeq+miSM4DXAg+hee0eCvwP8C8dN/9CYG+aIRdTP/tfCRxNt0MujkqyblX9vqreOVWY5MFAl0Miep/vVNL/G7p/vjC850xVHZPkITSJX+9sTD+rqts6bHpqWM3v21mnjkiyuKoOpPurzr4cuMtUlO3UlC9P8p8dtz1sq1XVVT3L1+BBGElSBxzSI42Y9kvOHbP0VNWVHbc3UsNqkmxQVdfOZ5vDkOSDwKNo5v6H5ovu6VX19uFFJUmaRCb8czCMKROntb0ZzRjrP/SUdzl14eOAs6vqd0nuRXPU/TE0ieD7quq3XbTbtj3M13oHoKrqZ2muf7ALcE5VfaPjdrejOTF4PZoj+6EZV3898PdTVxzuoN3vAm+qqlN7ytagueDbS6qqs6sbJ9kR+DQwdUG7fwEeRHOBtRdU1U+7ansUJHkusCPNe/2DqvrvIYckSZpAJvx9asePv4hm2sTL2uLNaa52++V2NpWu2t4LeB1wNrAd8A9VdVS77i4XEBpwu2cCj25PVD4IuJHmyO/ObflzOmp3mK/1vjTTJa4BHAs8juakyqcA36qq93bY9qnA31bVCdPKHw/8Z1U9uqN2Nwdunbro1rR1O1bVj7tot63/RJoZiNaludLws6vqR0keA3y0qnbsqm1JkhYKE/4+Jfkl8IiqumVa+ZrAmVW1dYdtnwH8ae8Ya+C/qurALOcCQgNo9+yqenj7ePqVSbucpWfYr/V2wFo05w1s3vMLxwlV9agO2z5vtueW5Px2GtiJMm1WpDv+3trlzr7MjoIkzwE+AGxEc4Q/NL8s3WeogUmSJo4n7fbvdmBT4OJp5Zu067q0+tRUiVV1UZKdaE6s3JJuT6r8RZJXVtXBwGlJllTVSe2JpbesaOdVMMzX+tb2BNkbk/yqqn4HzcWYknTd9jeTfJ1mdqCp2YgeQHNia2dTYw5Z70mq+0xbt+Z8BjIE/wo8cz6GqUmSFjYT/v69kWbKxPO4MxnbAngwzXSGXfpNku2mxli3R/qfQTPGusupC18NHJjkncDVwE+TXErz/F/dYbtvZHiv9c1J1q6qG4HHThUmWY+Ov2xU1V5Jns6d5y5MzdLz8a7PHxiid0293lX1P1OFSR7E3adFnTRXmuxLkuaDQ3rmIMlqzP+UiUMdY922cW/ggTRfEC/retaYts1hvdZrVdVNM5RvCGxSVWd02b4WjiQHAvenmdr3jr+5qvrqsGKSJE0mE/45mu8pE0eh7WE+52Fr599/NM1sRWcNMY49q+qgYbU/DJP+nJMcPENxVdWr5j0YSdJEc0hPn2abMjHJ9XQ4ZeIMbf+6LZ5q+7VVdcoQ2u1ymshHAQfRfMn4JvD2qrquXXdiVe3QRbtt/d8Dnl9VVyd5Gc2VT38A7JfkoKr6aFdtryi0IbU7TJP+nN88/XoDSbYaVjCSpMllwt+/zzH7lIkH0xwFHkbbn+uw7eW12+Vz/gSwH3A8zbkCP0ryrKr6Fc387F1aVFVXt4/3opkd6Zoka7fxdJrw91xv4YSpE7Vb009gnggrutbDUIPr3v8mefrUieFJHg4cDmw73LAkSZPGy7j3b53piS9AVR0PrDOhbQ+r3XWr6piqur6qPkRzou4x7ReNrseg3ZJks/bx74Gpi5zdBHR2ASq443oLRwFvoJkhadee1ZOa/H6W5voOAAfS/Jr0gbZspiEvk+R9NEn/ukkeSzPd7kuHHJMkaQJ5hL9/w5wycVhtD6vdJFlv6kq+VfW99oqkRwIbdNguwD8C305yJHAm8N0kxwB/QfcJ6GuAx/ZebyHJ4qo6kMkd3rJaVd3aPl7SM+/+j9oLkU2sqvp6knsA3wbuTXPRsfOGHJYkaQJ50u4czDJl4tHzMWXisNoeRrtJXgxc0P6S0Fu+BfCuqnpNV2237awHvBh4CO3MRMBRVXVOx+2eVVXb9CyvS3PU9yzgyV1d6GyYkhwOfKOqDm5PYv14z7UevlBVfzLkEAcuyUe56y9VTwYuAC6CZnrWIYQlSZpgJvzSiEjyXeBNU9dbaMvWoBn28pKq6nRI0TC0X64OpPkF5Wqa8ftT13rYq6pOG2J4nUiy+/LWV9Uh8xWLJGlhMOEfgGFOHzisthdau/PR9rCvtzBMw7jWgyRJC4Vj+AdjmOOrh9X2Qmu387ar6rLlrJvYZB+gqm4AJu5o/vIk2ZFmNqotaT6LQzMP/wOHGZckafJ4hH8O2ikTp8azF3A5zXj2sye17YXW7rDb1sKR5Byak8R/DtxxBemqumZoQUmSJpLTcvYpyduBL9MchTsR+Fn7+EtJ9p7Ethdau8NuWwvOb6vqm1V1VVVdM3UbdlCSpMnjEf4+Jfkl8IiqumVa+ZrAmVW19aS1vdDaHXbbWliSHEBzbYev0lznAYAur9otSVqYHMPfv9uBTbn7FU83addNYtsLrd1ht62F5XHt/WPb+9AMIXvycMKRJE0qE/7+vRE4Lsl53HkRqi2AB9NcCXYS215o7Q67bS0sS2co8ydXSdLAOaRnDpKsBuzAXS9C9bOqum25O45x2wut3WG3rYUjyZt7Fu8JPAM4u6peNaSQJEkTyoRfkkZAkrVoZoN62rBjkSRNFmfpkaTRsDbNxcckSRoox/BL0hAkOYM7x+yvDiwC3j28iCRJk8ohPZI0BEm27Fm8Fbiyqm4dVjySpMllwi9JkiRNMMfwS5IkSRPMhF+SJEmaYCb8kiRJ0gQz4ZckSZImmAm/JEmSNMFM+CVJkqQJZsIvSZIkTTATfkmSJGmCmfBLkiRJE8yEX5IkSZpgJvySJEnSBDPhlyRJkiaYCb8kSZI0wUz4JUmSpAlmwi9JkiRNMBN+SZIkaYKZ8EuSJEkTzIRfkiRJmmAm/NIsklR7W9xxO69q29ljFeq4qK1jp8FF1q0ki6de4wHU9YUktyTZehCxSZI0SUz4F6AkOyb53yTXJPm/JL9K8tEkaw47tn4k2alNFC8aUH37tfV9btqqA9vb7wbRzixtrwHsB1wN/NcqVPVZmlgvG0BYM+p53SvJL5OkZ91netbt11UMy/HvwNRrKUmSeqwx7AA0v5LsBhwKrA6cBvwMWAz8HfAu4OahBTdgSVYDqKrbV2b/qnrjQAOa2TOABwAHVdVKv/ZV9e5VCSLJGlV16xx22RrYGfhOkvWA3Val/ZU1FXdV/TzJecDzkuxVVdcMIx5JkkaRR/gXkCRrAx+nSfYPBR5TVa+pqqcCDwNubLd7VJJjklydZFn7a8BDe+qZGj6yd5JTkvwhyTeSrN+zzeOTfLvd//dJjm/bJ8m2Sb6e5Kp2/ZFJtujZd+pI8evbI8k3JDk0yZrtkJXvtZtu2TskJMnSdvkDSU6g+fKyRZK3JDmvjfOmJKcleV67z37Avm19u7f7L50Wx+J2eVGSTye5JMnv2ue0S0/cn2u3/1T7mt2Y5PQk2y3nbXlGe//9nnpe0dZzWpJ/b1+/s5Jsn+Q9SX6b5IIkfznDe7LT1HudZP8k5yT5Y5LLkrxmWpz/meTYJDcDf57kHkn2aff5Q5Kzk/zj1BenHjcBfwReO/W6AWsD101/ckn+JsnP2vfw4iQfT3Lf2V6MJF9sY72p3ee7SR45w/N8R5Iz21imfB9YE3jqcl5vSZIWHBP+hWVHYIP28b/0Hvmuql9V1c1JNqFJnJ4GHA+cQpOULu1N6Fv/DJwO/B/wdOBNAEkeASylSbzOBr4CbAismeT+wA/adT8CTgCeA3wryVrT6t8f+AnNL1EvAV5GM2TlyHb9Ddw57KbXW4GrgC/RJIRbAWcAnwOOAh4BHNom8se3MdDGeiBwxPQXrk16jwb2oBl+cxTwWODrSXactvnfArcCFwKPBD46vb4ej+ppe7pHAo9r1z2c5ovO89qYt6IZxjOb/0fz/mxE8zqcDDxk2jZ7Aveg+fL3O+C9wPuAewNfpnnP/h14+7T9/o/mPX1Wks1ofh26APhh70ZJng58tX2OX6V5v/6+rXs2W9L8/X26jflJwGEzbLc/zXv61Z6yqddw++XUL0nSgmPCv7Bs1PP44lm2eRlwX2BpVT2jqv4SOBW4P/D8advuW1W7Ax9rl6cSrdcCawFHV9UTqmoP4KE0SeXLgPWB84FL2vtlNL8wPGla/X9XVa/gzoRv+6o6v6e9a6vqjTMMvTm0qp5ZVS+rqiuAtwH/A1wL/Lptby3gz6rqGOCYdr8T2/o+xt0tAR4P/B74i6p6WRvHasDrpm37jar6G+D1016XmUx9ibphhnV/AJ5C8wUGYD3guTRJP8BmSRZN3ynJhsCL28Wdq+pVVfUs4J+mbfqDqtqpql5F88Xu79vyF7fv2avb5TfMENsnab6IHUzzZeRTwPSTb6f2e1/7d7ITzRehpyWZ/uVjygtovtDcQPNlEuBhSTadtt37qmq3qur9m5w612L6F1NJkhY0x/AvLFf1PN4SOHeGbRa3971HnM8Btmv36XVKe399e79ue79Ve3/81IZVdRs0M7O0RQ9vb70e3Gf9K/LjqQdpTkQ+Hth2hu3uliwvx+L2/tKq+kP7+Jz2fkWvyzrLqXdqm3vPsO6iqvpjkut7ys6tqtty5/my69B8gek19frfXFVTsVBVt0zb7ic9jxf1xDn13k89v00y7YTuqjoxyck0v9TcRJP4T/+lY3FvfVV1dZKrab48bgmc17txmhl2Tmbm93kRcHnP8o9n2OY+7f31M6yTJGnB8gj/wvIT7hxn/c7esdlJtkxyD+CituhhPftNjd+f/qvA1Eme04/sXtjeP66n/tXSZKlT9X+1qjJ1AzYBPtNn/be197P9/faO696GJtm/jeZE09WAs6bC6rM+euJ+QNpzEZj76zKTqaPY07/89MZ1h6kvTisw9fqv2Xv+QJoZgXr1vk7LaH5RgDvf+6nnd8UsJxR/sr0/vKqunmH9Rb31JbkfzTAhmPkXpr+mSfbPoPmVaeOedZm27U3c3dRreMoM6yRJWrBM+BeQ9sj0G4DbgZcCJyc5KMnXgF/SHOE9FPgt8KQkRyc5hmZIypXMMLZ9Fp+iSch2bU+kPQg4k2ZIyhdojsA+J8m32hNHvwNcyl0TvOW5tL3fvD2JdvoY815Xt893dZrx6MfSJP4z1ff0NNOTPneGek6iGeu/LvDDJJ+neS0L+ESfcc/ka+39E1ehjrtok+8vtovHpZky86s0Y/Rn26e4M4H/YpJP04yjhzuHUE33BZoj/G+bZf3H2/t/SjPl6VKaXxWPrapfzrD9le391jTnUnx7tnhn8USaE7WPneN+kiRNNBP+BaaqvkAzVv4bwBY0M6w8nOYkzxur6vJ2/bdphmgsAb4OPKmqru2zjV/QjNf+Ds3R9ZfQfIm4ua3/iTSJ7nY0Xzw2o0kOZzpKPFP9FwEfauvcg+a8gNm2vYwmMb+ybffn3HUoC8DhwLdovvC8nrufSzA1teezaIaubAT8Dc2R5GdV1Y/6iXsW/0tzIvJzpg+bWUWvAd5D85q+BNiB5nyJ5XkHzdSsN9KcA3AtzfkDH5hp46r6Y1V9pz1PYqb1X6cZk38mzXkH6wH/CbxwlvYPo/mV5xaacxfev4J475DksTRfFI6Y5dcGSZIWrDQH9iQNS5JX0SS6r6mqT69oe91dkkNpvkhsU1XnrWh7SZIWEhN+SZIkaYI5pEeSJEmaYCb8kiRJ0gQz4ZckSZImmAm/JEmSNMFM+CVJkqQJZsIvSZIkTTATfkmSJGmC/X+ApvD5bsFHZwAAAABJRU5ErkJggg==\n", "text/plain": [ "<Figure size 864x720 with 4 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "from os.path import expanduser\n", "home = expanduser(\"~\")\n", "ax = df.hist(column='Concentration (microMolar)', by=\"Compound\", bins=25, grid=False, figsize=(12,10), color='#86bf91', zorder=2, rwidth=0.9)\n", "for y in ax:\n", " for x in y:\n", " # Set x-axis label\n", " x.set_xlabel(\"Concentration (microMolar)\", labelpad=20, weight='bold', size=12)\n", "\n", " # Set y-axis label\n", " x.set_ylabel(\"Number of Images\", labelpad=20, weight='bold', size=12)\n", "\n", "plt.savefig(home+'/figure.png')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create an OMERO.figure\n", "Create an OMERO.figure programmatically." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## URL to retrieve IDR data " ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "BASE_URL = \"https://idr.openmicroscopy.org/webclient\"\n", "IMAGE_DATA_URL = BASE_URL + \"/imgData/{id}\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Helper methods\n", "Methods used to generate the json file, see https://github.com/ome/omero-figure/blob/master/docs/figure_file_format.rst" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "code_folding": [ 0, 13, 33, 44 ] }, "outputs": [], "source": [ "def get_image_label(value):\n", " \"\"\"Display the mean as\"\"\"\n", " value = \"%s μM\" % \"{:.2f}\".format(value)\n", " labels = []\n", " labels.append({\n", " \"text\": value,\n", " \"size\": 18,\n", " \"position\": \"topleft\",\n", " \"color\": \"ff0000\"\n", " })\n", " return labels\n", "\n", "\n", "def get_column_label(mean, value):\n", " \"\"\"Display the mean as\"\"\"\n", " mean = \"mean concentration: %s μM\" % \"{:.2f}\".format(mean)\n", " labels = []\n", " labels.append({\n", " \"text\": compound.capitalize(),\n", " \"size\": 24,\n", " \"position\": \"top\",\n", " \"color\": \"000000\"\n", " })\n", " labels.append({\n", " \"text\": mean,\n", " \"size\": 12,\n", " \"position\": \"top\",\n", " \"color\": \"000000\"\n", " })\n", " \n", " return labels\n", "\n", "\n", "def get_scalebar_json():\n", " \"\"\"Return JSON to add a 10 micron scalebar to bottom-right.\"\"\"\n", " return {\"show\": True,\n", " \"length\": 0.5,\n", " \"units\": \"MILLIMETER\",\n", " \"position\": \"bottomright\",\n", " \"color\": \"FFFFFF\",\n", " \"show_label\": True,\n", " \"font_size\": 10}\n", "\n", "\n", "def get_panel_json(image, x, y, width, height):\n", " \"\"\"Get json for a figure panel.\"\"\"\n", " img_json = {\n", " \"imageId\": image['id'],\n", " \"y\": y,\n", " \"x\": x,\n", " \"width\": width,\n", " \"height\": height,\n", " \"orig_width\": image['size']['width'],\n", " \"orig_height\": image['size']['height'],\n", " \"sizeT\": image['size']['z'],\n", " \"sizeZ\": image['size']['t'],\n", " \"channels\": image['channels'],\n", " \"name\": image['meta']['imageName'],\n", " \"theT\": image['rdefs']['defaultT'],\n", " \"theZ\": image['rdefs']['defaultZ'],\n", " \"pixel_size_x\": image['pixel_size']['x'],\n", " \"pixel_size_y\": image['pixel_size']['y'],\n", " \"baseUrl\": BASE_URL,\n", " \"labels\": [],\n", " }\n", " return img_json" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "code_folding": [ 0, 22 ] }, "outputs": [], "source": [ "def create_column(term, panel_x, panel_y):\n", " df1 = df[df['Compound'].str.contains(term, na=False, case=False)]\n", " if len(df1.index) == 0:\n", " return\n", " count = 0\n", " total = 0\n", " max = float('-inf')\n", " min = float('inf')\n", " for row in df1.index:\n", " concentration = df1['Concentration (microMolar)'][row]\n", " if concentration != \"unknown\":\n", " count = count + 1\n", " c = float(concentration)\n", " total = total + c\n", " if c > max:\n", " max = c\n", " if c < min:\n", " min = c\n", " panel_y = get_images(max, panel_x, panel_y, df1, compound=term, mean=count/total)\n", " get_images(min, panel_x, panel_y, df1)\n", " \n", " \n", "def get_images(value, panel_x, panel_y, data, compound=None, mean=-1):\n", " s = str(value)\n", " df1 = data[data['Concentration (microMolar)'] == s]\n", " rows = 0\n", " for row in df1.index:\n", " image_id = df1['Image'][row]\n", " if rows < 2:\n", " qs = {'id': image_id}\n", " url = IMAGE_DATA_URL.format(**qs)\n", " image_data = session.get(url).json()\n", " j = get_panel_json(image_data, panel_x, panel_y,\n", " panel_width, panel_height)\n", " j['labels'].extend(get_image_label(value))\n", " if rows == 0 and compound is not None:\n", " j['labels'].extend(get_column_label(mean, compound))\n", " panels_json.append(j)\n", " panels_json[-1]['scalebar'] = get_scalebar_json()\n", " else:\n", " break\n", " rows = rows + 1\n", " panel_y += panel_height + spacing\n", " return panel_y " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create the figure " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "figure_json = {\"version\": 5}\n", "panel_width = 150\n", "panel_height = panel_width\n", "spacing = panel_width/5\n", "margin = 40\n", "\n", "panels_json = []\n", "panel_x = margin\n", "panel_y = 2*margin\n", "for compound in compounds:\n", " create_column(compound.lower(), panel_x, panel_y)\n", " panel_x += panel_width + spacing\n", " panel_y = 2*margin\n", "\n", "figure_json['panels'] = panels_json\n", "figure_json[\"figureName\"] = \"Compounds Concentration\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Save the figure as a json file\n", "You can then download the ``.json`` file, by clicking ``File > Open``, selecting it and cliking ``File > Download``. \n", "\n", "If you are running the notebook in [Google Colab](https://colab.research.google.com/notebooks/intro.ipynb#recent=true), click on the ``Files`` icon on the left-hand side. The files are saved under the ``root`` directory. \n", "\n", "Alternatively, you can copy the content of the ``json`` file directly from this notebook UI. In OMERO.figure use ``File>Import from JSON...``." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "code_folding": [] }, "outputs": [], "source": [ "with open(home+'/figure.json', 'w', encoding='utf-8') as f:\n", " json.dump(figure_json, f, ensure_ascii=False, indent=4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Generated OMERO.figure\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### License (BSD 2-Clause)\n", "\n", "Copyright (C) 2021 University of Dundee. All Rights Reserved.\n", "\n", "Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n", "\n", "Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ] } ], "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.7.10" } }, "nbformat": 4, "nbformat_minor": 4 }