{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "hWpqO3PtSA3s" }, "source": [ "## Self-play\n", "Following notebook will show you how to train agent to learn play in our [game](../../environment.rst) by sefl-play using our [API](../../api/index.rst)\n", ". This notebook is easier to understand if you has already read about our [game](../../environment.rst). \n", "\n", "In this example, we will train an agent to control robot on the board with 3 robots and battery isn't considered." ] }, { "cell_type": "markdown", "metadata": { "id": "7_pLHbYRCTbs" }, "source": [ "### Install our library." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2024-11-28T08:42:29.001608Z", "iopub.status.busy": "2024-11-28T08:42:29.00094Z", "iopub.status.idle": "2024-11-28T08:42:31.704286Z", "shell.execute_reply": "2024-11-28T08:42:31.70335Z", "shell.execute_reply.started": "2024-11-28T08:42:29.001561Z" }, "id": "9nSQYwzN6MWP", "trusted": true }, "outputs": [], "source": [ "%pip install -q rbgame" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2024-11-28T08:46:33.459882Z", "iopub.status.busy": "2024-11-28T08:46:33.459048Z", "iopub.status.idle": "2024-11-28T08:46:33.464612Z", "shell.execute_reply": "2024-11-28T08:46:33.463781Z", "shell.execute_reply.started": "2024-11-28T08:46:33.459847Z" }, "id": "pE56ej286MWT", "trusted": true }, "outputs": [], "source": [ "import os\n", "import time\n", "import math\n", "from pprint import pprint\n", "from typing import Any\n", "\n", "import numpy as np\n", "import yaml\n", "import matplotlib.pyplot as plt\n", "import torch\n", "import gymnasium as gym\n", "from torch import nn, optim\n", "import pygame\n", "from tianshou.utils.net.common import Net\n", "from tianshou.policy import DQNPolicy, C51Policy\n", "from tianshou.data import PrioritizedVectorReplayBuffer\n", "from rbgame.trainer import DecentralizedTrainer\n", "from rbgame.agent.rl_agent import OffPolicyAgent" ] }, { "cell_type": "markdown", "metadata": { "id": "_SEY3dLv14yZ" }, "source": [ "### Create the neural network and policy.\n", "Simply, policy is neural network with 2 main methods:\n", "\n", "* `forward()`, what shows how policy can provide action based on the input observation.\n", "* `update()`, what shows how policy can update its networks.\n", "\n", "For policies implementions, we use friendly and easy customizable library tianshou. Visit [their documentation](https://tianshou.org/en/stable/index.html) for more details.\n", "\n", "Because our action space is discrete, the most efficient and suitable simple algorithm recommended is [DQN](https://arxiv.org/pdf/1312.5602).\n", "\n", "For now, we're using decentralized method which mean each agent controls one robots and they only learns to optimize its own reward, they're not concerned about what other do. Therefore, in training phase, we train agents independently and in test phase, they can play together as one team. For example, we train 8 robots and after that, we let 4 robots play in one team. \n", "\n", "Because observation from our environment is feature vector of all robots so we don't need complicate CNN or RNN to extract features. We need only simple multi-layer perceptron." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2024-11-28T08:47:32.541455Z", "iopub.status.busy": "2024-11-28T08:47:32.540543Z", "iopub.status.idle": "2024-11-28T08:47:36.171367Z", "shell.execute_reply": "2024-11-28T08:47:36.170261Z", "shell.execute_reply.started": "2024-11-28T08:47:32.541417Z" }, "id": "mPI_FNdq6MWW", "trusted": true }, "outputs": [], "source": [ "# see about Net object in https://tianshou.org/en/stable/03_api/utils/net/common.html#tianshou.utils.net.common.Net\n", "net = Net(\n", " # state_shape is obsevation vector shape,\n", " # every robot have 3 features (x, y, mail_index) and we have 3 robots on the board\n", " state_shape=3*3,\n", " # 5 actions are possible\n", " action_shape=5,\n", " # network hidden layer sizes\n", " hidden_sizes=[1024, 1024, 512, 512, 256, 256, 128, 128, 64, 64],\n", " # LayerNorm for avoid vanishing and exploding gradients\n", " norm_layer=nn.LayerNorm,\n", " # GPU divice\n", " device='cuda',\n", " # dueling part of network, see https://arxiv.org/pdf/1511.06581\n", " dueling_param=[{'hidden_sizes':[32], 'norm_layer':nn.LayerNorm},\n", " {'hidden_sizes':[32], 'norm_layer':nn.LayerNorm}],\n", ")\n", "# see about DQNPolicy in https://tianshou.org/en/stable/03_api/policy/modelfree/dqn.html#tianshou.policy.modelfree.dqn.DQNPolicy\n", "policy = DQNPolicy(\n", " model=net,\n", " # Adam optim with learning rate = 0.0001\n", " optim=optim.Adam(net.parameters(), lr=0.0001),\n", " # discrete action space with 5 possible actions\n", " action_space=gym.spaces.Discrete(5),\n", " # discount_factor \\gamma\n", " discount_factor=0.99,\n", " # multi-step return n, see https://arxiv.org/pdf/1509.06461\n", " estimation_step=30,\n", " # frequency for target network updating\n", " target_update_freq=500,\n", " # Double DQN, see https://arxiv.org/pdf/1509.06461\n", " is_double=True,\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "qVq2-Nyz_PLd" }, "source": [ "Let see our network architure." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "w25x_3fO_OgY", "outputId": "e17bbffa-b49d-4dd3-f252-8903f964594c" }, "outputs": [ { "data": { "text/plain": [ "Net(\n", " (model): MLP(\n", " (model): Sequential(\n", " (0): Linear(in_features=9, out_features=1024, bias=True)\n", " (1): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (2): ReLU()\n", " (3): Linear(in_features=1024, out_features=1024, bias=True)\n", " (4): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (5): ReLU()\n", " (6): Linear(in_features=1024, out_features=512, bias=True)\n", " (7): LayerNorm((512,), eps=1e-05, elementwise_affine=True)\n", " (8): ReLU()\n", " (9): Linear(in_features=512, out_features=512, bias=True)\n", " (10): LayerNorm((512,), eps=1e-05, elementwise_affine=True)\n", " (11): ReLU()\n", " (12): Linear(in_features=512, out_features=256, bias=True)\n", " (13): LayerNorm((256,), eps=1e-05, elementwise_affine=True)\n", " (14): ReLU()\n", " (15): Linear(in_features=256, out_features=256, bias=True)\n", " (16): LayerNorm((256,), eps=1e-05, elementwise_affine=True)\n", " (17): ReLU()\n", " (18): Linear(in_features=256, out_features=128, bias=True)\n", " (19): LayerNorm((128,), eps=1e-05, elementwise_affine=True)\n", " (20): ReLU()\n", " (21): Linear(in_features=128, out_features=128, bias=True)\n", " (22): LayerNorm((128,), eps=1e-05, elementwise_affine=True)\n", " (23): ReLU()\n", " (24): Linear(in_features=128, out_features=64, bias=True)\n", " (25): LayerNorm((64,), eps=1e-05, elementwise_affine=True)\n", " (26): ReLU()\n", " (27): Linear(in_features=64, out_features=64, bias=True)\n", " (28): LayerNorm((64,), eps=1e-05, elementwise_affine=True)\n", " (29): ReLU()\n", " )\n", " )\n", " (Q): MLP(\n", " (model): Sequential(\n", " (0): Linear(in_features=64, out_features=32, bias=True)\n", " (1): LayerNorm((32,), eps=1e-05, elementwise_affine=True)\n", " (2): ReLU()\n", " (3): Linear(in_features=32, out_features=5, bias=True)\n", " )\n", " )\n", " (V): MLP(\n", " (model): Sequential(\n", " (0): Linear(in_features=64, out_features=32, bias=True)\n", " (1): LayerNorm((32,), eps=1e-05, elementwise_affine=True)\n", " (2): ReLU()\n", " (3): Linear(in_features=32, out_features=1, bias=True)\n", " )\n", " )\n", ")" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net" ] }, { "cell_type": "markdown", "metadata": { "id": "HROUqP_N_e-o" }, "source": [ "### Create memory.\n", "We'll use [Prioritized Replay Buffer](https://arxiv.org/pdf/1511.05952). To accelerate training, we'll use two stuffs:\n", "\n", "* First, agent parallel plays in many environments (neural network can feed forward batch of observations from many environments, its faster than feed each one through).\n", "* Second, agent not only save its own transitions, but also transitions of other agents.\n", "\n", "So we need to save transitions correctly in memory. That mean transitions for one agent and one environment need to be saved exactly in one replay buffer." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2024-11-28T08:48:57.685333Z", "iopub.status.busy": "2024-11-28T08:48:57.684277Z", "iopub.status.idle": "2024-11-28T08:49:01.45006Z", "shell.execute_reply": "2024-11-28T08:49:01.449036Z", "shell.execute_reply.started": "2024-11-28T08:48:57.685299Z" }, "id": "3LIxIvIA6MWX", "trusted": true }, "outputs": [], "source": [ "# see about PrioritizedVectorReplayBuffer in \n", "# https://tianshou.org/en/stable/03_api/data/buffer/vecbuf.html#tianshou.data.buffer.vecbuf.PrioritizedVectorReplayBuffer\n", "memory = PrioritizedVectorReplayBuffer(\n", " # total size of memory is product of maximum number parallel environments steps and number episodes\n", " # to train, so memory can storage all excuted transitions during training\n", " total_size=500*5000,\n", " # agent save not only its transitions but also transitions of other agents so\n", " # number buffers is product of number parallel environments and numbers robots\n", " buffer_num=3*16,\n", " # prioritization exponent \\alpha\n", " alpha=0.6,\n", " # prioritization importance sampling \\beta\n", " beta=0.4,\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "hIxQUPe1DfAZ" }, "source": [ "### Create agent.\n", "DQN is off-policy algorithm so we use [OffPolicyAgent](../../api/agent/rl_agent.rst).\n", "\n", "We're using self-play, which mean one agent'll play as all players, it controls one robot in current turn and continues to control other in next turn. So all elements in `agents` list point to one unique [OffPolicyAgent](../../api/agent/rl_agent.rst) object." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2024-11-28T08:49:29.395553Z", "iopub.status.busy": "2024-11-28T08:49:29.394948Z", "iopub.status.idle": "2024-11-28T08:49:29.399868Z", "shell.execute_reply": "2024-11-28T08:49:29.399031Z", "shell.execute_reply.started": "2024-11-28T08:49:29.395518Z" }, "id": "L-cPxA6n6MWX", "trusted": true }, "outputs": [], "source": [ "agent = OffPolicyAgent(\n", " policy=policy,\n", " memory=memory,\n", " # how many times agent samples from memory and learns per one step, using only in offpolicy algorithms.\n", " update_per_step=0.02,\n", ")\n", "agents = [agent]*3" ] }, { "cell_type": "markdown", "metadata": { "id": "LE0aZue-ECbw" }, "source": [ "### Create trainer.\n", "First, we need to adjust some hyperparameters during training. They're exploration coefficient ϵ, which decides how agent explores during training, and prioritization importance sampling β of Prioritized Replay Buffer.\n", "\n", "In this example, we'll let α decreases from 1.0 → 0.05 along 5000 episodes of traning by following function:\n", "$$ϵ = max(b*f^n, e)$$\n", "where $b=1.0$ - begin value, $f = 0.9995$ - decay factor, $e = 0.05$ - end value, and $n$ - number collected episodes.\n", "\n", "And the β is adjusted from 0.4 → 1.0 according to recommendation from [original paper](https://arxiv.org/pdf/1511.05952):\n", "$$\\beta = e + (b-e)*e^{-rn}$$\n", "where $b=0.4$ - begin value, $r = 0.002$ - decay rate, $e = 1.0$ - end value, and $n$ - number collected episodes." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def exponential_annealing(begin, end, decay_factor):\n", " return lambda episode: max(begin*decay_factor**episode, end)\n", "\n", "def natural_exponential_annealing(begin, end, rate):\n", " return lambda episode: end + (begin - end) * math.exp(-rate * episode)\n", "\n", "def cosine_annealing(begin, end, steps):\n", " return lambda x: max((1 - math.cos(x * math.pi / steps)) / 2, 0) * (end - begin) + begin if x <= steps else end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let see graphics of these functions." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "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A8HBwXXej4iIgEKhqJOH1NRUZGRk1MnDiRMn6gxu4+Li4OTkhNDQUFOf6/dR24ffOw0zGo3Q6XS8/hZy77334sSJEzh69Kjpo0+fPnjmmWdMnzMPllVaWopz587B19eX3wc2gGMoy+IYyjI4hrJOHENZFsdQ1qfFjqGabcl0G7d69WpRpVKJK1euFE+dOiW++OKLoouLS52V6qnxSkpKxCNHjohHjhwRAYgLFiwQjxw5Il68eFEUxZrHGbu4uIi//PKLePz4cfGhhx5q8HHGvXr1Evfv3y/u2bNH7NixY53HGRcVFYne3t7iuHHjxOTkZHH16tWiRqPh44yvmTp1qujs7CwmJCTUeYxoeXm5qc+UKVPEtm3bijt27BAPHTokRkVFiVFRUab3ax8jOnz4cPHo0aPili1bRE9PzwYfI/rqq6+KKSkp4uLFi/kY12veeOMNcefOnWJ6erp4/Phx8Y033hAFQRC3bdsmiiKvv1Suf3KMKDIP5vbPf/5TTEhIENPT08U//vhDjI6OFj08PMTc3FxRFHn9bQHHUM2LYyjpcQwlPY6hrBPHUJZlK2MoFqWaYNGiRWLbtm1FpVIp9uvXT9y3b5/UIbVYv//+uwig3seECRNEUax5pPFbb70lent7iyqVSrz33nvF1NTUOvsoKCgQn3rqKdHBwUF0cnISJ02aJJaUlNTpc+zYMXHQoEGiSqUS/f39xQ8++MBSp2j1Grr+AMSvv/7a1KeiokKcNm2a6OrqKmo0GvHhhx8Ws7Ky6uznwoUL4siRI0V7e3vRw8ND/Oc//ynq9fo6fX7//XcxPDxcVCqVYvv27escozV77rnnxHbt2olKpVL09PQU7733XtNgShR5/aXy1wEV82BeY8eOFX19fUWlUin6+/uLY8eOFdPS0kzv8/rbBo6hmg/HUNLjGEp6HENZJ46hLMtWxlCCKIpi8827IiIiIiIiIiIiujWuKUVERERERERERBbHohQREREREREREVkci1JERERERERERGRxLEoREREREREREZHFsShFREREREREREQWx6IUERERERERERFZHItSRERERERERERkcSxKERERERERERGRxbEoRUSSSEhIgCAIWLt2rdShNKv/b+/+Y6qs/jiAv68g3BvIvfxQEFQE7oWQUDeIllx+jB8jgsKaYTjgwkDTZVYbFiAOMjUIjOtc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iISEBHHhwgWT60+cOCGeffZZ4ezsLGxtbYWnp6dITk4WtbW194zpbnp7e0VeXp5Qq9XCxsZGuLi4iAULFoiysjJx+/ZtIcRf2xmXlpaKTZs2iZkzZwpbW1sRFhYmTp06ZdTendsZ19bWiqSkJOHu7i5sbGyEu7u7SElJMdlCuaOjQ2RmZgoXFxdhY2MjAgMDR91Wuru7W6SlpQkHBwehVCpFWlqaOHHixKjbULe0tIj09HTh5uYmJk+eLDw8PERiYqKoqamR6qxfv16EhIQIlUolFAqFePjhh8WGDRukeyciIrJEzKHujTkUcyiiiSAT4h+smkdEZEFaW1vh5eWF0tJS5OTkPOhwiIiIiP4vMIcionvhmlJERERERERERGR2nJQiIiIiIiIiIiKz46QUERERERERERGZHdeUIiIiIiIiIiIis+ObUkREREREREREZHaclCIiIiIiIiIiIrPjpBQREREREREREZkdJ6WIiIiIiIiIiMjsOClFRERERERERERmx0kpIiIiIiIiIiIyO05KERERERERERGR2XFSioiIiIiIiIiIzI6TUkREREREREREZHb/ATDN01EY+rfaAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# A scheduler to adjust exploration coefficient \\epsilon during training\n", "eps_schedule = exponential_annealing(1.0, 0.05, 0.9995)\n", "# A scheduler to adjust prioritization importance sampling \\beta during training\n", "beta_schedule = natural_exponential_annealing(0.4, 1.0, 0.002)\n", "\n", "fig, axes = plt.subplots(1, 2, figsize=(12, 4))\n", "axes[0].plot([eps_schedule(ep)for ep in range(5_000)])\n", "axes[0].set_ylabel(r\"$\\epsilon$\", rotation=\"horizontal\", fontsize=12)\n", "axes[0].set_xlabel(\"Number episodes\", fontsize=12)\n", "axes[0].set_title(r\"Typical $\\epsilon$ annealing schedule\", fontsize=12)\n", "axes[0].grid()\n", "axes[1].plot([beta_schedule(ep)for ep in range(5_000)])\n", "axes[1].set_ylabel(r\"$\\beta$\", rotation=\"horizontal\", fontsize=12)\n", "axes[1].set_xlabel(\"Number episodes\", fontsize=12)\n", "axes[1].set_title(r\"Typical $\\beta$ annealing schedule\", fontsize=12)\n", "axes[1].grid()\n", "fig.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we must to define some functions to specify what we do during training like adjusting hyperparameters and saving checkpoints. " ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2024-11-28T08:49:56.971802Z", "iopub.status.busy": "2024-11-28T08:49:56.971065Z", "iopub.status.idle": "2024-11-28T08:49:56.982351Z", "shell.execute_reply": "2024-11-28T08:49:56.981564Z", "shell.execute_reply.started": "2024-11-28T08:49:56.971764Z" }, "id": "fHKh2u9e6MWX", "trusted": true }, "outputs": [], "source": [ "FOLDER = 'DQNagent'\n", "os.makedirs(os.path.join(os.getcwd(), FOLDER), exist_ok=True)\n", "# best model checkpoint\n", "best_ckpt=os.path.join(FOLDER, 'best.pth')\n", "# last model checkpoint\n", "last_ckpt=os.path.join(FOLDER, 'last.pth')\n", "# optimizer checkpoint\n", "optim_ckpt=os.path.join(FOLDER, 'optim.pth')\n", "# policy config checkpoint\n", "policy_ckpt=os.path.join(FOLDER, 'policy.yaml')\n", "# detect model with best metric only begins after that episode\n", "episode_to_save=1000\n", "\n", "# called after a few episodes to change \\epsilon and \\beta\n", "def train_fn(episode: int, step: int) -> None:\n", " agent.policy.set_eps(eps_schedule(episode))\n", " agent.memory.set_beta(beta_schedule(episode))\n", "\n", "# called when detect better metric\n", "def save_best_fn(episode: int) -> None:\n", " if episode > episode_to_save:\n", " torch.save(agent.policy.state_dict(), best_ckpt)\n", "\n", "# called when training is finished\n", "def save_last_fn() -> None:\n", " torch.save(agent.policy.state_dict(), last_ckpt)\n", " torch.save(agent.policy.optim.state_dict() , optim_ckpt)\n", " policy_state = {}\n", " policy_state['type'] = agent.policy.__class__.__module__+\".\"+agent.policy.__class__.__name__\n", " policy_state['model'] = dict(\n", " type=agent.policy.model.__class__.__module__+\".\"+agent.policy.model.__class__.__name__,\n", " state_shape=3*3,\n", " action_shape=5,\n", " hidden_sizes=[1024, 1024, 512, 512, 256, 256, 128, 128, 64, 64],\n", " norm_layer=nn.LayerNorm.__module__+'.'+nn.LayerNorm.__name__,\n", " device='cuda',\n", " dueling_param=[{'hidden_sizes':[32], 'norm_layer':nn.LayerNorm.__module__+'.'+nn.LayerNorm.__name__},\n", " {'hidden_sizes':[32], 'norm_layer':nn.LayerNorm.__module__+'.'+nn.LayerNorm.__name__}],\n", " )\n", " policy_state['optim'] = dict(\n", " type=agent.policy.optim.__class__.__module__+\".\"+agent.policy.optim.__class__.__name__,\n", " )\n", " policy_state['action_space'] = dict(\n", " type=agent.policy.action_space.__class__.__module__+\".\"+agent.policy.action_space.__class__.__name__,\n", " n=5,\n", " )\n", " policy_state.update(dict(\n", " discount_factor=0.99,\n", " estimation_step=30,\n", " target_update_freq=500,\n", " is_double=True,\n", " ))\n", " with open(policy_ckpt, 'w') as file:\n", " yaml.dump(policy_state, file, default_flow_style=False, sort_keys=False)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "id": "qjDX9B9jGkqm" }, "outputs": [], "source": [ "# copy layout .csv file from our package to initalize environment\n", "%cp -r /usr/local/lib/python3.10/dist-packages/rbgame/assets ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we ready to create a [DecentralizedTrainer](../../api/trainer.rst)." ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "execution": { "iopub.execute_input": "2024-11-28T08:51:30.118922Z", "iopub.status.busy": "2024-11-28T08:51:30.118535Z", "iopub.status.idle": "2024-11-28T08:51:30.219622Z", "shell.execute_reply": "2024-11-28T08:51:30.218944Z", "shell.execute_reply.started": "2024-11-28T08:51:30.118891Z" }, "id": "2tL9Piyr6MWX", "trusted": true }, "outputs": [], "source": [ "trainer = DecentralizedTrainer(\n", " # environment arguments\n", " env_args = dict(\n", " colors_map='assets/csv_files/colors_map.csv',\n", " targets_map='assets/csv_files/targets_map.csv',\n", " # 5 mails to win\n", " required_mail=5,\n", " # 3 players\n", " robot_colors=['r', 'b', 'gr'],\n", " # 1 robot for each players\n", " num_robots_per_player=1,\n", " # battery isn't considered\n", " with_battery=False,\n", " # one step per turn\n", " random_num_steps=False,\n", " # maximum environment step\n", " max_step=600,\n", " ),\n", " # number parallel environments to train\n", " num_train_envs=16,\n", " # number parallel environments to test\n", " num_test_envs=16,\n", " batch_size=64,\n", " # after how many step update network\n", " update_freq=200,\n", " # after how many episodesdo a test\n", " test_freq=100,\n", " # number episodes to train\n", " episodes_per_train=5_000,\n", " # number episodes per test\n", " episodes_per_test=48,\n", " train_fn=train_fn,\n", " save_best_fn=save_best_fn,\n", " save_last_fn=save_last_fn,\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "kWKyBmBuIo_q" }, "source": [ "### Start training." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2024-11-28T08:51:32.615734Z", "iopub.status.busy": "2024-11-28T08:51:32.614897Z", "iopub.status.idle": "2024-11-28T08:51:32.900983Z", "shell.execute_reply": "2024-11-28T08:51:32.900205Z", "shell.execute_reply.started": "2024-11-28T08:51:32.6157Z" }, "id": "0yzuATGx6MWY", "trusted": true }, "outputs": [], "source": [ "agent.policy.to('cuda')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2024-11-27T21:30:34.505805Z", "iopub.status.busy": "2024-11-27T21:30:34.505465Z", "iopub.status.idle": "2024-11-27T21:30:34.509694Z", "shell.execute_reply": "2024-11-27T21:30:34.508775Z", "shell.execute_reply.started": "2024-11-27T21:30:34.505776Z" }, "id": "B4pCnjtX6MWY", "trusted": true }, "outputs": [], "source": [ "# def move_optimizer_to_device(optimizer, device):\n", "# for state in optimizer.state.values():\n", "# for k, v in state.items():\n", "# if isinstance(v, torch.Tensor):\n", "# state[k] = v.to(device)\n", "# move_optimizer_to_device(agent.policy.optim, 'cuda')" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "execution": { "iopub.execute_input": "2024-11-28T08:51:38.043662Z", "iopub.status.busy": "2024-11-28T08:51:38.043305Z", "iopub.status.idle": "2024-11-28T13:04:23.011198Z", "shell.execute_reply": "2024-11-28T13:04:23.010532Z", "shell.execute_reply.started": "2024-11-28T08:51:38.04363Z" }, "id": "X-9YjJik6MWY", "outputId": "665995ad-85a7-4f26-ffb7-0a73b98f1c38", "trusted": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "===episode 0112 done with number steps: 247.2, reward: +13.67===\n", "===episode 0224 done with number steps: 236.5, reward: +14.46===\n", "===episode 0336 done with number steps: 225.3, reward: +14.79===\n", "===episode 0448 done with number steps: 208.1, reward: +18.06===\n", "===episode 0560 done with number steps: 208.6, reward: +17.36===\n", "===episode 0672 done with number steps: 419.4, reward: +01.80===\n", "===episode 0784 done with number steps: 199.7, reward: +18.81===\n", "===episode 0896 done with number steps: 215.3, reward: +18.76===\n", "===episode 1008 done with number steps: 198.0, reward: +19.55===\n", "===episode 1120 done with number steps: 187.5, reward: +19.88===\n", "===episode 1232 done with number steps: 188.7, reward: +18.89===\n", "===episode 1344 done with number steps: 261.1, reward: +15.00===\n", "===episode 1456 done with number steps: 181.5, reward: +19.38===\n", "===episode 1568 done with number steps: 195.6, reward: +19.35===\n", "===episode 1680 done with number steps: 249.7, reward: +15.96===\n", "===episode 1792 done with number steps: 198.4, reward: +19.35===\n", "===episode 1904 done with number steps: 232.0, reward: +15.91===\n", "===episode 2016 done with number steps: 181.6, reward: +20.21===\n", "===episode 2128 done with number steps: 204.0, reward: +18.16===\n", "===episode 2240 done with number steps: 177.8, reward: +19.98===\n", "===episode 2352 done with number steps: 180.8, reward: +20.16===\n", "===episode 2464 done with number steps: 181.1, reward: +19.13===\n", "===episode 2576 done with number steps: 171.7, reward: +20.30===\n", "===episode 2688 done with number steps: 183.8, reward: +19.20===\n", "===episode 2800 done with number steps: 193.9, reward: +17.13===\n", "===episode 2912 done with number steps: 176.9, reward: +19.90===\n", "===episode 3024 done with number steps: 200.2, reward: +17.22===\n", "===episode 3136 done with number steps: 189.6, reward: +19.21===\n", "===episode 3248 done with number steps: 179.4, reward: +20.13===\n", "===episode 3360 done with number steps: 226.0, reward: +15.63===\n", "===episode 3472 done with number steps: 208.2, reward: +17.24===\n", "===episode 3584 done with number steps: 186.4, reward: +19.33===\n", "===episode 3696 done with number steps: 208.9, reward: +18.75===\n", "===episode 3808 done with number steps: 174.5, reward: +19.87===\n", "===episode 3920 done with number steps: 181.8, reward: +20.07===\n", "===episode 4032 done with number steps: 179.8, reward: +19.98===\n", "===episode 4144 done with number steps: 180.6, reward: +19.62===\n", "===episode 4256 done with number steps: 177.8, reward: +19.85===\n", "===episode 4368 done with number steps: 177.5, reward: +19.87===\n", "===episode 4480 done with number steps: 185.0, reward: +20.14===\n", "===episode 4592 done with number steps: 179.2, reward: +19.38===\n", "===episode 4704 done with number steps: 194.9, reward: +19.68===\n", "===episode 4816 done with number steps: 209.4, reward: +18.98===\n", "===episode 4928 done with number steps: 177.6, reward: +19.63===\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkwAAAGGCAYAAACJ/96MAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAACHpUlEQVR4nO3dd1xT1/sH8M8lQACRJUtkOcEJikpxFJw4atW2tvrVOmqtVu3XUdtqv62KWqm2rrbWUeuoHVZbR1tHpSpurQu3iKgoCm6WrJCc3x/3dxNCEsgkIXnerxcvkptzb05O1pNznnMuxxhjIIQQQgghGtmZuwKEEEIIIZaOAiZCCCGEkCpQwEQIIYQQUgUKmAghhBBCqkABEyGEEEJIFShgIoQQQgipAgVMhBBCCCFVoICJEEIIIaQKFDARQgghhFSBAiZik7744gs0aNAAIpEIkZGR5q6OzdizZw8iIyPh5OQEjuOQk5Nj7ipZhNDQULz00kvmrobe4uLi0KJFC3NXQ+727dvgOA7r16+v1vuNi4tDXFxctd4nqT4UMBGLsH79enAcJ/9zcnJCkyZNMHHiRDx48MCo97V37158+OGH6NixI9atW4f58+cb9fhEvSdPnuD111+Hs7Mzli9fjo0bN6JWrVrmrpbeCgsLMXv2bCQnJ2tV/sqVK5g9ezZu375t0noRQkzD3twVIKS8OXPmoH79+iguLsaRI0ewYsUK7Nq1C5cuXYKLi4tR7mP//v2ws7PD999/D0dHR6Mck1Tt1KlTyM/Px9y5c9G9e3dzV8dghYWFSEhIAACtehWuXLmChIQExMXFITQ01LSVs3EhISEoKiqCg4ODuatCrAgFTMSi9O7dG23btgUAvP3226hTpw4WL16MHTt2YMiQIQYdu7CwEC4uLnj48CGcnZ2NFiwxxlBcXAxnZ2ejHM9aPXz4EADg4eFh3opYmefPn9fonjpTEHqpCTEmGpIjFq1r164AgFu3bsm3/fjjj4iKioKzszO8vLwwePBg3L17V2k/IafizJkzePHFF+Hi4oKPP/4YHMdh3bp1eP78uXz4T8hzKCsrw9y5c9GwYUOIxWKEhobi448/RklJidKxhXyTv//+G23btoWzszNWrVqF5ORkcByHzZs3IyEhAfXq1UPt2rXx2muvITc3FyUlJZg8eTJ8fX3h6uqKUaNGqRx73bp16Nq1K3x9fSEWi9GsWTOsWLFCpV2EOhw5cgTt27eHk5MTGjRogB9++EGlbE5ODqZMmYLQ0FCIxWIEBgZi+PDhePz4sbxMSUkJZs2ahUaNGkEsFiMoKAgffvihSv002bJli/w58fb2xrBhw3Dv3j2l52PEiBEAgHbt2oHjOIwcOVLj8TIyMjB+/HiEhYXB2dkZderUwaBBg9QOZ124cAGxsbFwdnZGYGAg5s2bh3Xr1oHjOJXyu3fvRufOnVGrVi3Url0bffv2xeXLl5XKjBw5Eq6urrh37x4GDBgAV1dX+Pj4YNq0aZBKpQD4HBkfHx8AQEJCgvy1NHv2bLWPZ/369Rg0aBAAoEuXLvLyFYfzqno+haHrgwcPYvz48fD19UVgYKD89m+//RbNmzeHWCxGQEAAJkyYoJInFhoaqrbt1eXfZGRk4OWXX0atWrXg6+uLKVOm4O+//1Zbd4DvRevSpQtcXFxQr149LFy4UG17qKPr+7pDhw5wdnZG/fr1sXLlSqVy6nKYsrOzMWrUKAQGBkIsFqNu3bro37+/ymtEmzYEgNWrV6Nhw4ZwdnZG+/btcfjwYbWPy9D3FrEgjBALsG7dOgaAnTp1Smn7smXLGAC2cuVKxhhj8+bNYxzHsTfeeIN9++23LCEhgXl7e7PQ0FD27Nkz+X6xsbHM39+f+fj4sPfee4+tWrWKbd++nW3cuJF17tyZicVitnHjRrZx40aWnp7OGGNsxIgRDAB77bXX2PLly9nw4cMZADZgwAClOoWEhLBGjRoxT09PNn36dLZy5Up24MABduDAAQaARUZGspiYGPbVV1+x//73v4zjODZ48GD2n//8h/Xu3ZstX76cvfnmmwwAS0hIUDp2u3bt2MiRI9mSJUvY119/zXr27MkAsG+++UalDmFhYczPz499/PHH7JtvvmFt2rRhHMexS5cuycvl5+ezFi1aMJFIxMaMGcNWrFjB5s6dy9q1a8fOnTvHGGNMKpWynj17MhcXFzZ58mS2atUqNnHiRGZvb8/69++v9XPXrl07tmTJEjZ9+nTm7Oys9Jzs3buXvfPOOwwAmzNnDtu4cSM7duyYxmNu2bKFRUREsJkzZ7LVq1ezjz/+mHl6erKQkBD2/PlzebnMzEzm5eXF6tSpwxISEtiXX37JwsPDWUREBAPAbt26JS/7ww8/MI7jWK9evdjXX3/NFixYwEJDQ5mHh4dSuREjRjAnJyfWvHlz9tZbb7EVK1awV199lQFg3377LWOMsYKCArZixQoGgA0cOFD+Wjp//rzax5Oens7++9//MgDs448/lpfPzs7W6fkU2rpZs2YsNjaWff311+zzzz9njDE2a9YsBoB1796dff3112zixIlMJBKxdu3asdLSUvkxQkJC2IgRI1TqGBsby2JjY+XXCwoKWIMGDZizszObPn06W7p0KWvfvr28bQ8cOKC0b0BAAAsKCmKTJk1i3377LevatSsDwHbt2qXxeRbo8r4OCAhgvr6+bOLEieyrr75inTp1YgDY999/Ly9369YtBoCtW7dOvq1Dhw7M3d2dffLJJ2zNmjVs/vz5rEuXLuzgwYPyMtq24Zo1axgA1qFDB/bVV1+xyZMnMw8PD9agQQOlNjT0vUUsCwVMxCIIXwT//PMPe/ToEbt79y7btGkTq1OnDnN2dmaZmZns9u3bTCQSsc8++0xp34sXLzJ7e3ul7bGxsUqBVnkjRoxgtWrVUtqWkpLCALC3335bafu0adMYALZ//375tpCQEAaA7dmzR6msEDC1aNFC6cN1yJAhjOM41rt3b6XyMTExLCQkRGlbYWGhSn3j4+NZgwYNlLYJdTh06JB828OHD5lYLGbvv/++fNvMmTMZALZ161aV48pkMsYYYxs3bmR2dnbs8OHDSrevXLmSAWBHjx5V2VdQWlrKfH19WYsWLVhRUZF8+19//cUAsJkzZ8q3aQqK1VHXDsePH2cA2A8//CDf9t577zGO4+TBH2OMPXnyhHl5eSkFTPn5+czDw4ONGTNG6ZjZ2dnM3d1dabsQOM+ZM0epbOvWrVlUVJT8+qNHjxgANmvWrCofD2N8EFgx0BBo+3wKbdipUydWVlamVNbR0ZH17NmTSaVS+fZvvvmGAWBr165Vui9tAqZFixYxAGz79u3ybUVFRSw8PFxtwFTxuSkpKWH+/v7s1VdfrbRd9HlfL1q0SOl+IiMjma+vr/x9VzFgevbsGQPAvvjiC4310LYNhdd8ZGQkKykpkZdbvXo1A6DUhoa8t4jloSE5YlG6d+8OHx8fBAUFYfDgwXB1dcW2bdtQr149bN26FTKZDK+//joeP34s//P390fjxo1x4MABpWOJxWKMGjVKq/vdtWsXAGDq1KlK299//30AwM6dO5W2169fH/Hx8WqPNXz4cKVk0+joaDDG8NZbbymVi46Oxt27d1FWVibfVj4PKjc3F48fP0ZsbCxu3ryJ3Nxcpf2bNWuGzp07y6/7+PggLCwMN2/elG/7/fffERERgYEDB6rUk+M4APxwWtOmTREeHq7UrsJwaMV2Le/06dN4+PAhxo8fr5Qz0rdvX4SHh6u0m7bKt4NEIsGTJ0/QqFEjeHh44OzZs/Lb9uzZg5iYGKWlIby8vDB06FCl4yUlJSEnJwdDhgxReowikQjR0dFqH+O4ceOUrnfu3FmpbY1Nm+dTMGbMGIhEIvn1f/75B6WlpZg8eTLs7OyUyrm5uen1POzZswf16tXDyy+/LN/m5OSEMWPGqC3v6uqKYcOGya87Ojqiffv2VbaZru9re3t7jB07Vul+xo4di4cPH+LMmTNq70PIWUxOTsazZ8/UltG2DYXX/Lhx45TyIEeOHAl3d3elYxry3iKWh5K+iUVZvnw5mjRpAnt7e/j5+SEsLEz+4ZWWlgbGGBo3bqx234ozYurVq6d1YndGRgbs7OzQqFEjpe3+/v7w8PBARkaG0vb69etrPFZwcLDSdeFDNCgoSGW7TCZDbm4u6tSpAwA4evQoZs2ahePHj6OwsFCpfG5urtIHcsX7AQBPT0+lL4T09HS8+uqrGusK8O169epVeU5ORUKytjpCu4SFhancFh4ejiNHjlR635oUFRUhMTER69atw71798AYk99WPnDMyMhATEyMyv4Vn8e0tDQAipy4itzc3JSuOzk5qbRHxbY1Nm2eT0HF15+m58HR0RENGjRQef1qIyMjAw0bNpQH1oKKbSsIDAxUKevp6YkLFy5Uej+6vq8DAgJUktybNGkCgM9deuGFF1SOIRaLsWDBArz//vvw8/PDCy+8gJdeegnDhw+Hv78/AO3bUPhfsb4ODg5o0KCBymPT971FLA8FTMSitG/fXj5LriKZTAaO47B7926lX9cCV1dXpev6zFqr+IGvSWXHVle3yrYLwUB6ejq6deuG8PBwLF68GEFBQXB0dMSuXbuwZMkSyGQynY6nLZlMhpYtW2Lx4sVqb68Y6FWH9957D+vWrcPkyZMRExMDd3d3cByHwYMHq7SDNoR9Nm7cKP+CLM/eXvmjUFPbmpIuz6chMzI1vcalUqlBj1vf16Ou72t9TZ48Gf369cP27dvx999/49NPP0ViYiL279+P1q1bG+U+KrLE9xbRHwVMpMZo2LAhGGOoX7++/BelsYSEhEAmkyEtLQ1NmzaVb3/w4AFycnIQEhJi1PtT588//0RJSQn++OMPpd4GQ7rtGzZsiEuXLlVZ5vz58+jWrZvWAaNAaJfU1FSV3pvU1FS92+23337DiBEjsGjRIvm24uJildlKISEhuHHjhsr+Fbc1bNgQAODr62u0NaB0bStdy+ui/PNQvpejtLQUt27dUnrMnp6eamd9ZWRkKO0bEhKCK1eugDGmVHd17W0IXd/X9+/fV1lK4fr16wBQ5fpWDRs2xPvvv4/3338faWlpiIyMxKJFi/Djjz9q3YZCubS0NKXXvEQiwa1btxAREaF0f/q+t4jloRwmUmO88sorEIlESEhIUPnVyhjDkydP9D52nz59AABLly5V2i78Muzbt6/ex9aW8Ou64vDTunXr9D7mq6++ivPnz2Pbtm0qtwn38/rrr+PevXv47rvvVMoUFRXh+fPnGo/ftm1b+Pr6YuXKlUrTpHfv3o2rV6/q3W4ikUjlOf7666/l0/oF8fHxOH78OFJSUuTbnj59ip9++kmlnJubG+bPnw+JRKJyf48ePdK5jsJCqtqe3kX4gjfF6WC6d+8OR0dHfPXVV0rt9v333yM3N1fpeWjYsCFOnDiB0tJS+ba//vpLZQp/fHw87t27hz/++EO+rbi4WO3rxBC6vq/LysqwatUq+fXS0lKsWrUKPj4+iIqKUnsfhYWFKC4uVtrWsGFD1K5dW/661bYN27ZtCx8fH6xcuVKpDdevX6/y3Ory3rpz5w6uXbumtv7EMlAPE6kxGjZsiHnz5mHGjBm4ffs2BgwYgNq1a+PWrVvYtm0b3nnnHUybNk2vY0dERGDEiBFYvXo1cnJyEBsbi3///RcbNmzAgAED0KVLFyM/GlU9e/aEo6Mj+vXrh7Fjx6KgoADfffcdfH19kZWVpdcxP/jgA/z2228YNGgQ3nrrLURFReHp06f4448/sHLlSkRERODNN9/E5s2bMW7cOBw4cAAdO3aEVCrFtWvXsHnzZvl6U+o4ODhgwYIFGDVqFGJjYzFkyBA8ePAAy5YtQ2hoKKZMmaJXvV966SVs3LgR7u7uaNasGY4fP45//vlHnusl+PDDD/Hjjz+iR48eeO+991CrVi2sWbMGwcHBePr0qfxXvZubG1asWIE333wTbdq0weDBg+Hj44M7d+5g586d6NixI7755hud6ujs7IxmzZrh119/RZMmTeDl5YUWLVpoPKdaZGQkRCIRFixYgNzcXIjFYvmaW4by8fHBjBkzkJCQgF69euHll19Gamoqvv32W7Rr104pGfvtt9/Gb7/9hl69euH1119Heno6fvzxR3kvnGDs2LH45ptvMGTIEEyaNAl169bFTz/9JE/uN1aPia7v64CAACxYsAC3b99GkyZN8OuvvyIlJQWrV6/WuLL39evX0a1bN7z++uto1qwZ7O3tsW3bNjx48ACDBw/WqQ0dHBwwb948jB07Fl27dsUbb7yBW7duYd26dSo5TLq8t4YPH46DBw/qPKROqlG1zskjRANdppz//vvvrFOnTqxWrVqsVq1aLDw8nE2YMIGlpqbKy8TGxrLmzZur3V/dsgKMMSaRSFhCQgKrX78+c3BwYEFBQWzGjBmsuLhYqVxISAjr27evyv7CsgJbtmzR6rEJa748evRIvu2PP/5grVq1Yk5OTiw0NJQtWLCArV27VmVNIU11qDg1nDF+mv3EiRNZvXr1mKOjIwsMDGQjRoxgjx8/lpcpLS1lCxYsYM2bN2disZh5enqyqKgolpCQwHJzc1UbsYJff/2VtW7dmonFYubl5cWGDh3KMjMztWoHdZ49e8ZGjRrFvL29maurK4uPj2fXrl1TOyX+3Llz8rW1AgMDWWJiIvvqq68YAPk6R4IDBw6w+Ph45u7uzpycnFjDhg3ZyJEj2enTp+VlNL0+hOervGPHjrGoqCjm6Oio1RID3333HWvQoAETiURKU/O1fT6rasNvvvmGhYeHMwcHB+bn58feffddpXWMBIsWLWL16tVjYrGYdezYkZ0+fVrta+fmzZusb9++zNnZmfn4+LD333+f/f777wwAO3HihFI91b3fRowYobJ0hia6vK9Pnz7NYmJimJOTEwsJCVFZp6zisgKPHz9mEyZMYOHh4axWrVrM3d2dRUdHs82bN+vdht9++y2rX78+E4vFrG3btuzQoUNq21Db95awZAKxXBxjFM4SQqzL5MmTsWrVKhQUFJglgduaLV26FFOmTEFmZibq1atXrfcdFxeHx48fV5mXR4gpUA4TIaRGKyoqUrr+5MkTbNy4EZ06daJgyUAV27a4uBirVq1C48aNqz1YIsTcKIeJEFKjxcTEIC4uDk2bNsWDBw/w/fffIy8vD59++qm5q1bjvfLKKwgODkZkZCRyc3Px448/4tq1aypJ9YTYAgqYCCE1Wp8+ffDbb79h9erV4DgObdq0wffff48XX3zR3FWr8eLj47FmzRr89NNPkEqlaNasGTZt2oQ33njD3FUjpNpRDhMhhBBCSBUoh4kQQgghpAoUMBFCCCGEVIFymNSQyWS4f/8+ateuTcvZE0IIIVaIMYb8/HwEBATIT/JeGQqY1Lh//z6dFJEQQgixAXfv3kVgYGCV5ShgUqN27doA+EZ0c3OrsrxEIsHevXvRs2dPjUvzE9Oh9jcvan/zovY3H2p78zK0/fPy8hAUFCT/zq8KBUxqlD//lLYBk4uLC9zc3OhNYwbU/uZF7W9e1P7mQ21vXsZqf21TbyjpmxBCCCGkChQwEUIIIYRUgQImQgghhJAqUMBECCGEEFIFCpgIIYQQQqpAARMhhBBCSBUoYCKEEEIIqQIFTIQQQgghVaCAiRBCNMjMBA4c4P8TQmwbBUyEEIM9fuyE5GTOqgKL778HQkKArl35/99/b+4aEULMiQImQohB1q3jMGZMT/TsaW/WwMKYvUGZmcA77wAyGX9dJgPGjqWeJkJsmVkDpsTERLRr1w61a9eGr68vBgwYgNTUVKUyxcXFmDBhAurUqQNXV1e8+uqrePDgQaXHZYxh5syZqFu3LpydndG9e3ekpaWZ8qEQYpMyM4F33xWBMf5cTOYKLIzdG5SWpgiWBFIpcOOGYcetaWhI0jrR86ofswZMBw8exIQJE3DixAkkJSVBIpGgZ8+eeP78ubzMlClT8Oeff2LLli04ePAg7t+/j1deeaXS4y5cuBBfffUVVq5ciZMnT6JWrVqIj49HcXGxqR8SITaFDyyUT1xZnYHF06d8cDRmjHF7g+rUUd1mZwc0aqT/MWsaGpLkWVtw8d13QHAwPa96YRbk4cOHDAA7ePAgY4yxnJwc5uDgwLZs2SIvc/XqVQaAHT9+XO0xZDIZ8/f3Z1988YV8W05ODhOLxeyXX37Rqh65ubkMAMvNzdWqfGlpKdu+fTsrLS3VqjwxLmp/87l7lzE7OxkDmPxPJOK3G+v4+/crjvfkCWPbtjE2aRJjERGMcRxTuu/yfwcO6H+/o0apHi8khDGJxOCHZHSmeP3zzysz2fNaE0iljH3yieI1xnGMJSQwlp+vKFO+7Su+Vi1NaipjEyaovq5r8vNq6Gtf1+96i8phys3NBQB4eXkBAM6cOQOJRILu3bvLy4SHhyM4OBjHjx9Xe4xbt24hOztbaR93d3dER0dr3IfYFmv7xWhOgYHAN99IATD5tg8/5LcbqnwPR3AwEBTE9/wMHAgsWwacP89/5DdqBHDKnVwQifTvDTp8GFi3jj/mjh3Ali2AmxuQkQEsXmz449KFuV6r16/b5pDks2fA5s3AyJGAnx8wbx7/GgP4/7NmAbVrAz4+QLt2wODBIqxf3wzDh4ssstcmP5+vS6dOQFgYsHy5ahmpFLh6tfrrVhPZm7sCAplMhsmTJ6Njx45o0aIFACA7OxuOjo7w8PBQKuvn54fs7Gy1xxG2+/n5ab1PSUkJSkpK5Nfz8vIAABKJBBKJpMq6C2W0KUuMT5f2X7eOw7vviiCTcbCzY1ixQopRo1iV+xHNYmLKUP6jJD9fColEpnkHLfBJ1/by4T7GFEFD06YMsbEydO7M8OKLDH5+ys8rAAwaJIOfnxS6viUlEmDcOHsAHEaPlqJ3b/5x5ORwGDPGHjNnMvTpU4awMIMenla0fa2a4vPnxAkOFb8eRCKGkJAyndvUEmVmAjducGjYkOHxY+Dvv+3w998cTpzgIJVyVe7/+DH/d/q0HYDGSrfJZMA77zB07VpmlB8OQl0bNWJVHi8zE0hL4/D0KbBrlx1+/51DYSH/eOzsGGJjGZKTOXnOoWDpUhk6d5ZCJDK8vtXJ0Ne+rvtZTMA0YcIEXLp0CUeOHKn2+05MTERCQoLK9r1798LFxUXr4yQlJRmzWkRHVbX/o0dOGDeuZ7kEZQ7vvmsHkSgJ3t6U36av48frAmgPe3spyspE+PFHCbp02QuRSP9A9OJFb8hkHVW2f/TRv4iJyZJfP3OG/+/nB6xe7YRt2xph586G2LqVoVOnQwgMLNDpfrdubYQrV5rD3b0EsbH7sGsX/4Hq7Q1ERsYgJcUXr7+eh88+OwI7E/bPP36s+2vVWJ8/aWkemDWr0/9fYwA4AAzjxqXgwoU7uHDBKHdjNklJwfj228j/b1vh8SkEBeWhTZuHaNjwGZYsaasUXNjZybB06QHIZHZ4+NAFDx+64MoVLxw7Vk/pGDIZh65dn2PMmIto3vypUerKcQwDBqQhMvIxJBI7SCR2KC21Q1mZCBKJHS5dqoMjR+qpPJ569fLRrdsdxMVlwsurGM2aBWPFigjIZHbgOAaOY9i1yw79+t3FhAkpKr21NYG+r/3CwkKdynOMMbP/vJ44cSJ27NiBQ4cOoX79+vLt+/fvR7du3fDs2TOlXqaQkBBMnjwZU6ZMUTnWzZs30bBhQ5w7dw6RkZHy7bGxsYiMjMSyZctU9lHXwxQUFITHjx/Dzc2tyvpLJBIkJSWhR48ecHBw0PJRE2Opqv1lMmDHDg6ffmqH69dVv+WSksoQG2v2t0GNNW8ew5w5jhg0qAz794vw5AmH3bvL0K2b/m2akQE0bsz39AhEIoa0tMp/tctkQL9+IiQl2aFNGxkOH5ZC27dkRgYQEWGPwkIOa9aUYfhwpnJ769b2KCjgsGSJFBMmGNaLVpnkZA49e6r+nlX3WjXm58+TJ0B0tD3u3OHQr58Mc+dKERnJH/PRIwnc3Q06vNllZgKNGtlXmKjA0K0bw8CBDPHxMoSEKG5Zt47D+PEiSKUcRCKGb79V7uWTSCT45ZfDeOednirHFF673bvLMHOmDC+8oP374fZtYMMGO3z2mR0qBkDa4jiGzZulePllphIEZWYC6el8D9u//3L4z3/4nsxJk6RYuFCmd9CkS2+YMRj62s/Ly4O3tzdyc3O1+q43a9K3TCZjEyZMYAEBAez69esqtwtJ37/99pt827Vr17RK+v7yyy/l23Jzcynp24ppav/SUsbWrWMsPFxzYnBNTni0FK+/LmUAY/Pnl7GxY/l2HTXKsGPu2aP6PK1Zo92+mZmMeXry+336qfb32b8/v8+LLzImk6kvs3w5X8bFhbGbN7U/tq50Sbo21udPWRlj8fH8fTVqxFhODr89IIDfduKEQYe3CElJuk8QuHuXv72ytl+1SsJEIsXztHAhY+PGMebgoLiP3r0Z+/dfxTErJohfvcrYZ58xFhWl+fMKYKx+fcbatmWsY0fGunblj9upk2ETH9atU+wze7Z2+1S0Zo3iNWtnp/37tSqVJdNXd9K3WQOmd999l7m7u7Pk5GSWlZUl/yssLJSXGTduHAsODmb79+9np0+fZjExMSwmJkbpOGFhYWzr1q3y659//jnz8PBgO3bsYBcuXGD9+/dn9evXZ0VFRVrViwKmmqW0tJStWbOH7d0rYXfvMvb8OWNffcVYcLDiQ8DdnbH//Y+xJUuUv4gGDzZ37Wu+Fi34WXLbtknYwYOK9i4u1v+Yr76qCLw0fVlVZvNmxQe3ht9WSv74gy9vb8/YpUuay0mlfEAFMNatm+bAyhheeUX5y++779SXM9bnz8yZ/P04OzN2/rxie9eu/PZ16ww6vEX45BPj/miqOEuu4mv11i3G3n6byYMpgJ/dWT6w6NuXsWbNlOtkZ8fYCy+ozgLVVFdjzGr86ivFvosX69YOpppVWVUQZlMBE/h+S5W/deXemUVFRWz8+PHM09OTubi4sIEDB7KsrCyV45TfRyaTsU8//ZT5+fkxsVjMunXrxlJTU7WuFwVMNcuqVRLGcTL51F9XV8Wb1s+PsQULGCv/VN69y9h//8vf7ujIWEqK+epe00kkjDk68m2fmlrKpFLGAgPZ/wdQ+h0zO5sPXADGLlzQv27DhvHHaNhQeSp4RQUF/JIBAGMffVT1cdPS+KCisiDGGHr0UP4CunhRfTljfP7s3Km4n40blW8TpqJ/+KHeh7cIN24onjfhS1iXnkt1tG37GzcYGzGi8mUwHBwY69WLsdWrGXvwgN9vzRqm1HNVWV11KavJ3LmK+mizv1TK9wZ36GBYD5c62gRhNhUwWSoKmGoOdesAAfyX9rffMqapU1EmY6xfP75s06Z8rxTR3bVrfBuKxRJWXMy//t9/n982aJB+x1y4kN8/Otqwuj17xlhQEH+sd97RXG76dL5McDAfPGnjyy/5fdzcTDOkW1ys+HKvX7/yX/2Gfv7cvKkYwhw/XvX2b77hb+vXT6/DWwSZjO8RBPgeszt39Ou5rEjXtt+wQX1g8fHH/OtVncqGBA0pq45Mxti0aUz+43PTJvXlHj7kf4g2aKA5ALSzM6x9Kw7LqwvCKGCyABQw1Rz79ql/U/3zT9X7PnrEWN26fPlx40xfV4EuC9yZYjE8Yx7z99+FXpxn8tf/mTP8NicnxvLydDueTMZYkybG673Zv1/xmvjzT9XbL19W9GZt3679ccvKGGvfnt+vb1/jD80JQ5u+vox98QV/uXdv9WUN+fwpKmKsdWtFgKpuGFV4jzVurPPhLcbatYrXZFqa8Y6ra9vXhAVBZTL+Bwb+f4h6/Xr+fXTnDmOHDzM2dCjfMy/U392d77GfM0d56BHg210fOTn8kGTFz3XqYbJAFDDVHEJvhr4fQOWTQMulwZlMxTH5b77hu7W1KWuMJEpjH1Powu/SJUP++i8f9FQc3qlKcjK/n6tr5cNoupg6VRF8PHyo2C6TMRYbq3/vyaVLii+OH380Tl0Fs2bxxx08mB8yBvhE85IS1bKGfP6MHs0f29ub/0JU5949xevFkLw0fRka4GdlMebhwT+GhQuNWzd92t4YQ2emVlbG2H/+o7n3COATz7//XrlX9u5dPsAuv+/Klbrdd3Y2Y5GRQs915cOnFDBZAAqYaoYVKxRvSiGHSZ8PoA8+4I/h5WXaX3rqfl0Kfy4ujPn48MMvLVsqfvUb85eoKX7dDh7MH2f48EtKr//ZsyvvFdFEyDt6+23961RRURFjzZvzxx0wQNEbJAyPODvzybn6EAJGLy/+g95YhFlPq1fzAbWvL389OVm1rD6fP3fvKoZe7Oz4Hw6ayGT80COgOY/KVFavNjzAf+01fv+oKOOf2kbfz35Dh86qw82b6j+rBg9m7NSpyveVyRR5ogBjy5Zpd5/p6XzOofAD5+xZ7WYpUsBkRhQwWb4tWxQJlB9/XMbWrNnDkpIken0AlZQopvJ26cL/ujKF8sND+v4ZkkSp6f4NOWbLlvwx/ve/40qv/9RURZf+o0faHevpU37IBGDs5En966ROSopiivfatfw56Xx8+OuJifoft7RU8Wu4Tx/jDHUWFCiGCdPT+W3CL/b//U9dHXT7/CnfywgwNnBg1ftER/NlN2/W4YEY6O5d7WeJabJtm2K/c+eMX0dr/uw39PNCJlP8GNWmd+/cOX6SDsD/cNRm6NSmzyVHiDb27weGDuXfhmPHArNmyeDtXYzYWP0WS3N0BH7+GahViz9v1xdfGL/OANC4sfpznp07B9y8CVy4ABw7BiQl8WcUN+b50Sq7f32PWVYGpKbyl4OD85Vua9IEaNOGL/Pbb9od78cfgeJioFUr/jxdxhQRwZ8XDAAmTgRefhl49Aho1gyYOlX/4zo4AGvX8u26a5dxziV25AjfbiEhgLCOr3BqzH/+0f+4gHDKGeXzxP3xR9XnqmvalP9/7Zph96+LtDT+PV6eLuezy80FJkzgL3/wAVBuHWOihcaNobKavS6fFxwHLFgAfPopf/3DD4G5c9WXPXgQiI0FHjzg3/9Hjxr2WWcqFDCRGuXsWWDAAKC0FHj1Vf5kksZYyr9JE+Drr/nLn34K/Puv4cesKDAQaNlScV0kAlat4j/I69fnb4uJ4b8c334bWLhQtawhq+cGBgLduimuc5xhx0xP558HFxcGHx/VUwz85z/8/59/rvpYjPFBIsA/dlOcnuH99/kvgcJC/gMZAPr25QNmQ/j4KF+XyfhAXt8T5u7fz//v2lXRDj168P9PneJPEKuvtDT9TqorBEzVeZJWTaeeSUpSDaTU+fBD4P59/jmfOdO4dbMFgYHA6tWQn19On88gjgPmzFEESjNnAp98ovz8bd8OxMcDeXnAiy/ywVPdukZ7GEZFAROpMW7cAHr35s/A3aUL3yNhzJNFjhwJvP46/+t+yBD+foyt4P9PbbZkCX/6g9GjNZedNo0/RxoA/Ppr5WW1Vf7USfHxhh3z8mX+f3g4U/vl9sYb/Afm4cPA3buVH+vUKeDiRcDJCRg2TP86VSYriw/yylu8WP/ARmBoT0hF+/bx/7t2VWwLDATCw/lg58AB/Y4LqP/Vrk2vQXg4/786A6aDB5WvC8Hj/PnA4MHA8+eV77t6NX95zRrA2dk0dbR2o0fzn1MHDlT9eVWZTz5R9Nx/9hkfzN69y3/GvfIKUFLC/xDeswcodxY0i0MBE6kRsrKAnj2Bhw+B1q35XyVOTsa9D6HHJTiYHyIbNYr/oDD0C1VQWAjcusVfHjpUu19qMTH8/9u3Db9/iYTvoRNcumTY8a5c4f83a6b+9sBA/hcjAGzaVPmxhN6l114DPD0Nq5cm+vauVMXQoYvynj1TPEflAybAOMNyjx4pX9e210DoYUpNVW1DU2AM+OUX/vKSJfz7MCMD+PZbwN4e2LyZf29UDIABoKgIGDOGvzx2rOI1SPQTGAjExRnWuw3wwZHQi//ll/zn7KJF/HPdqROwZYvlB7YUMJFqlZmpexCSkwP06sUHGw0bArt3A9qcJ1EfHh7ATz/xwdPvvxsnJ0WQmsp/ONSpozqMo0n79vz/kycNv/+LF/kcodq1+S/4zEw+ENWX0MPUrJnm8ZEhQ/j/wpefOvn5itvfflv/+lTFmIFNecLQRfljr1ih3xfMwYP8ayQ8HAgIUL5NGJbT88TsAPheWQDo10+3XoP69fmhy6Ii4M4d/e9fWxcv8vlSYjH/wyUuDggKAt59l6+3nx9fpm1bvleivDlz+OA4IIDPoSGWY+JE4PPPVbcfPw5kZ1d/fXRFAROpNt9/zwcf2gYhmZn8h2GvXnxCtL8/sHevYpjKVEJDla8bmpMiqKpHRp3oaP6/MXKqhGO88IKix+DUKf2PJwRMTZtqDphee43vETh3TnPC8K+/8sMrTZqYtjfAGDkZmowezT8+odezeXP9jlM+f6miuDi+zjdu6NfjWFamyCd75x3deg3s7fnnB6ieYTmhR7JPH8DdXfm2Tp2AM2f413FODl9m/nx+iGf1akXu37ffqu5LzE/4EVieMXp6qwMFTKRaVJydI5Px3eaJiXz3+r59QEoK/6FXWKgIrnr35ntXnJz44KlBA9PX1dg5KQJ9AqaoKL63KyODn0FiCCFgio5WfGjpGzCVnyFXWQ9TnTp8rhSguZfJ1Mne5RkrJ0Odxo35ABGoeghSk8oCJjc3RQCtTy/Tvn38a8jbW/Gc6KK68pgYU7Tf4MHqy9SrByQn858pjAH/+x8/xDN2LP/Z0rYt0L+/aetJ9GOqnt7qQAETqRbq8kcYAz7+mE8O7t6dz00KDuan97/9tnL50lL+y7c6mOoNrU/A5O6u+KIypDcIUARM7dsrpu3re0zFDDk+sK1M+WG5ioHohQt8veztgeHD9auLroyVk6GO8AW/eTMfVOoiO5vvteM4vn7qCMNy+uQxCcNxgwfzyyHoqrpmyp06xQ+/16rFz2LURCzmewjVDbudO2e83ENiXKbs6TU1CphItVAXhHAc/0u3c2c+iPDz47841ZHJqq/LVl1OijHe0MIXjS4BE6DoDTJkWC4vTxGwtWunHDBpM0W7IsVwnObp34L+/flkzrQ05aRzgJ/BJJQx9VBrdejRA/Dy4ntyKs7yqoow+y0yUvOPAyFg2rdPt+TrggJg61b+sr6zEKtrLSahd+nll/mgqSrq1uyqKUM8tsqUPb2mRAETqRZCECIMudjZ8UMxe/YAhw7xX8DZ2XyvxdWr5u+yHT2arxfA/xo3tPejpETxAa5vwGRI4veZM3xgFBzM54K1asUn8T59ys8I1JUQfGmTq+Pqyn/5AcprMhUVARs38peFWU01naMjvz4YoPuwXGXDcYL27fmk/SdP+F4UbW3fzg91N26sPodEG9XRwyST8TltAN/zrI2aPMRjy0zZ02sqFDCRajN6NJ+oCQDLlqn/VcFx/BCUJXTZxsTwX04SieG/qtPS+F+97u66L8pWPvFbn94gYV9A8WXp6KhY+VifYTmhh0nb5GZhWG7TJr4dAL7HIyeHD+KEKfPWQBiW+/13/geAtrQJmBwcFMN1ugzLCcNxw4bpnyfWpAm/75MnqssTGMuRI/xik+7u/GQPbdTkIR5Ss1DARKqVMIwQHFx5OUvosrWz43tiAOD8ecOOJfTING2q+xdWy5Z8vkZOjv7DDOUTvgXCUIY+Q32KJQW0K9+rF79kw/37/EKWgCLZe/Ro4y5Aam6xsXwv3rNn/KxObdy+zff02dvzQ9SV0XV5gexsRdmhQ7XbR53y+Wqm6mUSeuUGDuRf89qyhM8LYv0oYCLVSlidV5vcBEvoshV6YYwVMOk6HAfwvUGtW/OX9c1jqtjDBOif+F1+hpy2PUxisWKo6pdfgOvX+RwfOzt+nR1rIhLxK8YD2g/LCb1LwpBbZYSA6cgRflizKr/8wv9QiYnh1zEzhCnzmMrK+MULAc2z4ypjCZ8XxLpRwESqlS4BkyWIiOD/mzNgAgxL/L5/n58xZGfHnxC34jHPntVtRpcuM+TKE4blfvuNX9gR4HuegoK0P0ZNIXzh79ihfDoaTbQZjhOEhfHT6ktK+KCpKuWH4wxlyjym/fuBx4/5ZQ+0aQdCqhsFTKRa2WrApO8MOYEhC1gK+zRvzidgC8LC+N6MwkJFQKcNXWbIlRcXxw9VPX3K57AB1pPsXdELL/DBZEEBsGtX5WUZ0y1g4jjth+WuXOEDYnt77ZOoK2PKtZiE3rjXXtNv2QNCTI0CJlKthIDJxcW89dBWixZ8UPDwof5L9ysv8qjfMYTeoHPndEskBtTnLwH844qK4i/rMiynywy58kQixT5C8vrDh7odo6bgOEUvU2WnhQH410ZWFr84q3DuwKpoGzAJvUt9+hhnHTNT9TCVlCiWPdBnOI6Q6kABk43R51xuxsKYYniipvQwubjw05YBfiVyfaSn8zPtatXSf/ipYUP+pLQlJfxij7pQl78k0GfFb11nyAmE115548db7wKDwhf/zp38Olia7NvH/+/YUfsTSnfrxv9PSdE8Y00m48+LCBhnOA5QBEx37ih+/BjD3r1Abi5//rdOnYx3XEKMiQImG6LrudyMrbhY0bNQUwImwPBhOaFHJjxctyGs8jhOvzwmmUwRDKkLmPSZKafrDDmButXerXmBwYgIftizpITPZdJEl+E4gZ+fYgbn/v3qp10eOcIHNm5u/Ml2jaH8iaOFXlNjEIbjXn/dumZMEutCAZONUHcuN2OcUFYX5X+R1pQhOcB4AZO+w3ECfQKm1FS+d8PZWX2PkBAwXbzIB7RV0WeGnMDWFhjUZlhOJlP0uuma6KxY9Vv9x7gwHDdokPY9V9owdh5TYaEioKThOGLJKGCyEZp+3aelVV8dhIBJLK5ZvyINXVrAWAGTPonfQtmoKPWnnQkOBnx9+UBImyFHfWfIAba5wKAQACQl8TPAKjp/nl+vqXZt/oSxuhAW+9y3j1NZ0LS4mD+fHWC84TiBsfOYdu7kPxtCQ/VfhZyQ6kABk41Q9+seANat0+2cVIaoaTPkBEIPU2qqdr0wFRk6Q04g9AZdu8bne2hDU8K3gON0W49J3xlyAltbYDA8nA+4y8oUSc3lCcNxsbGaz6OoyYsv8mt03b3L4f595TfVzp38ayQoiC9nTMZei0kYjhs8WP9VyAmpDhQw2YjAQOXubuHLbuNGfmq3cLoKU6ppCd+CgAA+d0MqVQQM2pJKjRcw+fryv8IZA06f1m6fyhK+BbrkMek7Q648W1tgUHjfqVvEUkj41mfdIRcXPlEcAM6f91W6TRiOGzpU/7w5TYzZw5SXxwd3AA3HEctHAZMNET44R4wAMjL4YMnODli7lt+my+KF+qipPUwcp+hl0nWmXEYG3yslFgP16xteF13ymIqLFcOIlQVMusyU03eGnC0T1j9KTuYXERVIJIoTPOu7UKMwLHf+vI9829OniiDE2MNxgCKHKS3N8M+MHTv4pPjwcEUSOyGWyqwB06FDh9CvXz8EBASA4zhs375d6XaO49T+ffHFFxqPOXv2bJXy4cI73MadOMH/HzyY/3U/bBj/q9fenp9+PGSI7mv86KKmBkyA/onfQo9MWJhx8rZ0CZhSUvgvZR+fyvONhB6m1NSqh/r0nSFny0JD+fWVGFOc+gPgA9Tnz/mVrVu21O/YQuL3xYve8uBl82b+eY+MNE1gGxTE925JJHxOmyFoOI7UJGYNmJ4/f46IiAgsX75c7e1ZWVlKf2vXrgXHcXhVOCmVBs2bN1fa74g25w+wco8fK6Zvl89nGTSIP6u6oyN/yorXXuN/8ZlCTVu0sjxDAyZjBRi6JH6XH46r7MvI25v/UgcqH+ozZIacrVM3LCfkL3Xpov+wWZs2gKcnQ2GhA06f5p9kY54KRR07O0UvkyF5TE+eKE5ObIxVyAkxNbMGTL1798a8efMwcOBAtbf7+/sr/e3YsQNdunRBgwYNKj2uvb290n7e3t6mqH6NIvQuhYfzCyCW9/LLfNe4kxPw559A//7andRTVzU1hwlQnilXcUZSZYwdMLVuzfdUCeeHq0xVCd/laTMsZ8gMOVv3+ut8oHHiBHDrFr/NkPwlgUgEdOnCvyD/+YfDzZvA0aP8fQnn7jMFY+Qxbd3KB+GRkYoAjBBLpuO8DPN58OABdu7ciQ0bNlRZNi0tDQEBAXByckJMTAwSExMRHByssXxJSQlKynWr5P3/srwSiQQSiaTK+xPKaFPWXI4etQMgQvv2Mkgkqhne3boBO3ZwGDhQhL//5tCnjwxffy1FVhaHRo2YURJ08/L4Ojg7q6+Dvqqj/Rs1Ahwc7JGbyyE9XaJ1wHD5sgiAHZo0KYNEokOkpYGjI9C8uT0uXOBw7FgZBg7UfMyTJ+0BcGjTpur7btPGDps3i3DypObn5vx5DoA9wsNlkEql8okCNeH1b2516gCxsSIcOGCHn3+W4r33ZDh2jH9+OneWwJCmi4tj2LrVEfv2ARwnBSBC164y+PhIDTpuZZo04d/Lly/r/17+5Rf+vTFokBQSSTVN1TUyeu2bl6Htr+t+NSZg2rBhA2rXro1XXnml0nLR0dFYv349wsLCkJWVhYSEBHTu3BmXLl1C7dq11e6TmJiIhIQEle179+6Fiw7jR0lVndjJjHbt6gDAB7VqXcCuXRkay33yiRfmzn0ByckOaNmSA8CB4xjGj09Bjx53DKrDmTONADRHTk4mdu06Z9Cx1DF1+9erF4fbt92xbt1ZtG9f9YnlGAMuXeoLwA6PHh3Erl0FRqmHn18EgFD8+ustiMXqz5qbn++AGzf6AACePduLXbsq/2AoK6sDoBMOHy7Brl171ZbZsaMJgKZwd1f//Fny698SNG0aggMHIrFmTQGk0ksoLe2IOnWKkJa216DVzh0dXQD0wIkTHG7cKAJQC82bp2DXrrvGqrqK58/rAmiPkydzsWvXIZ33f/pUjOTkeACAt/c+7Nplgi7takSvffPSt/0LhWEPLXGM6TLAYDocx2Hbtm0YMGCA2tvDw8PRo0cPfP311zodNycnByEhIVi8eDFGa1j0RV0PU1BQEB4/fgw3N7cq70MikSApKQk9evSAgwWeZlsqBXx97ZGfz+HUKYk8H0eTnTv5niZAkfgiEjGkpZUZ1NM0Z44d5s0TYexYKb7+2ni/KKur/UeNEuGnn+wwc6YUn3xSdf3v3gUaNnSAvT1Dbm6Z0c7AvnYth3Hj7BEXJ8Pevep/3e/dy+Gll+zRqBHDlStVT2UqKAC8ve0hk3G4c0cCf3/VMsOGibB5sx3mz5di2jTF47f017+lePIECAqyR1kZh/79Zdixww7Dhsmwdq1hva0SiQQNGjA8eMCPdTs5Mdy/XwZXV2PUWr0rV4DISAfUrs3w+HGZzgnbn31mh4QEESIjZfj332pY08RE6LVvXoa2f15eHry9vZGbm6vVd32N6GE6fPgwUlNT8euvv+q8r4eHB5o0aYIblfyEE4vFEIvFKtsdHBx0ehJ0LV9dUlOB/Hw+d6h1a4cqZ2u5u6tuk0o5ZGQ4GDQ1Xlj00dVVBAcH4y/1ber2b92an0146ZJ29RdWUW/cmIOLi/Hq1aED///MGTvY2dmpfT7PnuX/R0dzWrWJpyefl3L5MpCS4qD23GNCvkrLluofv6W+/i2Fvz8QH89P+d+xg08f7d7dDg4OhqeS1qmTKw+Yios5bN3qYNJFQZs25fOn8vM5PHrkgHr1tN/3++8BoUP//Hk7/PCDXY1fwJRe++alb/vruk+NWIfp+++/R1RUFCKq6hpRo6CgAOnp6ahbt64JalYzHD/O/2/fXrup7aY651dNTvoGdJ8pZ+yEb0GzZnwb5udrPgGqNgtWVlTZApY0Q844Ki7O2KWL4cfMzASuXq2jtM3U54l0dFR8HuiS+C2c01LAWPWf05IQfZk1YCooKEBKSgpS/n81wFu3biElJQV37ihyZfLy8rBlyxa8/fbbao/RrVs3fPPNN/Lr06ZNw8GDB3H79m0cO3YMAwcOhEgkwhBTThmxcMIMuRde0K68cM4vgZ2dcc75VZPXYQIUAVN6Oh+sVMVUAZNIxJ8bDgBOnlS9nTH9AqbKZsrRDDnjqLjOlTFSX27c4MCY8piYVAqD8qK0oc9JeDWd09LUdSXEGMwaMJ0+fRqtW7dG69atAQBTp05F69atMXPmTHmZTZs2gTGmMeBJT0/H43JntczMzMSQIUMQFhaG119/HXXq1MGJEyfg4+Ojdn9boGvABPDn+BKabPdu45zzq6YHTD4+/GlSAODixarLmypgAipfwDIjA3j4kF+QVFgOQRvlzylXMbPR0HPIEb4X5b//Vd5mjN6VRo0YOE75CTNGj3BV9DmnnLrcuOqoKyHGYNYcpri4OFSVc/7OO+/gnfJ9uBXcvn1b6fomdSdssmE5OYovbl0CJoDPZXr0yHgBTk0PmAC+l+n+fX5YTsglUocx451DTp3KAiZhW0QEv7aWtlq14odanj4Fbt4EGjZU3GaMc8jZusp6VwzpvQ0MBMaPT8HKlZGQSjmIRMbpEa6KPmsx7d6tfL266kqIMdBvRSsnfHk2aMCfvFUXwiybAuPMhq/RK30LtM1jevAAePaM741p0sT49RAWo7xwQXWRUV0WrCzP0VHRI1VxWI7OIWc4U+UGAkCPHneQllaGAweA27eN0yNcFV0DprIyYNky/vKCBajWuhJiDBQwWTl9huMEQk+QsQKmmp70DWh/El6hR6ZhQ916ebQVFAT4+fFfQhXrok/+kqD8sFx5dA45wwm5gcLEC2P3rgQGAnFx1ddbExbG/8/O5nuyq7J1K3DnDj+0/d571VtXQoyBAiYrZ0jAJPQwCT1DhrKWITmAz2GSVrJ8jBAwCb/CjY3jFAFR+cTvsjLgzBn+siEBU/mhPpohZzyjR/O9KtbQu+LmBvlyAlXlMTEGLFrEXx4/HnB2Nm3dCDEFCpisGGPGCZiMPSRXkwOmxo35HqPCwsrP1G7KhG+Bujymy5f5utWuregB0OeYZ8/ygRJAM+SMrbp7gkxJ22G5Y8f416lYzAdMhNREFDBZsbQ0Po/GyQlVru6tDuUwqbK3B1q25C9XlsdUHQGTkKNUPmASLrdrp99strAwPtgqLFR8CdIMOaKJtgHT4sX8/zff1D2XkhBLQR9/VkxYsDIqik/o1RX1MKmnTeK3KWfICdq25f+np/On3QD0T/gW2Nkp1ngSjkUz5Igm2qzFlJ4ObNvGX5482eRVIsRkKGCyYoYMxwGKwMYYOUwymeLUKNYeMD1+zK+DBCi+UEzB01MxA09I0jYk4VtQcQFLmiFHNNFmLaZly/j0gF696DVEajYKmKyYoQGTMXuYyp8U2loCJk0z5YRf26Ghpn+s5RO/CwqAS5eUt+uj4kw5miFHNBECpps3FT+Iynv2DFi7lr/8/vvVVy9CTIECJiv1/Dm/Rg9gGQFT+V6qmj5DplUr/n9mJr/IY0WmniFXXvnE77Nn+Z68evUUK5LrQwiYLlzgn3uaIUc08fMDPDz4151wsunyvvuOf++3bAl061bt1SPEqChgslKnT/MfYoGB+s/GMUXA5OLCT4mvydzd+d4jQP2wXHUkfAvKJ34Lywvom78kCA7mE3PLyvi1c2iGHNGE4zTnMZWWAl99xV+eOrXmv+8JoYDJSgkJ3/r2LgGmGZKr6cNxAmFFbHMHTBERgIMDnzf166/8NkOG4wD+i03oZVq3jv9PM+SIJppmym3ZAty7x58/zobPfU6sCH0EWilD85cA4yZ9W8sMOUFlid/VGTCJxYrgzZAFKysSAqbkZP4/DccRTdQlfjOmWEpg4kT+dUpITUcBkxUydMFKgSmG5Kw9YMrN5U/OC1RPDhOgHCBxnGJZAEMIAZOAAiaiiboepoMH+Zw6Z2dg3Djz1IsQY6OAyQplZPAnf7W3B9q00f84FDBpJgRMly8DEoliu/ClUa8en+tUHcoHTI0a8aesMFTFgIlmyBFNhIApNVVxuiChd2nkSKBOHbNUixCjo4DJCgm9S61bGzYjzVRJ39YgNJRfEbu0VHkoojpnyAnu3lVcvnED+P57w4/p46NIbAcALy/Dj0msU2goP+RWXMz/WLt+HfjzT/42WqiSWBMKmKyQMRK+AUVvECV9q7KzUywvUH5YrjrzlwB+aYOZMxXXGQPGjuW3G8rbW3G5c2fjBGLE+ohEigVUr10DlizhL/frp9hOiDWggMkKGSN/CVD0MJWUKE7Eqi9rG5ID1OcxVXfAlJbGLx9RnlTK9zQZIjNTkUQO8PdhrECMWB+hR/XIEWDDBv4yLVRJrA0FTFamuBg4d46/bKyACTB8ppw1Bkzqlhao7oCpcWPV6f4iEZ/LZIi0NL63qjxjBGLEOgkB05IlQFERnzv54ovmrRMhxkYBk5U5d45PQvbxAerXN+xYjo584jhg+LCcteUwAcqnSGGMf4wZGfy26gqYAgOB1av5IAng/69apf9ipQJTBWLEOgmLVwqnR6GFKok1ooDJygj5SzExhn9gcZzxEr+tsYepRQs+qHj0CMjOViR/+/pW78yg0aOB27eBAwf4/6NHG35MUwVixDpVPPmuMdZuI8TS2Ju7AsS4jJW/JKhVC8jJMTxgsrakb4DvLWvcmJ9Off48HzgB1TtDTmDIKXA0GT0aiI/nh+EaNaJgiaiXmQnMnau8bfx4oE8fes0Q60IBk5UxdsAk9DBRDpN6ERGKgCknh99mTWsWmSIQI9alsokH9Noh1oSG5KzIvXv8mjx2dkDbtsY5Jg3JVa78TLnqTvgmxBJQvhuxFRQwWRHhbPUtWvCLKhqDsQMma0r6BpRnylHARGwR5bsRW0FDclakfMK3sVAPU+WEHqbUVMU0fAqYiK2hfDdiCyhgsiLGzl8CjLfatzUmfQNAQAA/I+7JE/66pyfg52feOhFiDpTvRqydWYfkDh06hH79+iEgIAAcx2H79u1Kt48cORIcxyn99erVq8rjLl++HKGhoXByckJ0dDT+/fdfEz0CyyGRAKdP85eNGTBR0nflOE7RywTwvUu0/gwhhFgfswZMz58/R0REBJYvX66xTK9evZCVlSX/++WXXyo95q+//oqpU6di1qxZOHv2LCIiIhAfH4+HDx8au/oW5cIFftE4Dw/jnr+JhuSqVj5gCg42Xz0IIYSYjlmH5Hr37o3evXtXWkYsFsPf31/rYy5evBhjxozBqFGjAAArV67Ezp07sXbtWkyfPt2g+loyYTguOlp1xoohKOm7asJyAgCwaRPQrZtxFo8khBBiOSw+hyk5ORm+vr7w9PRE165dMW/ePNTRsIxyaWkpzpw5gxkzZsi32dnZoXv37jguZESrUVJSgpKSEvn1vLw8AIBEIoFEIqmyjkIZbcqaytGjIgB2aN9eColEVmV5bTk72wEQIS9PBolEqvdxCgvtAXBwdJTA2M1kzvbPzAQ2bOAfG8Anfo8dy9C1a5nN5HNYwuvfllH7mw+1vXkZ2v667mfRAVOvXr3wyiuvoH79+khPT8fHH3+M3r174/jx4xAJc1jLefz4MaRSKfwqZN36+fnhWsW1+8tJTExEQkKCyva9e/fCRYcukaSkJK3LGtuBA90AuMLO7iR27XpktONmZDQA0BJpaVnYteu0XseQSjmUlr4MADh2LAm1a5vmw8Uc7X/xojdkso5K26RSDj/9dBItWz6p9vqYkzlf/4Ta35yo7c1L3/YvFGYjacmiA6bBgwfLL7ds2RKtWrVCw4YNkZycjG7duhntfmbMmIGpU6fKr+fl5SEoKAg9e/aEm5tblftLJBIkJSWhR48ecHBwMFq9tMWfy4y/3wED2qF5c+Md++FDDmvWAO7uddGnTx+9jpGbq7g8YEAPiMVGqtz/M2f7t2oFzJrFIJMpMr1FIoahQ6NtqofJnK9/W0ftbz7U9uZlaPsLo0nasuiAqaIGDRrA29sbN27cUBsweXt7QyQS4cGDB0rbHzx4UGkelFgshljNt7iDg4NOT4Ku5Y1l3jzF5agoB6xebbwcGnd3/v/z53ZwcNAvOaq0lP8vEgG1ajmYbBaZOdq/fn1+0b6xY/nTQfCL9nGoX9/2PjzN9fonPGp/86G2Ny9921/XfWrUSt+ZmZl48uQJ6tatq/Z2R0dHREVFYd++ffJtMpkM+/btQ4wxV3O0EOfOAQMHAitWKLbJZPyXd2amce7DGEnf5RO+rXHK/ejRwO3bwIED/H9K+CaEEOtj1h6mgoIC3LhxQ3791q1bSElJgZeXF7y8vJCQkIBXX30V/v7+SE9Px4cffohGjRohPj5evk+3bt0wcOBATJw4EQAwdepUjBgxAm3btkX79u2xdOlSPH/+XD5rrqZjDPj7b+DLL4FycaESY5740hgBk7UuWlkeLdpHCCHWzawB0+nTp9GlSxf5dSGPaMSIEVixYgUuXLiADRs2ICcnBwEBAejZsyfmzp2rNHyWnp6Ox48fy6+/8cYbePToEWbOnIns7GxERkZiz549KongNUFmJn8m8MaNAV9f4Jdf+EDp0iX+dpEI6NcP+OMP5bOFG/PEl0KQY8jClda8BhMhhBDbYNaAKS4uDkw4AZcaf//9d5XHuH37tsq2iRMnynucaqrvvwfeeYcPhDiOzyUS1vtxdQXGjAEmTQJCQviyyjk0xuvtMOaQHAVMhBBCaqoalfRtKzIzFcESwA/D5eTwvUxTpvDBkaenorwpT3xZPmBiTL8cJGtetJIQQohtoIDJAl2/rjzEJti4EejZU/0+psqhEQKmsjJ+tps+SwJQDxMhhJCarkbNkrMVv/2muk0k4k/sWt3KBzn6DsvZQtI3IYQQ66ZzwJSbm4unT5+qbH/69KnOi0ARVcuWKZYJEM4JZ+y8JF3Y2yt6lfRN/KYeJkIIITWdzgHT4MGDsWnTJpXtmzdvVlqZm+ju11/5HCUA+OwzICPDMtb2MTTxmwImQgghNZ3OAdPJkyeVlgIQxMXF4eTJk0aplC3avx94800+sXriRGDGDL5HKS7O/Ov7GCtgoqRvQgghNZXOAVNJSQnKyspUtkskEhQVFRmlUrYmJQUYMACQSIDXXgOWLrWsFbGph4kQQoit0zlgat++PVavXq2yfeXKlYiKijJKpWzJrVtA795Afj7fm7RxI5+zZEkMDZgo6ZsQQkhNp/OyAvPmzUP37t1x/vx5+Qlw9+3bh1OnTmHv3r1Gr6A1e/SIXz8pO5s/6/327YCTk7lrpcrQ1b6ph4kQQkhNp3MPU8eOHXH8+HEEBQVh8+bN+PPPP9GoUSNcuHABnTt3NkUdrVJBAdC3L3/qk5AQYPdufjVvS0RDcoQQQmydXgtXRkZG4qeffjJ2XWxCZiZw9Sowfz5w6hRQpw5/Mt2AAHPXTDNK+iaEEGLrtAqY8vLy4ObmJr9cGaEcUVX+/HAA4OAA/PUXEBZm3npVhXKYCCGE2DqtAiZPT09kZWXB19cXHh4e4NRM4WKMgeM4SKVSo1fSGlQ8PxzAnyzX3EsGaIOG5AghhNg6rQKm/fv3w8vLCwBw4MABk1bIWqWlqZ4fTibjT5hr6UETJX0TQgixdVoFTLGxsQCAsrIyHDx4EG+99RYCLf1b3sI0bsyf6qR80CQSAY0ama9O2qIeJkIIIbZOp1ly9vb2+OKLL9QuXEkqFxgIrF6tWGPJnOeH0xUlfRNCCLF1Os+S69q1Kw4ePIjQ0FATVMe6jR7Nr7t04wbfs1QTgiXAsICJMUr6JoQQUvPpHDD17t0b06dPx8WLFxEVFYVaFb4FX375ZaNVzhoFBtacQElgSMBUWsontwMUMBFCCKm5dA6Yxo8fDwBYvHixym00S846GZL0XX4fGpIjhBBSU+kcMMkqTvUiVs+QHiYhYHJw4P8IIYSQmkjnU6P88MMPKCkpUdleWlqKH374wSiVIpbFGAETDccRQgipyXQOmEaNGoXc3FyV7fn5+Rg1apRRKkUsiyEBEyV8E0IIsQY6B0zCit4VZWZmwt1Szx5LDCIETM+f87PedEE9TIQQQqyB1jlMrVu3Bsdx4DgO3bp1g729YlepVIpbt26hV69eJqkkMS8h2GEMKCrSLXmbAiZCCCHWQOuAacCAAQCAlJQUxMfHw1XodgDg6OiI0NBQvPrqq0avIDG/8gFSQYF+ARPNkCOEEFKTaR0wzZo1CwAQGhqKN954A05OTiarFLEsdnZ8D9Hz53zA5Our/b7Uw0QIIcQa6JzDNGLECBQXF2PNmjWYMWMGnj59CgA4e/Ys7t27p9OxDh06hH79+iEgIAAcx2H79u3y2yQSCT766CO0bNkStWrVQkBAAIYPH4779+9XeszZs2fLhw6Fv/DwcF0fJqlA38RvSvomhBBiDXQOmC5cuIAmTZpgwYIF+PLLL5GTkwMA2Lp1K2bMmKHTsZ4/f46IiAgsX75c5bbCwkKcPXsWn376Kc6ePYutW7ciNTVVq5XEmzdvjqysLPnfkSNHdKoXUVU+8VsX1MNECCHEGui8cOWUKVMwcuRILFy4ELVr15Zv79OnD/7zn//odKzevXujd+/eam9zd3dHUlKS0rZvvvkG7du3x507dxAcHKzxuPb29vD399epLqRyQsCjaw8TBUyEEEKsgc49TKdPn8bYsWNVtterVw/Z2dlGqZQmubm54DgOHh4elZZLS0tDQEAAGjRogKFDh+LOnTsmrZct0HdIjpK+CSGEWAOde5jEYjHy8vJUtl+/fh0+Pj5GqZQ6xcXF+OijjzBkyBC4ublpLBcdHY3169cjLCwMWVlZSEhIQOfOnXHp0iWlHrHySkpKlFYvFx6fRCKBRCKpsm5CGW3K1lS1aokA2CEnpwwSifaLMRUU2AEQwclJConENKfVsYX2t2TU/uZF7W8+1PbmZWj767qfzgHTyy+/jDlz5mDz5s0A+BPu3rlzBx999JHJlhWQSCR4/fXXwRjDihUrKi1bfoivVatWiI6ORkhICDZv3ozRo0er3ScxMREJCQkq2/fu3QsXHbpGKg4hWpP8/HYAAnDy5GV4ed3Wer/U1EgAIcjMTMWuXWkmqh3Pmtu/JqD2Ny9qf/Ohtjcvfdu/UJiVpCWdA6ZFixbhtddeg6+vL4qKihAbG4vs7GzExMTgs88+0/VwVRKCpYyMDOzfv7/S3iV1PDw80KRJE9y4cUNjmRkzZmDq1Kny63l5eQgKCkLPnj21uj+JRIKkpCT06NEDDlZ6htktW0Q4cQKoX78F+vRppvV+P/4oAgC0aROGPn0am6RuttD+loza37yo/c2H2t68DG1/daNlldE5YBKSsY8cOYILFy6goKAAbdq0Qffu3XU9VJWEYCktLQ0HDhxAnTp1dD5GQUEB0tPT8eabb2osIxaLIRaLVbY7ODjo9CToWr4mEeLGoiIRHBxEWu9XVCTsr9t++rDm9q8JqP3Ni9rffKjtzUvf9td1H50DJkGnTp3QqVMnfXcHwAcz5Xt+bt26hZSUFHh5eaFu3bp47bXXcPbsWfz111+QSqXypHIvLy84OjoCALp164aBAwdi4sSJAIBp06ahX79+CAkJwf379zFr1iyIRCIMGTLEoLraOkr6JoQQYsv0CphOnTqFAwcO4OHDh5DJlBN5Fy9erPVxTp8+jS5dusivC8NiI0aMwOzZs/HHH38AACIjI5X2O3DgAOLi4gAA6enpePz4sfy2zMxMDBkyBE+ePIGPjw86deqEEydOmDQh3RbQwpWEEEJsmc4B0/z58/HJJ58gLCwMfn5+4DhOflv5y9qIi4sDY5pnXFV2m+D27dtK1zdt2qRTHYh2DO1hooCJEEJITaZzwLRs2TKsXbsWI0eONEF1iKUSAh5a6ZsQQogt0nnhSjs7O3Ts2NEUdSEWjHKYCCGE2DKdA6YpU6aoPfcbsW40JEcIIcSW6TwkN23aNPTt2xcNGzZEs2bNVKblbd261WiVI5ZDn4CJMUr6JoQQYh10Dpj++9//4sCBA+jSpQvq1Kmjc6I3qZn0CZiENZgACpgIIYTUbDoHTBs2bMDvv/+Ovn37mqI+xELpk/RdvizlMBFCCKnJdM5h8vLyQsOGDU1RF2LB9OlhEgImJyfATudXGiGEEGI5dP4amz17NmbNmqXzSetIzSYETEVFgFSq3T6U8E0IIcRa6Dwk99VXXyE9PR1+fn4IDQ1VSfo+e/as0SpHLIcQMAF8IKTNOZAp4ZsQQoi10DlgGjBggAmqQSydWAyIRHzvUkGBdgET9TARQgixFjoHTLNmzTJFPYiF4zg+8MnL0z7xmwImQggh1oJScYnWdE38plW+CSGEWAsKmIjWdA2YKIeJEEKItaCAiWhN3x4mCpgIIYTUdBQwEa1RwEQIIcRWUcBEtKbrat8UMBFCCLEWWs2Smzp1qtYHXLx4sd6VIZaNkr4JIYTYKq0CpnPnzildP3v2LMrKyhAWFgYAuH79OkQiEaKiooxfQ2IxKOmbEEKIrdIqYDpw4ID88uLFi1G7dm1s2LABnp6eAIBnz55h1KhR6Ny5s2lqSSwC5TARQgixVTrnMC1atAiJiYnyYAkAPD09MW/ePCxatMiolSOWhQImQgghtkrngCkvLw+PHj1S2f7o0SPk5+cbpVLEMumb9E05TIQQQmo6nQOmgQMHYtSoUdi6dSsyMzORmZmJ33//HaNHj8Yrr7xiijoSC0E9TIQQQmyVzueSW7lyJaZNm4b//Oc/kEgk/EHs7TF69Gh88cUXRq8gsRyU9E0IIcRW6RQwSaVSnD59Gp999hm++OILpKenAwAaNmyIWvStaPWoh4kQQoit0ilgEolE6NmzJ65evYr69eujVatWpqoXsUBCwEQLVxJCCLE1OucwtWjRAjdv3jRFXYiFEwIfWriSEEKIrdE5YJo3bx6mTZuGv/76C1lZWcjLy1P6I9aLhuQIIYTYKp0Dpj59+uD8+fN4+eWXERgYCE9PT3h6esLDw0NpbSZtHDp0CP369UNAQAA4jsP27duVbmeMYebMmahbty6cnZ3RvXt3pKWlVXnc5cuXIzQ0FE5OToiOjsa///6rU72IeroETFIpUFLCX6aAiRBCSE2n8yy58qt+G+r58+eIiIjAW2+9pXZJgoULF+Krr77Chg0bUL9+fXz66aeIj4/HlStX4OTkpPaYv/76K6ZOnYqVK1ciOjoaS5cuRXx8PFJTU+Hr62u0utsiXQImYYYcQAETIYSQmk/ngCk2NtZod967d2/07t1b7W2MMSxduhSffPIJ+vfvDwD44Ycf4Ofnh+3bt2Pw4MFq91u8eDHGjBmDUaNGAeCXQdi5cyfWrl2L6dOnG63utkgImCQSoLQUcHTUXFYYjuM4QENsSwghhNQYOgdMgsLCQty5cwelpaVK2401c+7WrVvIzs5G9+7d5dvc3d0RHR2N48ePqw2YSktLcebMGcyYMUO+zc7ODt27d8fx48c13ldJSQlKhPEjQJ6LJZFI5GtNVUYoo03ZmowPkBwAADk5ElQ2ApuTw5d1cWEoKyszab1spf0tFbW/eVH7mw+1vXkZ2v667qdzwPTo0SOMGjUKu3fvVnu7VCrV9ZBqZWdnAwD8/PyUtvv5+clvq+jx48eQSqVq97l27ZrG+0pMTERCQoLK9r1798JFhyleSUlJWpetqeztX0JZmQh//LEfPj7FGsvdvl0bQFfY25dg166/q6VuttD+loza37yo/c2H2t689G3/wvK5I1rQOWCaPHkycnJycPLkScTFxWHbtm148OBBjT757owZMzB16lT59by8PAQFBaFnz55wc3Orcn+JRIKkpCT06NEDDg4Opqyq2bm52eHpU6B9+65o2lRzuZMnOQCAl5cYffr0MWmdbKn9LRG1v3lR+5sPtb15Gdr+us7s1zlg2r9/P3bs2IG2bdvCzs4OISEh6NGjB9zc3JCYmIi+ffvqeki1/P39AQAPHjxA3bp15dsfPHiAyMhItft4e3tDJBLhwYMHStsfPHggP546YrEYYrFYZbuDg4NOT4Ku5WsiV1fg6VOgpMQBlT1UxQw5rtraxBba35JR+5sXtb/5UNubl77tr+s+Oi8r8Pz5c/lsM09PTzx69AgA0LJlS5w9e1bXw2lUv359+Pv7Y9++ffJteXl5OHnyJGJiYtTu4+joiKioKKV9ZDIZ9u3bp3EfohttV/umNZgIIYRYE50DprCwMKSmpgIAIiIisGrVKty7dw8rV65U6gnSRkFBAVJSUpCSkgKAT/ROSUnBnTt3wHEcJk+ejHnz5uGPP/7AxYsXMXz4cAQEBGDAgAHyY3Tr1g3ffPON/PrUqVPx3XffYcOGDbh69SreffddPH/+XD5rjhhG29W+aZVvQggh1kTnIblJkyYhKysLADBr1iz06tULP/30ExwdHbF+/XqdjnX69Gl06dJFfl3IIxoxYgTWr1+PDz/8EM+fP8c777yDnJwcdOrUCXv27FFagyk9PR2PHz+WX3/jjTfw6NEjzJw5E9nZ2YiMjMSePXtUEsGJfrRdi0nIpaMeJkIIIdZA54Bp2LBh8stRUVHIyMjAtWvXEBwcDG9vb52OFRcXB8aYxts5jsOcOXMwZ84cjWVu376tsm3ixImYOHGiTnUh2tE2YKIhOUIIIdZE5yG5iifedXFxQZs2bXQOlkjNRAETIYQQW6RzD1OjRo0QGBiI2NhYxMXFITY2Fo0aNTJF3YgF0jXpm3KYCCGEWAOde5ju3r2LxMREODs7Y+HChWjSpAkCAwMxdOhQrFmzxhR1JBZE16Rv6mEihBBiDXQOmOrVq4ehQ4di9erVSE1NRWpqKrp3747Nmzdj7NixpqgjsSCU9E0IIcQW6TwkV1hYiCNHjiA5ORnJyck4d+4cwsPDMXHiRMTFxZmgisSSUA4TIYQQW6RzwOTh4QFPT08MHToU06dPR+fOneFZ2VlYiVWhgIkQQogt0jlg6tOnD44cOYJNmzYhOzsb2dnZiIuLQ5MmTUxRP2JhhACIkr4JIYTYEp1zmLZv347Hjx9jz549iImJwd69e9G5c2d5bhOxbtTDRAghxBbp3MMkaNmyJcrKylBaWori4mL8/fff+PXXX/HTTz8Zs37EwlDSNyGEEFukcw/T4sWL8fLLL6NOnTqIjo7GL7/8giZNmuD333+Xn4iXWC/qYSKEEGKLdO5h+uWXXxAbG4t33nkHnTt3hru7uynqRSwUBUyEEEJskc4B06lTp0xRD1JDUNI3IYQQW6TzkBwAHD58GMOGDUNMTAzu3bsHANi4cSOOHDli1MoRy1O+h6mS8yZTDhMhhBCronPA9PvvvyM+Ph7Ozs44d+4cSkpKAAC5ubmYP3++0StILIsQMMlkQHGx+jISCf8HUMBECCHEOugcMM2bNw8rV67Ed999BwcHB/n2jh074uzZs0atHLE85YfYNOUxlR+uo4CJEEKINdA5YEpNTcWLL76ost3d3R05OTnGqBOxYCKRImjSlMckbLe3Bxwdq6dehBBCiCnpHDD5+/vjxo0bKtuPHDmCBg0aGKVSxLIJvUZV9TBRwjchhBBroXPANGbMGEyaNAknT54Ex3G4f/8+fvrpJ0ybNg3vvvuuKepILExVSwtQwjchhBBro/OyAtOnT4dMJkO3bt1QWFiIF198EWKxGNOmTcN7771nijoSC1NVwERrMBFCCLE2OgdMHMfhf//7Hz744APcuHEDBQUFaNasGVxdXVFUVARnZ2dT1JNYEAqYCCGE2Bq91mECAEdHRzRr1gzt27eHg4MDFi9ejPr16xuzbsRCCQFTVUnflMNECCHEWmgdMJWUlGDGjBlo27YtOnTogO3btwMA1q1bh/r162PJkiWYMmWKqepJLIi2Sd/Uw0QIIcRaaD0kN3PmTKxatQrdu3fHsWPHMGjQIIwaNQonTpzA4sWLMWjQIIhEIlPWlVgISvomhBBia7QOmLZs2YIffvgBL7/8Mi5duoRWrVqhrKwM58+fB8dxpqwjsTCUw0QIIcTWaD0kl5mZiaioKABAixYtIBaLMWXKFAqWbBAFTIQQQmyN1gGTVCqFY7llm+3t7eEqfHMSm0JJ34QQQmyN1kNyjDGMHDkSYrEYAFBcXIxx48ahVoVuhK1btxq1gqGhocjIyFDZPn78eCxfvlxl+/r16zFq1CilbWKxGMWazhRLdEZJ34QQQmyN1gHTiBEjlK4PGzbM6JVR59SpU5BKpfLrly5dQo8ePTBo0CCN+7i5uSE1NVV+nYYNjYuSvgkhhNgarQOmdevWmbIeGvn4+Chd//zzz9GwYUPExsZq3IfjOPj7+5u6ajaLcpgIIYTYGr0XrjSH0tJS/Pjjj3jrrbcq7TUqKChASEgIgoKC0L9/f1y+fLkaa2n9KGAihBBia3Q+NYo5bd++HTk5ORg5cqTGMmFhYVi7di1atWqF3NxcfPnll+jQoQMuX76MwMBAtfuUlJSgpKREfj0vLw8AIJFIIJFIqqyXUEabstbAyYkDYI+CAgaJpEzl9oICEQA7ODqWQSJhJq+PrbW/paH2Ny9qf/OhtjcvQ9tf1/04xpjpv9GMJD4+Ho6Ojvjzzz+13kcikaBp06YYMmQI5s6dq7bM7NmzkZCQoLL9559/hgtN9VJx7Zonpk9/EX5+z7Fq1T8qt3/0UWekpnphxoyTiI7ONkMNCSGEkMoVFhbiP//5D3Jzc+Hm5lZl+RoTMGVkZKBBgwbYunUr+vfvr9O+gwYNgr29PX755Re1t6vrYQoKCsLjx4+1akSJRIKkpCT06NEDDg4OOtWtJrp4EYiKcoCvL0NmpmoPU5s29rh0icPu3WXo1q16ephsqf0tDbW/eVH7mw+1vXkZ2v55eXnw9vbWOmCqMUNy69atg6+vL/r27avTflKpFBcvXkSfPn00lhGLxfLlEspzcHDQ6UnQtXxN5enJ/y8o4NQ+XmGWnLu7PaqzOWyl/S0Vtb95UfubD7W9eenb/rruUyOSvmUyGdatW4cRI0bA3l45xhs+fDhmzJghvz5nzhzs3bsXN2/exNmzZzFs2DBkZGTg7bffru5qWy0h6buwEJDJVG+npG9CCCHWpkb0MP3zzz+4c+cO3nrrLZXb7ty5Azs7Rdz37NkzjBkzBtnZ2fD09ERUVBSOHTuGZs2aVWeVrVr5Bd4LC5WvA7TSNyGEEOtTIwKmnj17QlOqVXJystL1JUuWYMmSJdVQK9vl5ARwHMAYv7RA+YCJMVq4khBCiPWpEUNyxLJwnOa1mEpKFMN0FDARQgixFhQwEb1oCpjKn5CXhuQIIYRYCwqYiF6qCpgcHQH7GjHgSwghhFSNAiaiFyFgKt+jVP46DccRQgixJhQwEb0IAVHFHiZK+CaEEGKNKGAieqlqSI4CJkIIIdaEAiaiFwqYCCGE2BIKmIheqsphohlyhBBCrAkFTEQvmnqYKIeJEEKINaKAiehFU9I3DckRQgixRhQwEb1QDhMhhBBbQgET0QsFTIQQQmwJBUxEL5T0TQghxJZQwET0QknfhBBCbAkFTEQvlPRNCCHEllDARPRCOUyEEEJsCQVMRC8UMBFCCLElFDARvVDSNyGEEFtCARPRCyV9E0IIsSUUMBG9CAFRSQkgkSi205AcIYQQa0QBE9GL0MMEKA/LUcBECCHEGlHARPTi6Ag4OPCXyw/LUQ4TIYQQa0QBE9GbusRv6mEihBBijShgInqruHilTAYUFSnfRgghhFgDCpiI3irOlBOCJYACJkIIIdaFAiait4oBU/mhOWfn6q8PIYQQYioUMBG9aQqYnJ0BO3plEUIIsSIW/bU2e/ZscByn9BceHl7pPlu2bEF4eDicnJzQsmVL7Nq1q5pqa3sqJn3TopWEEEKslUUHTADQvHlzZGVlyf+OHDmiseyxY8cwZMgQjB49GufOncOAAQMwYMAAXLp0qRprbDsqJn3TDDlCCCHWyuIDJnt7e/j7+8v/vL29NZZdtmwZevXqhQ8++ABNmzbF3Llz0aZNG3zzzTfVWGPboWlIjgImQggh1sbe3BWoSlpaGgICAuDk5ISYmBgkJiYiODhYbdnjx49j6tSpStvi4+Oxffv2Su+jpKQEJSUl8ut5eXkAAIlEAkn5835oIJTRpqw1cXGxAyBCbq4UEokMubkcAHu4uMggkUirrR622v6WgtrfvKj9zYfa3rwMbX9d97PogCk6Ohrr169HWFgYsrKykJCQgM6dO+PSpUuoXbu2Svns7Gz4+fkpbfPz80N2dnal95OYmIiEhASV7Xv37oWLDktWJyUlaV3WGmRnhwMIw+XLGdi16yKOHg0A0A5FRU+xa9fRaq+PrbW/paH2Ny9qf/Ohtjcvfdu/UEi81ZJFB0y9e/eWX27VqhWio6MREhKCzZs3Y/To0Ua7nxkzZij1TOXl5SEoKAg9e/aEm5tblftLJBIkJSWhR48ecBDOF2IDLl2yw5YtgI9PKPr0CcKjRxwAIDjYC3369Km2ethq+1sKan/zovY3H2p78zK0/YXRJG1ZdMBUkYeHB5o0aYIbN26ovd3f3x8PHjxQ2vbgwQP4+/tXelyxWAyxWKyy3cHBQacnQdfyNZ0QSxYW2sHBwQ7Fxfx1V1f+enWztfa3NNT+5kXtbz7U9ualb/vruo/FJ32XV1BQgPT0dNStW1ft7TExMdi3b5/StqSkJMTExFRH9WwOJX0TQgixFRYdME2bNg0HDx7E7du3cezYMQwcOBAikQhDhgwBAAwfPhwzZsyQl580aRL27NmDRYsW4dq1a5g9ezZOnz6NiRMnmushWDUKmAghhNgKix6Sy8zMxJAhQ/DkyRP4+PigU6dOOHHiBHx8fAAAd+7cgV25JaU7dOiAn3/+GZ988gk+/vhjNG7cGNu3b0eLFi3M9RCsWsWFK4X/OuTJE0IIITWCRQdMmzZtqvT25ORklW2DBg3CoEGDTFQjUl7FHiZa6ZsQQoi1sughOWLZaKVvQgghtoICJqI3ymEihBBiKyhgInorHzAxRjlMhBBCrBcFTERvQsAklQKlpdTDRAghxHpRwET0Vj4wKiigpG9CCCHWiwImojeRCHBy4i8XFFAPEyGEEOtFARMxSPk8JgqYCCGEWCsKmIhB1AVMlPRNCCHE2lDARAxSfrVvymEihBBirShgIgYRAqbcXKCkhL9MARMhhBBrQwETMYgQHD14oLqNEEIIsRYUMBGDCD1MQsBkZweIxearDyGEEGIKFDARgwgB08OH/H8XF4DjzFcfQgghxBQoYCIGqRgw0XAcIYQQa0QBEzFIxSE5CpgIIYRYIwqYiEEqJn1TwEQIIcQaUcBEDEI9TIQQQmwBBUzEIOXXYQJolW9CCCHWiQImYhAhYBJQDxMhhBBrRAETMQgFTIQQQmwBBUzEIBUDJAqYCCGEWCMKmIhBKvYwUQ4TIYQQa2Rv7gqQmo2G5AghRDPGGMrKyiCVSs1dFasjkUhgb2+P4uJije3r4OAAkUhklPujgIkYhAImQghRr7S0FFlZWSgsLDR3VawSYwz+/v64e/cuOA3n5OI4DoGBgXCt+GWlBwqYiEEoYCKEEFUymQy3bt2CSCRCQEAAHB0dNX6pE/3IZDIUFBTA1dUVdnaqGUaMMTx69AiZmZlo3LixwT1NFDARg1DSNyGEqCotLYVMJkNQUBBcKLnTJGQyGUpLS+Hk5KQ2YAIAHx8f3L59GxKJxOCAyaKTvhMTE9GuXTvUrl0bvr6+GDBgAFJTUyvdZ/369eA4TunPycmpmmpse5ydgfI/muhzgRBCFDR9kZPqYcxePYt+Jg8ePIgJEybgxIkTSEpKgkQiQc+ePfH8+fNK93Nzc0NWVpb8LyMjo5pqbHvs7JR7laiHiRBCiDWy6CG5PXv2KF1fv349fH19cebMGbz44osa9+M4Dv7+/qauHvl/rq5AQQF/mQImQggh1eXIkSPo168fnj17Bg8PD5Pel0UHTBXl/v8Jy7y8vCotV1BQgJCQEMhkMrRp0wbz589H8+bNNZYvKSlBSUmJ/HpeXh4AfsqiRCKpsl5CGW3KWiNXV3sAfLenWFwGiYRV6/3bevubG7W/eVH7m09lbS+RSMAYg0wmg0wmq+6q2QTGFN81mtpZJpOBMaY2h0nX90yNCZhkMhkmT56Mjh07okWLFhrLhYWFYe3atWjVqhVyc3Px5ZdfokOHDrh8+TICAwPV7pOYmIiEhASV7Xv37tUpWS8pKUnrstakrCwOgDsA4OzZw8jJyTNLPWy1/S0Ftb95Ufubj7q2t7e3h7+/PwoKClBaWmqGWhlPaWkpHB0dLboO+fn5avPFSktLUVRUhEOHDqGsrEzpNl2Xe+BY+RDNgr377rvYvXs3jhw5ojHwUUcikaBp06YYMmQI5s6dq7aMuh6moKAgPH78GG5ublrdR1JSEnr06AEHBwet62Yt4uJEOHaMf6FeuiRBkybVe/+23v7mRu1vXtT+5lNZ2xcXF+Pu3bsIDQ01eOJRZiaQlgY0bgzo8PWnt65du6J58+awt7fHTz/9hJYtW2LZsmX48MMPceTIEdSqVQs9evTA4sWL4e3tjb/++gvDhw/Ho0ePIBKJkJKSgqioKHz44YdITEwEAIwZMwbFxcXYuHEjnjx5gvfeew+HDx/Gs2fP0LBhQ0yfPh1DhgyptA779u3Drl27MHXqVNy9exfR0dF4/fXXMWHCBDx58kTtkFxxcTFu376NoKAglechLy8P3t7eyM3N1eq7vkb0ME2cOBF//fUXDh06pFOwBPCrfLZu3Ro3btzQWEYsFkMsFqvdV5cPIF3LW4vatRWXPTwcYK4msNX2txTU/uZF7W8+6tpeKpWC4zjY2dnJez4YA3Rdw3LDBuC99wCZjJ9k8/XXwIgRuh3DxUV5NrM2fvjhB7z77rs4evQocnJy0L17d7z99ttYunQpioqK8NFHH2Hw4MHYv38/YmNjkZ+fj/Pnz6Nt27Y4fPgwvL29cfDgQfljP3ToED766CPY2dmhtLQUbdu2xfTp0+Hm5oadO3dixIgRaNy4Mdq3b6+2DgBw7949vPbaa5gwYQLeeecd/Pvvv5g2bRoAKLVzeXZ2duA4Tu1zpOv7xaIDJsYY3nvvPWzbtg3JycmoX7++zseQSqW4ePEi+vTpY4IaEkB58UpK+iaEEPUKC1UX+9WFTAZMmMD/6aKgQPfP5saNG2PhwoUAgHnz5qF169aYP3++/Pa1a9ciKCgI169fR5MmTRAZGYnk5GS0bdsWycnJmDJlChISElBQUIDc3FzcuHEDsbGxAIB69erJAx0AeO+99/D3339j8+bNSgFT+ToAwMcff4yGDRti0aJF8tvPnDmDZcuW6fbg9GTRywpMmDABP/74I37++WfUrl0b2dnZyM7ORlFRkbzM8OHDMWPGDPn1OXPmYO/evbh58ybOnj2LYcOGISMjA2+//bY5HoJNoICJEEKsS1RUlPzy+fPnceDAAbi6usr/wsPDAQDp6ekAgNjYWCQnJ4MxhsOHD+OVV15B06ZNceTIERw8eBABAQFo3LgxAL4jY+7cuWjZsiW8vLzg6uqKv//+G3fu3NFYBwC4evUqoqOjlbaVD7BMzaJ7mFasWAEAiIuLU9q+bt06jBw5EgBw584dpW64Z8+eYcyYMcjOzoanpyeioqJw7NgxNGvWrLqqbXOEIMnBAWYbjiOEEEvn4qJYgkUb9+4BTZvyPUsCkQi4cgWoV0+3+9VVrXK/fgsKCtCvXz8sWLBApVzdunUB8N/Ta9euxfnz5+Hg4IDw8HDExcUhOTkZz549k/cuAcAXX3yBZcuWYenSpWjZsiVq1aqFyZMnqyTH17KwX+AWHTBpk4+enJysdH3JkiVYsmSJiWpE1BF6mGiVb0II0YzjdOuFb9IEWL0aGDsWkEr5YGnVKlT7xJo2bdrg999/R2hoKOzt1YcNnTt3Rn5+PpYsWSIPjuLi4vD555/j2bNneP/99+Vljx49iv79+2PYsGEA+Fnw169fr7Jjo2nTpvjjjz+Utp06dcqQh6YTix6SIzWDEDBZ2I8BQgip8UaPBm7fBg4c4P+PHl39dZgwYQKePn2KIUOG4NSpU0hPT8fff/+NUaNGQSqVAgA8PT3RqlUr/PTTT/JRoRdffBFnz57F9evXlXqYGjdujKSkJBw7dgxXr17F2LFj8eDBgyrrMW7cOKSlpeGDDz5Aamoqfv75Z/zyyy8meczqUMBEDCYETBzHT38lhBBiPIGBQFxc9SwpoE5AQACOHj0KqVSKnj17omXLlpg8eTI8PDyUUmJiY2MhlUrlAZOXlxeaNWsGf39/hIWFyct98sknaNOmDeLj4xEXFwd/f38MGDCgynoEBwfj999/x/bt2xEREYHVq1fj008/NfbD1ciih+RIzXDuHP//3j0gJITvQjbHryBCCCGGq5jqAvC9Qlu3bq10v6VLl2Lp0qVK21JSUlTKeXl5Yfv27TrXAQBeeuklvPTSSwD4oby8vDy8++671XKSY+phIgbJzAR+/FFxXSbjx9upp4kQQog1oYCJGCQtjV+MrTypFKhknVBCCCGkxqGAiRikcWN+9dnyRCKgUSPz1IcQQggxBQqYiEECA/mcJeEk0MK0V3MlJxJCCCGmQEnfxGCjRwPx8fwwXKNGFCwRQgixPhQwEaMIDKRAiRBCKtJmAWZiOsZsfxqSI4QQQozM4f/PE1VYWGjmmtg24XQrIiFvxADUw0QIIYQYmUgkgoeHBx4+fAgAcHFxAcdxZq6VdZHJZCgtLUVxcbHadZhkMhkePXoEFxcXjad00QUFTIQQQogJ+Pv7A4A8aCLGxRhDUVERnJ2dNQajdnZ2CA4ONkqwSgETIYQQYgIcx6Fu3brw9fWFRCIxd3WsjkQiwaFDh/Diiy/Kh0ArcnR0NNoq4BQwEUIIISYkEomMkkNDlIlEIpSVlcHJyUljwGRMlPRNCCGEEFIFCpgIIYQQQqpAARMhhBBCSBUoh0kNYaGrvLw8rcpLJBIUFhYiLy+vWsZRiTJqf/Oi9jcvan/zobY3L0PbX/iO13ZxSwqY1MjPzwcABAUFmbkmhBBCCDGl/Px8uLu7V1mOY7RuuwqZTIb79++jdu3aWq3dkJeXh6CgINy9exdubm7VUENSHrW/eVH7mxe1v/lQ25uXoe3PGEN+fj4CAgK0WnqAepjUsLOzQ6AeJ0Zzc3OjN40ZUfubF7W/eVH7mw+1vXkZ0v7a9CwJKOmbEEIIIaQKFDARQgghhFSBAiYjEIvFmDVrFsRisbmrYpOo/c2L2t+8qP3Nh9revKq7/SnpmxBCCCGkCtTDRAghhBBSBQqYCCGEEEKqQAETIYQQQkgVKGAyguXLlyM0NBROTk6Ijo7Gv//+a+4q1TiHDh1Cv379EBAQAI7jsH37dqXbGWOYOXMm6tatC2dnZ3Tv3h1paWlKZZ4+fYqhQ4fCzc0NHh4eGD16NAoKCpTKXLhwAZ07d4aTkxOCgoKwcOFCUz80i5eYmIh27dqhdu3a8PX1xYABA5CamqpUpri4GBMmTECdOnXg6uqKV199FQ8ePFAqc+fOHfTt2xcuLi7w9fXFBx98gLKyMqUyycnJaNOmDcRiMRo1aoT169eb+uFZvBUrVqBVq1bytWRiYmKwe/du+e3U9tXr888/B8dxmDx5snwbPQemM3v2bHAcp/QXHh4uv92i2p4Rg2zatIk5OjqytWvXssuXL7MxY8YwDw8P9uDBA3NXrUbZtWsX+9///se2bt3KALBt27Yp3f75558zd3d3tn37dnb+/Hn28ssvs/r167OioiJ5mV69erGIiAh24sQJdvjwYdaoUSM2ZMgQ+e25ubnMz8+PDR06lF26dIn98ssvzNnZma1ataq6HqZFio+PZ+vWrWOXLl1iKSkprE+fPiw4OJgVFBTIy4wbN44FBQWxffv2sdOnT7MXXniBdejQQX57WVkZa9GiBevevTs7d+4c27VrF/P29mYzZsyQl7l58yZzcXFhU6dOZVeuXGFff/01E4lEbM+ePdX6eC3NH3/8wXbu3MmuX7/OUlNT2ccff8wcHBzYpUuXGGPU9tXp33//ZaGhoaxVq1Zs0qRJ8u30HJjOrFmzWPPmzVlWVpb879GjR/LbLantKWAyUPv27dmECRPk16VSKQsICGCJiYlmrFXNVjFgkslkzN/fn33xxRfybTk5OUwsFrNffvmFMcbYlStXGAB26tQpeZndu3czjuPYvXv3GGOMffvtt8zT05OVlJTIy3z00UcsLCzMxI+oZnn48CEDwA4ePMgY49vawcGBbdmyRV7m6tWrDAA7fvw4Y4wPeO3s7Fh2dra8zIoVK5ibm5u8vT/88EPWvHlzpft64403WHx8vKkfUo3j6enJ1qxZQ21fjfLz81njxo1ZUlISi42NlQdM9ByY1qxZs1hERITa2yyt7WlIzgClpaU4c+YMunfvLt9mZ2eH7t274/jx42asmXW5desWsrOzldrZ3d0d0dHR8nY+fvw4PDw80LZtW3mZ7t27w87ODidPnpSXefHFF+Ho6CgvEx8fj9TUVDx79qyaHo3ly83NBQB4eXkBAM6cOQOJRKLU/uHh4QgODlZq/5YtW8LPz09eJj4+Hnl5ebh8+bK8TPljCGXovaIglUqxadMmPH/+HDExMdT21WjChAno27evSjvRc2B6aWlpCAgIQIMGDTB06FDcuXMHgOW1PQVMBnj8+DGkUqnSEwUAfn5+yM7ONlOtrI/QlpW1c3Z2Nnx9fZVut7e3h5eXl1IZdccofx+2TiaTYfLkyejYsSNatGgBgG8bR0dHeHh4KJWt2P5Vta2mMnl5eSgqKjLFw6kxLl68CFdXV4jFYowbNw7btm1Ds2bNqO2ryaZNm3D27FkkJiaq3EbPgWlFR0dj/fr12LNnD1asWIFbt26hc+fOyM/Pt7i2p5PvEkLkJkyYgEuXLuHIkSPmropNCQsLQ0pKCnJzc/Hbb79hxIgROHjwoLmrZRPu3r2LSZMmISkpCU5OTuaujs3p3bu3/HKrVq0QHR2NkJAQbN68Gc7OzmasmSrqYTKAt7c3RCKRSsb+gwcP4O/vb6ZaWR+hLStrZ39/fzx8+FDp9rKyMjx9+lSpjLpjlL8PWzZx4kT89ddfOHDgAAIDA+Xb/f39UVpaipycHKXyFdu/qrbVVMbNzc3iPhirm6OjIxo1aoSoqCgkJiYiIiICy5Yto7avBmfOnMHDhw/Rpk0b2Nvbw97eHgcPHsRXX30Fe3t7+Pn50XNQjTw8PNCkSRPcuHHD4l7/FDAZwNHREVFRUdi3b598m0wmw759+xATE2PGmlmX+vXrw9/fX6md8/LycPLkSXk7x8TEICcnB2fOnJGX2b9/P2QyGaKjo+VlDh06BIlEIi+TlJSEsLAweHp6VtOjsTyMMUycOBHbtm3D/v37Ub9+faXbo6Ki4ODgoNT+qampuHPnjlL7X7x4USloTUpKgpubG5o1ayYvU/4YQhl6r6iSyWQoKSmhtq8G3bp1w8WLF5GSkiL/a9u2LYYOHSq/TM9B9SkoKEB6ejrq1q1rea9/nVLEiYpNmzYxsVjM1q9fz65cucLeeecd5uHhoZSxT6qWn5/Pzp07x86dO8cAsMWLF7Nz586xjIwMxhi/rICHhwfbsWMHu3DhAuvfv7/aZQVat27NTp48yY4cOcIaN26stKxATk4O8/PzY2+++Sa7dOkS27RpE3NxcbH5ZQXeffdd5u7uzpKTk5Wm9hYWFsrLjBs3jgUHB7P9+/ez06dPs5iYGBYTEyO/XZja27NnT5aSksL27NnDfHx81E7t/eCDD9jVq1fZ8uXLaVo1Y2z69Ons4MGD7NatW+zChQts+vTpjOM4tnfvXsYYtb05lJ8lxxg9B6b0/vvvs+TkZHbr1i129OhR1r17d+bt7c0ePnzIGLOstqeAyQi+/vprFhwczBwdHVn79u3ZiRMnzF2lGufAgQMMgMrfiBEjGGP80gKffvop8/PzY2KxmHXr1o2lpqYqHePJkydsyJAhzNXVlbm5ubFRo0ax/Px8pTLnz59nnTp1YmKxmNWrV499/vnn1fUQLZa6dgfA1q1bJy9TVFTExo8fzzw9PZmLiwsbOHAgy8rKUjrO7du3We/evZmzszPz9vZm77//PpNIJEplDhw4wCIjI5mjoyNr0KCB0n3YqrfeeouFhIQwR0dH5uPjw7p16yYPlhijtjeHigETPQem88Ybb7C6desyR0dHVq9ePfbGG2+wGzduyG+3pLbnGGNMtz4pQgghhBDbQjlMhBBCCCFVoICJEEIIIaQKFDARQgghhFSBAiZCCCGEkCpQwEQIIYQQUgUKmAghhBBCqkABEyGEEEJIFShgIoQQQgipAgVMhNiY27dvg+M4pKSkmLsqcteuXcMLL7wAJycnREZGmuQ+Ro4ciQEDBsivx8XFYfLkySa5L0NVR92q43VQsc0JqckoYCKkmo0cORIcx+Hzzz9X2r59+3ZwHGemWpnXrFmzUKtWLaSmpqqcJLOmsOQATJ2goCBkZWWhRYsW5q4KITUCBUyEmIGTkxMWLFiAZ8+embsqRlNaWqr3vunp6ejUqRNCQkJQp04dI9aKaCISieDv7w97e3tzV4WQGoECJkLMoHv37vD390diYqLGMrNnz1YZnlq6dClCQ0Pl14Uhj/nz58PPzw8eHh6YM2cOysrK8MEHH8DLywuBgYFYt26dyvGvXbuGDh06wMnJCS1atMDBgweVbr906RJ69+4NV1dX+Pn54c0338Tjx4/lt8fFxWHixImYPHkyvL29ER8fr/ZxyGQyzJkzB4GBgRCLxYiMjMSePXvkt3MchzNnzmDOnDngOA6zZ8/WeJyFCxeiUaNGEIvFCA4OxmeffSa//eLFi+jatSucnZ1Rp04dvPPOOygoKNDUvCpKSkowbdo01KtXD7Vq1UJ0dDSSk5OVyhw9ehRxcXFwcXGBp6cn4uPj8ezZM4wcORIHDx7EsmXLwHEcOI7D7du3tWrH58+fY/jw4XB1dUXdunWxaNEireq7Y8cOtGnTBk5OTmjQoAESEhJQVlYmv53jOKxYsQK9e/eGs7MzGjRogN9++01+e8UhuWfPnmHo0KHw8fGBs7MzGjdurPS6qap9pVIppk6dCg8PD9SpUwcffvghKp6qVCaTITExEfXr14ezszMiIiKU6lRVHQgxJwqYCDEDkUiE+fPn4+uvv0ZmZqZBx9q/fz/u37+PQ4cOYfHixZg1axZeeukleHp64uTJkxg3bhzGjh2rcj8ffPAB3n//fZw7dw4xMTHo168fnjx5AgDIyclB165d0bp1a5w+fRp79uzBgwcP8PrrrysdY8OGDXB0dMTRo0excuVKtfVbtmwZFi1ahC+//BIXLlxAfHw8Xn75ZaSlpQEAsrKy0Lx5c7z//vvIysrCtGnT1B5nxowZ+Pzzz/Hpp5/iypUr+Pnnn+Hn5weADzri4+Ph6emJU6dOYcuWLfjnn38wceJErdtx4sSJOH78ODZt2oQLFy5g0KBB6NWrl7yeKSkp6NatG5o1a4bjx4/jyJEj6NevH6RSKZYtW4aYmBiMGTMGWVlZyMrKQlBQkFbt+MEHH+DgwYPYsWMH9u7di+TkZJw9e7bSuh4+fBjDhw/HpEmTcOXKFaxatQrr169XCiAB4NNPP8Wrr76K8+fPY+jQoRg8eDCuXr2q9phCu+7evRtXr17FihUr4O3trXX7Llq0COvXr8fatWtx5MgRPH36FNu2bVO6j8TERPzwww9YuXIlLl++jClTpmDYsGHyYL2yOhBidowQUq1GjBjB+vfvzxhj7IUXXmBvvfUWY4yxbdu2sfJvyVmzZrGIiAilfZcsWcJCQkKUjhUSEsKkUql8W1hYGOvcubP8ellZGatVqxb75ZdfGGOM3bp1iwFgn3/+ubyMRCJhgYGBbMGCBYwxxubOnct69uypdN93795lAFhqaipjjLHY2FjWunXrKh9vQEAA++yzz5S2tWvXjo0fP15+PSIigs2aNUvjMfLy8phYLGbfffed2ttXr17NPD09WUFBgXzbzp07mZ2dHcvOzmaMKbe7UP9JkyYxxhjLyMhgIpGI3bt3T+m43bp1YzNmzGCMMTZkyBDWsWNHjXUsfzxBVe2Yn5/PHB0d2ebNm+W3P3nyhDk7O6scq2K95s+fr7Rt48aNrG7duvLrANi4ceOUykRHR7N3332XMaZ4HZw7d44xxli/fv3YqFGj1N6fNu1bt25dtnDhQvntwmtKaPPi4mLm4uLCjh07pnTs0aNHsyFDhlRZB0LMjQavCTGjBQsWoGvXrhp7VbTRvHlz2NkpOov9/PyUEnlFIhHq1KmDhw8fKu0XExMjv2xvb4+2bdvKex/Onz+PAwcOwNXVVeX+0tPT0aRJEwBAVFRUpXXLy8vD/fv30bFjR6XtHTt2xPnz57V8hMDVq1dRUlKCbt26abw9IiICtWrVUroPmUyG1NRUeU+UJhcvXoRUKpU/LkFJSYk8pyolJQWDBg3Sus5A1e1YVFSE0tJSREdHy7d7eXkhLCysyuMePXpUqUdJKpWiuLgYhYWFcHFxAaD8HAvXNc2Ke/fdd/Hqq6/i7Nmz6NmzJwYMGIAOHToAqLp9nZyckJWVpfQ4hNcU+/9huRs3bqCwsBA9evRQut/S0lK0bt26yjoQYm4UMBFiRi+++CLi4+MxY8YMjBw5Uuk2Ozs7lRwQiUSicgwHBwel6xzHqd0mk8m0rldBQQH69euHBQsWqNxWt25d+eXyX6Cm5OzsbNLjFxQUQCQS4cyZMxCJREq3CcGOPnWoqh1v3Lihd30TEhLwyiuvqNzm5OSk1zF79+6NjIwM7Nq1C0lJSejWrRsmTJiAL7/8Uq/jVSTkO+3cuRP16tVTuk0sFldLHQgxBOUwEWJmn3/+Of78808cP35cabuPjw+ys7OVgiZjrplz4sQJ+eWysjKcOXMGTZs2BQC0adMGly9fRmhoKBo1aqT0p0uQ5ObmhoCAABw9elRp+9GjR9GsWTOtj9O4cWM4OztrXHKgadOmOH/+PJ4/f650H3Z2dlX21gBA69atIZVK8fDhQ5XH6+/vDwBo1apVpUseODo6QiqVKm2rqh0bNmwIBwcHnDx5Ur7Ps2fPcP369Urr26ZNG6Smpqocs1GjRkq9jeWfY+G68Byr4+PjgxEjRuDHH3/E0qVLsXr1agBVt6+7uzvq1q2r9DiE15SgWbNmEIvFuHPnjkqdg4KCqqwDIeZGARMhZtayZUsMHToUX331ldL2uLg4PHr0CAsXLkR6ejqWL1+O3bt3G+1+ly9fjm3btuHatWuYMGECnj17hrfeegsAMGHCBDx9+hRDhgzBqVOnkJ6ejr///hujRo1SCQqq8sEHH2DBggX49ddfkZqaiunTpyMlJQWTJk3S+hhOTk746KOP8OGHH+KHH35Aeno6Tpw4ge+//x4AMHToUDg5OWHEiBG4dOkSDhw4gPfeew9vvvlmlcNxANCkSRMMHToUw4cPx9atW3Hr1i38+++/SExMxM6dOwHwSeenTp3C+PHjceHCBVy7dg0rVqyQz3gLDQ3FyZMncfv2bTx+/BgymazKdnR1dcXo0aPxwQcfYP/+/bh06RJGjhypFPSoM3PmTPzwww9ISEjA5cuXcfXqVWzatAmffPKJUrktW7Zg7dq1uH79OmbNmoV///1XYyL8zJkzsWPHDty4cQOXL1/GX3/9JQ+utGnfSZMm4fPPP8f27dtx7do1jB8/Hjk5OfLj165dG9OmTcOUKVOwYcMGpKen4+zZs/j666+xYcOGKutAiNmZOYeKEJtTMfmYMT4B19HRkVV8S65YsYIFBQWxWrVqseHDh7PPPvtMJem74rHUJR+HhISwJUuWyO8LAPv5559Z+/btmaOjI2vWrBnbv3+/0j7Xr19nAwcOZB4eHszZ2ZmFh4ezyZMnM5lMpvF+1JFKpWz27NmsXr16zMHBgUVERLDdu3crlakq6Vs4zrx581hISAhzcHBgwcHBSonPFy5cYF26dGFOTk7My8uLjRkzhuXn52tsq4r1Ly0tZTNnzmShoaHMwcGB1a1blw0cOJBduHBBXiY5OZl16NCBicVi5uHhweLj49mzZ88YY4ylpqayF154gTk7OzMA7NatW1q1Y35+Phs2bBhzcXFhfn5+bOHChVq17Z49e1iHDh2Ys7Mzc3NzY+3bt2erV6+W3w6ALV++nPXo0YOJxWIWGhrKfv31V/ntFZO+586dy5o2bcqcnZ2Zl5cX69+/P7t586bW7SuRSNikSZOYm5sb8/DwYFOnTmXDhw9XanOZTMaWLl3KwsLCmIODA/Px8WHx8fHs4MGDWtWBEHPiGKuQJEEIIaTG4zgO27Zto1OTEGIkNCRHCCGEEFIFCpgIIYQQQqpAywoQQogVomwLQoyLepgIIYQQQqpAARMhhBBCSBUoYCKEEEIIqQIFTIQQQgghVaCAiRBCCCGkChQwEUIIIYRUgQImQgghhJAqUMBECCGEEFIFCpgIIYQQQqrwf0ZSh8j2WhCQAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "train_stat = trainer.train(\n", " # self-play, all elements in agents list point to one unique OffPolicyAgent object.\n", " agents, \n", " # Only the first agent learns, the other agents are the same agent.\n", " [i == 0 for i,_ in enumerate(agents)]\n", ")" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "-ZqDUgo3OIls", "outputId": "5acd4204-7858-4ee7-c9f6-85ed0b4387fc" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'num_collected_episodes': 5008,\n", " 'num_collected_steps': 1553841,\n", " 'num_gradient_steps': 29952,\n", " 'training_time': 990.6171650886536}\n" ] } ], "source": [ "train_stat.pop('reward_metric_stats')\n", "pprint(train_stat)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Training takes about 15 minutes on Colab GPU." ] }, { "cell_type": "markdown", "metadata": { "id": "sXU0S_eRM4e3" }, "source": [ "### Evaluation.\n", "Let see how agent perform in environment with bigger required number mails." ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "execution": { "iopub.execute_input": "2024-11-27T21:30:37.776548Z", "iopub.status.busy": "2024-11-27T21:30:37.775796Z", "iopub.status.idle": "2024-11-27T21:30:37.813503Z", "shell.execute_reply": "2024-11-27T21:30:37.812682Z", "shell.execute_reply.started": "2024-11-27T21:30:37.776514Z" }, "id": "4PBU3D6Q6MWY", "trusted": true }, "outputs": [], "source": [ "tester = DecentralizedTrainer(\n", " env_args = dict(\n", " colors_map='assets/csv_files/colors_map.csv',\n", " targets_map='assets/csv_files/targets_map.csv',\n", " required_mail=15,\n", " robot_colors=['r', 'b', 'gr'],\n", " num_robots_per_player=1,\n", " with_battery=False,\n", " random_num_steps=False,\n", " max_step=2000,\n", " ),\n", " num_test_envs=16,\n", " episodes_per_test=48,\n", ")" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "execution": { "iopub.execute_input": "2024-11-26T22:19:57.726051Z", "iopub.status.busy": "2024-11-26T22:19:57.725655Z", "iopub.status.idle": "2024-11-26T22:19:57.776138Z", "shell.execute_reply": "2024-11-26T22:19:57.775144Z", "shell.execute_reply.started": "2024-11-26T22:19:57.726017Z" }, "id": "an_r03VB6MWZ", "outputId": "44e215ab-b063-4794-ca77-bc1e7cd407d5", "trusted": true }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# load best model to perform\n", "agent.policy.load_state_dict(torch.load(f=best_ckpt, weights_only=True, map_location=torch.device(agent.policy.model.device)))" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "execution": { "iopub.execute_input": "2024-11-27T21:19:19.67718Z", "iopub.status.busy": "2024-11-27T21:19:19.676402Z", "iopub.status.idle": "2024-11-27T21:19:29.046448Z", "shell.execute_reply": "2024-11-27T21:19:29.045625Z", "shell.execute_reply.started": "2024-11-27T21:19:19.677145Z" }, "id": "oueoNlE16MWZ", "outputId": "0e5fcee0-de81-47aa-ad58-c4e92b03d09c", "trusted": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'count_wins': {'b': 17, 'gr': 13, 'r': 18},\n", " 'mean_num_steps': 579.6458333333334,\n", " 'num_collected_episodes': 48,\n", " 'num_collected_steps': 27823,\n", " 'reward': 65.62430555555545,\n", " 'time_spans': 572.7916666666666}\n" ] } ], "source": [ "pprint(tester.test(agents, True))" ] }, { "cell_type": "markdown", "metadata": { "id": "aNmR0Py4Osic" }, "source": [ "The game process statistics can be evaluated by method `DecentralizedTrainer.test(agents, eval_metrics=True)`. It show you average time span of the game process in `'time_spans'` key and number of wins for each player across all episodes of test in `'count_wins'` key. It seem like we have balance game when all players have almost the same number of wins.\n", "\n", "Our trained model work well, no game is ended without winner. But because it's example so we have small number robots on the board. For more robots and robot moves with battery, which mean larger observation space and agent also have to learn to charge the battery when it is low, we need longer training and tuning hyperparameters." ] } ], "metadata": { "accelerator": "GPU", "colab": { "gpuType": "T4", "provenance": [] }, "kaggle": { "accelerator": "nvidiaTeslaT4", "dataSources": [ { "isSourceIdPinned": true, "modelId": 175330, "modelInstanceId": 152882, "sourceId": 179440, "sourceType": "modelInstanceVersion" } ], "dockerImageVersionId": 30786, "isGpuEnabled": true, "isInternetEnabled": true, "language": "python", "sourceType": "notebook" }, "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 0 }