File size: 34,871 Bytes
cf14949
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Environment - Enhanced"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import gym\n",
    "from gym import spaces\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import os\n",
    "import random\n",
    "import imageio\n",
    "from tqdm import tqdm  \n",
    "from itertools import count\n",
    "from collections import namedtuple, deque\n",
    "\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "import random\n",
    "import matplotlib.image as mpimg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class RoverGridEnv(gym.Env):\n",
    "    metadata={'render.modes': ['human']} \n",
    "    def __init__(self, max_ts=20):     \n",
    "        super(RoverGridEnv,self).__init__()\n",
    "        self.max_ts=max_ts      # The Max_Timestamps is set to 20 by default.\n",
    "        self.grid_size=(15,15)   \n",
    "        self.action_space=spaces.Discrete(5) \n",
    "        self.observation_space=spaces.MultiDiscrete([15,15,15,15,15,15])\n",
    "        self.rover_positions=np.array([[6,4],[10,4]])\n",
    "        self.operation_desks=np.array([[6,3],[10,3]])\n",
    "        self.rooms=np.array([[4,7],[4,10],[4,13],[8,7],[8,10],[8,13],[12,7],[12,10],[12,13]])\n",
    "        self.human_position=np.array([8,9])\n",
    "        self.targets=np.array([[5,10],[9,13]])\n",
    "        self.actions=[(0,-1),(0,1),(-1,0),(1,0),(0,0)]  # Down,Up,Left,Right,Wait\n",
    "        self.rover_done=[False,False] \n",
    "        self.reset()\n",
    "    \n",
    "    def seed(self,seed=None):\n",
    "        np.random.seed(seed)\n",
    "        random.seed(seed)\n",
    "        \n",
    "    def reset(self):\n",
    "        self.current_step=0\n",
    "        self.rover_positions=np.array([[6,4],[10,4]])\n",
    "        self.rover_done=[False,False]\n",
    "        self.human_position=np.array([7,8])\n",
    "        self.current_step=0\n",
    "        return self._get_obs()\n",
    "    \n",
    "    def _get_obs(self):\n",
    "        return np.concatenate((self.rover_positions.flatten(),self.human_position))\n",
    "    \n",
    "    def step(self,actions):\n",
    "        rewards=np.zeros(2)\n",
    "        done=[False,False]\n",
    "        info={'message': ''}        \n",
    "        for i,action in enumerate(actions):\n",
    "            if self.rover_done[i]:\n",
    "                done[i]=True \n",
    "                continue\n",
    "            prev_distance=np.linalg.norm(self.targets[i]-self.rover_positions[i])\n",
    "            if self._is_human_adjacent(self.rover_positions[i]):\n",
    "                rewards[i] -= 5\n",
    "            else:\n",
    "                delta=np.array(self.actions[action])\n",
    "                new_position=self.rover_positions[i]+delta\n",
    "                if self._out_of_bounds(new_position):\n",
    "                    rewards[i] -= 15\n",
    "                    continue\n",
    "                if self._collision(new_position,i):\n",
    "                    rewards[i] -= 15\n",
    "                    continue\n",
    "                self.rover_positions[i]=new_position\n",
    "                new_distance=np.linalg.norm(self.targets[i]-new_position)\n",
    "                if new_distance < prev_distance:\n",
    "                    rewards[i]+=30 \n",
    "                else:\n",
    "                    rewards[i] -= 20 \n",
    "                if np.array_equal(new_position,self.targets[i]):\n",
    "                    rewards[i]+=100\n",
    "                    self.rover_done[i]=True \n",
    "                    done[i]=True\n",
    "\n",
    "        # move human randomly\n",
    "        self._move_human()\n",
    "        self.current_step+=1\n",
    "        all_done=all(done) or self.current_step >= self.max_ts\n",
    "        if all_done and not all(done):  # if the maximum number of steps is reached but not all targets were reached\n",
    "            info['message']='Maximum number of timestamps reached'\n",
    "        return self._get_obs(),rewards,all_done,info\n",
    "\n",
    "    def _is_human_adjacent(self,position):\n",
    "        for delta in [(1,1),(1,-1),(-1,1),(-1,-1)]:\n",
    "            adjacent_position=position+np.array(delta)\n",
    "            if np.array_equal(adjacent_position,self.human_position):\n",
    "                return True\n",
    "        return False\n",
    "\n",
    "    def _out_of_bounds(self,position):\n",
    "        return not (0 <= position[0] < self.grid_size[0] and 0 <= position[1] < self.grid_size[1])\n",
    "    \n",
    "    def _collision(self,new_position,rover_index):\n",
    "        if any(np.array_equal(new_position,pos) for pos in np.delete(self.rover_positions,rover_index,axis=0)):\n",
    "            return True  # Collision with the other rover\n",
    "        if any(np.array_equal(new_position,pos) for pos in self.rooms):\n",
    "            return True  # Collision with a room\n",
    "        if any(np.array_equal(new_position,pos) for pos in self.operation_desks):\n",
    "            return True  # Collision with an operation desk\n",
    "        if np.array_equal(new_position,self.human_position):\n",
    "            return True  # Collision with the human\n",
    "        return False\n",
    "    \n",
    "    def _move_human(self):\n",
    "        valid_moves=[move for move in self.actions if not self._out_of_bounds(self.human_position+np.array(move))]\n",
    "        self.human_position+=np.array(valid_moves[np.random.choice(len(valid_moves))])\n",
    "    \n",
    "    # def render(self,mode='human',save_path=None):\n",
    "    #     fig,ax=plt.subplots(figsize=(7,7))\n",
    "    #     ax.set_xlim(0,self.grid_size[0])\n",
    "    #     ax.set_ylim(0,self.grid_size[1])\n",
    "    #     ax.set_xticks(np.arange(0,15,1))\n",
    "    #     ax.set_yticks(np.arange(0,15,1))\n",
    "    #     ax.grid(which='both')\n",
    "\n",
    "    #     # draw elements\n",
    "    #     for pos in self.rover_positions:\n",
    "    #         ax.add_patch(Rectangle((pos[0]-0.5,pos[1]-0.5),1,1,color='blue'))\n",
    "    #     for pos in self.operation_desks:\n",
    "    #         ax.add_patch(Rectangle((pos[0]-0.5,pos[1]-0.5),1,1,color='darkgreen'))\n",
    "    #     for pos in self.rooms:\n",
    "    #         ax.add_patch(Rectangle((pos[0]-0.5,pos[1]-0.5),1,1,color='black'))\n",
    "    #     ax.add_patch(Rectangle((self.human_position[0]-0.5,self.human_position[1]-0.5),1,1,color='purple'))\n",
    "    #     for pos in self.targets:\n",
    "    #         ax.add_patch(Rectangle((pos[0]-0.5,pos[1]-0.5),1,1,color='yellow',alpha=0.5))\n",
    "\n",
    "    #     if save_path is not None:\n",
    "    #         plt.savefig(save_path)\n",
    "    #         plt.close()\n",
    "    \n",
    "    # def close(self):\n",
    "    #     plt.close()\n",
    "\n",
    "    def render(self, mode='human', save_path=None):\n",
    "        fig, ax=plt.subplots(figsize=(7,7))\n",
    "        ax.set_xlim(0, self.grid_size[0])\n",
    "        ax.set_ylim(0, self.grid_size[1])\n",
    "\n",
    "        rover_start_img_path='images/rover_moving.png'   \n",
    "        rover_moving_img_path='images/rover_moving.png' \n",
    "        rover_dest_img_path='images/rover_dest.png'     \n",
    "        rover_human_collision_path='images/rover_human_collision.png' \n",
    "        rover_room_collision_path='images/rover_room_collision.png'   \n",
    "        rover_desk_collision_path='images/rover_desk_collision.png'   \n",
    "        rover_rover_collision_path='images/rover_rover_collision.png' \n",
    "        desk_img_path='images/desk.png'\n",
    "        room_img_path='images/room.png'   \n",
    "        human_img_path='images/human.png' \n",
    "        target_img_path='images/target.png' \n",
    "\n",
    "\n",
    "        for i, pos in enumerate(self.rover_positions):\n",
    "           \n",
    "            if self.rover_done[i]:\n",
    "                rover_img=mpimg.imread(rover_dest_img_path)  \n",
    "            elif np.array_equal(pos, self.rover_positions[i]):\n",
    "                rover_img=mpimg.imread(rover_start_img_path) \n",
    "            elif self._is_human_adjacent(pos):\n",
    "                rover_img=mpimg.imread(rover_human_collision_path) \n",
    "            elif self._collision(pos, i):\n",
    "               \n",
    "                if any(np.array_equal(pos, pos) for pos in self.rooms):\n",
    "                    rover_img=mpimg.imread(rover_room_collision_path)\n",
    "                elif any(np.array_equal(pos, pos) for pos in self.operation_desks):\n",
    "                    rover_img=mpimg.imread(rover_desk_collision_path)\n",
    "                elif any(np.array_equal(pos, self.rover_positions[i]) for i in range(len(self.rover_positions)) if i != 0):\n",
    "                    rover_img=mpimg.imread(rover_rover_collision_path)\n",
    "            else:\n",
    "                rover_img=mpimg.imread(rover_moving_img_path)  \n",
    "            ax.imshow(rover_img, extent=(pos[0]-0.5, pos[0]+0.5, pos[1]-0.5, pos[1]+0.5))\n",
    "\n",
    "      \n",
    "        for pos in self.operation_desks:\n",
    "            desk_img=mpimg.imread(desk_img_path)\n",
    "            ax.imshow(desk_img, extent=(pos[0]-0.5, pos[0]+0.5, pos[1]-0.5, pos[1]+0.5))\n",
    "\n",
    "        for pos in self.rooms:\n",
    "            room_img=mpimg.imread(room_img_path)\n",
    "            ax.imshow(room_img, extent=(pos[0]-0.5, pos[0]+0.5, pos[1]-0.5, pos[1]+0.5))\n",
    "\n",
    "        human_img=mpimg.imread(human_img_path)\n",
    "        ax.imshow(human_img, extent=(self.human_position[0]-0.5, self.human_position[0]+0.5, self.human_position[1]-0.5, self.human_position[1]+0.5))\n",
    "\n",
    "        for pos in self.targets:\n",
    "            target_img=mpimg.imread(target_img_path)\n",
    "            ax.imshow(target_img, extent=(pos[0]-0.5, pos[0]+0.5, pos[1]-0.5, pos[1]+0.5))\n",
    "\n",
    "        if save_path is not None:\n",
    "            plt.savefig(save_path)\n",
    "            plt.close()\n",
    "\n",
    "    def close(self):\n",
    "        plt.close()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initial Setup\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkoAAAJGCAYAAACk4ariAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABD2ElEQVR4nO3deXhU9d3//9eZJZM9JIEkRBMISF0AQUUUcYFKpdbbhd5urVKq9693F1zpbdW7X2ytC7WLpbYWb717W3vfdekiaLXVUkRQlDWCIoqA7CEhLMkkk8x6Pr8/IpEIJ2SZyUyS5+O65uKaM2fOec9cb8555ZzPnGMZY4wAAABwBFeyCwAAAEhVBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHnmQX8Fm2bauqqko5OTmyLCvZ5QAAgD7GGKOGhgaVlpbK5Wr/mFHKBaWqqiqVlZUluwwAANDH7dy5U8cff3y786RcUMrJyZHUUnxubm6SqwEAAH2N3+9XWVlZa+ZoT8oFpUOn23JzcwlKAAAgYToyxIfB3AAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA4ISgAAAA46HZSWLl2qSy+9VKWlpbIsSwsWLHCc91vf+pYsy9LcuXO7USIAAEBydDooBQIBjRkzRo8++mi7882fP1/Lly9XaWlpl4sDAABIJk9n33DxxRfr4osvbnee3bt36+abb9arr76qSy65pMvFAQAAJFOng9Kx2Lat6dOn64477tDIkSOPOX8oFFIoFGp97vf7410SAABAl8R9MPdDDz0kj8ejW265pUPzz5kzR3l5ea2PsrKyeJcEAADQJXENSmvWrNEvf/lL/e53v5NlWR16z9133636+vrWx86dO+NZEgAAQJfFNSi98cYb2rt3r8rLy+XxeOTxeLR9+3Z997vf1dChQ4/6Hp/Pp9zc3DYPAACAVBDXMUrTp0/XlClT2kybOnWqpk+frhtuuCGeqwIAAEi4TgelxsZGbd68ufX51q1btXbtWhUUFKi8vFyFhYVt5vd6vSopKdGJJ57Y/WoBAAB6UKeD0urVqzV58uTW57NmzZIkzZgxQ7/73e/iVhgAAECydTooTZo0ScaYDs+/bdu2zq4CAAAgJXCvNwAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAeeZBcAdEYkElE0Gu3WMjwej7xeb5wqQm/S0/1jG6O/vbO3W+vrri+dViSXZSW1hr6C7U//RFBCr9DY2Kjnn39BK5YsU2D/QRnb7tJyLJdLmYX5Gn/eBF155TRlZ2fHuVKkomT1j20bvfBOja6ZOLRL6+uuZ97Yqi+OGSSXm6DUHWx/+jeCElJeY2Oj7r3nPlVUNWpW+XDlD85QV/9ANsboYDioV155Wz96b4Puuff7bKz6uGT3T0aaWycMzunaCrspPc2dlPX2JcnuHyQfQQkp7/nnX1BFVaOuGzFKtqSGcEhul0sul6U0r1fNoZDS09IUjkQVibV/WNySpQJfpq4fMVr/u+ldLZj/oq6f/tWe+SBIilTpn5fX7NY/1lZJ6rmjO+ForMfW1VelSv8geQhKSGmRSEQrlizTrPLhsiW91lyrzKHFysvJktfjUVF+vnZU16hkYIEO+BtU3xBod3nRWFRN22p0YUaRvlg2XL94fZmuufYqxgz0UanUP7GYrQvGVuik8sI4fbpj+9PrG3psXX1RKvUPkoeghJQWjUYV2F+n/MEZagiHlDm0WOedfbqsw459Dyxu2fGUHldyzOUZY7TUrFHj7qDyfRkK7D+oWCzGhqqPSsX+sXpwYDUjk7onFfsHPY/LAyDlGTsmy5KMjNxud7d2NJZlye1xy5iWw+DG5tREX0f/oDvoHxCUAKCHcIQH6H0ISgCQNKYH5wHQFYxRAoAe0hA22hf4bKhJXFiKdO1yPwAOQ1ACgB4SikpNkZ5bXxeviwjgMJx6AwAAcMARJQBIAGOMvvrrSgXCMd3229WK2baMLL27cVuP1RCLGV3/m0pJ0rM3j+ux9QJ9CUEJABIkK92t5245I9llaNovViW7BKDXIigBQIKkuS01R4y8SbwpbcwYeVxcmADoKoIS+h2XZXE9G3RZZ/pn3LAB+seGgxpbUdClde0+0CRLUmlBZpfeL0l7DjZraFFWl9+P+GL70/swmBv9zugThiknq+s7HvRvnemfy8cN1potBxSKdO0KzJuqGrRpT0OX3nvIlj0Nmjp6ULeWgfhh+9P7EJTQ72RnZsjjdie7DPRSHe0fy7KUn+XVrv1N2rbX6Wappt1LJE0aVawLRhZ14DJKzsvZVhvQmPLcY9aLnsH2p/chKAFAgliSDjSEtH5HncJR+yhZxjrivibxnCdmG1UdCKggJ62TlQM4hKCEfmdXTa2aQ6Fkl4FeqrP9k+Z1KRy1tXNfoENjU+I5z/6GkI7LT1cSx5LjM9j+9D4EJaQ8y+WWMUaWLEVjURnT9ftaGWP08a4qBcNhGRlZLg6B93XJ7p+CbJ8G5vr0cU2jbLtn78m2szags0/o2kBytEh2/yD5+NUbUprH41Fm4QAdDAdV4MtU07YaLTVr5PZ0bQMTi8bUtK1a2ZnF2hcMKKswX27GC/RZqdA/Pq9LQwZlacPOOu2tD6poQHqX1t0VW2oa9NWzS3psfX1NKvQPko+ghJTm9Xo1YdJEvfLyMl0/YrQuzChS4+6guvpHnWVJ2ZnFckl6ZccWTbj0fHm93rjWjNSRKv1TWpCpyo8P6KH573dtxV0UisR085TyHl1nX5Iq/YPkIigh5U2bdrnuW/e+fr/pXV1cNlz5vgx19UokRkb7ggG9smOLqoYU6MZpl8W5WqSaVOif7HSPrj13qK49d2iX1ttVP13wvrxuS5bFIKWuSoX+QXJZpjsnXBPA7/crLy9P9fX1ys3lJ61oEQgEtOCFv+qtRW8osP+gjN2169JYLreyCvM1YfK5mjbtMmVlcSG+/iBZ/RON2frWk+t11TlDurS+7npu2TY9fuNoedwMR+0Otj99T2eyBkEJvUokElEs1rWN1CFut5vD3f1UT/ePbYwWvlfbrfV11xdGD5KLI0pxwfan7+hM1uDUG3oVr9fLRgZd1tP947IsTT21qMfWh8Ri+9M/cTwWAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAAUEJAADAQaeD0tKlS3XppZeqtLRUlmVpwYIFra9FIhHdeeedGj16tLKyslRaWqqvfe1rqqqqimfNAAAAPaLTQSkQCGjMmDF69NFHj3itqalJlZWVmj17tiorK/X8889r48aNuuyyy+JSLAAAQE+yjDGmy2+2LM2fP19XXHGF4zyrVq3S+PHjtX37dpWXlx9zmX6/X3l5eaqvr1dubm5XSwMAADiqzmQNT6KLqa+vl2VZGjBgwFFfD4VCCoVCrc/9fn+iSwIAAOiQhA7mDgaDuvPOO/WVr3zFMbHNmTNHeXl5rY+ysrJElgQAANBhCQtKkUhEV199tYwxmjdvnuN8d999t+rr61sfO3fuTFRJAAAAnZKQU2+HQtL27dv12muvtXv+z+fzyefzJaIMAACAbol7UDoUkjZt2qTFixersLAw3qsAAADoEZ0OSo2Njdq8eXPr861bt2rt2rUqKCjQ4MGDdeWVV6qyslIvvfSSYrGYqqurJUkFBQVKS0uLX+UAAAAJ1unLA7z++uuaPHnyEdNnzJihH/7wh6qoqDjq+xYvXqxJkyYdc/lcHgAAACRSQi8PMGnSJLWXrbpxWSYAAICUwr3eAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHHiSXQDQGZFIRNFotFvL8Hg88nq9HZrXNkZ/e2dvt9bXXV86rUguy0pqDX1FT/cP+hb6p38iKKFXaGxs1PPPv6AVS5YpsP+gjG13aTmWy6XMwnyNP2+CrrxymrKzs9ud37aNXninRtdMHNql9XXXM29s1RfHDJLLTVDqjmT1D/oG+qd/Iygh5TU2Nuree+5TRVWjZpUPV/7gDHX1AIsxRgfDQb3yytv60XsbdM+93z/mxiojza0TBud0bYXdlJ7mTsp6+5Jk9w96N/oHBCWkvOeff0EVVY26bsQo2ZIawiG5XS65XJbSvF41h0JKT0tTOBJVJNb+YXFLlgp8mbp+xGj976Z3tWD+i7p++lc7VMfLa3brH2urJPXc0Z1wNNZj6+qrUqV/0DvRPyAoIaVFIhGtWLJMs8qHy5b0WnOtMocWKy8nS16PR0X5+dpRXaOSgQU64G9QfUOg3eVFY1E1bavRhRlF+mLZcP3i9WW65tqrOjRmIBazdcHYCp1UXhinT3dsf3p9Q4+tqy9Kpf5B70P/QCIoIcVFo1EF9tcpf3CGGsIhZQ4t1nlnny7rsGPfA4tbgkvpcSXHXJ4xRkvNGjXuDirfl6HA/oOKxWKd2lBZPTiwmpFJ3ZOK/YPeg/6BxOUB0AsYOybLkoyM3G53t4KKZVlye9wypuUwuLE5tdXX0T/oDvoHBCWgEzjCAwD9C0EJ6BbTg/MAAHpap4PS0qVLdemll6q0tFSWZWnBggVtXjfG6J577tHgwYOVkZGhKVOmaNOmTfGqF0iqhrDRvsDhD33m+dEeXZ8n0rXLtQAA4qTTQSkQCGjMmDF69NFHj/r6T37yEz3yyCN67LHHtGLFCmVlZWnq1KkKBoPdLhZItlBUaor03KOL17UDAMRJp3/1dvHFF+viiy8+6mvGGM2dO1f/7//9P11++eWSpN///vcqLi7WggULdO2113avWgAAgB4U18sDbN26VdXV1ZoyZUrrtLy8PJ111ll6++23jxqUQqGQQqFQ63O/3x/PkoAuM8boq7+uVCAc022/Xa2YbcvI0rsbt/VYDbGY0fW/qZQkPXvzuB5bLwCgRVyDUnV1tSSpuLi4zfTi4uLW1z5rzpw5uvfee+NZBhA3WeluPXfLGckuQ9N+sSrZJQBAv5T0X73dfffdqq+vb33s3Lkz2SUBrdLclpojRlFbSXuEYkYeFxcmAIBkiOsRpZKSliuT1tTUaPDgwa3Ta2pqNHbs2KO+x+fzyefzxbMMoF0uy+rw9ZDGDRugf2w4qLEVBV1a1+4DTbIklRZkdun9krTnYLOGFmV1+f2Ir870D/BZ9E/vE9cjShUVFSopKdGiRYtap/n9fq1YsUITJkyI56qALht9wjDlZHUsuFw+brDWbDmgUKRrV9DdVNWgTXsauvTeQ7bsadDU0YO6tQzET2f6B/gs+qf36fQRpcbGRm3evLn1+datW7V27VoVFBSovLxct912m+6//36NGDFCFRUVmj17tkpLS3XFFVfEs26gy7IzMyS3W2Ed407flqX8LK927W/Str0BnXhc7lHmMpKxHC/ZPWlU8Sfz6BiX9XZezrbagC465fh2a0XP6Wj/AEdD//Q+nQ5Kq1ev1uTJk1ufz5o1S5I0Y8YM/e53v9P3vvc9BQIB/fu//7vq6up07rnn6pVXXlF6enr8qgZ6iCXpQENI63fUqaI4W16P6zNZ5shwc2Qm6vo8tm1UdSCggpy0Ln8GAEDXdTooTZo0ScY4327Bsiz96Ec/0o9+9KNuFQYkyq6aWhWGQnJ3cP40r0vhqK2d+wIaXpJzzPk7Mv6go/PsbwjpuPx0uRnUkDI62z/A4eif3ifpv3oDjsVyuWWMkSVL0Vi03aB+LMYYfbyrSsFwWEZGluvYm6uCbJ8G5vr0cU2jbLtn78m2szags0/o2kBytEh2/6B3o38Q11+9AfHm8XiUWThAB8NBFfgy1bStRkvNGrk9XdvAxKIxNW2rVnZmsfYFA8oqzJfb3f6yfF6XhgzK0oadddpbH1TRgJ47jbylpkFfPbukx9bX16RC/6D3on8gEZSQ4rxeryZMmqhXXl6m60eM1oUZRWrcHVRX/6izLCk7s1guSa/s2KIJl54vr9d7zPeVFmSq8uMDemj++11bcReFIjHdPKW8R9fZl6RK/6B3on8gEZTQC0ybdrnuW/e+fr/pXV1cNlz5vgx19UokRkb7ggG9smOLqoYU6MZpl3XofdnpHl177lBde+7QLq23q3664H153ZYsi0FKXZUK/YPei/6BZbpzwjUB/H6/8vLyVF9fr9zco/0cG/1RIBDQghf+qrcWvaHA/oMydteua2S53MoqzNeEyedq2rTLlJXV/oUcozFb33pyva46Z0iX1tddzy3bpsdvHC2Pm+GE3ZGs/kHfQP/0PZ3JGgQl9CqRSESxWNc2Uoe43e4OH+62jdHC92q7tb7u+sLoQXJxRCkuerp/0LfQP31HZ7IGp97Qq3i93h7dyLgsS1NPLeqx9SGxerp/0LfQP/0Tx/MBAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAcEJQAAAAceJJdAID+wxijWCwm27ZljGnzmmVZcrlccrvdsiwrSRUCQFsEJQAJZ4zR5qo9eito9Pq+Or17MKDqUEgNkahiRsryuDUwzauRA7L0+UEFmprj0bDBJckuGwAISgASr7ohqK9/tFcrDzQoqsOOJFluyZKabKk2GNEH1XWaX1Oni/Kz9eKggfJ42EQBSC7GKAFIuA3792nVAX/bkOQgZqQlBxtVHwz1QGUA0D6CEoCEam5u1hsbPlDMHDskHRKVtG7P3sQVBQAdRFACkDChUEgrFi/Uyo82duBY0qdiMVv/XLRQOzZ9lLDaAKAjCEoAEmbHpg+18uW/aKft6lRQsiVV7tmjN+Y/q5rqPYkqDwCOiaAEICECjY1a/Oc/qG5frRrTszv3Zkuq86Zrw5rl2vD2Utm2nZgiAeAYCEoAEuLDtWu048MNislSxO3t1HuNLIW9PhljtGrRK2rw1yeoSgBoH7+9BRB3kUhE6958TbYdU8ztVUa4ScOqt6qgYb9ym/zKaWqQNxqRzw4rP1M69QSPsgd49WEoT6/tzdPO9IFymZajSP59tfpwXaXOuuDCJH8qAP0RQQlA3G36YIP279ohS5a8sYi+vGy+JMmSkWWMXJaUl2E06nij8080yvS1vC/mlaaGXfrHO24Fwy2jmmzb1voVb2n8+Z/nit0AehxBCUDcbfnoQzU11MvIyJLkNp+OMUpzG4083uj0oUZDCiWP+9P3uVzS6eW26hqNln1kyciSJSlcX6fGhgbl5Ob2+GcB0L/FfYxSLBbT7NmzVVFRoYyMDA0fPlz33XffEfd1AtA3hUIhhev2KxwMHjbVyGUZHZdv9K/jbX1pjNGworYh6ZB0r3TeiS1HnVreadTc6Ff17l09Uj8AHC7uR5QeeughzZs3T0899ZRGjhyp1atX64YbblBeXp5uueWWeK8OQIpp8PvVXLe/zR9HliV9YaTRuGFGmWmfTGtnGeneT2b4ZBHB5oBq99ZoxMmnJKpsADiquAelt956S5dffrkuueQSSdLQoUP1zDPPaOXKlfFeFYAUFAgE1HBgf5tpbkua+Dkjj1v6YIdflmXppLKcNvM4TZekaDgsf31dIssGgKOK+6m3c845R4sWLdJHH7VcUXfdunV68803dfHFFx91/lAoJL/f3+YBoPcKBpvV1Njg+Prm3Y3avLuxw9MlKRqJKNDgvEwASJS4H1G666675Pf7ddJJJ8ntdisWi+mBBx7Qddddd9T558yZo3vvvTfeZQBIkmAwqObA0QOPJH3prMFHPe3mNF1q+eVbJBKJS30A0BlxP6L0xz/+UX/4wx/09NNPq7KyUk899ZR+9rOf6amnnjrq/Hfffbfq6+tbHzt37ox3SQB6UDQSUTQUcnzd7bLkch0ZiZymS5IxRtFoNG41AkBHxf2I0h133KG77rpL1157rSRp9OjR2r59u+bMmaMZM2YcMb/P55PP54t3GQCSxLZtRWOxttOMtOtAVEMGuo95LSRjjHYfiMmYtMMnyhhuYwKg58X9iFJTU5NcrraLdbvd3KsJ6Cd86enKzM5ucxotZku/W9yovfV2u5cKMcZorz+mJxc3Kta6ybA0ePjnNG7CeYksGwCOKu5B6dJLL9UDDzygl19+Wdu2bdP8+fP18MMPa9q0afFeFYAUdMKIz2nytTdocMWIlusCSDJGen9XWI+/3qy99aGjhiVjjKrrw/rN62Ft2BU+dGUAlQ47QRd+9UadPGpUD34KAGgR91Nvv/rVrzR79mx95zvf0d69e1VaWqpvfvObuueee+K9KgApKDMzU+MnXajjR5ykJX/+P21c9baMiSpkW1q826fLqjdpkOWV0gdKnqyWN0UDMsF9qtoT1dLdn1OO3STLslQ6bITOu3qGTh41OrkfCkC/FfeglJOTo7lz52ru3LnxXjSAXsLtdqusvFxXfONmrR5xklYvfFmRmkY1+XJlR5tlGnfLNG7/zLuMTLRQwbQspcdCKj3hpE+OJBGSACQP93oDkDDZOTkaO+kLqnRlao9/gayGgLZllGmUDsiltqffbEnbMo5XKCtH1ceXybrgEpVVDE9O4QDwibiPUQKAQzYdOKibVm7QQ9FsBdOy1FQwUD8b+DX5rawj5q13ZevhwulqzstXQ2au7g9laOaK97TlABehBZA8BCUAcWfbtt7eVaMvr96iZw4GtS8UUXrdfoWzc7Uqe5QezrlWocMOaIfk0c9zrtWa7JEKZ+cq/cB+1QbD+r8DQV2+eqOWV9Xwy1kASUFQAhB37+w/oJs27tT7DQHZliUjI3coqFhamiLuNP0h6wt62zdKRi33vX3LN1pPZ16kiDtN0bR0eZubZCTZlqUN/mbdsqFK67ZxMVoAPY+gBCCuDtTX6zd76vVuXZOMLCkWU/aH76l5X620/WN5/HXa6S7SE9mXqtY1QHtd+Xoi+1Ltcg9U5oFaZdfukTfUrKIN6+QKh2RktLa+QfN21qqOe0EC6GEEJQBxVdkU1F+27tGhG45kbflQRa/9TccXDVRJ7W4NWvSSbCPNzzhff8m8QH/OnKQFGefL6/drxD9fkre5SU0FA3XcO8s1+N3VsmIxRST9qS6ktXX8/gRAzyIoAYibWCymV2v8qo9+Op4o7cA+pYVCmvG16zX21FOVvnunZIzCVpp+mvNV/SznKwpbXg3c/IEkafuESdr4xS+r/vihyt/+sdICDZKkumhMrxzYzVglAD2KP88AxI1t21pWW99mWrhwkEK+dD351O9V729Q8PghrVfs3uEpaZ0v7+A+2bl58g8uk+316uCwz6nojYXyhsM6dIvdZbV1sm37iNskAUCiEJQAxI1t29rS2NRmWmD4ido75V/U/ME6RUqHqW7cOZJ1ZNC5/d++LtsYfXP7AUnSkJNP1iNfnKj/b/sBrWuOSJI2Nza3e684AIg3ghKAuPF4PLrd1CtsDjs9Zkk6qazl0apOn7nepLKrGyVJ96olFGUHLVXvqNP0YERf/iQc+eTmaBKAHmWZFPvzzO/3Ky8vT/X19crNzU12OQAAoI/pTNbgTzMAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHXB4AvUokElE0Gj32jO3weDzyer1xqgi9Cf2D7qB/+ieCEnqFxsZGPf/8C1qxZJkC+w/KdPE2FpbLpczCfI0/b4KuvHKasrOz41wpUhH9g+6gf/o3rqOElNfY2Kh777lPFVWNmlo+TPlpGYfugNFpxhgdDAf1yo4t2n5cnu659/tsrPo4+gfdQf/0TVxHCX3K88+/oIqqRl03YpQKfJlqjITVFI0qaMdku10KRCOKuSw1x2Lyh0PtPhojERX4MnX9iNEq312nBfNfTPbHQ4LRP+gO+gecekNKi0QiWrFkmWaVD5ct6bXmWmUOLVZeTpa8Ho+K8vO1o7pGJQMLdMDfoPqGQLvLi8aiatpWowszivTFsuH6xevLdM21VzFmoI+if9Ad9A8kghJSXDQaVWB/nfIHZ6ghHFLm0GKdd/bpsg479j2wuFCSVHpcidNiWhljtNSsUePuoPJ9GQrsP6hYLMaGqo+if9Ad9A8kTr2hFzB2TJYlGRm53e42G6nOsixLbo9bxkiWLBk7FsdKkYroH3QH/QOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEvodl2Wp65eMQ39H/6A76J/eh6CEfmf0CcOUk5WZ7DLQS9E/6A76p/chKKHfyc7MkMftTnYZ6KXoH3QH/dP7EJQAAAAcEJTQ7+yqqVVzKJTsMtBL0T/oDvqn9yEoIeVZLreMMbJkKRqLyhjT5WUZY/TxrioFw2EZGVkuDoH3dfQPuoP+gSfZBQDt8Xg8yiwcoIPhoAp8mWraVqOlZo3cnq5tYGLRmJq2VSs7s1j7ggFlFebLzXiBPov+QXfQP5AISkhxXq9XEyZN1CsvL9P1I0brwowiNe4Oqqt/1FmWlJ1ZLJekV3Zs0YRLz5fX641rzUgd9A+6g/6BRFBCLzBt2uW6b937+v2md3Vx2XDl+zLU1SuRGBntCwb0yo4tqhpSoBunXRbnapFq6B90B/0Dy3TnhGsC+P1+5eXlqb6+Xrm5uckuBykiEAhowQt/1VuL3lBg/0EZO9al5Vgut7IK8zVh8rmaNu0yZWVlxblSpCL6B91B//Q9nckaBCX0KpFIRLFY1zZSh7jdbg5391P0D7qD/uk7OpM1OPWGXsXr9bKRQZfRP+gO+qd/4vIAAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADghKAAAADhISlHbv3q3rr79ehYWFysjI0OjRo7V69epErAoAACBhPPFe4MGDBzVx4kRNnjxZf//73zVo0CBt2rRJ+fn58V4VAABAQsU9KD300EMqKyvTk08+2TqtoqIi3qsBAABIuLifenvxxRc1btw4XXXVVSoqKtJpp52mJ554wnH+UCgkv9/f5gEAAJAK4h6UPv74Y82bN08jRozQq6++qm9/+9u65ZZb9NRTTx11/jlz5igvL6/1UVZWFu+SAAAAusQyxph4LjAtLU3jxo3TW2+91Trtlltu0apVq/T2228fMX8oFFIoFGp97vf7VVZWpvr6euXm5sazNAAAAPn9fuXl5XUoa8T9iNLgwYN1yimntJl28skna8eOHUed3+fzKTc3t80DAAAgFcQ9KE2cOFEbN25sM+2jjz7SkCFD4r0qAACAhIp7ULr99tu1fPlyPfjgg9q8ebOefvppPf7445o5c2a8VwUAAJBQcQ9KZ555pubPn69nnnlGo0aN0n333ae5c+fquuuui/eqAAAAEirug7m7qzMDrAAAADorqYO5AQAA+gqCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgAOCEgAAgANPsgsA0D3BYEiv/3OlHvv1H7X8rXUKhyLdWl6aL03nnDtW37zpak36/JnypafFqVKkIvoHaJ9ljDHJLuJwfr9feXl5qq+vV25ubrLLAVKabRst/Psyfe+2n6uopFDnnDtWmVkZ3VpmU6BZy5ZWal9tnX76yH9oytQJsiwrThUjldA/6K86kzU4ogT0YrFoVE/M+7OKigv044dv16ljT5TX273/1pFwRGvf2ai7Zz2s/573F02+cLw83VwmUhP9AxwbY5SAXqSmep/Wv7tJtt1yIDhmG61c/p4mnn9aXHZykuRN82rsaSfqnPNO04q317Wuy7ZtrX93k2qq93d7HUgO+gfoPIIS0Iv8+dl/aMa1/6loNPrJFKNwKKKMzIw2OznTFJS9aKViz74qe9FKmcamI5bV3jzeNK8yM9MVCkZk1LKji0Si+to1d+n5Py1M6GdE4tA/QOdxPBToRRr8AVXt2qv2hhaapqDs3y6Q3lgr0xSUMtNlNnws179dISszvcPzHLFcY1S1q1b++kACPhl6Av0DdB5BCehlbNvW8mXr5PF6FAlHZNt2m9fN2++27MACzbKkln/fXCcz6gRZk8d1eJ6OrAu9D/0DdA5BCehlIpGopl18i+PrpvagTFNQh35nZKnlCIC1r65T83RkXeh96B+gcwhKQC/j9Xr0l5fnfvJXelT/esmtbV63BuW3nAo59Ne+1HI6ZOCATs3TkXWh96F/gM4hKAG9jMvl0plnj5bPl6ZgMCSXq+1vMqyzRsls+LjlVEhTs6zMDOm8sbLGj+zUPB1ZF3of+gfoHIIS0Ivk5mXr+LLidi/gZ2VnyvVvV7SMF9lXJw0cIGv8SFmHXUiwI/McsVzL0nFlxcrLy47jJ0JPon+AziMoAb3IlddO1eQpZ8njOfRf11JauldNgWZFwhF507wtUzPT2wyqPZr25gmHIwoEmpWe4ZP1yUgUr9ej//3TjzVoUH7cPg96Fv0DdB7HQYFepKi4QCePHCaXq2Xn43a7dPaEMXpzaaXWvvOhIuHu3adLatnJvbPmAy1b+o7OPufU1nW5XC6dMnK4BhUVdHsdSA76B+g87vUG9GK2bfTPV9/S9279uQYOGqAJ556mrKyjX8emowKBZi1b+o4OHKjXzx65QxdedDb36uqj6B/0V53JGgkPSj/+8Y91991369Zbb9XcuXOPOT9BCeicUDCspa+v1n/P+4uWv71O4WD3jgr40r2aMHGs/u1b/6rzJp0hn4+7v/dl9A/6o5QJSqtWrdLVV1+t3NxcTZ48maAEJIgxRrFoTLZtWm8ZcYi956BiO/fJVZAt95Aiyetud1mWLLlcltweN0cC+gn6B/1NZ7JGwgZzNzY26rrrrtMTTzyh+++/P1GrAaCWXxR99g7tsV37FHxptUwoIntvnVyjhyi2crM8pxyvtLNOTFKlSEX0D+AsYYO5Z86cqUsuuURTpkxpd75QKCS/39/mAaD7Yrv3K/DT+Qo+vVSRNVtk9jfINThfjT94Ws3PvSETjLR7zy/0b/QP0CIhR5SeffZZVVZWatWqVcecd86cObr33nsTUQaAaEx29UGp+qACG3dLPq9yfvw1+Tfv0aYbfqnAr7+pETkZGpjGlUJwFPQPEP8xSjt37tS4ceO0cOFCnXrqqZKkSZMmaezYsUcdoxQKhRQKhVqf+/1+lZWVMUYJ6KbYrv0K/mmZmv/4puyqAy3TLEt/vGC43vv8WFlnjlK+16Mst0tfHzxA5elpYkgJDqF/0JcldTD3ggULNG3aNLndnw74i8VisixLLpdLoVCozWufxWBuoGuMMTJGkjFyuV2HJiry/g41/vAZNa/dqt9eeLJ+dv5I+fMLlJ+Vqe8OGagzczL0v9V1+s5xBTorJ12yLFmWGIjbz9A/6E+SGpQaGhq0ffv2NtNuuOEGnXTSSbrzzjs1atSodt9PUAK6xraN3nh9tRoamvQvl1/QOt0YI0VjemrdBj0ZkN6IuGQ+2Ym5JJ2QmaafnlCi3+zar5nbt2nAgByde8Hp7Oj6GfoH/UlnskbcB3Pn5ORo1KhRbR5ZWVkqLCw8ZkgC0HXRaFRzfvSE3n9vc5vplmXJ8nr09XGnauF5o3Rj6ae3kLAlfdQU1u/31Kks3av3392kOT96QtForIerR7LRP8DRcQsToI+wbVvvrdvU7jxey9LPP1eiN86o0EMnFCvLZem0bJ+uLcnTPRVFkqT31n4kY/Nrpv6G/gGOrkd+qvD666/3xGqAfi92jL/kLctSnsetcwdkakJehm4tK5AlS97DxpREo7EjLjqI/oH+AY7EbzqBXqapKahlSyr10Ufb1egPtF7LJhqNKRaL6c0la2Rsu0vLfnNppaLRmH724JNyfzKg17IsZedm6XMnDtG555+ujMzu3QsMyUX/AJ3DTXGBXsIYo61bdunH9/233npjrfz+RkUiUSX8j3dL8no9ysvL1sQLztCd379RQ4cdx2DdXob+AT6VErcwARBf27dV6T9u+ak2bdyub3z7Sl1+5edVUjJQliuxOxxjG+3ZU6sFf16k3z72vPbVHtTDv/6eyocMTuh6EV/0D9A1BCWgl1jwl9f0/nub9cMHb9I1131RLlfP/RajYtjxuvU/pmtQUYHumz1PLz6/WDfd/tUeWz+6j/4BuoZfvQG9xPw/LtSEiWP1hS9OaN3J2batv/xxoa771zu14M+LZH9mbMnO7Xv0Hzf/VHfc+nPt3FHd5rXOvtflcmnqlyZq/IRT9ZfnXk3sh0Xc0T9A13BECeglNn20XVOmnqP8/E/Pp0ciUf3w7ke1e1eN1r+7SV+67HylpX36989fFyzRH556SbKk4SeU6Vs3X92t9+YX5OmEEeV6beHynvnQiBv6B+gaghLQS+TkZKmxsUnhSFQZnpbbALlcLp159mj5X23U+AmjjzidMnxEmQYfVySXZWn4Cce3ea0r7w2HI2psDCgnNyuBnxSJQP8AXcOv3oBe4uvX/qe2b6vS47+/VyeMKJdlWTLGqKZ6v6p21+q44wepqLiwza+Jgs0hfbxllyzLUsWw45Se4Wt9rbPv9aWn6aON2/XNGT/Q8BPK9Ns/3N+jnx/dQ/8An0rqvd66i6AEHN2bSyr1za//UOPOGqnv3/tNlZWVKD3Dl/CfWRtjFGwOaceOat0/e57eWfOhnvj9vZpw7tiErhfxRf8AnyIoAX1QU1NQz/7f3/TzOb9TUXGBzjxrlAYU5MqV4B2dbYwOHvBr1fL3tK+2Tv/xnzfomuu+qIwMLhzYm9A/wKcISkAf1dwU1DtrPtATv/mT3lq2Vvtq6xJ+Xy2Xy9LAQfk659yx+sZ3rtLY00/i6sq9FP0DtCAoAQAAOODK3ACOEA6HtXv7drksS6VDhsjr9Sa7JPQi9A/6K4IS0MfFYjHV7dwlLVulIRu3ylTV6MBJFdIVX1RBxVC53e5kl4gURv+gvyMoAX2UMUYH9taq+vU3NWLzTnkaGiU7JquuXgV/XaTwinVqmHKO7Cu+pPyiQdykFG3QP0ALxigBfVBDXb0OrFyjAes+UE5Ts6ymoIykgFwyG7coa/9+WZKMx6P68uPkv3yKBk25QFn8n4PoH/R9DOYG+qnmpib5129U5spKZcmSNf40aWChmuf/XetzC7V4zDjFwhGd/49XNGblCmUGGiXLkklLU+DkE9T85YuUN36cMrK4cnJ/RP+gvyAoAf1MKBRS1Qcfylq2SuXBqKzTRklnnCo7M1O79jfob7v9+mBgiSKfDMB1RyIa/uEHuvDlF3XChg3yhYKyJNkZ6Yqcdor2XvUvKhk9Uj6fr/0Vo0+gf9DfEJSAfiIWi2nf9h3SslUq3LJD7tEnSeedLVOYrwP1TXq90dbbVoaaXG7ps2NIjJE3HNaoytW68OW/qmzrx/JEozKWJTs7U/snnSXXtEtUOIwBu30V/YP+iqAE9AP11dUyK95V5rr18gSaZPnSpG9+TY25uXqrLqwlJl11bq/MsQbZGqPMxkaNe+tNTfr7yyraU9WyU7QsRQvzFbxkivSlC5U3uKhnPhh6BP2D/oygBPRxu9a8o8EvL5LVHJJlGxlJ/swsrRl/tt48ZYz2etJkW65jLudwlm2roLZWExf9Q+PfWKoBBz4ZsOt2y5QPVc2t03XcGWMT8XHQw+gf9HdccBLo4/a8+ppK39kgFQ9SY/4ArT/hRL1+2njtKiqR7XLYwRmjdL9fFWtWamjlKqX7/WoYWKQtZ5+jXaPHKJKRof3FxfrrNV9V5Tnn6vxX/6Yxq1Yqq6FB1vatqlq4mB1dH0H/AB3HESWgF9q1fJU8j/2vdg88Tksu/pK2jDhRtvso40gOMUYD9lTpgid+o/J31shl260vRb1p+uDCL+it67+uYG5e6/yuWEzDN36gC/7+skr37VH0O19T2dln9sCnQ6LRP+jvOPUG9HHGGPn9fv1wW6OCA0ucd3AtMyuveo++8Mufq3TDe/JalnLcHnktl0J2TA2xqKIul1Zf9RW9/ZXp0uFHFIxRRm2VfjgsTzk5OVxUsI+gf9DfdSZrdO4kNICUYFmW0tLSZLusY+7kcmuqNeVXD6v0g/VKsyyVeH0a6EnTAI9Xg7w+DfT65LZtfW7pYg2o3vPZFSnqcistLY2dXB9C/wAdR1AC+ihjjJoPHtS4/3pUx73/nnyyVOJNV4bL3brTcn1ydMBjWcreV6ucvTVJrhqpgv4BWhCUgD7IGCN/Xb0WLlqsecaj2owsFXl9Sne5jvjL3pJkyZLLtuWyY8kpGCmF/gE+RVAC+hhjjPz19Vq8cJGqdldpcWGRHjx9omqzc444zWKMUdC2FTW2mnNy1TQgP0lVI1XQP0BbBCWgDzHGqLGhQUv++Zqqq6okt1vKGaB/lJbrO6eOV1V6hsxh84aNrdpISDFJVaNO1YHjy9ssKxYOK9rUmJTPgp5H/wBHIigBfYht21r51tuq2rW7dScnT8vVlf9RNFjfPnW8dmRkSpJCxlZ1OKSgsbWvYpiWX3u9Ymlpkj7ZyQWb1VRTpdDB/Un8ROhJ9A9wJIIS0IfU7t2rHdt2tJwiyc6TPN7W0yW2ZelvxaX69pjx2pieob2H7eT+efMsHSgrb7OsUP1B2ZFwMj4GkoT+AY5EUAL6kIP7DygcCrXs4LxpR44pkfRqwSB9e/iJ2pKRqX0Vw/WPW+/Q3uEjjpiXnVz/Q/8AR+IWJkAfYh+6YvLRrlljjBSLSg31Wpqbr59NnqozLpqi/UOHOcyf2FqReugf4EgEJaAPyc3Lk8frVSQaadmpuT0tO7HDdnKKRpQ/cKCyvnCh9hUN4kKAaEX/AEfi1BvQh5QMHqziwSWSbbfs1MJBKRKWQs2Sv06KRlQ4cKAmfeFCDWQnh8+gf4AjcUQJ6EM8Xo/GnzNBzU1N2l+7r2Xn9skRAcuyNKikWOd/frIKBw1kJ4cj0D/AkQhKQB9iWZYGFQ3SF750sTa8+5527tihYHOzMrOyNKRiqE4ePUrZ2dnt7uSMMTK2LcMgk36H/gGORFACeinLsmTpyB2WZVnKG5Cns8+dqHGxs2SMkcuy5PZ4Wt7zyU7OGFuxYFCxcFifHXkbC4Vkoi23o3C5LI4e9EH0D9AxBCWgl3K73SrL8GjzUV6zLEuW21KaO+2o7zXGVujgAYX8dS3jUdoxJCdbLhfDGfsa+gfoGLoX6KW8Xq8m236VRJvlNqbll0kdFAuFFfbXO+/kTMvGodQjTR3gkdfrjU/RSBn0D9AxHFECerHTPzdcg6prtGHbBgVDoQ6/zxgjE4u2O096mk+nlA3VkONKu1smUhT9AxwbQQno5cpKilVWUpzsMtBL0T9A+whKQB8Ti8UUDocViUQUiUQUi8Vk27aMMa1XXna5XLIsSy6XS263W16vV16vV2lpaXK73Un+BEgm+gdoi6AE9AFNTU2qqanR/v371dTUpGg0Ktu2W3dy0ienSz4Zh3L4r5cO7excLpc8Ho8yMzNVWFiokpISZWRkJO0zoefQP4AzghLQB9TW1urjjz9WOBxu/eu/PYe/HovFFIlEJLXsAAOBgOrr6+V2u1VeXu60CPQh9A/gjKAE9AHl5eUaOHCg/H6/Ghsb1dzcrGAwqGAwqEgkcsTRgcOPAni9XqWnpys9PV0ZGRnKzs5Wbm6uMjMzk/yp0FPoH8AZQQnoAyzLUlZWlrKyspJdCnoh+gdwxnWUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHMQ9KM2ZM0dnnnmmcnJyVFRUpCuuuEIbN26M92oAAAASLu5BacmSJZo5c6aWL1+uhQsXKhKJ6KKLLlIgEIj3qgAAABLKMsaYRK6gtrZWRUVFWrJkic4///wjXg+FQgqFQq3P/X6/ysrKVF9fr9zc3ESWBgAA+iG/36+8vLwOZY2Ej1Gqr6+XJBUUFBz19Tlz5igvL6/1UVZWluiSAAAAOiShR5Rs29Zll12muro6vfnmm0edhyNKAACgJ3XmiJInkYXMnDlT69evdwxJkuTz+eTz+RJZBgAAQJckLCjddNNNeumll7R06VIdf/zxiVoNAABAwsQ9KBljdPPNN2v+/Pl6/fXXVVFREe9VAAAA9Ii4B6WZM2fq6aef1gsvvKCcnBxVV1dLkvLy8pSRkRHv1QEAACRM3AdzW5Z11OlPPvmkvv71rx/z/Z0ZYAUAANBZSR3MneDLMgEAAPQY7vUGAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADggKAEAADgIGFB6dFHH9XQoUOVnp6us846SytXrkzUqgAAABIiIUHpueee06xZs/SDH/xAlZWVGjNmjKZOnaq9e/cmYnUAAAAJkZCg9PDDD+sb3/iGbrjhBp1yyil67LHHlJmZqf/5n/9JxOoAAAASwhPvBYbDYa1Zs0Z333136zSXy6UpU6bo7bffPmL+UCikUCjU+ry+vl6S5Pf7410aAABAa8Ywxhxz3rgHpX379ikWi6m4uLjN9OLiYn344YdHzD9nzhzde++9R0wvKyuLd2kAAACtGhoalJeX1+48cQ9KnXX33Xdr1qxZrc/r6uo0ZMgQ7dix45jF90d+v19lZWXauXOncnNzk11OyuH7aR/fT/v4ftrH99M+vh9nqfbdGGPU0NCg0tLSY84b96A0cOBAud1u1dTUtJleU1OjkpKSI+b3+Xzy+XxHTM/Ly0uJLzNV5ebm8v20g++nfXw/7eP7aR/fT/v4fpyl0nfT0YMxcR/MnZaWpjPOOEOLFi1qnWbbthYtWqQJEybEe3UAAAAJk5BTb7NmzdKMGTM0btw4jR8/XnPnzlUgENANN9yQiNUBAAAkREKC0jXXXKPa2lrdc889qq6u1tixY/XKK68cMcD7aHw+n37wgx8c9XQc+H6Ohe+nfXw/7eP7aR/fT/v4fpz15u/GMh35bRwAAEA/xL3eAAAAHBCUAAAAHBCUAAAAHBCUAAAAHBCUAAAAHKRcUHr00Uc1dOhQpaen66yzztLKlSuTXVJKmDNnjs4880zl5OSoqKhIV1xxhTZu3JjsslLSj3/8Y1mWpdtuuy3ZpaSU3bt36/rrr1dhYaEyMjI0evRorV69OtllJV0sFtPs2bNVUVGhjIwMDR8+XPfdd1+HbpbZFy1dulSXXnqpSktLZVmWFixY0OZ1Y4zuueceDR48WBkZGZoyZYo2bdqUnGKToL3vJxKJ6M4779To0aOVlZWl0tJSfe1rX1NVVVXyCu5hx+qfw33rW9+SZVmaO3duj9XXFSkVlJ577jnNmjVLP/jBD1RZWakxY8Zo6tSp2rt3b7JLS7olS5Zo5syZWr58uRYuXKhIJKKLLrpIgUAg2aWllFWrVum//uu/dOqppya7lJRy8OBBTZw4UV6vV3//+9+1YcMG/fznP1d+fn6yS0u6hx56SPPmzdOvf/1rffDBB3rooYf0k5/8RL/61a+SXVpSBAIBjRkzRo8++uhRX//JT36iRx55RI899phWrFihrKwsTZ06VcFgsIcrTY72vp+mpiZVVlZq9uzZqqys1PPPP6+NGzfqsssuS0KlyXGs/jlk/vz5Wr58eYfutZZ0JoWMHz/ezJw5s/V5LBYzpaWlZs6cOUmsKjXt3bvXSDJLlixJdikpo6GhwYwYMcIsXLjQXHDBBebWW29Ndkkp48477zTnnntusstISZdccom58cYb20z78pe/bK677rokVZQ6JJn58+e3Prdt25SUlJif/vSnrdPq6uqMz+czzzzzTBIqTK7Pfj9Hs3LlSiPJbN++vWeKSiFO38+uXbvMcccdZ9avX2+GDBlifvGLX/R4bZ2RMkeUwuGw1qxZoylTprROc7lcmjJlit5+++0kVpaa6uvrJUkFBQVJriR1zJw5U5dcckmbHkKLF198UePGjdNVV12loqIinXbaaXriiSeSXVZKOOecc7Ro0SJ99NFHkqR169bpzTff1MUXX5zkylLP1q1bVV1d3eb/WF5ens466yy20w7q6+tlWZYGDBiQ7FJSgm3bmj59uu644w6NHDky2eV0SEJuYdIV+/btUywWO+I2J8XFxfrwww+TVFVqsm1bt912myZOnKhRo0Ylu5yU8Oyzz6qyslKrVq1Kdikp6eOPP9a8efM0a9Ys/ed//qdWrVqlW265RWlpaZoxY0ayy0uqu+66S36/XyeddJLcbrdisZgeeOABXXfddckuLeVUV1dL0lG304dew6eCwaDuvPNOfeUrX1Fubm6yy0kJDz30kDwej2655ZZkl9JhKROU0HEzZ87U+vXr9eabbya7lJSwc+dO3XrrrVq4cKHS09OTXU5Ksm1b48aN04MPPihJOu2007R+/Xo99thj/T4o/fGPf9Qf/vAHPf300xo5cqTWrl2r2267TaWlpf3+u0HXRSIRXX311TLGaN68eckuJyWsWbNGv/zlL1VZWSnLspJdToelzKm3gQMHyu12q6amps30mpoalZSUJKmq1HPTTTfppZde0uLFi3X88ccnu5yUsGbNGu3du1enn366PB6PPB6PlixZokceeUQej0exWCzZJSbd4MGDdcopp7SZdvLJJ2vHjh1Jqih13HHHHbrrrrt07bXXavTo0Zo+fbpuv/12zZkzJ9mlpZxD22K20+07FJK2b9+uhQsXcjTpE2+88Yb27t2r8vLy1m319u3b9d3vfldDhw5NdnmOUiYopaWl6YwzztCiRYtap9m2rUWLFmnChAlJrCw1GGN00003af78+XrttddUUVGR7JJSxoUXXqj33ntPa9eubX2MGzdO1113ndauXSu3253sEpNu4sSJR1xO4qOPPtKQIUOSVFHqaGpqksvVdlPodrtl23aSKkpdFRUVKikpabOd9vv9WrFiBdvpTxwKSZs2bdI///lPFRYWJruklDF9+nS9++67bbbVpaWluuOOO/Tqq68muzxHKXXqbdasWZoxY4bGjRun8ePHa+7cuQoEArrhhhuSXVrSzZw5U08//bReeOEF5eTktI4HyMvLU0ZGRpKrS66cnJwjxmplZWWpsLCQMVyfuP3223XOOefowQcf1NVXX62VK1fq8ccf1+OPP57s0pLu0ksv1QMPPKDy8nKNHDlS77zzjh5++GHdeOONyS4tKRobG7V58+bW51u3btXatWtVUFCg8vJy3Xbbbbr//vs1YsQIVVRUaPbs2SotLdUVV1yRvKJ7UHvfz+DBg3XllVeqsrJSL730kmKxWOu2uqCgQGlpackqu8ccq38+Gxy9Xq9KSkp04okn9nSpHZfsn9191q9+9StTXl5u0tLSzPjx483y5cuTXVJKkHTUx5NPPpns0lISlwc40l//+lczatQo4/P5zEknnWQef/zxZJeUEvx+v7n11ltNeXm5SU9PN8OGDTPf//73TSgUSnZpSbF48eKjbmtmzJhhjGm5RMDs2bNNcXGx8fl85sILLzQbN25MbtE9qL3vZ+vWrY7b6sWLFye79B5xrP75rN5weQDLmH56+VkAAIBjSJkxSgAAAKmGoAQAAOCAoAQAAOCAoAQAAOCAoAQAAOCAoAQAAOCAoAQAAOCAoAQAAOCAoAQAAOCAoAQAAOCAoAQAAODg/wfmcbw/SwqIXQAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 700x700 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "env=RoverGridEnv()\n",
    "print(\"Initial Setup\")\n",
    "observation=env.reset()\n",
    "env.render()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}