{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Configurations for Colab" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import sys\n", "IN_COLAB = \"google.colab\" in sys.modules\n", "\n", "if IN_COLAB:\n", " !apt install python-opengl\n", " !apt install ffmpeg\n", " !apt install xvfb\n", " !pip install PyVirtualDisplay==3.0\n", " !pip install gymnasium==0.28.1\n", " from pyvirtualdisplay import Display\n", " \n", " # Start virtual display\n", " dis = Display(visible=0, size=(400, 400))\n", " dis.start()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 04. Dueling Network\n", "\n", "[Z. Wang et al., \"Dueling Network Architectures for Deep Reinforcement Learning.\" arXiv preprint arXiv:1511.06581, 2015.](https://arxiv.org/pdf/1511.06581.pdf)\n", "\n", "The proposed network architecture, which is named *dueling architecture*, explicitly separates the representation of state values and (state-dependent) action advantages. \n", "\n", "![fig1](https://user-images.githubusercontent.com/14961526/60322956-c2f0b600-99bb-11e9-9ed4-443bd14bc3b0.png)\n", "\n", "The dueling network automatically produces separate estimates of the state value function and advantage function, without any extra supervision. Intuitively, the dueling architecture can learn which states are (or are not) valuable, without having to learn the effect of each action for each state. This is particularly useful in states where its actions do not affect the environment in any relevant way. \n", "\n", "The dueling architecture represents both the value $V(s)$ and advantage $A(s, a)$ functions with a single deep model whose output combines the two to produce a state-action value $Q(s, a)$. Unlike in advantage updating, the representation and algorithm are decoupled by construction.\n", "\n", "$$A^\\pi (s, a) = Q^\\pi (s, a) - V^\\pi (s).$$\n", "\n", "The value function $V$ measures the how good it is to be in a particular state $s$. The $Q$ function, however, measures the the value of choosing a particular action when in this state. Now, using the definition of advantage, we might be tempted to construct the aggregating module as follows:\n", "\n", "$$Q(s, a; \\theta, \\alpha, \\beta) = V (s; \\theta, \\beta) + A(s, a; \\theta, \\alpha),$$\n", "\n", "where $\\theta$ denotes the parameters of the convolutional layers, while $\\alpha$ and $\\beta$ are the parameters of the two streams of fully-connected layers.\n", "\n", "Unfortunately, the above equation is unidentifiable in the sense that given $Q$ we cannot recover $V$ and $A$ uniquely; for example, there are uncountable pairs of $V$ and $A$ that make $Q$ values to zero. To address this issue of identifiability, we can force the advantage function estimator to have zero advantage at the chosen action. That is, we let the last module of the network implement the forward mapping.\n", "\n", "$$\n", "Q(s, a; \\theta, \\alpha, \\beta) = V (s; \\theta, \\beta) + \\big( A(s, a; \\theta, \\alpha) - \\max_{a' \\in |\\mathcal{A}|} A(s, a'; \\theta, \\alpha) \\big).\n", "$$\n", "\n", "This formula guarantees that we can recover the unique $V$ and $A$, but the optimization is not so stable because the advantages have to compensate any change to the optimal action’s advantage. Due to the reason, an alternative module that replaces the max operator with an average is proposed:\n", "\n", "$$\n", "Q(s, a; \\theta, \\alpha, \\beta) = V (s; \\theta, \\beta) + \\big( A(s, a; \\theta, \\alpha) - \\frac{1}{|\\mathcal{A}|} \\sum_{a'} A(s, a'; \\theta, \\alpha) \\big).\n", "$$\n", "\n", "Unlike the max advantage form, in this formula, the advantages only need to change as fast as the mean, so it increases the stability of optimization." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/jinwoo.park/miniforge3/envs/rainbow-is-all-you-need/lib/python3.8/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "import os\n", "from typing import Dict, List, Tuple\n", "\n", "import gymnasium as gym\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "import torch.optim as optim\n", "from IPython.display import clear_output\n", "from torch.nn.utils import clip_grad_norm_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Replay buffer\n", "\n", "Please see *01.dqn.ipynb* for detailed description." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "class ReplayBuffer:\n", " \"\"\"A simple numpy replay buffer.\"\"\"\n", "\n", " def __init__(self, obs_dim: int, size: int, batch_size: int = 32):\n", " self.obs_buf = np.zeros([size, obs_dim], dtype=np.float32)\n", " self.next_obs_buf = np.zeros([size, obs_dim], dtype=np.float32)\n", " self.acts_buf = np.zeros([size], dtype=np.float32)\n", " self.rews_buf = np.zeros([size], dtype=np.float32)\n", " self.done_buf = np.zeros(size, dtype=np.float32)\n", " self.max_size, self.batch_size = size, batch_size\n", " self.ptr, self.size, = 0, 0\n", "\n", " def store(\n", " self,\n", " obs: np.ndarray,\n", " act: np.ndarray, \n", " rew: float, \n", " next_obs: np.ndarray, \n", " done: bool,\n", " ):\n", " self.obs_buf[self.ptr] = obs\n", " self.next_obs_buf[self.ptr] = next_obs\n", " self.acts_buf[self.ptr] = act\n", " self.rews_buf[self.ptr] = rew\n", " self.done_buf[self.ptr] = done\n", " self.ptr = (self.ptr + 1) % self.max_size\n", " self.size = min(self.size + 1, self.max_size)\n", "\n", " def sample_batch(self) -> Dict[str, np.ndarray]:\n", " idxs = np.random.choice(self.size, size=self.batch_size, replace=False)\n", " return dict(obs=self.obs_buf[idxs],\n", " next_obs=self.next_obs_buf[idxs],\n", " acts=self.acts_buf[idxs],\n", " rews=self.rews_buf[idxs],\n", " done=self.done_buf[idxs])\n", "\n", " def __len__(self) -> int:\n", " return self.size" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dueling Network\n", "\n", "Carefully take a look at advantage and value layers separated from feature layer." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "class Network(nn.Module):\n", " def __init__(self, in_dim: int, out_dim: int):\n", " \"\"\"Initialization.\"\"\"\n", " super(Network, self).__init__()\n", "\n", " # set common feature layer\n", " self.feature_layer = nn.Sequential(\n", " nn.Linear(in_dim, 128), \n", " nn.ReLU(),\n", " )\n", " \n", " # set advantage layer\n", " self.advantage_layer = nn.Sequential(\n", " nn.Linear(128, 128),\n", " nn.ReLU(),\n", " nn.Linear(128, out_dim),\n", " )\n", "\n", " # set value layer\n", " self.value_layer = nn.Sequential(\n", " nn.Linear(128, 128),\n", " nn.ReLU(),\n", " nn.Linear(128, 1),\n", " )\n", "\n", " def forward(self, x: torch.Tensor) -> torch.Tensor:\n", " \"\"\"Forward method implementation.\"\"\"\n", " feature = self.feature_layer(x)\n", " \n", " value = self.value_layer(feature)\n", " advantage = self.advantage_layer(feature)\n", "\n", " q = value + advantage - advantage.mean(dim=-1, keepdim=True)\n", " \n", " return q" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## DQN + DuelingNet Agent (w/o Double-DQN & PER)\n", "\n", "Here is a summary of DQNAgent class.\n", "\n", "| Method | Note |\n", "| --- | --- |\n", "|select_action | select an action from the input state. |\n", "|step | take an action and return the response of the env. |\n", "|compute_dqn_loss | return dqn loss. |\n", "|update_model | update the model by gradient descent. |\n", "|target_hard_update| hard update from the local model to the target model.|\n", "|train | train the agent during num_frames. |\n", "|test | test the agent (1 episode). |\n", "|plot | plot the training progresses. |\n", "\n", "\n", "Aside from the dueling network architecture, the authors suggest to use Double-DQN and Prioritized Experience Replay as extra components for better performance. However, we don't implement them to simplify the tutorial. There is only one diffrence between DQNAgent here and the one from *01.dqn.ipynb* and that is the usage of clip_grad_norm_ to prevent gradient exploding." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "class DQNAgent:\n", " \"\"\"DQN Agent interacting with environment.\n", " \n", " Attribute:\n", " env (gym.Env): openAI Gym environment\n", " memory (ReplayBuffer): replay memory to store transitions\n", " batch_size (int): batch size for sampling\n", " epsilon (float): parameter for epsilon greedy policy\n", " epsilon_decay (float): step size to decrease epsilon\n", " max_epsilon (float): max value of epsilon\n", " min_epsilon (float): min value of epsilon\n", " target_update (int): period for target model's hard update\n", " gamma (float): discount factor\n", " dqn (Network): model to train and select actions\n", " dqn_target (Network): target model to update\n", " optimizer (torch.optim): optimizer for training dqn\n", " transition (list): transition information including\n", " state, action, reward, next_state, done\n", " \"\"\"\n", "\n", " def __init__(\n", " self, \n", " env: gym.Env,\n", " memory_size: int,\n", " batch_size: int,\n", " target_update: int,\n", " epsilon_decay: float,\n", " seed: int,\n", " max_epsilon: float = 1.0,\n", " min_epsilon: float = 0.1,\n", " gamma: float = 0.99,\n", " ):\n", " \"\"\"Initialization.\n", " \n", " Args:\n", " env (gym.Env): openAI Gym environment\n", " memory_size (int): length of memory\n", " batch_size (int): batch size for sampling\n", " target_update (int): period for target model's hard update\n", " epsilon_decay (float): step size to decrease epsilon\n", " lr (float): learning rate\n", " max_epsilon (float): max value of epsilon\n", " min_epsilon (float): min value of epsilon\n", " gamma (float): discount factor\n", " \"\"\"\n", " obs_dim = env.observation_space.shape[0]\n", " action_dim = env.action_space.n\n", " \n", " self.env = env\n", " self.memory = ReplayBuffer(obs_dim, memory_size, batch_size)\n", " self.batch_size = batch_size\n", " self.epsilon = max_epsilon\n", " self.epsilon_decay = epsilon_decay\n", " self.seed = seed\n", " self.max_epsilon = max_epsilon\n", " self.min_epsilon = min_epsilon\n", " self.target_update = target_update\n", " self.gamma = gamma\n", " \n", " # device: cpu / gpu\n", " self.device = torch.device(\n", " \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", " )\n", " print(self.device)\n", "\n", " # networks: dqn, dqn_target\n", " self.dqn = Network(obs_dim, action_dim).to(self.device)\n", " self.dqn_target = Network(obs_dim, action_dim).to(self.device)\n", " self.dqn_target.load_state_dict(self.dqn.state_dict())\n", " self.dqn_target.eval()\n", " \n", " # optimizer\n", " self.optimizer = optim.Adam(self.dqn.parameters())\n", "\n", " # transition to store in memory\n", " self.transition = list()\n", " \n", " # mode: train / test\n", " self.is_test = False\n", "\n", " def select_action(self, state: np.ndarray) -> np.ndarray:\n", " \"\"\"Select an action from the input state.\"\"\"\n", " # epsilon greedy policy\n", " if self.epsilon > np.random.random():\n", " selected_action = self.env.action_space.sample()\n", " else:\n", " selected_action = self.dqn(\n", " torch.FloatTensor(state).to(self.device)\n", " ).argmax()\n", " selected_action = selected_action.detach().cpu().numpy()\n", " \n", " if not self.is_test:\n", " self.transition = [state, selected_action]\n", " \n", " return selected_action\n", "\n", " def step(self, action: np.ndarray) -> Tuple[np.ndarray, np.float64, bool]:\n", " \"\"\"Take an action and return the response of the env.\"\"\"\n", " next_state, reward, terminated, truncated, _ = self.env.step(action)\n", " done = terminated or truncated\n", " \n", " if not self.is_test:\n", " self.transition += [reward, next_state, done]\n", " self.memory.store(*self.transition)\n", " \n", " return next_state, reward, done\n", "\n", " def update_model(self) -> torch.Tensor:\n", " \"\"\"Update the model by gradient descent.\"\"\"\n", " samples = self.memory.sample_batch()\n", "\n", " loss = self._compute_dqn_loss(samples)\n", "\n", " self.optimizer.zero_grad()\n", " loss.backward()\n", " # DuelingNet: we clip the gradients to have their norm less than or equal to 10.\n", " clip_grad_norm_(self.dqn.parameters(), 10.0)\n", " self.optimizer.step()\n", "\n", " return loss.item()\n", " \n", " def train(self, num_frames: int, plotting_interval: int = 200):\n", " \"\"\"Train the agent.\"\"\"\n", " self.is_test = False\n", " \n", " state, _ = self.env.reset(seed=self.seed)\n", " update_cnt = 0\n", " epsilons = []\n", " losses = []\n", " scores = []\n", " score = 0\n", "\n", " for frame_idx in range(1, num_frames + 1):\n", " action = self.select_action(state)\n", " next_state, reward, done = self.step(action)\n", "\n", " state = next_state\n", " score += reward\n", "\n", " # if episode ends\n", " if done:\n", " state, _ = self.env.reset(seed=self.seed)\n", " scores.append(score)\n", " score = 0\n", "\n", " # if training is ready\n", " if len(self.memory) >= self.batch_size:\n", " loss = self.update_model()\n", " losses.append(loss)\n", " update_cnt += 1\n", " \n", " # linearly decrease epsilon\n", " self.epsilon = max(\n", " self.min_epsilon, self.epsilon - (\n", " self.max_epsilon - self.min_epsilon\n", " ) * self.epsilon_decay\n", " )\n", " epsilons.append(self.epsilon)\n", " \n", " # if hard update is needed\n", " if update_cnt % self.target_update == 0:\n", " self._target_hard_update()\n", "\n", " # plotting\n", " if frame_idx % plotting_interval == 0:\n", " self._plot(frame_idx, scores, losses, epsilons)\n", " \n", " self.env.close()\n", " \n", " def test(self, video_folder: str) -> None:\n", " \"\"\"Test the agent.\"\"\"\n", " self.is_test = True\n", " \n", " # for recording a video\n", " naive_env = self.env\n", " self.env = gym.wrappers.RecordVideo(self.env, video_folder=video_folder)\n", " \n", " state, _ = self.env.reset(seed=self.seed)\n", " done = False\n", " score = 0\n", " \n", " while not done:\n", " action = self.select_action(state)\n", " next_state, reward, done = self.step(action)\n", "\n", " state = next_state\n", " score += reward\n", " \n", " print(\"score: \", score)\n", " self.env.close()\n", " \n", " # reset\n", " self.env = naive_env\n", "\n", " def _compute_dqn_loss(self, samples: Dict[str, np.ndarray]) -> torch.Tensor:\n", " \"\"\"Return dqn loss.\"\"\"\n", " device = self.device # for shortening the following lines\n", " state = torch.FloatTensor(samples[\"obs\"]).to(device)\n", " next_state = torch.FloatTensor(samples[\"next_obs\"]).to(device)\n", " action = torch.LongTensor(samples[\"acts\"].reshape(-1, 1)).to(device)\n", " reward = torch.FloatTensor(samples[\"rews\"].reshape(-1, 1)).to(device)\n", " done = torch.FloatTensor(samples[\"done\"].reshape(-1, 1)).to(device)\n", "\n", " # G_t = r + gamma * v(s_{t+1}) if state != Terminal\n", " # = r otherwise\n", " curr_q_value = self.dqn(state).gather(1, action)\n", " next_q_value = self.dqn_target(next_state).max(\n", " dim=1, keepdim=True\n", " )[0].detach()\n", " mask = 1 - done\n", " target = (reward + self.gamma * next_q_value * mask).to(self.device)\n", "\n", " # calculate dqn loss\n", " loss = F.smooth_l1_loss(curr_q_value, target)\n", "\n", " return loss\n", "\n", " def _target_hard_update(self):\n", " \"\"\"Hard update: target <- local.\"\"\"\n", " self.dqn_target.load_state_dict(self.dqn.state_dict())\n", " \n", " def _plot(\n", " self, \n", " frame_idx: int, \n", " scores: List[float], \n", " losses: List[float], \n", " epsilons: List[float],\n", " ):\n", " \"\"\"Plot the training progresses.\"\"\"\n", " clear_output(True)\n", " plt.figure(figsize=(20, 5))\n", " plt.subplot(131)\n", " plt.title('frame %s. score: %s' % (frame_idx, np.mean(scores[-10:])))\n", " plt.plot(scores)\n", " plt.subplot(132)\n", " plt.title('loss')\n", " plt.plot(losses)\n", " plt.subplot(133)\n", " plt.title('epsilons')\n", " plt.plot(epsilons)\n", " plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Environment\n", "\n", "You can see the [code](https://github.com/Farama-Foundation/Gymnasium/blob/main/gymnasium/envs/classic_control/cartpole.py) and [configurations](https://github.com/Farama-Foundation/Gymnasium/blob/main/gymnasium/envs/classic_control/cartpole.py#L91) of CartPole-v1 from Farama Gymnasium's repository." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# environment\n", "env = gym.make(\"CartPole-v1\", max_episode_steps=200, render_mode=\"rgb_array\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Set random seed" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "seed = 777\n", "\n", "def seed_torch(seed):\n", " torch.manual_seed(seed)\n", " if torch.backends.cudnn.enabled:\n", " torch.cuda.manual_seed(seed)\n", " torch.backends.cudnn.benchmark = False\n", " torch.backends.cudnn.deterministic = True\n", "\n", "np.random.seed(seed)\n", "seed_torch(seed)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Initialize" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cpu\n" ] } ], "source": [ "# parameters\n", "num_frames = 10000\n", "memory_size = 1000\n", "batch_size = 32\n", "target_update = 100\n", "epsilon_decay = 1 / 2000\n", "\n", "# train\n", "agent = DQNAgent(env, memory_size, batch_size, target_update, epsilon_decay, seed)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Train" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABIYAAAE/CAYAAAAzEsgaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAACSsUlEQVR4nO3dd3wkd3k/8M8zs7vqbXW6fj7JFexz5awDO4AJxaYTSAhOaAk/HBJIgOQXYiAh/CAQQk9CMaZDwMYYOxjcsI0LxvZV+7rvfEV30lWdet02z++PmVmtVrva3j/v1+teJ822766kmZ1nnyKqCiIiIiIiIiIiqj1GqRdARERERERERESlwcAQEREREREREVGNYmCIiIiIiIiIiKhGMTBERERERERERFSjGBgiIiIiIiIiIqpRDAwREREREREREdUoBoaqmIhcICJPi8iEiPxdqddDRERUzkSkT0ReUep1EBFR5RGRj4nId5yvu0VERcRT6nURpYOBoer2EQCPqGqLqv5XqRcTT0RuFpF9ImKJyLsTXP5hETkpImMi8j0RqYu5zC8id4rIlIgcEZE/i7vty0XkWRGZFpGHRWRtzGUiIv8hIkPOv8+LiBT0yRaJiPhE5Hbn5EZF5Jq4y/9RRHY5wcLDIvKPcZc/LCKDIjIuIttF5I2LPNa9IjIZ8y8oIjsL88yIiIiIiMqXqn5WVf9PqddBlA0GhqrbWgC7k10oImYR15LIdgB/A2Bb/AUici2AGwG8HEA3gLMB/L+Yq3wdQBDAMgB/DuCbInKRc9slAO4A8C8A/AC2APhZzG1vAPAmAJcCuATA6wD8Vd6eVQ7y9KnC4wDeDuBkoocA8E4AHQCuA/ABEXlbzOUfBLBCVVthv07/IyIrEj2Iqr5aVZvdfwCeAPDzPKyfiIiIiIiIioSBoSolIr8F8DIAX3OyOc4XkR+IyDdF5B4RmQLwMhF5rVNuNi4i/SLyyZj7cFMg/8K5bERE3iciV4rIDhEZFZGvxT3uX4rIXue698dm6sRT1a+r6kMAZhNc/C4A31XV3ao6AuDTAN7tPEYTgLcA+BdVnVTVxwHcBeAdzm3fDGC3qv5cVWcBfBLApSLyvJj7/pKqDqjqMQBfcu87jdf1XBF51MliOiMiP4u57CIReUBEhkXklIh8zNleJyJfFZHjzr+vutlPInKNiAyIyD+JyEkA3xcRQ0RuFJGDTkbTbSLiT2d9qhpU1a86r0kkweWfV9VtqhpW1X0Afgng6pjLd6hq2P0WgBfAmjRel24ALwbw43TWSURUzlLst5eIyK+dY+CwiPxORAznsn8SkWNOVuY+EXl5aZ8JERElIyIrReQXTrb8YXFab4jIJ50M/J85+/NtInJpzO0S7uud2/3PIo91l3PcOCAi74257JPO+/0fOfe5W0TWp3o8onxiYKhKqeofAvgdgA84GR37nYv+DMBnALTAziyZgp1B0g7gtQD+WkTeFHd3GwCcB+BPAXwVwMcBvALARQDeKiIvBQDndh+DHZjpch7/liyfwkWwM4pc2wEsE5FOAOcDiMQ8J/fyixLdVlWnABxMdnncbVP5NIDfwM64WQ3gvwFARFoAPAjgPgArAZwL4CHnNh8H8EIAl8HOUuoF8M8x97kcdmbTWthZOn8HO6Pppc59jcDOkILzWDskrnQuGyIisIM5u+O2/1pEZgFsBPAI7IyrVN4J4HeqejjXdRERlYHF9tv/AGAA9nFuGezjnorIBQA+AOBKVW0BcC2AvqKumoiI0uIE9H8F+zxgFewqhQ+JXbUAAG+EnQnvB/BTAP8rIt4c9vW3wD52rATwxwA+GxfgeQOAW2Gfk90F4GvOOnlsoaJgYKj2/FJVf6+qlqrOquojqrrT+X4H7J3WS+Nu82nnur+BHUi6RVVPO9k2vwNwuXO9vwLw76q618k6+SyAyxbLGlpEM4CxmO/dr1sSXOZe3pLktqkuHwPQ7ARKUgnBDuCsdF6Tx53trwNwUlW/5GyfUNWNzmV/DuBTzms2CLsk7h0x92kB+FdVDajqDOzX8eNORlMAdsbTH4tTZqaql6jqT9NYayqfhL0P+H7sRlV9HezX6jUA7ldVK437eieAH+RhTURE5WCx/XYIwAoAa1U1pKq/U1WFnaVZB+BCEfGqap+qHizJ6omIKJUrAXSp6qecjPtDAL4NwG2xsFVVb1fVEIAvA6iH/YFBxvt6EVkD4A8A/JNznvAMgO9g/vnA46p6j6pGYGfguxlKPLZQUTAwVHv6Y78RkQ0y13B4DMD7ACyJu82pmK9nEnzf7Hy9FsB/Oun1owCGYfe0WZXFOicBtMZ87349keAy9/KJJLdNdXkrgEnnjX0qH4H9nDY5aZ5/6WxfAzsrKZGVAI7EfH/E2eYadEreXGsB3BnzOu6FfVBYlsb60iIiH4AdzHmtE3yaxznZuRfAtSLyhhT39Qews55uz9f6iIhKbLH99hcAHADwGxE5JCI3AoCqHgDwIdhB99MicquIxO7riYiofKwFsNJ9v+285/4Y5t5vR8+ZnA9JB2B/MJzNvn4lgGFVnYjZdgTzz5Fie4NOA6gXEQ+PLVQsDAzVnvjgx09hpyuuUdU2ADfBDnxkox/AX6lqe8y/BlV9Iov72o25SDmcr0+p6hCA/QA8InJe3OW7E91W7J5E5yS7PO62i1LVk6r6XlVdCTuz5xsici7s535Okpsdh33wcZ3lbIvebdz1+wG8Ou51rHcytHLmBLNuBPByVR1IcXUPkj8v17sA3KGqk/lYHxFRGUi633YyQv9BVc8G8HoAf++WA6jqT1X1D5zbKoD/KO6yiYgoTf0ADse9325R1dc4l0d7bDplZ6sxdxzIdF9/HIDfaT3hOgtAWu/teWyhYmBgiFpgR7BnRaQXdg+ibN0E4KMyNx2sTUT+JNmVxR6tXg87EOUVkXq3gSeAHwF4j4hcKCIdsHs7/ACI9gy6A8CnRKRJRK6GXQfsNj6+E8A6EXmLc/+fALBDVZ+Nue+/F5FVTsT9H5BmGZSI/ImIrHa+HYG9c44A+DWA5SLyIbGblraIyAbnercA+GcR6RJ7YtonACRsTOe4CcBn3BI853ZJx8YnWGOd87wBwOe8ruJc9uewS/xe6aTMxt7ueSLyahFpcGqo3w7gJQAeXeSxGgD8CVhGRkTVJel+W0ReJ/YgAgEwDvsYEBGRC0TkD8VuUj0LO6N2wRAAIiIqC5sAjDuNnRtExBSRdSJypXP5C0TkzU4rhw8BCAB4Kpt9var2w57e++/O+/JLALwHwE9SLZLHFioWBobob2AHWCZgv/G9Lds7UtU7YUewbxWRcQC7ALx6kZv8BvbO7SoANztfv8S5r/sAfB7Aw7BTLY8A+Ne4dTcAOA37Dfxfq+pu57aDsKeWfQZ28GYD5uqFAeBbsJvN7XTWeLezDQDglIj9eZI1Xwlgo4hMws60+qCqHnZSQ18J+9PjkwCegz0VDgD+DXYD5x3OY25ztiXzn859/8b5uTzlPId01gcA+2C/lqsA3O987X7y/W8AOgFsFnta3aSI3OTeNZw0VQCDsEfX/6mqbnMe98XO8471Jtg9mh5eZD1ERJVmsf32ebCHDUwCeBLAN1T1Edg9ID4H4Azs48BS2GUJRERUZpxePq+HPWTgMOx993cAtDlX+SXswTsjsHsBvdnpN5Ttvv56AN2ws4fuhN1f9IE0bsdjCxWFpNdWhYiIiIiIiKi6icgnAZyrqm8v9VqIioUZQ0RERERERERENYqBISIiIiIiIiKiGsVSMiIiIiIiIiKiGsWMISIiIiIiIiKiGsXAEBERERERERFRjfKUegEAsGTJEu3u7i71MoiIytLWrVvPqGpXqddRSjxOEBElxmOEjccJIqLE0jlOlEVgqLu7G1u2bCn1MoiIypKIHCn1GkqNxwkiosR4jLDxOEFElFg6xwmWkhERERERERER1SgGhoiIiIiIiIiIahQDQ0RERERERERENYqBISIiKjoRuUBEnon5Ny4iHyr1uoiIiIiIak1ZNJ8mIqLaoqr7AFwGACJiAjgG4M5SromIiIiIqBYxY4iIiErt5QAOqion6xARERERFRkDQ0REVGpvA3BLqRdBRESFJyLfE5HTIrIryeUiIv8lIgdEZIeIXFHsNRIR1ZqUgSERWSMiD4vIXhHZLSIfdLb7ReQBEXnO+b8j5jYfdXbm+0Tk2kI+ASIiqlwi4gPwBgA/T3DZDSKyRUS2DA4OFn9xRERUCD8AcN0il78awHnOvxsAfLMIayIiqmnpZAyFAfyDqj4fwAsBvF9ELgRwI4CHVPU8AA8538O57G0ALoK90/+G0z+CiIgo3qsBbFPVU/EXqOrNqrpeVdd3dXWVYGlERJRvqvoYgOFFrvJGAD9S21MA2kVkRXFWR0RUm1I2n1bVEwBOOF9PiMheAKtg77Svca72QwCPAPgnZ/utqhoAcFhEDgDoBfBkvhdPte3Jg0O4/Kx21Hvnxx2nAmHcu+skQhGrKOs4d2kzruz2p319VcW9u05ibCaUtzWYhuDai5ajrcE7b/tsKIJ7dp5AIJz4tbhwRSsuXdOelzWMTYdw/+6TiKjm5f5SuXR1Oy5c2VqUx6KCuh4sIyOiGrLn+DiWtPiwtKW+1EspV6sA9Md8P+BsO1GIB3ts/yBmQhFce9HyQtw9EVFFyGgqmYh0A7gcwEYAy5ygEVT1hIgsda62CsBTMTdzd+bx93UD7PRQnHXWWRkvnGrbmckArv/2U/iPt1yMP71y/u/Pr7Yfx4137CzaWhp9Jnb866vgMdNr2bXz2Bj+5ifb8r6Oydkw/vIPeuZte2Tfafz9bduT3ubsrib89h+uyfmxLUvx3h9vwabDi30AmF8XrWzF3X/34qI9HuWfiDQCeCWAvyr1WoiIiuU1//U7NPpM7PnUYtVUNU0SbEv4qVM+zie+/btDGJwIMDBERDUt7cCQiDQD+AWAD6nquEiifbZ91QTbFuzMVfVmADcDwPr164uTYkBVY2I2DAA4MxlccNnQlL3tsX98GXyewvZXv3/3SfzrXbtx6MwUzl/WktZtdgyMAQB++f6rsaw1908Lg2ELL/nCw5gNRxZcNhOyt/38fS/Cmo7GeZd9+u49ePrISM6PDwC3bD6KTYeH8f/ecFFR3lh9/r5n8dhz7DlT6VR1GkBnqddBRFRs08GFx2yKGgCwJub71QCOJ7piPs4nerv9+PKD+zE6HUR7oy+buyAiqnhpBYZExAs7KPQTVb3D2XxKRFY42UIrAJx2tqe9MyfKVsAJgiQqxxqbCaHOY+CszsYFl+XbVefY57Q7B8bSDgztOjaG9kYvLlndhkUCrGlzS+Ysa+H7IbeabnlrPZa3zQ9CtdR5EE5wm0ydHJvF5+55Fled04l3vmhtXp5TKqv9jRiaCiIcsdLO1CIiIqKKcBeAD4jIrQA2ABhzqxQKobfHD1VgS98IXnHhskI9DBFRWUtnKpkA+C6Avar65ZiL7gLwLufrdwH4Zcz2t4lInYj0wJ4osCl/SyYCZkN2xGNsOkFgaDq0oNdOoZzd1YwGr4mdx8bSvs3OY2O4eFV+gkIAYDr3kyjIE7Hs18k0Fj6WYQgiOQaGVBX//L+7ELIs/PubLy5KUAgAulrqoAoMTy3MGCMiIqLyJSK3wO49eoGIDIjIe0TkfSLyPucq9wA4BOAAgG8D+JtCrufSNe3wmQY29RWvHJ6IqNykkzF0NYB3ANgpIs842z4G4HMAbhOR9wA4CuBPAEBVd4vIbQD2wJ5o9n5VZb4s5dVsaPGMoWIFhkxDcOHKVuxKMzAUCEew/9QE3vMHZ+dtDYYhMAQJgzxusMiTIDDkMSTnRtF37zyBB/eewsdf83ys7WzK6b4y0dVsp3oPTgawNA/leERERFQcqnp9issVwPuLtBzUe01ctqYdG4vYJ5GIqNykM5XscSTuGwQAL09ym88A+EwO6yJalDtlK1lgqLVIgSEAuHhVG27b0o+IpQkzc2LtPzmJUERx8aq2vK7BTJL945aXGQnWZRqCSCS3wNB/P3QAF65oxV9c3Z3T/WSqq6UOADA4ESjq4xIREVH16e3x45uPHsRUIIymuoxm8xARVQU256CKVC4ZQwCwblUbpoMRHD4zmfK6bslZsQJDqTKGcu0xND4bwrpVrUXv87Ok2Q4MJWo+TkRERJSJ3h4/IpZi29H8DOUgIqo0DAxRRUqVMVTMwJAb5Emnz9DOY2Norfdgjb8hr2swJXGQJ7JoxpCRc4+hsKUwjeLvRtzAEDOGiIiIKFdXrO2AaQg2sZyMiGoUA0NUkdyMofEEgaHx2eIGhs7pakK918DOgfGU1911bAzr8th42pUsYyiySMaQaSDnHkMRSxPed6E11XnQ5DNxZpKBISIiIspNc50H61a1YeMhBoaIqDYxMEQVyc0YmgiE5wVEIpZiYjZc1B5DHtPA81e0YtfxxTOGgmEL+05O5L2MzF3DYqVkiXofuRlDmkNwKJ2+SoWypKWOGUNERESUFxt6/HimfzT64SMRUS1hYIgqUiDmoB2bNTQxa39dzIwhwC4n23N8PNrsOZH9pyYQjFhYV4DAkCGJJ4y56zETZCi5mT65lJOVMjDU1czAEBEREeVHb7cfwYiF7f2jpV4KEVHRMTBEFSn205zx2bnAkNtzqNiBoXUr2zAZCOPw0FTS67gj7QsRGPIkmTC2eMaQzLtONsKWVZJSMsDuM8RSMiIiIsqHK7v9EAH7DBFRTWJgiCqSW0oGzG9AXbLAkBPs2bVIA+qdx8bQUufBWn9j3h/fTDJhLGIpDEHCnkZuYMiq0FKyrpY6DDIwRERERHnQ1ujFBctasKmPgSEiqj0MDFFFis0YKofA0HnLmuHzGIsGhnYdH8dFq1oTTgjLlWlIwgBPRBWeJFPDPHnIGCp1YGh0OoRgTJCQiIiIKFsbevzYemQEoQjfWxBRbWFgiCpSuWUMeZ0G1MlG1ociFvaeGC9I42nADvIkyxhKFrhxtycqQUuHZSksTVymVgzuyPqhKWYNERERUe56ezoxHYxg9/HUk2aJiKoJA0NUkWZDEbjxiHIIDAHAupWt2H0scQPq505NIhguTONpADAMSfi4iwWGcs0Ycptdl6rHUFeLHRg6MxEsyeMTERFRdbmypwMAsOnwUIlXQkRUXAwMUUUKhK1oYKBcAkMXr2rDRCCMI8PTCy4rZONpwM0YWpj2vFhgyMixx1Ak2ti6NLuRJc0+AMDg5GxJHp+IiIiqy9KWepy9pIkNqImo5jAwRBVpNhRBW4MXPtNYEBjymQbqvcX/1V7fbX/K9OCeUwsue3DvKfibfOjpbCrIYxsiCcfOhy2rcBlD0cBQVjfPmRsY5Mh6IiIiypfeHj82HR5OmIlNRFStGBiiihQIW6j3mmht8GI8JjA0PhNCa4M34RSuQjt3aQt6u/340VN984I0/cPTeHDvKVzfu6YgjacBwGMmDgxFrOQ9gNxMn2x7DIVLnjHklJJNspSMiIiI8qO3x4/x2TD2nZoo9VKIiIqGgSGqSLOhCOo9JtoaPPMyhsZnwmhr8JRsXe++uhv9wzP47bOno9t+/NQRiAje/sK1BXvc5OPqraQ9gOYyhrKbvOEGokrVY6jea6Kl3sOMISIiIsqbDWd3AgA2HmKfISKqHQwMUUWaDVmo8xpoa/AuKCVrLUF/IderLlyGFW31+METhwEA08Ewbt10FNetW44VbQ0Fe1xTkoyrt+wys4S3caeSZZkq7QaUSjWVDLDLyQYnGRgiIqLC+uUzx3D4zFSpl0FFsKq9AavaG7Cpj32GiKh2MDBEFSkQtlDnMRMGhkrReNrlMQ2840Vr8fsDQ9h/agJ3Pn0M47Nh/MVV3QV9XNMQhBOUhEUsCx4zRWAoy+bTbqJRKQNDS5rrmDFEREQF98Fbn8G1X3ms1MugItng9BnSLN8jERFVGgaGqCIFQhHUJ8kYKmVgCACuv/Is1HkMfP/3ffjB7/tw8ao2vGBtR0Ef0zSSNZ9WmCkyhhIFlNJRLhlDZ5gxRERERRCMZFd6TZWnt8ePM5NBHGKWGBHVCAaGqCLNyxiaLq/AUEeTD390+Sr8bPNRPHd6Eu++qrvgzbBNQxJm/liafFy9J8dSslL3GAKALmYMERERUZ719vgBgGPriahmMDBEFWnWyRhqbfBiIhCGZSksSzE+W/rAEAC866puWAosafbhdZeuKPjjeZJlDEWSB4bMHMfVz00lK23G0MRsGLOhSMnWQERERNWlZ0kTljTXMTBERDWjdOObiHIQmzGkCkzMhgEBVFEWgaHnr2jFX17dg+ctb0Gdxyz44yXrMbRYxpC7PVHT6nRYZRAYWtLsAwCcmQxgdUdjydZBRERE1UNEon2GiIhqATOGqCLFZgwBwPhsCONOr6FSTiWL9YnXX4i3XrmmKI9lGomnkoUtTVrqlXuPoTIoJWupAwCWkxEREVFe9fb4cWx0BgMj06VeChFRwTEwRBUnHLEQthT1XjOaHTQ2E4o2oS6HjKFi8xhGwpKwiKUwkvYYMqLXyUYkmjFUut1IV3M9AODMZLBkayAiIqLqwz5DRFRLGBiiihMI21NB6jwGA0MOw5BoaVesSDoZQ1Z2U1bKIWNoSYtdSsaMISIiIsqnC5a1oLXew8AQEdWElIEhEfmeiJwWkV0x234mIs84//pE5Blne7eIzMRcdlMB1041ym00HJ8xNF7DgSGPIQkzhsJW6qlk2fYYcjOGkmUkFUNnE0vJKpmItIvI7SLyrIjsFZEXlXpNREREgP3+ppd9hoioRqTTfPoHAL4G4EfuBlX9U/drEfkSgLGY6x9U1cvytD6iBZJlDLnhiVoMDBmSeCqZZSm83sTx31x7DJXDuHqfx0B7oxdnJhkYqlD/CeA+Vf1jEfEBYAdxIiIqGxt6OvHg3tM4PT6Lpa31pV4OEVHBpMwYUtXHACQMlYuIAHgrgFvyvC6ipJJlDNVyKVnScfWWJu0B5AaGsu0x5JaglXIqGQB0NdcxY6gCiUgrgJcA+C4AqGpQVUdLuigiIqIY0T5DfcwaIqLqlmuPoRcDOKWqz8Vs6xGRp0XkURF5cY73T7RAbMZQo8+Ex5BoYMhjCBp9hR8PX25MM3EpWcRSmEniNp5oj6HKzRgC7MlkzBiqSGcDGATwfeeY8R0RaSr1ooiIiFwXrWxFo89kORkRVb1cA0PXY3620AkAZ6nq5QD+HsBPnU+FFxCRG0Rki4hsGRwczHEZVEtiM4ZEBG0N3mhgqK3BCzuRrbaYknhcfaSAGUPl0GMIAJY012GQgaFK5AFwBYBvOseMKQA3xl6BxwkiIiolj2ngBWs7GBgioqqXdWBIRDwA3gzgZ+42VQ2o6pDz9VYABwGcn+j2qnqzqq5X1fVdXV3ZLoNq0GzIyRhyeufEB4ZqkWkIwpGF08XSmUqWa2CoLDKGWEpWiQYADKjqRuf722EHiqJ4nCAiolLb0OPHsycnMDodLPVSiIgKJpeMoVcAeFZVB9wNItIlIqbz9dkAzgNwKLclEs0XCNsZQ3Ueu2SstcGLcScw1FLDgaFEAZ6IJp9KlnuPIZ13P6WypLkOU8EIpgLhkq6DMqOqJwH0i8gFzqaXA9hTwiUREREt0NvTCQDY3DdS4pUQERVOOuPqbwHwJIALRGRARN7jXPQ2LGw6/RIAO0RkO+xPf9+nqsy9pLxyM4bq4zKGxms4Y8hjCCJJS8mSjau3X79cewyVPjDkAwD2GapMfwvgJyKyA8BlAD5b2uUQERHNd8nqNvg8BjYdHir1UoiICibluHpVvT7J9ncn2PYLAL/IfVlEySXKGOobmoIAOKuzNnvXJssYCltWGhlDC0vQ0lEupWQt9fZubCoQKek6KHOq+gyA9aVeBxERUTL1XhOXrWlnnyEiqmq5Np8mKrrAgowhT0yPoZSxzqqULDBkWckzevLVYyhZc+tiqfPaAcLZMANDRERElH8bevzYdXwckyxbJ6IqxcAQVZz4jKE2p8fQ+Gy4ZkvJTENgKWDFBXnClpWy+XS2pWThMskYqnd+D9yAIREREVE+9fb4EbEU246wzxARVScGhqjiJOoxZKmdwVKzgSFxsn/i+gxFrOTj5D05ZwzZP4dSj6t3fw+YMURERESFcMVZHTANYTkZEVUtBoao4syG7ABAvXcuY8hVs4EhM3GQJ1LAjKGIk6BT6oyhumjGEANDRERElH9NdR5cvKoNG9mAmoiqFANDVHECYQuGzAUkGBhKnv0TthSGLJ4xFF9+li43Y6jUU8miGUMsJSMiIqIC2dDjx/b+segHlERE1YSBIao4s6EI6r0mxAl4tMYEg1prNDBkJCklsyyt/h5DbvNpvlEjIiKiAunt8SMYsfBM/2ipl0JElHcMDFHFCYQt1HnmfnWZMRSTMRRZmDHklpnFExEYkvtUstL3GHJKycLMGCIiIqLCWL/WDxGwzxARVSUGhqjiuBlDLgaGkmf/WKrRxtSJeAwjhx5D5ZIx5JaSMWOIiIiICqOt0YvnLW9lYIiIqhIDQ1RxmDG0kGnYr4elCzOGFgvcmIZEewVlyg0olbrHkNt8mj2GiIiIqJA29Pix9cgIQhG+5yCi6sLAEFWc+Iyh5joPTENgGoLmOk8JV1Y6ngQZQ5alUJ0LGiViB4aye8y5jKHS7kZMQ+A1hePqiYiIqKB6e/yYCUWw69hYqZdCRJRXDAxRxZkNW6iLCQyJCFrrPWit90QbUtcaI0GPIbcRtbnIX3k+MoZKnDAEAKj3mCwlIyIiooK6stsPgH2GiKj6MDBEFScQiswrJQPsErJaLSMDYppPx5SSRaKlXsn/zD2GZN1jyLIUpiFlEYyr85psPk1EREQF1dVSh7O7mhgYIqKqw8AQVZzZsDWvlAxgYMjt8xOb/TMXGFr8dtlOJQs7gaFyUO81mDFEREREBbehx49NfcNZv38iIipHDAxRxUmUMfSmy1fhjZetKtGKSm8uMDS3LZxmxlD24+qtkk8kc9V5DATYfJqIiKgiiMh1IrJPRA6IyI0JLm8TkV+JyHYR2S0if1GKdSbS2+PHxGwY+05OlHopRER5U5udeqmiBRJkDP3F1T0lWk15mBtXvzBjaLHgjZFrxlAZlJEBQL2XPYaIiIgqgYiYAL4O4JUABgBsFpG7VHVPzNXeD2CPqr5eRLoA7BORn6hqsARLnmdDTycAYOPhIVy4srXEqyEiyg9mDFHFSZQxVOvcAE1skMf92lgkMJRzjyGzjAJDnEpGRERUCXoBHFDVQ06g51YAb4y7jgJoEbuRYTOAYQDh4i4zsZXtDVjd0cA+Q0RUVXh2TRXH7jHEX91YboAmUWBosYyhXHsMlUspWb2XpWREREQVYhWA/pjvB5xtsb4G4PkAjgPYCeCDqlo2B/reHj82HR6GKvsMEVF14Nk1VZxAKIJ6j5n6ijUkOpUsJsjjlpUtVu7lMYwcegyVT/PpOg8zhoiIiCpEojcP8W9GrgXwDICVAC4D8DURWVC3JSI3iMgWEdkyODiY73UmtaHHj6GpIA4OThXtMYmIComBIao4s2ELdcwYmidRKZnbbmix4I2RQylZefUYMjDLjCEiIqJKMABgTcz3q2FnBsX6CwB3qO0AgMMAnhd/R6p6s6quV9X1XV1dBVtwvF6nzxDLyYioWvDsmipKKGIhYikzhuKYi2QMeRbpA2RPJcsuoFJWPYY8bD5NRERUITYDOE9EekTEB+BtAO6Ku85RAC8HABFZBuACAIeKuspFdHc2oqulDpsOD5V6KUREecGpZFRRAmE7iMGMofnmppLFZAw5de/GIlk9Zo4ZQx6jPH4OdV4z+rtBRERE5UtVwyLyAQD3AzABfE9Vd4vI+5zLbwLwaQA/EJGdsEvP/klVz5Rs0XFEBL09fmx0+gxJmWRQExFli4EhqihuVkj8uPpaF80Y0tiModTNpz05NJ8upx5DdikZM4aIiIgqgareA+CeuG03xXx9HMCrir2uTGzo8ePuHScwMDKDNf7GUi+HiCgn5fFxP1GaohlDHFc/j5u5E4nEBIYiqcfV5zaVzCqbHkN1HpNTyYiIiKhoenv8ANhniIiqA8+uqaIwYygxt6IrNmPILSUr1Lj6iLV4Y+tiqvcaCDr9p4iIiIgK7fylLWhr8DIwRERVIWVgSES+JyKnRWRXzLZPisgxEXnG+feamMs+KiIHRGSfiFxbqIVTbXKzQpgxNF80Y8haWEq2WPAmlx5DEctatLF1MbmBwgBH1hMREVERGIbgym4/NvUxMERElS+ds+sfALguwfavqOplzr97AEBELoQ9WeAi5zbfEBGmdlDezDon/nXMGJrHdP6S5zWfTiMwlEuPoXA59RhyAoUsJyMiIqJi2dDjx+EzUzg9PlvqpRAR5SRlYEhVHwOQbij8jQBuVdWAqh4GcABAbw7rI5onWkrGcfXzmE7GkJVxxpCRW/PpMukx5GYMzTJjiIiIiIpkw9l2n6GNLCcjogqXSz3OB0Rkh1Nq1uFsWwWgP+Y6A862BUTkBhHZIiJbBgcHc1gG1RKOq0/Mk2BcvRvwWSx4Yxqoiqlk7u/DLDOGKoqI9InITqckeUup10NERJSJC1e0oslnss8QEVW8bM+uvwngHACXATgB4EvO9kRniQnPOlX1ZlVdr6rru7q6slwG1ZoAM4YSciePRay5wIgb8FmsD5DHMBC2sgumRCwtnx5Dzu8DR9ZXpJc5JcnrS70QIiKiTHhMAy/o9jMwREQVL6vAkKqeUtWIqloAvo25crEBAGtirroawPHclkg0hxlDiXmigaG5bdGMISP5a5XbuHpd9L6LKVpKxsAQERERFdGGHj/2nZrAyFSw1EshIspaVmd1IrIi5ts/AuBOLLsLwNtEpE5EegCcB2BTbkskmsNx9YkZkjxjaLFSMo8h80bcZ8LuMZTVTfPODRS6gUOqGArgNyKyVURuiL+QJcdERFTuenvsPkObOZ2MiCqYJ9UVROQWANcAWCIiAwD+FcA1InIZ7Df1fQD+CgBUdbeI3AZgD4AwgPerKj/Cp7yJZgxxXP08cxlDmTWfNgxBJJJLj6Hy+DkwY6hiXa2qx0VkKYAHRORZZ+ABALvkGMDNALB+/frsflGJiIgK6JLVbfB5DGw6PIxXXbS81MshIspKysCQql6fYPN3F7n+ZwB8JpdFESXDjKHETHOR5tMpxtWHc2g+7SmX5tMeNp+uRKp63Pn/tIjcCbss+bHFb0VERFQ+6jwmLl/Tjk3MGCKiClYeH/cTpck98a9nxtA8pizMGHJLxBYfV59LjyErGpAqNTdQGOC4+oohIk0i0uJ+DeBVmCtLJiIiqhgbevzYdWwMk4FwqZdCRJQVnl1TRQmEIzANgcfkr24sN/gT2y/I7Te0WFZP7j2GyiswxFKyirIMwOMish12L7q7VfW+Eq+JiIgoY709nbAU2HpkpNRLISLKSspSMqJyMhuymC2UQLTHUCQ2MGT/v3jGkJF9jyEtn1Iy93ci2+bTU4EwRmdCWNXekM9l0SJU9RCAS0u9DiIiolxdsbYdHkOw8dAQXnp+V6mXQ0SUMZ5hU0UJhCOoY3+hBRbLGFo8MITsewxFdNH7LqZcM4a+/MB+XPeVxzDMUbNERFQkn/71nlIvgfKk0efBulVt2HSYfYaIqDIxMEQVhRlDiYkIDMl8KplpGDn0GFJ4yqTHUK7Np/efmsBEIIxvPXown8siIiKaR2M+wPnu44dLuBLKtw1n+7F9YJRl7URUkXiGTRUlELaYMZSEGTdhzEp7Kll2wZSIpTDKpMeQxzTgMSTrN2NHh6cBAD98sg+nx2dzXs9zpybwlQf2zzsBICIiOnxmqtRLoALZ0ONHKKJ4+uhoqZdCRJQxBoaoosyGItHsEJrPNCQaDALmMoYW6wNkGgJLkVUAo5x6DAF2OVk2GUPhiIVjIzN43SUrEIoovvFI7llDX3lwP/7zoecwFeSnhkREZLMszbp8m8rfC9b6IQKWkxFRRWLzaaoos6FItJ8MzecxjHlvON0SMSNFYMi9bqZlYXaPofIJ0tV7jazG1R8fnUXYUrzkvC4013nw041H8d6XnJ11I+rR6SAe3HMaABAKW0BdVndDRERV5k3f+D12DIyVehlUIG0NXjx/eSs29Q0BOK/UyyEiykj5nNURpSEQtpgxlER8j6FImhlDQHYNqMupxxAA1Hmyyxg6Mmyn9Z/V2Yi/fbn9Ru5rv30u63X8escJBJ2RcKFIdmV6RERUfZIFhfadnMCOgdHiLoYKorfHj61HRhDMckoqEVGp8AybKkqAGUNJeUwjYfPpxfoAeWIyhjJVTj2GAKDOa2A2i4yhI0N2f6G1nY1Y1d6AP9twFm7bMoB+p+9Qpu7YNhD9OsjAEBFRTbEsxZnJQEa3ufarj+ENX/t9gVZExbShx4/ZkIVdx5kZRkSVhYEhqijMGErOkMTNp9PJGIpUQ48hj4lAFs2n+4en4fMYWNZSDwB4zx/0IGIpHtx7KuP7OnxmCtuOjuJ5y1sAAKEIe0kQEdWS/3zoOaz/twdxciz3QQZUea7s8QNgnyEiqjw8w6aKwh5DyXmSNJ9ONZUMsPsFZUJVEbF00fsutnqvkV0p2dA01nQ0RHsxrfE3Ym1nI544OLTguuGIhfHZUNL7umPbAAwB3rp+DQCWkhER1ZrfPmv3mDs+NlPilVApLGmuwzldTQwMEVHFYWCIKgozhpJbMK5eFYYAski5V7Y9htLpX1Rs9V4zq+bTR4ansbazad62q87pxFOHhhaU2H3t4QO45guPYDZBZpJlKe7YdgxXn7sEqzvsxtXsMUBEVFt2HrNLiL76YPa96qiy9fZ0YnPfcFZl+kREpcIzbKoozBhKzjQEEWsuEBG2FJ4UU8PcqWKZvnkJpzHxrNiyGVevqjg6NIWz/I3ztr/onCWYmA1jd0yPAFXF/z59DMNTQWzuW/hJ4Ka+YRwbncFbrlgNrxO8ZI8hIqLadPD0ZKmXQCWyocePidkw9p4YL/VSiIjSxsAQVZTZkIV6L39tE/EYgtiKsIilSDVN3pNljyFLyy9jqM5jJMzkWczwVBBTwcjCwNDZnQAwr5zs2ZMT6HMaVT+yb3DBfd2xbQBNPhOvumgZfKb9woeYMUREFejk2OyiZbM038RsCAcHGQgiWy/7DBFRBeIZNlUMVUUgHEGdhxlDiRhxGUORtDKGsusxlE7/omKr95oZTyU7Mjw3kSxWV0sdzl/WPC8wdN+ukxABLl7Vhof3nZ53/ZlgBPfsPIlXX7wCjT4PvG5giM2niagCvfDfH8Irv/xoqZdRMd76rafw8i/x9SLbyvYGrPE3MDBERBWFgSGqGKGIwlIwYygJjyHzSsLSaQ4912Mos8wWN5BUThlD2TSfPjqUODAEAFedswSbDw9H+wTdt+skruz2448uX4VDg1PR2wLAb/acxGQgjLdcsRoA4IuWkmXe84iIqBycGs9s5HotS1QypFlM+6Tq0dvdiU19w/w9IKKKwTNsqhhuY2FmDCVm5hAYyrbHUDllDNUlGFf/7ccO4RVffhT//dBzOJFgQswRJ7izumNhYOhF53RiJhTB9oFRHBqcxL5TE7juouV42fOWAgAe2T+XNfSLbcewqr0BG5z0ca9pvy7BMN8QEhHVotEZluLVsg09fgxPBVliSEQVg4EhqhhuNggzhhKLn0oWTiMw5MlyKpnbY8hM1cSoiOxSsvkZQxsPD+HI0BS+9MB+XP253+K9P9qCyUA4evnR4Wksb61P2ND8hT2dEAGeODCE+3afBABct245epY0YW1nY7TP0KnxWTz+3CDefMWqaDPuaI8hNp8mIqpKD+w5hSdjyo3jcSJVbXP7DG1kORkRVYjyOaujqrfpcG4ptcwYWtzCjCEL5iKj6t3b2NfNLmOonErJ6jwGgmELVsxzGZkO4cpuPx79x2vw3pecjQf2nMKd2wailx8dnsJZCcrIAKCt0Yt1K9vwxMEzuH/XSVy6ug0r2+0x9Nec34UnDp7BbCiC/336GCwF/ujyVdHbehkYIiKqau/90RZc/+2nkl4eCFv4wE+3FXFFVE7WdjZiaUsd+wwRUcVgYIiKYs/xcbz1W0/m9MmJmzFUx4yhhEyJDwylLvXKNjDk9hgqp1IyN+snEJM1NDIdREejD2s7m/DRVz8fz1vegl9sOxa9/MjQNNb6EweGAOCqczqx9cgItg+M4bp1K6Lbr7lgKWZDFjYeHsYvtg3g8rPacXZXc/Ryt8cQA0NERNXnsf0LJ1Mm8usdJwq8EipXIoLeHj82HmKfISKqDDzDpqIYc2rtJ2bDKa6ZnDuKPFHZDyXOGPKY6TafzjRjyJp3+3LglhjGjqwfnQ6hvdEb/f4tV6zGM/2jODg4iZlgBKcnAgtG1cd60Tmd0dfmunXLo9tfeHYn6jwGvvHwAew/NRltOu1yM4aCHFdPRFXiyYNDePf3N9V8iVQ4YuGd39tU6mVQBdjQ48fJ8VkMjCzscUhEVG4YGKKiCDqZE7lkULiZIHUe/tom4jHjAkOKlKVk7jj7TN/oz/UYKqfA0PyMIctSjDoZQ643Xr4ShgB3bBtA/4jdeDpZKRkAXNnth8cQPG95C3qWNEW3N/hMvPDsTmw8PAyfaeB1l6yYdzu3x1CQ4+qJqEq8/6fb8Mi+QYxOB0u9lJL66oPPlXoJVCF6ezoBsM8QEVWGlGfYIvI9ETktIrtitn1BRJ4VkR0icqeItDvbu0VkRkSecf7dVMC1UwVxMydyCgwxY2hRhsxvPh2xrIJPJSunHkPxGUMTs2FYinkZQ0tb6vGS87tw57ZjOHxmCgCwtrNp4Z05muo8+PArz8eHX3n+gsuuuaALAPCKC5eiPSb4BABej/26sJSMiKi67D81UeolUIU4b2kz2hu92HQ4eZNyIqJykU7qxQ8AXBe37QEA61T1EgD7AXw05rKDqnqZ8+99+VkmVTo3MJRLaQ0zhhbnMSSayQMA4UgaU8nMLANDZdhjyG1KPus0KR9xPtXuiAvavPmK1Tg+NovbNvcDwKKlZADw/pedi2svWr5g+6suWo72Ri/e/sK1Cy6LTiVjKRkRUVXrvvHuUi+BypRhCK7s9jNjiIgqQsozbFV9DMBw3LbfqKrbLOYpAKsX3JAoRjBin6xn2ssmFnsMLc40JBqwAexyr1SBG0PcHkOZBTDcQFI5BYbmMobs5zLq9LWKzRgCgFdduAwtdR489OxptNR50BF3ebpWtTfgmU+8Cleds2TBZaYhEJkroSQiIqLas6HHjyND0zg5NlvqpRARLSofqRd/CeDemO97RORpEXlURF6ch/unKpCXUjJmDC3KjM8YsjRlqZcn26lk5dhjyM0YCs3PGIov86r3mnit0xPorM5GSIo+TNkQEXhNg4EhIiKiGrbB6TO0qY9ZQ0RU3nI6wxaRjwMIA/iJs+kEgLNU9XIAfw/gpyLSmuS2N4jIFhHZMjiY3thPqlz5KCVjxtDiPIYR12NIYRRqXH20x1D5BOnq4ppPj0ZLyRZmBL3ZmSK2dpHG07nymQZCYTafJqLqwr0aUfqev6IFzXUe9hkiorKX9VmdiLwLwOsA/LmqnT6gqgFVHXK+3grgIICFXVvty29W1fWqur6rqyvbZVCFCEQzhrJ/S+neBwNDiRkLxtWnkTFURT2G4ptPj0zZpWTxPYYAYP3aDrzk/C5cc/7Sgq3HawqbTxNR1SifvX3hBZxedUS58pgGXrC2A5vYZ4iIylxWgSERuQ7APwF4g6pOx2zvEhHT+fpsAOcBOJSPhVJlc0tqwjmcKLsn/D6WkiXkiQsMha3UPYbMaI+h7DKGyikwVBdXSjY6HYQI0NqwMGPIMAQ/+stevPXKNQVbj89j5JQhVwtExHRKj39d6rUQEQHAc6cmcME/34e7th8v9VKoSvT2+LH/1CSGp4KlXgoRUVLpjKu/BcCTAC4QkQEReQ+ArwFoAfBA3Fj6lwDYISLbAdwO4H2qyhA55aXHkHtb9hhKzIwLDFnpBIaqqceQkzEUcJpPj0yH0NbgLdkavabBjKHUPghgb6kXQUTk2n18HADw0N5TJV4JVYsNPX4AwGb2GSKiMuZJdQVVvT7B5u8mue4vAPwi10VR9Yn2GMqhlMy9j1TlUbXKlIUZQ40pegC5PYIyzxgqv5+FW2IYO64+URlZsfjYfHpRIrIawGsBfAZ2TzoiIqKqc/HqNtR5DGw6PIxrL1pe6uUQESXE1AsqinxkDAUjCp9pFGSKVDUwTVnQfNpM8VKZzhWsqugx5DSfdjKGxmbsjKFSYcZQSl8F8BEAfJGIKojWePdpvgWhTNV5TFx+Vjv7DBFRWWNgiIrCzZzIKTAUtthfaBF2xtDc6xuxFGbKjKHq6TFU74lrPj0dTDiRrFh8HiOnZuvVTEReB+C0M6RgsetxeiVRmWBAhCh7vT2d2H18DBOzoVIvhYgoIZ5lU1EE8zCVLBSx4E2VAlPD4nsMpTOVzBC3x1BmATu3x1A5lZJ5TAOmIXOlZFOhkpaSeU1h8+nkrgbwBhHpA3ArgD8Ukf+JvxKnVxJRIe0YGMXpiVkAwH899ByeOzVR4hVRtdrQ44elwNYjI6VeChFRQgwMUVHkq/k0M4aSi59KFtHUzaerKWMIsLOGZp1SstHpINpLGhhij6FkVPWjqrpaVbsBvA3Ab1X17SVeFhHVmDd87fd4xZcexXQwjC8/sB9v+eYTUMw/HgbDFk6Pz5ZohdVLRK4TkX0ickBEbkxynWucITe7ReTRYq8xny4/qx0eQ7CR5WREVKZSNp8myodAnkrJvCYDQ8mYRoIeQ6mmkpnZTSVzewx5UpSqFVu910QgHEEwbGEqGCl5KdlkIFyyxyciotTGZ8MJv3aPnh/62dO4Z+fJIq+quomICeDrAF4JYADAZhG5S1X3xFynHcA3AFynqkdFZGlJFpsnjT4PLl7dxj5DRFS2yuusjqpWfppPW/AxMJSUaQgsjZ1KZqWdMZTxuHrn+mUWF0K918RsyMLodBAA0N5U2qlkbD6dmqo+oqqvK/U6iCg98Rk11ebE2PzsoPt2MShUAL0ADqjqIVUNwi4pfmPcdf4MwB2qehQAVPV0kdeYdxt6OrFjYBQzwUipl0JEtECZndZRtYqOqw/nNq6epWTJxWcMWVbqUi+3x1DGpWRanhlDdV4Ds6EIRqbt5o7tJZ5Kxh5DRFQ9yqt0uFA+f9++Ui+hFqwC0B/z/YCzLdb5ADpE5BER2Soi7yza6gpkQ48foYji6X72GSKi8lNeZ3VUtdwT5HCGTY5j2c2n+SubjGkIVOdGz4ctK2Vz6GwzhsJl2mOozjM/Y6ikzac5lYyIqCKMTi+cFMW9d0ElevMQ/5J7ALwAwGsBXAvgX0Tk/AV3VEHTK1/Q3QERsJyMiMoSz7KpKPIxrj4UUWYMLSIa5HGyeSIWYKTqMZRtKZnzcyynqWQAUO81EAjHZAyVsMcQp5IREVWGP7npyVIvodYMAFgT8/1qAMcTXOc+VZ1S1TMAHgNwafwdVdL0ytZ6Ly5c0crAEBGVJZ5lU1FEewzlWErGcfXJGXFBnkgaGUMismDMfTrC0R5D5fXzqPeYCMRmDLHHEBFRnlRvDs2x0Zmkl4mU13GuSmwGcJ6I9IiID/Z0yrvirvNLAC8WEY+INALYAGBvkdeZd709fmw7OsIPjoio7DAwREUR7TGUY/NplpIlF18WFrY02kNoMfG9idJhRXsMldcb5nqvgdmYjKFSTyVjYIiIqLpIjfRaKiRVDQP4AID7YQd7blPV3SLyPhF5n3OdvQDuA7ADwCYA31HVXaVac75s6PFjNmRh57GxUi+FiGgejqunoshHKVkwbKGOpWRJxTeStixNK3BjiiCSYe+ncu0xZE8li2B0Ogifx0CD1yzZWth8moiqS3nt7wst2bOt9qlsxaKq9wC4J27bTXHffwHAF4q5rkK7stsPwO4z9IK1HSVeDRHRHJ5lU1FEm0/n0IyXzacX5waBrJiMITON0juPIcg0XheJlGfGUJ3HwGzIwsh0EB2N3pKWAHhNNp8mIiKiOZ3NdTh3aTM2HR4q9VKIiObhWTYVRSCcj+bTHFe/GNMJmkUzhlRhplNKZlZjxlAI7Q2l6y8EAD5TEIxYUGVwiIiIiGy9PX5s6RvJuL8jEVEh8SybiiIYjtj/51hKxoyh5NwgUGyPoXQyejxZ9hgypPyactZ7TQTClh0YKmF/IQDRIGamry0RERFVrw09fkwEwth7YrzUSyEiiuJZNhVFPjKGghxXv6jYcfWWpVBNb2qYIdlNJfMY5fezqPMamA1FnFKy0mYMuUFM9hkioqpSAbHu505NIGIp/u/Pt+OpQyzZofLS22P3GdrIsfVEVEbK78yOqo6qxjSfzmVcfQQ+ZgwlFR1XH1FEMpgalk3GUMTSsisjA5xx9WGnx1BTaTOG3MAQJ5MRUTUoswRRAMAd2wbwtd8+N2/bgdMTeOVXHsMXf7MPt28dwJ99+6kSrY4osRVtDTjL38g+Q0RUVniWTQUXdrJXgFx7DCm8aTRTrlWxGUORaA+g1H/ipinRhtXpCkfKMzBU57Wf79BUEO2lzhhysttyKZ8kIqLk/v627fjib/bP23ZqPAAA2HZkJC+PUX5HOqoGvT1+bDo8zD6ERFQ2GBiignNLaURyLSVj8+nFuIGaiGXFBIZS385jGFn1GCrHwFC9xx5Prwp0lLjHUF00Y4hv+oiIiGhOb48fI9MhHDg9WeqlEBEBYGCIisANDDX5PFmfJEcsOwuGzaeTcwM1YUtjpoalfr0MQRY9hqyyG1UP2M2nXaXPGLJfH/YYIiKqHsIcIsqDDewzRERlhmfZVHBuKU1TnYmIpRmXLQFzmUbMGEpuLmMoppQsjfevdsZQZsGLsu0x5J37/WhvYI8hIqJ8Yw4kUe7O8jdiWWsdNjEwRERlgmfZVHDRjKE6DwAglGEQApgLLrH5dHKeRIGhNF4v0xBkGrso1x5DsRlDHU2cSkZElC/lt8cvjnJsuk2VT0TQ29PJPkNEVDZ4lk0F546qb3YDQ1mUk4Wc+2ApWXJGTCmZGxhKayqZKYhkmjFUpj2G6mIyykrdY8jHjCEiIiJKorfHj5Pjs+gfnin1UoiIGBiiwnMzJhp9djZHKIsMiiBLyVJyg0CWNTeu3kzjo04zy3H17DG0OPd3lc2niYgy99ONR3HTowdLvQwwmYMKZa7PEMfWE1HppTzLFpHvichpEdkVs80vIg+IyHPO/x0xl31URA6IyD4RubZQC6fK4QZ15jKGMg8MhcL2OzNmDCXnBoHCliIScZtPpxEYEsmi+XR5ZgyVY48hlpIREWXuY3fuxOfufTbn+2Fch8rVuV3N6Gj0ss8QEZWFdM6yfwDgurhtNwJ4SFXPA/CQ8z1E5EIAbwNwkXObb4iICapp8T2GglkEhpgxlJoZkzHkNpNOKzBkZB4YipRpj6E6Z1x9S70HnhIHEb1O52+WkhFRNSn3DJp8HZncp8keQ1QohiG4stvPyWREVBZSnjmp6mMA4vdYbwTwQ+frHwJ4U8z2W1U1oKqHARwA0JufpVKlig8MhbMorXHvw5fOmK0a5THnMoYsTT9jyO4xlGFgSBWmUX5BOreUrL3E/YWAmIwhBoaIqAowQEKUf709fhwdnsaJMfYZIqLSyvbMbpmqngAA5/+lzvZVAPpjrjfgbFtARG4QkS0ismVwcDDLZVAlCEYiAIAmt8dQNqVkETafTsWQualk4QyaT5uGUTU9htzm0x0l7i8EzK2FGUNERESUyIaeTgBgORkRlVy+z7ITnSkmPONU1ZtVdb2qru/q6srzMqicsJSsODxOBk/suHojrR5DqKIeQ27GUOkDQ+wxRETVJB8lZI/sO43JQDj3OyohZk5RPl24shXNdR4Ghoio5LI9yz4lIisAwPn/tLN9AMCamOutBnA8++VRNeC4+uJwK7syHVefXcaQVaaBITdjqAxKyZgxRERVKNvASP/wNN79/c34x59vz++CCkzy1rWIaCHTEKzv7mBgiIhKLtuz7LsAvMv5+l0Afhmz/W0iUiciPQDOA7AptyVSpYvPGMrmRJkZQ6m5GUOWzpWSpZMx5DEEVhalZOUZGLIzhsqhlMxtPh3kuHoiIkwF7UyhQ4NTJV5JesrvCEfVqrfHj+dOT2JoMlDqpRBRDUtnXP0tAJ4EcIGIDIjIewB8DsArReQ5AK90voeq7gZwG4A9AO4D8H5VjRRq8VQZ3KBOToGhaPNpBoaScQM1YUujgZ60MoZMiU4xS1e59hjymgbOW9qMi1a2lnopqDOdnlosJSOiKpKspGzjoSGMTAVT3n5oKvnJ70N7T6H7xrtx4PRktsuLYkieKsWGHj8AYHPfSIlXQkS1zJPqCqp6fZKLXp7k+p8B8JlcFkXVJZoxFG0+nUUpmXMblpIl5waGIpYVzRhKaypZFuPqw5ai3lt+gSEAeODvX1rqJQAAvB6OqyeiyvbY/kEsb6vH+ctaFi0hsyzFn978FADgnr97MZrqTAxOBLC+249dx8YQjFhodN4DnJkM4sTYDFa0NSy4n7t3ngAAPNM/mvWa8xUQYmCJiuXiVe2o8xjYdHgY161bXurlEFGNShkYIsrVglKyLDIo3MlmLCVLzhMNDM01kzbTaAZhimQ1lawcS8nKCZtPL05E6gE8BqAO9rHodlX919KuiohivfN7djeAvs+9dtHrxR5B3vLNJzATikRv97r/fhwAcN+HXhy9zunxAExD0FznQaOvst6K5qMJN1Esn8fAFWd1YFPfUKmXQkQ1jGfZVHDBBc2nsxhXH3YzhhiMSMaIyRiKNp9O4/Uys+wxVI6lZOXEfX2YMZRUAMAfquqlAC4DcJ2IvLC0SyKiXLlBocWcmQyg9zMP4c3feCLvj88jE1Wi3h4/9hwfx/hsqNRLIaIaxcAQFVwwYkFkrjFwNuPqA2w+nVKijCEjjYwhj8mMoUIQEfhMg82nk1Cb20jE6/zji0VUYNuOjmBwYn6fn30nJ/DjJ/uKtob/uO9ZAMCzJyfmX8A9ANWoDT1+WApsPcI+Q0RUGjzLpoILhi34TCPaODqcw7h6Np9OzkyUMWSkfr3MLHsMpXPftc7nMZgxtAgRMUXkGQCnATygqhtLvCSiivTjJ/vw+wNnANj9fkan7SbQp8Zn8ZLPP4yjQ9PR6775G0/g9U55l+varz6Gf/nl7rQeS2stesPPQKgILj+rAx5DsPEQx9YTUWnwzI4KLhC24PMYOTXjdW/D5tPJuf2EwpZm1Hw62x5DBjOGUvKawh5Di1DViKpeBmA1gF4RWRd7uYjcICJbRGTL4OBgSdZIVAn+5Ze78effseOq//3bA7jsUw/g9MQs/vfpYzg6PI3/2XgEADATtMu8To7PZvwYUowICQ8rVKMafCYuWd2GTYfZZ4iISoNn2VRwwYiFOo8RDerkNK6epWRJmaabMaRzzafTCQwZBnsMFYjXZMZQOlR1FMAjAK6L236zqq5X1fVdXV2lWBpRRTkzGcD9u08CsBs8x/uTb+W/p09eVUAyUhoV2kRZ6e3pxI6BsWgAl4iomHiWTQXnlpJFpzRlNa7ePrlmMCI5N2MoYikimsG4evYYKhivaWTVU6sWiEiXiLQ7XzcAeAWAZ0u6KKIK97c/fTrhdnWOCbuOjRdzOUmlmuzFowvVog1n+xG2FE8fZZ8hIio+Boao4IJOKZkvh4yhQMS+D+FHdUm5gZqwpYhY1rxtqW6XeY8hi0G6NNR5DITYfDqZFQAeFpEdADbD7jH06xKviaiijc3Mn2iU6SFTs5zFXs1Hg2p+blReXrC2A4YAGw+zzxARFZ+n1Augwvv4nTsRsRSfe8slJXl8NzDkjk4PZzmuno2nF+cGaixL4b7E6QRv7B5Dmf1M2GMoPV7TiDZOp/lUdQeAy0u9DqJq9pvdpwCkztBxPbDnFF510fJFr5Nl7CgjeXkI506yXa97O4b2qVha6724cGUrNjEwREQlwDPtGrD7+Di2D4yV7PGDTraPG6TItpTMazIQsZhcMoYszeyTYvYYSo/XIywlI6Kiid2LT8yGsSXD0dfTi/Q2qZiE3UpZJ1ECvd2d2HZ0hIMriKjoGBiqAdPBcHR0bSm4PYZEBL4sm/G6WUeUnIjAEMDSzKaSeYy53kTpCrPHUFrYfJqISiV2n15uWS+pgkzlcHSpmEAYVZXeHj8CYQs7j42WeilEVGN4pl0DpgIRjE6HUl+xQGKDOl5TsiqtsTOG+OuaiscwELY0OmUsrYwhcy7TKF0RS6PNrik5r2nwUz8iKoiIpdiaYUZQKppGCGnT4WHcvnUg4/suyrj7PHKTaCtr1VTpruzuAMA+Q0RUfDzTrgHTwTBmQhHMhkoz/jIQsVDnMQEAHtPIeAKWex/MGErNMOyThWjGUBrBm6wzhljal5LdfJqBISLKv288fABv+eYTuPPpxEGa42MzBXncD/3sGfzfn2/P+HbpBJ2Ial1ncx3OW9rMPkNEVHRsPl0DppyeAWMzIdR7zaI//vyMoezGd4eccjRanMcw7HH1bmAojeCNIZlnDFnsMZQWjqsnokK5b/dJAMCHfzYXpNl7Ym4c/Udu3xH9utANoxnyIcqf3h4/fvnMcTs7m++1iKhIeKZd5UIRK1rKUqpysmA4Eg0M+VhKVlCGYF5gKJ3gTew0s3So08PINPjzSMUuneQpExHl30wBsoAzCSANjEzjob2n8r6GfClUhhKrqKnQenv8mAyEsef4eOorExHlCc/sqlzshJFSNaAORizUOUEdb5alNUGWkqXFYxrzSsmMNN7Bms7PJt2MIfdq7DGUGptPE1E+/PipI+i+8e75Jb8ZxD0KESR59Vd/h/f8cEtWty1oBlPcfed6qOKhjoqtt8cPANh4eKjEKyGiWsIz7So3HQxHvx6dKVXG0PxSslA24+rDynH1aTANmdd8OpOMoXR7DIUtO9Dh4c8jJZ+HpWRElLvP3r0XABAIZ5cl9P3f9+VxNbaJQDj1lTKUz3iR2+y60GV0RPm2oq0BZ/kb2WeIiIqKgaEqNxXIT8bQu763CffuPJHVbWMDQx5DssqgsJtPF78/UqUxRRCxrIzG1ZvRHkPp/Vzcq7HuPTUfp5IRUR64ZWOZDAnIRrGCKCnH1efh8MJm11TJNvT4sblvOO0yfyKiXDEwVOXmZQxl2WMoHLHw6P5BPHkou5TWYEzjaF+WpWR282kGIlIxDUHEAixVGAJIOqVk0R5D6T1GNGOIgaGUWEpGRPn0+wO1UVqSU4CKhyaqAr09foxMh3BgcLLUSyGiGsHAUJWblzGUZSnZtPNJ5dBkdhlHsf2Bsi4lY4+htNiBITtjyJNmc2i3JCzdjKFIBv2Lal22v+9ERInF7E+KvAsuxsPxqEJk29DTCQDYyHIyIioSnmlXufkZQ9kFdmacBtZnJgMZ39ayFKGIxgSGJKueK0FOJUuLxxBE1A7epDs0zMy4x5DTv4gZXCmxxxARUfoYRieyrfE3YHlrPfsMEVHR8Ey7yk05QR2PIVmXkrmTzYamMg8suSfF8zOGsislY2AoNTdjKJJJxpDhZgylOZUsg/5Ftc5n2j21lN1PiShL/cPTBbnfJw8uLEsr1p4q1S6RCalU60QEvT1+bDo8xPcQRFQUPNOuctPO1JAV7fU5BIbs+xjKImMoGhgy5wJD4SxKaziuPj2mIQhHFBFL0w7cuCVhGWcMMTCUktc0oJp+0I2ICABmQxHsOjYGYH5gaGBkBqGIhaHJAAKh3LIRr//2UzndnvLjvT/aUuolUJnq7fHj1HgARwsUHCYiiuXJ9oYicgGAn8VsOhvAJwC0A3gvgEFn+8dU9Z5sH4dy42YMrWxrwEiOpWQj0yGEIxY8GWTuuBOZ6mJKybLJGIptYE3JmYbA0swCQ25JWLqBIfYYSp/X+b0PsRSSiDLwkdt34K7tx7H546/An31nY3T7v929F31DU/ifp44W5HHLZa9eTgkSUuBX5YE9pwp6/1S5NvT4Adh9htZ2NpV4NURU7bI+U1HVfap6mapeBuAFAKYB3Olc/BX3MgaFSsvNGFrV3oCxbJtPB+caWA9nGFxyA0OxpWTZ9hhixlBqpiEIW4pwBoEh0yk5SzerhT2G0ucGg0LhMjrLIaKiUNWsR00/0z8KYH6fQNfjz53JZVmLWmy16Uy5TFe1fq6wWMnP939/uIgroWpw7tJm+Jt82HiIfYaIqPDydab9cgAHVfVInu6P8mQqGEGdx0Bnsy/nHkNA5pPJ4gNDvmx7DEUUXgYiUrJ7DCkilgUzzXfengybT0eiPYYYqEvF/b1nA2qi2nPTo4dw9sfuwfhsdsfeWpaPwFGuWUfZ3PyObccWbOs7M4W3futJ/L9f7cltQVVGRK4TkX0ickBEblzkeleKSERE/riY6ysHIoIruzuwqW9hPzAionzL15nd2wDcEvP9B0Rkh4h8T0Q68vQYlIXpYBhNdR60N/owE4pgNhRJfaM4M6G5TywzDgxFewyZAJzm0xlmT9iBDmUpTho80cBQ+s2h3ZKwTMfVs8dQaj4nmMnAEFHt+dlmu9wr0+NmKpWaf1jokqxiP04iO52+ULGu+eIjnCwVR0RMAF8H8GoAFwK4XkQuTHK9/wBwf3FXWD56ezrRPzyD46MzpV4KEVW5nM+0RcQH4A0Afu5s+iaAcwBcBuAEgC8lud0NIrJFRLYMDg4mugrlwVQggkafibYGLwBkVU42L2NoKrMG1PEZQx5T0g5AuEJxk80oOUPsUrKIZaVd6uVeL90fi/vzY4+h1OZKyRgYIqLM/d2tzxT18bKdfpSvqUmVPn3pB0/0lXoJlaIXwAFVPaSqQQC3Anhjguv9LYBfADhdzMWVE7fP0OY+BheJqLDycab9agDbVPUUAKjqKVWNqKoF4Nuwd/4LqOrNqrpeVdd3dXXlYRmUyHQwjCafBx2NPgDIqpxsJiYwdCbDTz4DYfu283oMZXiSHD/ZjJLzmALLUkQUaZeSmQYzhgolGhhixhARZWG702uoGmhMrlMps3pydc/Ok6VeQjVYBaA/5vsBZ1uUiKwC8EcAbiriusrO81e0oqXOg43MOiOiAsvHmfb1iCkjE5EVMZf9EYBdeXgMytJUMILGOhPtjXbGUDaTydyMIdOQjEfWB8Lzgzo+j4FQhuPq47OOKLnYjKG0p5Jl22OIPZ9SYo8hIsq3Ck+qATA/SBQrnw2uc+WuJFINL3j5SfSDjn+hvwrgn1R10R4I1V6BYBqC9d0dLEckooLL6UxbRBoBvBLAHTGbPy8iO0VkB4CXAfhwLo9BuZkO2BlDbilZNhlD08EIvKZgSbMv5+bT2Yyrd6/PHkOpuT2GwpFMppK5GUOZBYaYMZSaL5oxxBMLolr19YcPVEx/kGLtqYoRa8n1Ie7afhxfuP/ZjLOcKS0DANbEfL8awPG466wHcKuI9AH4YwDfEJE3xd9RLVQg9PZ04sDpSZzJ8MNZIqJMeHK5sapOA+iM2/aOnFZEeTUVjMDf5ENHk11KNjaTecbQTDCMBq+Jzqa6rHsM1cWUkoUthaqm/cmg26yagaHUTMNAxFJYmnlgKN2xym4AKd1StVrm/s7yxIKodt2+dQDPnhzHr//2xaVeStnLR4+hZNlI2fj6wwfzdl80z2YA54lID4BjsIfY/FnsFVS1x/1aRH4A4Neq+r9FXGPZ6HX6DG3pG8Z161akuDYRUXZ4pl3lolPJGtxSsuwyhhp9HnQ2+zLuMRSMxGcMZZ5BEYzM71NEyZmGndETtjTtjB5PlhlD6QaeapnXKbdjjyGqFO/78VY8sOdUqZdRFWI//Ijt1ZerfAY+SqUYnyvwCFW+VDUM4AOwp43tBXCbqu4WkfeJyPtKu7ryc/GqNtR7DfYZIqKCyiljiMqfO5Ws0WfCa0p2pWQh+z6WNNehb2gqo9sG43oMxZ4opxvoCToZQz72tEnJYxiIqCJiKYy0M4bsn0OmPYbSnXpWy9hjiCrNfbtP4r7dJ9H3udeWeillZ2QqiC1HRvDKC5eVeimFU+KYUzn1GKLCUtV7ANwTty1ho2lVfXcx1lSufB4DV5zFPkNEVFhMwahybsaQiKC90ZdlKVkEDT4TnU356DGU+ZSm+KwjSs5wegxFipIxxJ9HKhxXT1R5Nh4awr6TEwu2X/7pB/DeH23BybHZEqyKMlX5eVVEc3p7/NhzYhzjs5l/wEtElA6e2VUxy1KnDMwEALQ3eDEylU0pWRiNPhOdzXWYDkYwHQynfdtkpWSZZFCw+XT6PIYgbFkIWwojzU9eDfYYKhhmDBFVnj+9+Slc+9XHkl4eCOevLIzmy0ePIWERGVWh3h4/VO0+Q0REhcAz7So2E7LfvDb57IrB9kYvRrPOGLJ7DAHIKGso0VQyAAhn0GPIzbZgYCg10xBYlh3kSbfUK/OMISv6WLS4bDLkaoWIrBGRh0Vkr4jsFpEPlnpNVDlOj89GP6Q4MjSF7hvvxtYjI3l9jO/87lBOt48NcjB7Zb5U8Z98f+5gWbpgCMAQJzxRBbl8TQe8prDPEBEVDHsMVbEp501zY52TMdToQ//wdMb3Mx2MYEWbiSVuYGgqiDX+xrRuG1jQYyjzE+UAS8nSZspcxlBjmqVeboDHDfik4v7o2GMotWhPrTBPCxMIA/gHVd0mIi0AtorIA6q6p9QLo/LX+9mH8PwVrbj3gy/GY8+dAQDcsW0AL1jbkbfH+Le79+Lai5anfbwrlmKMei+1fD/Hv731ady94wTO7mrCocHMeiUSlYMGn4lLVrezzxARFQzPtKvYdCAuY6jBm13zaaccrbOpDkBmn7ItbD6deWAoFHcflJxpCiIW7HH1acZtMs0YCjNjKG0sJUtOVU+o6jbn6wnYk2lWlXZVVEn2nhhHMGxhxvkQZO+J8bw/hpVDhIKNlMvH3TtOAACDQlTRenv82DkwllFLByKidPFMu4pFM4bcHkPZlpKFnObT2ZSSRSx4TYn2sYn2GMogg4LNp9PnMQQRy0I4omk3hzaiGUMZNp/mSU9KvujvOwNDixGRbgCXA9hY4qVQhTn/n+/FZ+95FgCw7egoum+8O/rBw2wocS+gYNjCv/5yF0uJSijV4YOHF6KFNvT4EbYUTx8dLfVSiKgK8Uy7ik0HnYyhOrfHkA+zISvpm+Xk9xOelzF0ZiqzjKHYTB+fZ25cfbrYfDp9hgjCzlSydF8uT4aBoWjzaWYMpcQeQ6mJSDOAXwD4kKqOx112g4hsEZEtg4ODpVkgFdyfffspdN94d97ubyYUwXOnJvC8f7kPd20/vuDy+3efxA+fPIJP/boyqxYLWUqmi3RDyjVYw6bQRLl5wdoOGAL2GSKiguCZdhWbCtgZQw0xGUMAMionsyzFbMhCg8+DBp+JJp+JMxOZNZ+OzfTxOFks4TT72bj3Acz1a6HkPIbAshQR1ehrnYqZYSmZO72MPYZSY2BocSLihR0U+omq3hF/uarerKrrVXV9V1dX8RdIRfHEwaG83+fu43aM8aG9pxZc5paHpRsMp9T4ShIVXku9FxetbMOmw/nfZxIRMTBUxaIZQ9EeQ3YpWCblZO5kM7ccrbO5DkOZZgzFBIayKyWzr8tSstRMIzZjKN2pZPbryoyh/HODmcEMpvDVCrEbsHwXwF5V/XKp10PVKVF2jdv7h3+V1U0rsEv3TDCzjG6qPb09fjx9dBSBMH9XiCi/eKZdxdyMITeo05FFxpAbXJoLDPky7jEUG9DJqpSMzafTZhoCSxVhy0o7cONeLf1x9ewxlC4Rgc80mDGU2NUA3gHgD0XkGeffa0q9KCqe/uHpeU1Uj4/O5O2+3d1Tor1asfZclbiHrMBYygLuz/5MBu9VysX2gdFSL4HKXG+PH4GwhZ0DY6VeChFVmZofV//wvtNQVfzh85aVeil5F99jqC0aGMogY8i5jwavExhqqsPASPoj7+N7DGVTWsPm0+nzOBlDlpV+Ro+I2AGlDDOG0i1Vq3VeU9h8OgFVfRyVee5MefLizz887/urPvdb3PT2K3DduhXFWUCWQRD2yslObP+iQgWgtveP4n+eOgIAODqc/nsVokpxZbcfgN1naL3zNRFRPtT8md3Xf3sA//ngc6VeRkEsnErmlJJlkjEUcu/DDi4tafZhaCr9wFIgbMHnMaPf5zKuns2nUzMMgar9+maS0eOWoKXDDSCZ7DGUFq+HGUNE6doe9yn4dDCc95KguWyi7O4329tVumIkiWb7yn7k9u04NT6LN3799/i1M5qeqBr5m3w4f1kzNrEBNRHlWc2faY/NhDCSQaCkkkwHIjANQZ2TaRMtJZvJrZRseCqYdnZJfCmZ23MllEHPFTdjyMOeNim5r1EwYmUUuHHH3KdjLmOIP490sJSMKt3hM1M4lscyr3SdHJvFhZ+4H9945GDW95EoqORm/JRz2VSpKnWL9ZKkHFefJCtrOhjG1iMjuHXT0XmT7G7bMoANn30on0skKlu9PX5s6RtGmO8tiCiPGBiaCWEkg9KqSjLljJl3G202eE34TCOj5xstJfPNlZJFLMVYmsGlYDiCujyUkvk8RvR5UHKGE6wJhKyMAjeZZAy5ASSDP4+0eE0jo2brROXmZV98BFd/7rcZ3cayNNrnLtbWIyPovvFuHDg9kfI+3LLlL9y/L6PHBrDo8aJYuy5N+g2lEpuVFYpYCEcsfOCn23DhJ+7HW775BG68Y2cJV0dUWr09nZgKRrDnxHipl0JEVaTmA0PjsyFMzIarMuo+HYhEJ5IB9hvl9kYvxnJsPg0g7clkyaaSZVZKpmw8nabYjKFMAjfZ9RhiYCgdPo8RzXojqhWfv38fLvrX+zEZFxz61fbjAIDH9p8pyjoW26uVc8ZQOa+tkBIdVc77+L248Y6dLBEjcvQ6vYVYTkZE+VTTZ9uBcASzIfuELd0MmEoyFQyjsc6ct6290ZvhVLL5fYqWNNcBmJv2EYpYuHfniaRBhYWlZM64+oxKySJsPJ0mM2b0fCaBG0+GPYZE5rKTaHFeU6J9sohqxZ1PDwDIbNhBPkX3TonG1UcvKmz0pVB7yEKOYS9FQMqyFN033o1vPHIg6U/k9q0DRV0TUTlb3laPtZ2N2MjAEBHlUU2fbY/PzH2SWY19hqaD8zOGAKC9wZdVKZnbfDqaMeQEhr77+GH89U+24XcHEn/6Gz+VzP06kxPlUFijvYlocbEvU7pTydzrRjLIGGK2UPq87DFENexPv/VUqZdAefCpX+1B/3Bh+kxFnGjU5++bKxnk5DeixfV2+7G5bzjtbG8iolRqOjAUmyVUqk81C2kqEI5m+rjaG70ZZUctKCVrsjOGhqYCmJgN4aZH7aagm5N8ahFfSuZxIhfhNBsdA3bWESeSpceMeZ0yCQx5DCODHkPK/kIZYCkZ1bJkTat5KlNZvvf7w3m9v9jMpL0xfVLcD6M+9LNn8vp4RNVmw9mdGJ0O4bnTk6VeChFViZo+2x6fnQuQVG3GUF1cxlCGpWQzofnNpzsavRCxS8m+93gfRqdD6Gqpw+a+9AJDcz2GMptKxlKy9MSOqM+0+TQzhgqDGUNEc1LFlPNVyrTYSProZRUanarQZSf18y1zZWK/2XOqhCshqhwbetw+Q0MlXgkRVYuaPtuOzZypxslk7lSyWO2NmZWSTQfDMA2JloB5TAMdjT4cHJzEd353CNddtBxvuHQlnukfRTBBeViycfWJrptMKK4cjZKLDdhk0gMok8BQxNKMspFqnc80Mvp9J6oGpS4FWvzxnXH1xVlKRRmaDOD0xGxGt/ncvc+mdb3nTs1lNsRmOfz4qSMZPR4RAas7GrCirZ59hogob2r6bHu8ykvJ4qeSAXbGUCBsYdbJBEp5H8EIGr3mvNG/nU0+3LPzBCaDYXz4lefjyu4OBMIWdh0fW3D7QFxQR0TsZrxZjKun1GIDNoXKGIpYCg8DdWmzf995CkqVb3Q6iI2HKv/T6VwrYUsd9Mp3plNsM+svPbAfvZ95KKPbuyXliXTfeHf067+95enMF0dECYkIenv82HR4uKAN6YmodtT02d34THWXkiWcStZgN49ON2toJhiJlpG5Opt9UAVef8lKXLC8BS9Ya6ezbklQThYMW6iLC+pkWloTYo+htJlZZgzZU8nS+5mE2WMoIz4PS8moOrzju5vwpzc/lXYQeTHJTmTyvWtZ7Hyp4OdSZbabTBTA+dtbnkbPR+/J+b6/93h+exARUWq9PX6cngjgyNB0qZdCRFUgp7NtEekTkZ0i8oyIbHG2+UXkARF5zvm/Iz9Lzb/xWXsqWWu9J6O+O5VAVRNPJWv0AkDaz3c6GFlQjtbZXAdDgA+94jwAQFdLHXqWNGFz38iCNSTK9vEYmWVQxE82o+QKkTF0x7YBfOCn26LfRyyLPYYy4DXZfJoq06nxWXzh/rkyod0JskLL1WIBprmLsosMFXrMfaEkKvn61fbjebnvf0+znIyI8meuzxDLyYgod/k4236Zql6mquud728E8JCqngfgIef7sjQ2E0K918DS1vqqKyULhC1ELF2YMeQEhtLNGJoORtAQF1z6q5ecja++7XKc3dUc3bZ+bQe29M1PZw1bClUsyBjKNIMiGFF4WUqWltjAkGmk/5otFhh6/LkzuH/3yejPNmJlNvGs1rHHECVzaHASP3yir9TLSOrDP3sGX394YZZJPsoWpEhZh4mWWqzHjo0fZfqKMSmTiFI5p6sZ/iYfnmIDaiLKg0Kcbb8RwA+dr38I4E0FeIy8GJ8JobXei45Gb9U1n3bHzMdnDHU02qVk6WYMzYQWNrC+ZHU73nDpynnbruz2Y2Q6hIODU9Ft7slwfMZQxqVkYQs+k++S0zEvMJTBS2YaknRc/ch0EKGIRjPsIpYFD38eaeNUMkrmTV//Pf71rt2w8lCaVQiBuICmG1Apz9XOl84eqlLbcpwcz6w5NBFVJxFBb7efGUNElBe5BoYUwG9EZKuI3OBsW6aqJwDA+X9pohuKyA0iskVEtgwODua4jOyMzYTQ1uBFe6Ov6krJpgL2SXx8UMcNDGWSMRR/H4ms77YrBmP7DEUDQ2aiwBDH1RdCbImXmUH5nWeRjKFh529jZMr+nQlbCpMfZ6fNzpCr0DNQKig32FqLf06lbJbqvtz8qySiStfb48fAyAyOjc6UeilEVOFyPdu+WlWvAPBqAO8XkZeke0NVvVlV16vq+q6urhyXkZ3x2RBaG6o8Y6gutx5DM8EIGrypA0M9S5rQ2eTDptjAUMTNGJp/e0+GU8nYfDp9xryMocx6DCXLGHLLLIecwBDH1WfGaxoIsZSMFlEumSsP7T1V8Mco9kSvRP2AihaIS/I4qoqfbT6KYNjCbZv70X3j3dHA/Nu/sxHdN97NZrI1ikdWylSv02doM7OGiChHOZ1tq+px5//TAO4E0AvglIisAADn/9O5LrJQ3IyhjkYfRqZDVTXucSqYOGOo3muiwWtGsz9SSTdjSESwvrsDW2IaUCcrJfNlWFrD5tPp8+TQfDpZOcuw87sywsBQVrweQYClZJRAuWUKveeHW+Z9H7+8Yiw3X4fhcnttXeOzIfz4qSP4p1/sxPn/fC8+8osdAIAfPdkHAHj8wJkSro6IKs3zV7Sipd6DjQwMEVGOsj7bFpEmEWlxvwbwKgC7ANwF4F3O1d4F4Je5LrJQxmfCaK33oK3Ri2DYwkwoUuol5c10IHHGEAAnQyr9qWTxzaeTubLbj6PD0zjl9D8ILNpjKP13/6GIxebTaZrffDqTwJCRMGMoHLEw4ZS7DMcEhthjKH1uILSaAs+UH+X0K5FJGUI66y6XwMzi4+qL9wNwX44rPvUAPvHL3QsuPzMZKNpaqHyV0S6BKoRpCK7s9mMTG1ATUY5yOdteBuBxEdkOYBOAu1X1PgCfA/BKEXkOwCud78tSbMYQkH55VT5Ylha0IW2yjCEAaG/0YWwmvYyhmeDC5tPJrO+201ndrKHkPYYyKyULMGMobbHlY5kEhpL1GBqdmfubGGKPoax4TQOqSNrDiagcfjNe85+/W7CtHNaVveSNst3dV7bPL5tyOPexkpXsFrvEjoiqR2+PHwcHpxhgJqKcZH22raqHVPVS599FqvoZZ/uQqr5cVc9z/i/L3EbLUkzE9BgC0m/InA/ffPQgrv3qYwW7/2knMBQ/lQyw+wylkzGkqpgOpVdKBgAXrWxFg9fEZqfPkNtjKH5cvTfD8d0hNp9OW2wmT2YZQ4l7DMWWHLp/Hywly4z7u8sG1BSvnOKrYzPpfzCSqG/PguskuUqq51yM16QUQZgzEwH0nZlKevnXHj6A7hvvLuKKiKhasM8QEeVDzZ5tTwbDsBTRqWRAcTOGnukfxaHBKUw608PybcopJWusWxjUsXsqpQ6CBcIWVIGGNANDXtPA+u4OPHnQTmddbFx9sk9NEwlFFF6WLqXFyCljaGGwLjaAODQZU0pm1OyuI2Nu4/Qg+wxRERw4PYmH9+Wntd+CHkN52A2XU/lcvtay98Q4TozZpXjv/v4mfO7eZxdcZyIQxjVffCQ/D0hEFGPdyjY0eE32GSKinNTs2d248+loa0wpWTEzhvqHp+f9n2+pMobSCYK5k80a05hK5nrROZ3Yd2oCgxOBRQJDyUvJVBW3bjoaXX/EUkQshc9Mfw21LDZgk0lgyEhSSub2FfKaguEpO0WZGUOZ8TlBzUyy5Ki25LPXzSu+/Cj+4vub83Z/iVRCj6FouVjCWjLnsjw91qv/83d40b//FgDwyL5B3PToQcyGIiwOI6Ki8HkMXLG2HZsYGCKiHNRsYMhNm2+tjy0lK07GkKpiYMT+dLFQgSE3YyjRqPmORh9Gp4NJp1C5pqN9itJrPg0AV52zBADw1KEhBCP2Ghb2GEpeSrbnxDhuvGMn7t15EgCiASSvh2+x02FmOZUsaY8hJ1i6trMJw87fR9iyGBjKgJsxVMieYkS1JJ0g62J7KPeybANyCsVf/89W3LX9+LztH71jR/Tr5/3LfTg4mLx0jIgon3q7O7H35HhGZcFERLFqNjA0PmMHPdoavGhzAkOjaY5wz9XodChaQtY/kv4kmExMO02jjQQn8O2NXliK6LSpZGacjKF0S8kAYN3KVrTUefDEwaHkGUOe5OPq3Ylmblp+IEkDa0osNmCT6Ge/2O0S9hhygkHndDUxYyhLcz2GGBiiwooNdOw9MZ7z/cVn/eSjN0+qTKKHnz2NXcfGAABfuH9fwuuc/8/35riGhYsYGJnGxGz6J1T37jqJv7vlaYzH3OaWTf05rYuIKFu9PX6oAlv6mDVERNmp2bPtaMZQgwd1HhONPnPeBKZC6h+ZyxIqWMZQMJI00yfd0rloKVkGgSGPaWDD2X48efBM0nH1vkXG1Z8et4MPJ50AkXsyzebT6cl3xtDIdBB1HgMr2xswMmX/fURUM7rvWseMIUolXyVNP3rySPTre3aeyNO9LlTIPkHPnpzA6/77cQCY1y/j3+/di4/fuTOLe1TctrkfTx8dWfRaf/AfD+NNX/99xvf+xIEzWayJKDEeWSlbl5/VDq8pLCcjoqzV7Nm2+ylfW4OdLZRuQ+Z86B+2s2F8HgMDIwXqMRQIoylB42kA6GhyMqRSBMKms8gYAoAXnbMEfUPTODJkP7f4bB+PIQgnzRhyAkNj8wNDXmYMpSU2MJTpVLKEgaGpIPxNPnQ2+TAZCCMQjiAcYcZQJtzf3QB7DFGcTP6KVDXh32isR/LUdHruMbO/bb73EN969BB+svFo+o/vZAXNhCL4yC924I++8UTKtWVT+jXplG0TEZVSvdfEpavb2YCaiLJWs2fbsc2ngfQbMueDmzF0xVnt0SBRvi2WMdSeZsbQTCjzHkMAcNU5nQDmTlIWjKv3GAgmyxiasANCbsZQkKVkGYnN5DEz6P6aNDA0HUR7ow/+pjoAdjNqlpJlxuf0x+K4eoq32G/E3TtO4GMxGTI/fuoIzvnYPRicCKR33wX8dUtnXH3K+yjwn4N7LPn9gaHoNvcDB9eZyWC0j9pi+oen8dl79ka/f+kXHol+/X9/vj3HlRIR5Udvjx+7jo1hqkATj4moutXs2fbYTAiGAM1O0KO4GUPTaG/04vkrWtE/Mp3XiTSu6WAYTUkyfdqdYFiqN8TZlJIBwAXLWuBv8uGZ/lEAyUrJEmdPnJ5IkjHEUrK0zCslMzMpJTOS9hjyN3nhd7LMGBjKnDtRj6Vk84nI90TktIjsKvVaSi3RIeD9P92Gn8ZkyPxi2zEAKFiWaSILYssZ/NknO6oVY8/xq+3H8fE7F/5abT0yv5xs74lxXPapB+Zt2+4ct1wP7T2NF3/+Ydz82KG8r5MoHj8+oFz09vgRthRPHx0t9VKIqALV7Nn2+EwILfXeaIPe4mYMzWBNRyPWdDRiOhiJjgTPp6lABI11KXoMTaVZSpbBuHrAbnr8orM74cYZMhlXf9rJFDozGUQwbMU0n2YgIh3zmk8XKmOIPYYy4nV+d0MsJYv3AwDXlXoRpeQGhCYz+HS3HE4cs/0s4/TELI6Nppclm2zymNuYejH//L+Lxxrjd43dN94d/fqNcX2GPvXrPSkfj4ioHKzv9sMQYNPhodRXJiKKU7OBobGZULS/EFDcjKGB4Wms8Tdgjb8RQGEmky2WMdTa4IVI6oyhmSwzhgDgRU45GZB4XP1iGUNu0OHU+Gy0/IbNp9Mzv/l0+q9Z0ubTU0F0NHrhb7KDicNTQafHEH8e6XKz3YLMGJpHVR8DwGYIAI6mMYRgsVDskaEp/HxL8olY4YhV9Iy12PU+edA+Sen9zEO4d9fJtG7/3OmJhNsPn0ndByhZ4Eqh2HN8nJ+mE1FVaq7zYN2qNvYZIqKs1OzZ3fhsGK0Ncxk1HY1ejM2EUjb3zJVlKQbcjCF/A4DCTCabCiTvMWQagrYGb3QUeTJzpWSZ9RgC5voMGWJPKovlcaaSxZfQWZZicCKA561oAeAGhth8OhOxfYUyKfcyEgSGIpZibCYEf6NvXmDILiXLz3prgRsYTZYBQRTvZV98JOlliYIer//vx/GPt+9A31DiY8nLv/wozvt4biPe560hw+tf/+2nMn6M1/7X4wm3j+UwPbTvzBRe81+/w5cf2J/1fRARlbPebj+e7h9FIMzG+ESUmZo9vYvPGGpr9EEVmJgtbDnZ6YkAghELq/12KRkwf3x9vkwHk08lA9LLkJoJhiEC1Hsz/zXpWdKE5a31CTN93LKw+J42w9NBhC3FJavbAQAnxmbZfDpDppldYMhjCMLW/MDF+EwIltrNytsavDDEyRiymDGUiblx9eVQBFRZROQGEdkiIlsGBwdLvZyiic2K+dpvn5tX6pTI+Gx4we1iy9OOJAkYpSJxeUrp7lFUFcfjGj3Hm8iyOWqqMrHFfPE3DAgRUXXr7fEjGLawYyB12S0RUayaPbsbnwmhtT62lMz+OlUWTa7cINCajgY01Xngb/IVZDLZYlPJALunUqpPXqeDETR4zejY30yICP7gvCVoiXmNXXMnyvMDEaedUfWXrm4DYGcMBdl8OiOeHMbVW2pnbbncwKG/yQfTELQ3+jA8FYTFHkMZcYOjbD6dOVW9WVXXq+r6rq6uUi+nJNxgxjPRpsiK9/14K+58egDdN96NnUne/P/gib6cHzvZ9LFP/Wr3orf77uOHF2xzp4S5/uuh57JfGBERJXRltx8AsInlZESUoZo42956ZAQf+Ok2hGNOzBL1GAJSj3DPlVs25vYXWtPRsOiUmScOnMFHbt+e0eSyUMRCMGwl7TEEpJcxNB2KZNVfyPWx1zwf33/3lQu2RwND4fnP6ZRz4nDu0mY0+kxmDGXByLKUzA30RDQ2MGQHDtudoKm/yef0GLI4lSwDbvNp9hiiZDLZv4/PhnHf7pP48M/sMek/3XSkUMtK6rYtA4tenqiHz7VfeaxAqyGqHjyyUq46mny4YFkL+wwRUcZq4mz79q39+PWOEzgUk2Y/PhtCa0xgyD35TdWQOVdudtCqdru/0Gp/46I9hu7ddRK3bRnAoDPGPR3R3kBJppIB9sj6VFPJZoIRNOQQGPI3+bBuVduC7clOlAedjKGlLfVY3lqPkzE9hth8Oj2eec2nM+sxBGBen6ERZ1qeGzT1N/kwxHH1GWuu8+CVFy7Dirb6Ui+lrIjILQCeBHCBiAyIyHtKvaZykEmQyL5+5o/x5MEhPHHgTMrrLSgli/uzf9kXH4mWuVmW4p6dJzA+G8LdO08suK9CZ+MSEZGtt8ePrX3D8z4QJyJKpSbOtjf3jQAA9p4YBwAEwhHMhqzEGUMpgiW56h+ZxrLWOtQ7I+DXdDTi2OhM0qbXx53RvvtOJZ7Qkoh7Qt9av1gpmS9lEGw6GEajN/PG06m4GUPxPW3cUoOuljosb6vHyZiMITafTo+ZZSmZJ1FgKKaUDAD8jT6MOD2GWEqWvvZGH779zvV48Xm1WQqVjKper6orVNWrqqtV9bulXlMh3ba5H9033o1T44l774QiFjYeGkLPR+9Z9H7i//Ju3Zx8Glky13/7KfzZdzZmfLtYYzOhaE+jj96xExf8y734m59swyWf/E1O90tEtUFErhORfSJyQERuTHD5n4vIDuffEyJyaSnWWYl6e/yYCkaw+/h4qZdCRBWk6s+2h6eCOHB6EgCwxwkMjc/YTS9jAyfFLCVzm04DwBp/A0IRTXqycMwNDJ1MPzAU7WPkb0x6nY5GL6aCkUUnJU3nmDGUTNJSsvEA2hq8qPeadsbQGDOGMiUicGM2mfUYcoN1CwND0VKy5rkeQ8wYIsrM7dvs8qtk49a/cP8+/OnNqad3ZdPzLRuqii1H5pcixH5+MR7To+6WTUfZXJ0oD2rlr0hETABfB/BqABcCuF5ELoy72mEAL1XVSwB8GsDNxV1l5ertYZ8hIspc1Z9tbz1iZwv5PAb2OJFzt+lybClZS70HhuQ2CjcdAyMz8wI20clkScrJ3Iyh/RlkDLnlaosFhtqdLJDFsoZmgrn1GErGbSQdX0p2emIWy1rrAADL2+pxanwWgWjGEAMR6fI4QZ7cM4ZC8JqCZqcksbPJ7ksVijBjiChbiUq//v2eZ/FsBsH/YvjC/fsQn8ga+0HCiz//cJFXRERVpBfAAVU9pKpBALcCeGPsFVT1CVUdcb59CsDqIq+xYi1rrUd3ZyP7DBFRRqo+MLSlbxg+08C1Fy3H3hP2G+/x2YWBIcMQtDV4C5oxFIpYODE2gzUdDdFtbvCmf2ThZLKJ2VB0DPG+U5NpP07/yDS8pmB5a/KeJulMYZsuUGDIHVcfP6Xp1HgAS1vsNS9vq0fYUpxwRh6z+XT63EnyZgaZBWaCwNDodBDtjb5ohkJHoy96omgwMESUEfcvJtGkr019wzh4Ov19fD5FLMW3Hzu0YPs3HjlYgtUQUY1YBSC2DnbA2ZbMewDcW9AVVZneHj829w3PmzZLRLSYqj/b3tw3jEtWt+GyNe04MxnA4EQgmhUU22MIcCd1FS5j6PjoDCy1G067VrbXQyRxxpAbFOlqqcNzpybS3rn3D09jZXvDohkjbuncohlDoQgaFhl5ny03oyUcV3owOBHA0hYnY8gJah11XheWkqUvmjGUQZZVosDQ8FQwGkAEgM5mX8xjMDBElAm3x10ybtlwKvn+y/vFtgF85p69eb5XIqJFJdqVJXyTKyIvgx0Y+qckl98gIltEZMvg4GAel1jZNvR0YmwmhP2nyysblYjKV1Wfbc+GIth5bAzru/14/ooWAPabc7c3Qmv9/MBQe6O3oFPJoiVeMT2G6jx2P53+BCPr3ROFa87vwnQwkvaJQ//IzLzHSKQ9rYyhMBq9xSklU1WcnpjF0ta5jCFgLmDG5tPpc4M8mQRv3NvENgQfmQ5FA4jAXBNq+/r8eRDFOz0xmzDIb1kazf68b9dJdN94d8IsnXz70K1P40+/9WTSy4cmA9h2ZCTp5UREBTIAYE3M96sBHI+/kohcAuA7AN6oqkOJ7khVb1bV9aq6vquLQx5c7DNERJmq6rO77f2jCEUUV3Z34MIVrQDmB4YSZgwVcCrZXFPohnnb13Q0YmB4YdDH7S/0suctBZB+A+qB4ekFjxEvnYyhwjWfXlhKNjIdQiiicxlDbXMZQyLMUMmEG+QxMiglS9hjaCo4LzAU+zV/HkQL9X7mIbz48w9jKhDGDT/aEh0qEIlpLPSjJ48AQNZZOpn0nv7fZ47P6zHxju9uxFcf3B/9/gX/9mBWU82IqDBq6Mi6GcB5ItIjIj4AbwNwV+wVROQsAHcAeIeq7k9wH7SI1R0NWNlWzz5DRJS2qg4MbXE+CX3B2g60N/qwoq3eDgw5n9y2Nswvk0pnhHsu+oen4TEEK9rmB21W+xsSZgwdH52BaQiuPncJgPRG1k8FwhiaCmJ1HjKGCtV82u0XFBsYckfVL3MyhpY01cFjCEanQ/CaRtEm8VSDXDKG4ptPd8RkCcWWkrHHEFFyd20/jt/sOYWvPGCfy1iJOk5nKZe7+t1zZ/DVB5/L21qIiLKhqmEAHwBwP4C9AG5T1d0i8j4ReZ9ztU8A6ATwDRF5RkS2lGi5FUlE0Nvjx6bDw9A8HoOIqHplHRgSkTUi8rCI7BWR3SLyQWf7J0XkmLMTf0ZEXpO/5WZmc98wzl/WjHYn0+H5K1qx58Q4xmZCqPcaqPPMD3p0NHoL2mOof2QmYe+fNR2NODk+i0A4Mm/78dFZLG+tR1uDF6vaG9KaTDYwknoiGQA0eE34PEbSQFgwbCFsaWGmkiUKDI0HAABLnalkhiHRIBEbT2fGbTqd2bj6+YEhVcXo9PweQ8wYIsqM+148n+/J+faeiKqBqt6jquer6jmq+hln202qepPz9f9R1Q5Vvcz5t760K648vT2dGJwIoG8o8eRjIqJYuZxxhwH8g6o+H8ALAbxfRC50LvtKzI78npxXmYWIpdh6ZATru/3Rbc9f0YKDg1MYnAgs6C8EAB1NPsyEIpgNRRZclg/9SUq81vgboWoHgmIdG53Bqnb7+hcsb0mrlMztbxE7+SwREXECYYkDQzNB+zUoSPPpaCnZ3CmOW3LhlpIBiI6uZ+PpzJiGwBBklGXlifYYsn8mE4EwwpbOCwbVe000OYHCTIJORNXm248dQveNd2NidvEPEn62xS7TCsZNYMzFu763KW/3RURE1Wuuz1DC9kxERPNkfcatqidUdZvz9QTsVNDFRk0W1f5TE5iYDePK7o7otgtXtEUDRvH9hYC5jIihqfyXk6kqjg5P46wEmTzutr6hqXnbj4/OYGW7nTVz/rIWHBqcWjDiPd5cH6PFM4aAxaewzTjBseKVkjkZQ864egDRkjtvBtO1yA68eTJsDu02k3YzhkadXluxpWQA4HfKyZgxRJVic98w7t5xIq/3+aOn+gDYk/v6h6fRfePdeGDPqYTXjViKL96/L6+PT0RElMo5XU3obPJh4yH2GSKi1PKSiiEi3QAuB7DR2fQBEdkhIt8TkY7ktyycLX32TnD92vkZQ4Dd0Lg1QWDo3KXNAIBnU4wVzsbJ8VkMTwXxvOWtCy67YLm9rj3H5x43YilOjs1iZTRjqBnBiIUjMcGjL96/Dz9+6si8++ofnkGD10Rn3Al9Iu2NXowlCQxNB+0+TMUrJZtFS71nXrPraCkZM4YyYoog06FhbqDHzWwYdjLJYkvJAMDfNFfqR1QJbt3Uj88WaBy7QLB9YBQAcOfTA9Htk04fO8Cejuk2nCYiWgxLRSmf3D5DbEBNROnI+YxbRJoB/ALAh1R1HMA3AZwD4DIAJwB8KcntbhCRLSKyZXBwMNdlLLC5bwTLW+uxOqakam1nExqc8euJMoYuWtkKEWDnsbG8r2fngH2f61a1LbisrcGLtZ2N2BXzuIMTAYQtjQaGzl9mB4/2nZwEAOw6NoavPXwA33/88Lz76h+xy9XSKSOyM4YSZ0dNu6VkBRxXHwrPvQU6PRGYV0YGACucyWQcVZ8Z08g8Y8gNij550E43dn8v2hvjMoacQBEzhqhSeAxB2FqYaTkZCGPQyVScDUVSloXdtrkfX7j/WQDzewa5X9+z82R0W+zEsXw2niYiIspEb48fx0ZnMJBgyA0RUayczrhFxAs7KPQTVb0DAFT1lKpGVNUC8G0AvYluq6o3q+p6VV3f1dWVyzIWsCzFEweH0NvjnxcgMQ2JZue01i/sndNU58HZS5qw61j+M4Z2HR+HIcCFKxZmDAHAupVt2HV8LjB0zBlV7/YYOqerGYbMTSb7sjPt5tCZKZyZDERv1z88jTUpJpK52tMqJct/jyG3NCwYV0rmZgi5lrWx+XQ23B5DmVjjb0Rvtx93bBuINp4GAH98KZmTMcQeQ1QpPKZESyT3n5rAY/vtDyJe8aVHceVnHgQAvPa/foeLP/kbAMDodBDHnf1vrI/8Yge+/vDBedtEgE/9es+ij8+wEBERlYrbZ2hzH7OGiGhxuUwlEwDfBbBXVb8cs31FzNX+CMCu7JeXnT0nxnFmMoCXnr8w4PR8JzCTKGMIAC5e1TYvcydfdh0bw7lLm+eVSsVat6oN/cMz0RNy98TEzRiq95roXtKE/ScnsPXICH777Gm84vnLAABb+kYA2H2MBkZm0uovBNhlQqPTwYRjLKMZQ4UoJXOyWcIxgaFT47NJM4ZYSpYZ0xB4sgimvfmKVTg4OIXtA2MYdnsMxZWSdUZ7DPFnQpXBzhiy93Gv+spjeKfTvPnk+Fyz/4ODcyW6V3/ut7jqc78FAHz38cP4u1ueXnCfsbtMN+somYf2Ju49REREVGjPW96KlnoPNrGcjIhSyOXs7moA7wDwh3Gj6T8vIjtFZAeAlwH4cD4WmolH9p0GALwkQWDoQqfPUKIeQ4AdoDk5PpvyzX6mdh4bS1hG5rrYuczNVpoLDM1l0VywrAX7T03gS7/ZhyXNPnzxTy6Bz2NE+ymNTocwGQjPK59bTHujF2FLMRkIL7hsKlDAHkNuKVlkbjR6ooyh5a0sJcuGx5CsMnpec8kK1HkM3LFtAKPTQRiCBdP73Abt/JFQpTANA5FI+nk7U8G5qZSf/vUe3LX9+ILrHEuQUZTMh3+2Pe3rElFtYy4u5ZtpCHq72WeIiFLLZSrZ46oqqnpJ7Gh6VX2Hql7sbH+DquZ3HEwaHt43iItXtaErLgMFSJ0xtC4aoMlf1tApJ9C0bmXywNBFK+11uf2Njo/OoKXeg5aYE/Pzl7Xg0JkpPHFwCH99zblob/ThstXt2HzEzhjKZCIZMNc/ZjRBOdnOY2PwGJJwilqu4kvJxmZCCIatBT+vpe64ekYhMmIYAjODUfWu1novXnXRcty1/ThOjc+ivdG3oMm029TcZMYQVQiPOZcxlK3RJL3YiIiIyl1vjx+HBqfy/qE3EVWXqju7G50O4umjI3jZBYn7Fq1b1Yarz+3E+m5/wsvjAzT54Daevnh18sBQR5MPqzsaogGpY6Oz0f5CLrc/0vLWevz5hrMAAOu7O7D72Bimg2H0D9ufYqfbY8jN/kjUgPqJg0O4/Kx2NNUVoMeQMX8qWXRUfVzGUJ3Hnq7mZSlZRrLNGALscrLR6RDu3XUS7Y0Lg6duzyE2n6ZKkaz5dCqxzagv+9QD0a+7b7w7L+siIiIqBvYZIqJ0VN0Z9++eOwNLgZdesDTh5fVeEz/5Py/EZWvaE17eUu91GlDnLzC06/gYZJHG066LV801oD4+OhPtLxR7uSHAh15xHuqdaWFXdvsRthTP9I/GZAylV0rm9o+Jzxganw1h58AoXnTOkrTuJ1OGIfAYMhcYGrcDQ8sSZHhdsLwFy1sXbqfkDMk+MPTic5egq6UOE7Nh+OMmkgFA95JGiCBhNh5ROYrtMZQJtxn1Yv76J1uzWRIREVHRrFvVhgavyT5DRLSo/KeDlNgj+wbR3uhNGvhJx0Wr2rA1j1H1XcfGcE5Xc8rsm3Wr2nDvrpMYmwnh+NgMrljbPu/yNf5GbPzYK+adlF9xVgdE7AbUdvmPd1752WLak2QMbTo0DEuBq87pTOt+suExBWGn78cppwlsfMYQAHz7nes5AStDHlOyzujxmAbedNlKfPt3hxeMqgeAc5e2YOs/v3LBtDKicmUaBlTtaZX5VogJlkRERPnkNQ28YG0H+wwR0aKqKmPIshSP7j+Nl5zXlVMw4eJVrTg+NouhyfzU4u48NoZ1KxfPFgLm+httPjyM0enQgowhYGGmRlujFxcsa8HmvmH0j8ykXUYGzGUMjUzNDww9cXAIdR4Dl5/VnvZ9ZcprGtEeQ/tPTQDAgqlkANBU54lmR1F6TMPI6ff/zVesBgD4mxIHGBkUokricXqa5dpniIiIqFL19vjx7MlxjCXoK0pEBFRZYGj38XGcmQzimiT9hdLlBmhi+wwNjExHAxiZOD0xi1PjgUUnkrncyWT37z4JAAt6DCWzvrsD246M4MjQVNplZIDdY2h5az0eevb0vO1PHDyDK7v9qPMULiDjMw1MByL4f7/ajW89dggvPm9JQfoZ1SJTkFNg6PkrWvHuq7rx6nUr8rgqotJws+ciDAwRUZnjXooKpbfHD1X2GSKi5KoqMLTYmPpMXLRy/mSyyUAYb73pSfzxN5/A2ExmkXb3Pi5OIzDkb/JhVXtDNFCTKGMokSu7/ZgKRnBkaDqjjCHDELz9hWfhd8+dwYHTdtBraDKAZ09O4EUFLCMD7Iyhn2/tx/d/34e/vLoH33v3lQV9vFqytrMp52lyn3zDRXjZ8xL36SKqJG6QNBTTgFqVp19ERFQ7LlvTDp9pYBMDQ0SURHUFhvYP4pLVbVjSnFtj3LYGL9Z2Nkb7R3zhvmdxYnwW47NhfPd3hzK6L/c+LkojMAQA61a1Ytgp7cokMORanWFA4Pres+DzGPjhE0cAAE8dsg8YhewvBACNPhP1XhP/ff3l+MTrL4SXI+nz5pNvuAg3v3N9qZdBVBaiGUORuWBQbPbQxkND0a8ZMCKiUmJHRSqUeq+JS9e0sc8QESVVFWfjw1NBfPfxw3j66AiuSTKNLFPrVrVh57ExbD0yjB89dQTvelE3XnvxCnz38cPRwE0iP9/Sj//78+0YdRo67zw2hrOXNKE5zTKpdU62kiGJp3QlsrK9IVp2tqYj/VIyAOhsrsMbLl2JX2wbwNhMCE8cPIPmOk9aGU65+OrbLsO9H3wxXn/pyoI+DhHVNtMJOsf2GIr9+qTT/B4AvvLA/uItjIiIqIh6e/zYdWwMU4FwqZdCRGWoogNDm/uG8f6fbMOGzz6IT/96Dy5d047re9fk5b4vXtWGY6Mz+PDPtmNlWwP+8doL8OFXnoeZUATfevRgwtuMTgfxqV/twe1bB/C6/34cu46NYdexsbT6C7nWrbavu7y1Hp4MsmjWd3cAsCeXZerdV3VjOhjBz7f048mDQ9jQ48/osbNxyep2rO1sKuhjEBF5E/QYGo1pvhkIzZWY/ddvDxRvYUREREXU29OJiKXYdnSk1EshojJU0YGhLX0j+P3BM3jHC7tx/4degjv/5mqsaMssYyYZN2Pm6PA0PvNH69BU58G5S1vwpstW4YdP9uF0zKfMrpsfO4TJYBif/+NLYFmKN3/zCZwYm80o+8bNGEq3jMz1motX4PxlzRn1GIo+5qo2XNndgZsePYRDZ6YK3l+IiKhYoj2GInMBoE/etTv69T27ThR9TURERMX2grUdMA3BJpaTEVECFR0YetdVa7HxYy/HJ15/IS5Y3pLX+163sg1eU/Dmy1fNK0/74CvOQyii+MYj87OGzkwG8P3f9+H1l6zEW9evwa//7sXY0GP3/rlibUfaj9vVUoe1nY04uyuzbJprL1qO33z4pfB5svuRvvuqHpyZDAAArjpnSVb3QURUbhKNqx+dmSsHfmTfYNHXREREVGzNdR6sW9nKPkNElFBFzwdv9BVu+W2NXtz9dy/G2s75GThrO5vw1vWr8dONR3HNBV3RoNE3HzmIQDiCD73iPAD2hLEf/EUvDg5O4vxlmQWtbnnvC9FUwOeWyKsuWoYVbfWYDUXwvDwH2YiI4onIdQD+E4AJ4Duq+rlCPE5LnRcAMDE7Vz4WjrDJNBER1Z7eHj9++OQRzIYiqPeapV4OEZWRis4YKrTzl7WgzrNwp/nhV56Ps7ua8Bc/2Iz/fPA5HB+dwY+fOoK3XLEaZ3c1R69nGpJxUAiwy8jaGr05rT1TXtPAl/7kUvz7my+GYXAuBhEVjoiYAL4O4NUALgRwvYhcWIjHam2w96X/HdM/aMsR9lcgIqLa09vTiWDYwo6BsVIvhYjKTEVnDJXK0pZ63Pk3V+Pjd+7EVx7cjx88cRiqir97+XmlXlpOrjqXJWREVBS9AA6o6iEAEJFbAbwRwJ58P5C/yQ4MPbDnVL7vmogorxabekuUD1c6w2p+vqUfYzOhFNcmonLzonM60552nikGhrLU4DPxpbdeisvXduBTv9qNP9+wNquJYERENWgVgP6Y7wcAbIi/kojcAOAGADjrrLOyeqBzlxa3NPacriYcHJwq6mMSUXU4lWCwCVE+tTf6cMnqNvx86wB+vnWg1Mshogw9+PcvxblLm1NfMQsMDOVARPCOF67Fa9YtR3ujr9TLISKqFInqVRc0/lHVmwHcDADr16/PujFQ3+dei+GpIAYnAljeWg/TaUgd+4mLqkJEov/Hb0/FsrSkZbix6wfs45NlKUQAS4Fg2EK918DAyAwGJwO4dHU7+oencejMJF6w1o/jozPobPbB3+jDM/2jGJ8N4cpuP06NBzAZCOO8pc04MjQNADh/WTMODE6i78wU1nf70XdmCqPTIVyyug1Hh6fh8xg4u6sZO/pHMREIY0OPH7uPj+OZ/lG85YrVePbkOFrqvbh8TTvOTAYwPB3EitYGHDwziVDYwqVr2nF0eBqj0yGsW9WKkekQjgxN4aIVbdh/egIeQ3DZmnYcOjOFidkwLl3dhpPjszBF4G/yoW9oGnUeA53NPkQshWkI6jwmTo3PIhSxsLytHhOzYYxOh7C0tQ7BsIUTo7Po6WrCwdOTsFRxztJmTMyGoapY1d6AA6cnMR2MYI2/Ef3D01jWWo+2Bi+e6R/FirZ6rGivx8hUCKcnZtHR6MPQVBD1XgPdnU04fGYKEUuxpLkOgXAEk4Ew1nY2YfexMaxoa8DytnqcHJvFVDCMFW31GJkOIWJZWN3RiGOjM1jSVIfmeg9mQxGYhsAQQShiRSfuTQXCaG/0QQDsPDaGNf5GNPrsMniPc52BkRkAwPK2eogAXsOA+2s9GQjDaxqYDIThMQRe00AoYqHea6LOY2A6GMHoTAhdzXXRXl11XhNHhqbQXOdBe4MPh85MosFnIhRWTAXDaK7zYCYUwfhMCN1LmjA0ab8eAsG6Va04OjyNiKUwRLD7+DguWtmKJS112HdyAqs7GhCKWDg6NI22Rq/9Mz0zjaWtdTg9HsBsKIK1nY2YDVk4MTaDtZ1NaG3w4PR4APVeA+cubUEwbOHMZABdLXUwRGAa9t/G4GQAnU11CEUsDIzM4Cx/IzyG4NTELPxNPtR5zLT+lhPtL1QVwYgFn2kgbCkiTsN7n2lgMhhGa70X4YgVvb67JhFBxFLMhiJoKtCnwESxfvyXG9A/Ml3qZRBRFlZ35GcCeyLivokspfXr1+uWLVtKvQwiorIkIltVdX2p15EvIvIiAJ9U1Wud7z8KAKr678luw+MEEVFi1XaMyBaPE0REiaVznGDzaSIiKrbNAM4TkR4R8QF4G4C7SrwmIiIiIqKaxJxVIiIqKlUNi8gHANwPe1z991R1d4mXRURERERUkxgYIiKiolPVewDcU+p1EBERERHVOpaSERERERERERHVKAaGiIiIiIiIiIhqFANDREREREREREQ1ioEhIiIiIiIiIqIaxcAQEREREREREVGNYmCIiIiIiIiIiKhGMTBERERERERERFSjRFVLvQaIyCCAI1nefAmAM3lcTiXjazGHr8UcvhZzKvW1WKuqXaVeRCnxOJERPt/qxudbvbJ9rjV/jAB4nMgQn291q6XnW0vPFSjgcaIsAkO5EJEtqrq+1OsoB3wt5vC1mMPXYg5fi9pUaz93Pt/qxudbvWrpuZabWnvt+XyrWy0931p6rkBhny9LyYiIiIiIiIiIahQDQ0RERERERERENaoaAkM3l3oBZYSvxRy+FnP4Wszha1Gbau3nzudb3fh8q1ctPddyU2uvPZ9vdaul51tLzxUo4POt+B5DRERERERERESUnWrIGCIiIiIiIiIioixUdGBIRK4TkX0ickBEbiz1eopJRNaIyMMisldEdovIB53tfhF5QESec/7vKPVai0FETBF5WkR+7Xxfk68DAIhIu4jcLiLPOr8fL6rV10NEPuz8fewSkVtEpL5WX4taVQ3HiWz29yLyUec57xORa2O2v0BEdjqX/ZeISCmeUzoy2a9X+vPNdL9dyc830/1yJT5XEfmeiJwWkV0x2/L2HEWkTkR+5mzfKCLdRX2CVaQajhFAbR4naukYAfA4UW3PtSyPE6pakf8AmAAOAjgbgA/AdgAXlnpdRXz+KwBc4XzdAmA/gAsBfB7Ajc72GwH8R6nXWqTX4+8B/BTAr53va/J1cJ7vDwH8H+drH4D2Wnw9AKwCcBhAg/P9bQDeXYuvRa3+q5bjRKb7e+ey7QDqAPQ4r4HpXLYJwIsACIB7Aby61M9vkeed1n69Gp5vJvvtSn6+me6XK/W5AngJgCsA7IrZlrfnCOBvANzkfP02AD8r9XOuxH+okmOE81xq7jiBGjpGOGvlcaKKnivK8DhRyRlDvQAOqOohVQ0CuBXAG0u8pqJR1ROqus35egLAXth/SG+EveOA8/+bSrLAIhKR1QBeC+A7MZtr7nUAABFphb2j+S4AqGpQVUdRo68HAA+ABhHxAGgEcBy1+1rUoqo4TmSxv38jgFtVNaCqhwEcANArIisAtKrqk2q/U/gRyvT3P8P9ekU/3yz22xX9fJHZfrkin6uqPgZgOG5zPp9j7H3dDuDl5fRJeAWpimMEUHvHiVo6RgA8ToDHiaIcJyo5MLQKQH/M9wPOtprjpIZdDmAjgGWqegKwDxIAlpZwacXyVQAfAWDFbKvF1wGwP/UaBPB9J732OyLShBp8PVT1GIAvAjgK4ASAMVX9DWrwtahhVXecSHN/n+x5r3K+jt9ejr6K9Pfrlf58M91vV+zzzWK/XLHPNYF8PsfobVQ1DGAMQGfBVl69qu4YAdTMceKrqJ1jBMDjBI8TRThOVHJgKFHEq+ZGrIlIM4BfAPiQqo6Xej3FJiKvA3BaVbeWei1lwgM7LfGbqno5gCnYqYg1x6nLfSPslMuVAJpE5O2lXRUVWVUdJzLY3yd73hXxemSxX6/o54vM99sV+3yz2C9X7HPNQDbPsZqefylV3etYC8eJGjxGADxO8DixUN6PE5UcGBoAsCbm+9Ww08xqhoh4Ye/8f6KqdzibTzlpZXD+P12q9RXJ1QDeICJ9sFOA/1BE/ge19zq4BgAMqOpG5/vbYR9IavH1eAWAw6o6qKohAHcAuAq1+VrUqqo5TmS4v0/2vAecr+O3l5tM9+uV/nwz3W9X8vPNdL9cyc81Xj6fY/Q2TqlFGxaWJFBqVXOMAGrqOFFrxwiAxwkeJ4pwnKjkwNBmAOeJSI+I+GA3VbqrxGsqGqdG8LsA9qrql2MuugvAu5yv3wXgl8VeWzGp6kdVdbWqdsP+Hfitqr4dNfY6uFT1JIB+EbnA2fRyAHtQm6/HUQAvFJFG5+/l5bBr7mvxtahVVXGcyGJ/fxeAtzkTKXoAnAdgk5OWPCEiL3Tu850ow9//LPbrlf58M91vV/LzzXS/XMnPNV4+n2Psff0x7L+RSv0kvJSq4hgB1NZxotaOEQCPE+BxojjHCS2DrtzZ/gPwGthd9w8C+Hip11Pk5/4HsNPBdgB4xvn3Gti1gw8BeM7531/qtRbxNbkGc5MJavl1uAzAFud3438BdNTq6wHg/wF4FsAuAD+G3c2/Jl+LWv1XDceJbPb3AD7uPOd9iJnCAWC98/dwEMDXAEipn1+K557Wfr3Sn2+m++1Kfr6Z7pcr8bkCuAV2b4wQ7E9t35PP5wigHsDPYTcg3QTg7FI/50r9Vw3HCOd51ORxolaOEc5aeZyooudajscJ94ZERERERERERFRjKrmUjIiIiIiIiIiIcsDAEBERERERERFRjWJgiIiIiIiIiIioRjEwRERERERERERUoxgYIiIiIiIiIiKqUQwMERERERERERHVKAaGiIiIiIiIiIhqFANDREREREREREQ16v8DpoYZKf1hgRQAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "agent.train(num_frames)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test\n", "\n", "Run the trained agent (1 episode)." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Moviepy - Building video /Users/jinwoo.park/Repositories/rainbow-is-all-you-need/videos/dueling/rl-video-episode-0.mp4.\n", "Moviepy - Writing video /Users/jinwoo.park/Repositories/rainbow-is-all-you-need/videos/dueling/rl-video-episode-0.mp4\n", "\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " " ] }, { "name": "stdout", "output_type": "stream", "text": [ "Moviepy - Done !\n", "Moviepy - video ready /Users/jinwoo.park/Repositories/rainbow-is-all-you-need/videos/dueling/rl-video-episode-0.mp4\n", "score: 200.0\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\r" ] } ], "source": [ "video_folder=\"videos/dueling\"\n", "agent.test(video_folder=video_folder)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Render" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Played: videos/dueling/rl-video-episode-0.mp4\n" ] } ], "source": [ "import base64\n", "import glob\n", "import io\n", "import os\n", "\n", "from IPython.display import HTML, display\n", "\n", "\n", "def ipython_show_video(path: str) -> None:\n", " \"\"\"Show a video at `path` within IPython Notebook.\"\"\"\n", " if not os.path.isfile(path):\n", " raise NameError(\"Cannot access: {}\".format(path))\n", "\n", " video = io.open(path, \"r+b\").read()\n", " encoded = base64.b64encode(video)\n", "\n", " display(HTML(\n", " data=\"\"\"\n", " \n", " \"\"\".format(encoded.decode(\"ascii\"))\n", " ))\n", "\n", "\n", "def show_latest_video(video_folder: str) -> str:\n", " \"\"\"Show the most recently recorded video from video folder.\"\"\"\n", " list_of_files = glob.glob(os.path.join(video_folder, \"*.mp4\"))\n", " latest_file = max(list_of_files, key=os.path.getctime)\n", " ipython_show_video(latest_file)\n", " return latest_file\n", "\n", "\n", "latest_file = show_latest_video(video_folder=video_folder)\n", "print(\"Played:\", latest_file)" ] } ], "metadata": { "kernelspec": { "display_name": "rainbow-is-all-you-need", "language": "python", "name": "rainbow-is-all-you-need" }, "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.8.12" } }, "nbformat": 4, "nbformat_minor": 4 }