diff --git a/Planning/Curve/B_spline.ipynb b/Planning/Curve/B_spline.ipynb deleted file mode 100644 index c9b271a..0000000 --- a/Planning/Curve/B_spline.ipynb +++ /dev/null @@ -1,472 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 8, - "source": [ - "import numpy as np\r\n", - "import matplotlib.pyplot as plt\r\n", - "from scipy import interpolate" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 47, - "source": [ - "class BSpline(object):\r\n", - " def __init__(self, knots: np.ndarray, control_points: np.ndarray, degree: int=3):\r\n", - " \"\"\"See also https://web.mit.edu/hyperbook/Patrikalakis-Maekawa-Cho/node17.html#fig:rep_cvx_hull_bspl\r\n", - " \"\"\"\r\n", - " n = len(control_points)-1\r\n", - " k = degree+1\r\n", - " assert len(knots) == n+1+k\r\n", - " self.n = n # 0->n control points\r\n", - " self.k = k # k order, k-1 degree\r\n", - " self.T = np.array(knots)\r\n", - " self.p = np.array(control_points)\r\n", - " \r\n", - " def calcBasisFunction(self, t):\r\n", - " \"\"\"Calculate all basis function values in time t\r\n", - " \"\"\"\r\n", - " N = np.zeros([self.n+1, self.k+1]) # basis function\r\n", - " # order 1 is constant\r\n", - " for i in range(self.n+1):\r\n", - " N[i,1] = 1 if self.T[i]<=tk+1, see https://en.wikipedia.org/wiki/B-spline\r\n", - " for k in range(1,self.k):\r\n", - " for i in range(self.n+1):\r\n", - " w_i_k = (t-self.T[i])/(self.T[i+k]-self.T[i]) if self.T[i+k]!=self.T[i] else 0\r\n", - " w_i1_k = (t-self.T[i+1])/(self.T[i+1+k]-self.T[i+1]) if self.T[i+1+k]!=self.T[i+1] else 0\r\n", - " if i= ub:\r\n", - " break\r\n", - " k+=1\r\n", - " \r\n", - " # deBoor's alg \r\n", - " c = self.p\r\n", - " p = self.k-1\r\n", - " x = ub\r\n", - " t = self.T\r\n", - " d = [c[j + k - p] for j in range(0, p + 1)]\r\n", - "\r\n", - " for r in range(1, p + 1):\r\n", - " for j in range(p, r - 1, -1):\r\n", - " alpha = (x - t[j + k - p]) / (t[j + 1 + k - r] - t[j + k - p])\r\n", - " d[j] = (1.0 - alpha) * d[j - 1] + alpha * d[j]\r\n", - "\r\n", - " return d[p]" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 48, - "source": [ - "ctr =np.array( [(3 , 1), (2.5, 4), (0, 1), (-2.5, 4),\r\n", - " (-3, 0), (-2.5, -4), (0, -1), (2.5, -4), (3, -1),])\r\n", - "x=ctr[:,0]\r\n", - "y=ctr[:,1]\r\n", - "\r\n", - "# uncomment both lines for a closed curve\r\n", - "#x=np.append(x,[x[0]]) \r\n", - "#y=np.append(y,[y[0]])\r\n", - "\r\n", - "l=len(x) \r\n", - "\r\n", - "t=np.linspace(0,1,l-2,endpoint=True)\r\n", - "t=np.append([0,0,0],t)\r\n", - "t=np.append(t,[1,1,1])\r\n", - "knots = t\r\n", - "print(t)\r\n", - "bs = BSpline(t, ctr, 3)\r\n" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "[0. 0. 0. 0. 0.16666667 0.33333333\n", - " 0.5 0.66666667 0.83333333 1. 1. 1.\n", - " 1. ]\n" - ] - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 35, - "source": [ - "ts = np.linspace(0,1,endpoint=False)\r\n", - "basis_func_val = np.zeros([len(x), len(ts)])\r\n", - "for ind, t in enumerate(ts):\r\n", - " basis_func_val[:,ind] = bs.calcBasisFunction(t)[:,-1]\r\n", - "for i in range(len(x)):\r\n", - " plt.plot(ts, basis_func_val[i,:])" - ], - "outputs": [ - { - "output_type": "display_data", - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAB18UlEQVR4nO2dd3xV5fnAv+/dN3tvIJAEQgJhyAZRNiK4B65W22ptrbW7tr/Wtnbv1tZWbbW1bgEXiiJL9t6ZEFb23sm9yR3v74+bIISMe2/uSOL5+okk557znufk3jznOc8UUkoUFBQUFIY+Kn8LoKCgoKDgGRSFrqCgoDBMUBS6goKCwjBBUegKCgoKwwRFoSsoKCgMEzT+OnFUVJRMTk721+kVFBQUhiSHDx+ukVJG9/Sa3xR6cnIyhw4d8tfpFRQUFIYkQogLvb2muFwUFBQUhgmKQldQUFAYJigKXUFBQWGYoCh0BQUFhWGCotAVFBQUhgn9KnQhxAtCiCohRHYvrwshxFNCiEIhxAkhxFTPi6mgoKCg0B/OWOj/BZb38fp1QFrn10PAPwculoKCgoKCq/Sr0KWUO4C6Pna5EfifdLAPCBNCxHtKwO4cPF/Hbz/KR2n7q6CgoHA5nvChJwLFl/xc0rntCoQQDwkhDgkhDlVXV7t1shMljfzzkzM0mixuHa+goKAwXPFpUFRK+ZyUcpqUclp0dI+Vq/0SE6wHoKq53ZOiKSgoKAx5PKHQS4ERl/yc1LnNK3Qp9Moms7dOoaCgoDAk8YRCfw/4XGe2yyygUUpZ7oF1eyQmxABAVZNioSsoKChcSr/NuYQQrwHXAlFCiBLgJ4AWQEr5DLABWAEUAm3AA94SFhSXi4KCgkJv9KvQpZR39fO6BB7xmET9EKjXEKTXUNWsuFwUFBQULmVIVorGBOsVl4uCgoJCN4akQo8O1isWuoKCgkI3hqRCjw0xKD50BQUFhW4MSYXe5XJRqkUVFBQUPmVoKvQQPSaLjeZ2q79FUVBQUBg0DE2FHqzkoisoKCh0Z2gq9JCuXHQlMKqgoKDQxdBU6J0WerUSGFVQUFC4yNBU6CFKPxcFBQWF7gxJhR6s12DQqhQfuoKCgsIlDEmFLoRQctEVFBQUujEkFTo4ctEVl4uCgoLCpwxhhW5QgqIKCgoKlzBkFbqjn4ui0BUUFBS6GLIKPTbEQEu7lValWlRBQUEBGMIKXRl0oaCgoHA5Q1ehd1WLKoFRBQUFBWAoK/Sufi6Kha6goKAADGGFHhuiuFwUFBQULmXIKvRQoxadRqW4XBQUFBQ6GbIKXQhBdJCSuqigoKDQxZBV6OAIjCotdBUUFBQcDGmFHhtsUBp0KSgoKHQypBV6TIjSz0VBQUGhi6Gt0IP1NJmtmC02f4uioKCg4HeGuEJXJhcpKCgodDG0FboyW1RBQUHhIkNboXda6JVKYFRBQUFhiCt0pZ+LgoKCwkWGtEKPCNChUQmluEhBQUGBIa7QVSqhDLpQUFBQ6MQphS6EWC6EKBBCFAohHu/h9ZFCiG1CiKNCiBNCiBWeF7VnlNmiCgoKCg76VehCCDXwNHAdkAHcJYTI6Lbbj4A3pZRTgNXAPzwtaG9EK7NFFRQUFADnLPQZQKGU8qyUsgN4Hbix2z4SCOn8PhQo85yIfePo56IodAUFBQVnFHoiUHzJzyWd2y7lp8C9QogSYAPwaE8LCSEeEkIcEkIcqq6udkPcK4kNNlDX2kGH1e6R9RQUFBSGKp4Kit4F/FdKmQSsAF4SQlyxtpTyOSnlNCnltOjoaI+cuCt1sbpFsdIVFBQ+2zij0EuBEZf8nNS57VK+CLwJIKXcCxiAKE8I2B8Xh0UrgVEFBYXPOM4o9INAmhBitBBChyPo+V63fYqARQBCiPE4FLpnfCr9oMwWVVBQUHDQr0KXUlqBrwEbgTwc2Sw5QognhRA3dO72beBBIcRx4DXgfiml9JbQlxKrVIsqKCgoAKBxZicp5QYcwc5Ltz1xyfe5wFzPiuYckUF6VEKx0BUUFBSGdKUogFoliAzSK5OLFBQUPvMMeYUOjsCo0kJXQUHhs86wUOixIQalha6CgsJnnmGh0GOUBl0KCgoKw0eh17a2Y7Up1aIKCgqfXYaFQo8OMSAl1LZ2+FsUBQUFBb8xLBR6bGe1qNJGV0FB4bPMsFDoMSGd1aJKYFRBQeEzzPBQ6F39XJTAqIKCwmeYYaHQo4K6FLriclFQUPjsMiwUuk6jIjJQp+SiKygofKYZFgodIDpYT7VioSsoKHyGGTYKPSbEoPjQFRQUPtMMH4UerDToUlBQ+GwzbBR6bIie6pZ2bHaftGFXUFBQGHQMG4UeE2zAZpfUKdWiCgoKn1GGkUJXUhcVFBQGN3Z7BwWnfkpj4xGvrD9sFHpsqKNatLxBUegKCgqDE7O5jJKSl2htO+uV9YeNQh8RHgBAcX2bnyVRUFBQ6BmTqRgAo2GEV9YfNgo9KkiHUaumuM7kb1E+00i7HUt5Oa37D2CtqfG3OG4jpaTibCN73irk/Mka5BAOtre3tVGUfYKGinLsNpu/xflMYzJ3KnSjdxS6U0OihwJCCEZEGBUL3YdIKWn+eBPm7JN0nD9Px/kLdBQVIdsd6aOqkBDinniC0JXX+1lS57FZ7RQeruLE1mKqLjQDcPTjIkJjjGQtSCJ9Vjw649D5synJzWbD03+kuaYaAJVaQ2hMLOHxCYTFJRA1chQZVy9ArdH6WdLPBmZTCUJo0etjvbL+0PlkOsGI8ACK6xSF7guk3U7lr35N/csvg1aLLikJXXIygXPnoksehSYmltpnn6XsO9+hZds24p74MerQUH+L3Sutje3k7CwjZ0cpbU0dhMUGMH/1WNKmx1KcW8fxrcXsfOM0+949y/jZ8Uy8Nomw2AB/i90rVouFPW++zMH1bxEWE8eqbz5Ou6mNhvIy6ivKqC8voyj7BNaOdgoP7GXVN3+ARqfzt9jDHpO5GIMhASHUXll/eCn0iAD2n6tDSokQwt/iDFukzUb5j5+g8a23iLj/fmK+822E5sqPUtD8q6l57jlqnv4HbYcPk/CbXxM4a5YfJO6bUwcr2PJiHnarZNSESLIWJDFifARC5fgMpU2PJW16LJXnmjjxSTHZO0o58UkJM1aOZvr1o/0s/ZXUFF9gw9/+QPWFc0xctIxrP/cldAbjFftJu53jmz9iywv/5O3f/pQbv/vjHvdT8BxmU4nX/OcwzBR6UriRlnYrDW0WwgMVa8MbyI4OSr//fZo//IioRx4h6muP9HrzFBoN0V/9KkFXX03Zd79H0f0PEPHAA0R/8xuoBok1WF7YwJYX84hNDmHhfeP7tLpjR4ewZHQmc25JZfea0xxYf46QSAPjZsX7UOLekXY7Rz9az45X/4vOGMCN3/0xqdNm9rq/UKmYvHQFOqORj/7xZ9b+8sfc8vhPMQQG+VDqzxYmczHR0cu8tv6wCYqCw0IHKFLcLl7BbjZT8ujXaf7wI2K+9z2iH/2aU09CxokTGf3WOsLuWk3df/5D0ec+j+zwfwFYY7WJDc+cJDjCwIqvZDntQgkM1bPo/gwSx4Wx9eV8ygobvCuoE0gp+eiff2Hbi/9i1MTJfP73f+9TmV9KxtULWPXNx6k8U8ibT/6QtqZGL0v72cRqbcFiqfeqhT68FLqSuug17K2tFH/5YVp27CDupz8h8gsPuHS8KiCA+J/8hITf/w7TsWNU/+1vXpLUOdpNVj54+jjSLln5yCQMga4FBdUaFcsfmkhwhIEPnzlJY7V/s6tyd2wld8dWZt58Jzd97wkCw8JdOj5txhxu+t6PqS8t4Y2ffJ/muqGboTRYMZlLAO9luMBwU+gRDv+fkrroWWwtrRR98Uu0HTpEwm9/Q/jq1W6vFbpqFWG3307tv5+ndd8+D0rpPHabnY3/yqaxysTyL090O7hpCNSy8pFJSLvkg6eP095m8bCkzlFfUcaW5/9JUsYE5txxt9vxo9GTr+LWHz5JS30tb/zk+zTVVHlY0s82ZpN3UxZhmCn0YIOW8ACtYqF7mOo//QnT8eMk/vlPhN5ww4DXi/3B4+iSkyn73vex1td7QELnkVKy843TFOfWcc0940ga55ol252w2ACu+/JEGqtMbPxXNjab3UOSOofNamXDU79HpVFz3SPfRqUaWPZEUsYEbv/RLzE1N7Hxn39ByqGbfz/Y6LLQDYYkr51jWCl0cPjRldRFz2E6doz6114j/N57CVm61CNrqgICSPzjH7DW11PxxBM+VRontpWQvaOUKUtGkjE3wSNrJo4L55p7xlGcV8/ON0779Hr2rHmFijOnWfrQo4RERXtkzbjUsVx99wMUZZ8gd8dWj6yp4KgSVasD0WoHZkT0xfBT6EouuseQFgvlT/wETWws0Y895tG1DRkZxHzjGzRv2kzDmjUeXbs3inJq2b3mNKMnRTHr5hSPrp0xN4EpS0eSs6OUk5+UeHTt3ijOOcGBd9cyYcESxs6a59G1Jy1eTvzYdD556XklSOohzKZijIYkr6ZUO6XQhRDLhRAFQohCIcTjvexzhxAiVwiRI4R41bNiOk9ShJHSBpPSF90D1P73v7SfOkXcj3+EOijQ4+tHPHA/gXNmU/mrX9N+1jvNirqwWmx88koBYXGBLH4gA5XK839Us29KYdSESPa+fYaWeu8OWzG1NLPh6T8RHhfPgvsf8vj6QqVi6YNfo6OtlR0vv+Dx9T+LmMzFGLzoPwcnFLpwlDQ9DVwHZAB3CSEyuu2TBvwAmCulzAS+4XlRnWNkRAAWm6SySem6OBA6ioupefofBC9ZTPCiRV45h1CpiP/1b1AZDJR+5zvYvZjKeHxLMc11Zq6+Mw2dwTvlF0IluPrOsdjtkv3vnvHKOcARB9j03N9oa6hnxaPf9VoxUNTIZKatuoWc7Vsoyj7hlXN8VpBSYjKVeDUgCs5Z6DOAQinlWSllB/A6cGO3fR4EnpZS1gNIKf0WHr+Yuqi4XdxGSknFz55EqNXE/uhHXj2XNjaG+F/9kvbcPKr/8levnKOtqYPDH10gOSuKEekRXjlHF6HRRiYtHEH+vgqqLjR55RzZ2zZxev8e5t55H3EpaV45Rxezbl1NaGwcm//9d6yDoHZgqGKx1GK3mzB6MSAKzin0RKD4kp9LOrddylhgrBBitxBinxBieU8LCSEeEkIcEkIcqq6udk/ifugqLiqudzN10dwEm34C6x8Dm9WDkjnH0aqj/PP4P9lVuotWS6vPzw/Q9MEGWnftIvob30Ab650mQpcSvHCho+johRcw5+d7fP39689i67Az99ZUj6/dE9OuS8YYrGX32kKPB0hNzU188r9/MSIzi+mrbvHo2j2h1elZ/KVHqC8vY/87b3r9fD0hLXbazzXStK0YU06tX2TYvn077733Hk1N7t2kTabODBcvW+ieevbUAGnAtUASsEMIMVFK2XDpTlLK54DnAKZNm+YVJ3dCmAEh3LDQ7XY4/ips/hm0dj5g6IJg2S89L2RPp5d2Xsh+gb8d/Rt26Uh9UwkV4yPGc1XsVRe/QvXebXBla2ig8te/xpCVRfjdd3n1XJcS881v0vTBBqr/+hQj/vkPj61bW9pC3q4yJi7wXTMtnVHDjFVj2P5qAWePVZMyJcZjax94dy0dZjMLH/gyQuWbnIbkrCmMn3ctB95ZS/qc+UQmjfTq+ewdNjouNNF+rpH2c410FDeD9VN1ETgrnrCVYxAa31z/kSNH2LZtGwAnT55k/vz5zJ49G00P/Yt642Lb3EFgoZcCl95Wkjq3XUoJ8J6U0iKlPAecwqHgfY5eoyYuxOCaQi8+CP9eBO8+AuHJ8OBWmP4g7P07HH/Da7J20dTRxGPbHuOvR/7KklFL2HbHNv619F88lPUQAdoA3ih4g8e2PcbCNxeyo2SHV2Wp+uMfsTU0EP/kzxBq73SE6wl1SAiRX/gCLdu2YTp+3CNrSinZteY0OqPG5020MubGE5EQyJ51hdgsnslNb6mv49jGDxg/71qiRozyyJrOcu3nvoTOaGTTv/6OtHsv195S0UrFbw9Q83w2zZ8UI62SoDkJRH4ug/gfzSTomiRa95VT9cxxrPXej5MVFRXx/vvvk5KSwte+9jXGjBnDli1bePrpp8nPz3f6CayrqMibOejgnEI/CKQJIUYLIXTAauC9bvu8g8M6RwgRhcMF4920hT4YERHgXHFRcwW89WV4fjE0l8PNz8EXP4bEq2D5r2HUPHjvUSj1zvw/gPy6fO5cfye7Snbx+IzH+f383xNljGJW/CwemfwILyx7gT137eHF5S+SEpbCtz75FocqDnlFlrbDh2lYs5aI+z+PIT3dK+foi4j77kUdEUH1Xz3jS79wspaS/HqmXz/a5dL+gaJSq5h7WypNNWZObPNMGuP+t9/EZrUw+zbfPTl1ERAaxvx7H6A0P5eT2zZ55RzWGhPVz59EqFVEPZBJwk/mEPvIZMJWjMGYEYk6SEfYdaOJvG881moTVX87irmgziuyADQ2NvLGG28QGhrKbbfdRlRUFHfddRf33XcfarWa119/nZdffhln3McmUzFabQQajeezxS6lX4UupbQCXwM2AnnAm1LKHCHEk0KIrrLBjUCtECIX2AZ8V0rpH2cXXbno/fjQpYSXb4Oct2Det+Brh2DSndCVI6rWwh0vQlAsvH4PNFd6XM63T7/NvRvupcPewX+W/4d7xt/TY46qTq1jauxUnlnyDAlBCTy69VFya3M9Lk/Vn//syDl/5BGPr+0MqsBAIh96kNY9e2ndf2BAa9lsdnavKyQsNoAJ13YP+fiGkRmRjJoQyaEN5zA1Dyyg2FRdxYnNHzFhwRLC4zxTEOUqE65dQsK4DPaufRWrxbNtDmyN7VT/+yTYJFFfmohhXAQqfc9PiMbMKGIfnYI6RE/Nf3No3HTB4xOlLBYLb7zxBhaLhbvuuguj8dNMopSUFL7yla+wfPlySkpKeP755+noJ2BsMpdgNHrXVQVO5qFLKTdIKcdKKVOklL/s3PaElPK9zu+llPJbUsoMKeVEKeXr3hS6P0ZEGKlsNtNu7WPcVlUuVJ50WOKLfwL6HlqGBkbB6lfAVA9v3gdWz+UW/+XwX3hizxNMjp7MmyvfZHLM5H6PiTBE8NyS5wjRhfDwpoc52+i5h6C2gwcxHTpM5Je+hCrAf4Mbwu+6C01sLNV/GVjZec6OUhoq25hzaypqtf/q5+bcmoqlw86B988NaJ29615DCJh1i/t9dAaKEILZt91FS10tuTu2eGxdW6uF6udPYjdZifrCBLQx/X/+NFFGor86iYApMTRvKaL25TyPBaCllKxfv56ysjJuueUWYmKujIGo1WpmzZrF6tWrMZvNnDp1qs81HX3QvetugWFYKQoOC11KKO0r0yXnbRAqyLip78Xis+Cmf0DxftjwHYdlP0AK6gp4IfsFbky5kWeXPEukMdLpY+MC43hu6XOohIoHP36Q0pbu4Qz3qHnmWdSRkYTdfptH1nMXlV5P1Fe+gunoUVp37nRrDXOrhQPvnyMpPZzkic7/br1BRHwgE65OIGdnGXVl7mUt1ZWVkrN9C5OWrPBYeb+7jJo4mbjUsRx4Z41H5pPazVZqXsjGWtdO1Ocz0SUFO32sSqcm/PaxhCxPxpxbi+mkZzpE7t27lxMnTnDttdeS3o/rcdSoUQQFBZGTk9PrPlLaMLeXeT3DBYarQu8vdVFKh0IfPd9hhffHhFvg6m/Dkf/BwX8PSDYpJX849AdC9CF8d/p3UbvRTGlUyCieXfIsJquJhz5+iBrTwD7IphMnaN29m8gvPIDKYBjQWp4g7NZb0I4YQfVf/uqW1XVow3na26zMvS1tUEyumr5qNFq9mt3rCt06fu/aV1Frtcy46XYPS+Y6Qghm3XInjVWV5O/ePqC1pMVGzYs5WMpbibx3PPoxrmdwCSEInp+ENi6Axo/OI60DC9ieOXOGTZs2MX78eObPn9/v/iqVioyMDE6fPk17e89P8GZzBVJaFQvdXUb2N+iiMhtqCyHzZucXXfAjGLscPnoc6i+4LdvO0p3sK9/Hw1kPDygFcVzEOP6x6B9Um6p5aNNDNHW4X8RS88yzqEJDCbvTf4/zlyK0WqK/9gjm3FyaP3YtANfW1EH2jlLSZ8URlTQ4Ju8Yg3RctXwURTm1LhcbVRedJ3/PDqZed4PLPc69xZipM4gemcz+t9/EbnfPSpc2Se0r+XScbyLizrEYB1DwJVSC0BVjsNWZadlT5vY6FouFdevWER0dzU033YTKybTQzMxMrFZrr24Xk7kI8G7b3C6GpUKPCdaj06go6U2hZ78FQg3pq5xfVKWC6/8I0g5HXnRLLqvdyh8P/ZGRwSO5c9ydbq1xKZNjJvPXBX/lbMNZ/nz4z26tYS4ooGXrViI+d59X+rW4S8jKlehSUqh+6imkC4/2J7eXYLPYmbrMt2l9/TFhfiI6g5qjHxe5dNzuN15GZzAyzQdFRM4ihGDmLXdSV1bC6f173VqjZW8Z5vw6wm5MJWDSwPP0DWPD0Y8Np2lrMbZW9wK2ubm5tLW1sXz5cvR6vdPHjRgxok+3i9nk/ba5XQxLha5SCZLCjD2nLna5W8ZcA4Eu+ldDkyBtGRx5CWyuf2jeOv0WZxvP8q2rvoVW7Zk0utkJs7kr/S7WnVrnVuZL7bPPogoMJOLeez0ij6cQajXRjz5Kx5kzNL3/vlPHWDpsZH9SSnJWFOFxg+fmBI5io8z5iZw5UuX0dKPywgLOHNrHtFU3Ywxy3rfsC9JmziE8IYn9b7/hslvM1txB06YL6MeGEzgzzmMyhV0/GtlupXmLazfNLg4fPkxERATJyckuHadSqcjMzOzV7eIoKlJhMHg/O2lYKnSApIheUhfLj0P9OdfcLZcy7QFHJWn+By4d1tLRwtPHnmZqzFQWjlzo3rl74auTv0q4IZxf7/+1S39c7WfP0fThR4Tfcw/qUO9WoLpD8NIl6DPGU/33p5FOpMnl7ynH3GphyhLvp4e5Q9aCEQiV4PiW4v53xmGdG4NDuGpF99ZJ/kelUjPzptupvnCOs0cOunRsl687bNUYj8Y4tLGBBE6Po2VfOZZq1yrFKysrKSoqYtq0aU67Wi4lMzMTm81GQUHBFa+ZTSUYDPGoVN6vhRi2Cn1EeC8Wes7boNJA+kr3Fk5dDKEj4JBrLUWfz36eOnMd35v+PY8H6oJ1wXxj6jc4Vn2M9886Z80C1D73HEKvJ+L+z3tUHk8hVCpiHnsMS3ExjR/0fQO12yXHthQTOzqE+NTBd3MCCArXM3Z6LHl7yjC39H2DKi8s4MKJo0y/8TZ0Rv+lkfZF+txrCImOZf9bzlvpHcXNtB2uJGhuItpoz19XyJJRCI2Kxg/Pu3Tc4cOHUavVTJo0ya3zJiUlERwc3KPbxWQu9om7BYaxQh8ZEUBDm4Um8yV/OBfdLddCgJtBGJUarvo8nNsOtc61SC1vKeel3Je4fsz1ZEZlunfefrgx9UYmRk3kz4f/7FRTr46SEhrXryf8zjvQRHi3A+FACJw/H31aKnX/+1+fSuPs0Wqaqk1MWTJyUGS29MbkJSOxdtjJ3tF39eiRDe+hMwYwaXGPfe4GBWqNhhk33kZ5YQFFJ/tv1yDtkvp3C1EFawlZ5J0AoTpYR/A1SZhza2k/69xgjo6ODo4fP05GRgaBge656rrcLoWFhZjNl7ck8EXb3Ity+OQsfuBi6uKlgdGyo9BwwX13SxdT7nNY+Yf/49Tufz3qKGV/bIpnp/5cikqo+MGMH1BtqubZE8/2u3/tv/+NUKmI+MIXvCaTJxBCEH7ffbTn5mE6fLjHfaSUHN1URGi0kdGT/Zun3R+RiUGMzIzkxLYSrJaeg73NdTWc2reLiQuXDFrrvIvMaxcTFB7B/rf773nUdqQSS0kLodeNRqX3Tk96gKCrE1GH6GjYcNapCtLs7Gza29uZNm3agM7bk9vFZjPT0VHlk5RFGM4K/WJf9Ev86Dlvg0oL6dcPbPHgOBi3Ao6+Apa+GwRl12TzwdkPuC/jPuKD4gd23n6YGD2Rm1Jv4qXclzjX2HtloqWyksZ1bxF66y0+aY87UEJXrUIdGkrdi//r8fXywgaqzjcxefEIr0wi8jRTlo7E1GyhYF9Fj68f/3gDdrudyctcyMLyExqtluk33Epx7klK8nsvrrGbrTR+dB7dyGACPNh9sidUOjUhy5KxlLRgOt5/n5VDhw4RHR3NyJEDi70kJiYSEhJymdvFbPZN29wuhq9Cj3D0Xijp8qNLCTnvQMoCMHogn3faA2Cqg7z1fe72h0N/IMIQwRcnfHHg53SCx6Y+hkFt4LcHf9uri6Luhf8g7XYiv/Qln8g0UFRGI2F33knzli10lFxZGXv04yIMQVrSZ3v3hukpEseGET0ymGObi6+wIC0d7Rzf/BGp02YSFuu5DBBvMnHRMowhoex/u/d+6U2bLmBvtRB2Y6pPXGIBU2LQJgY5ArB9dLssKyujrKyMadOmDViuS90uJpPDkDR1dllUXC4DJNSoJViv+dTlUnoEGosG7m7pYvS1ED66z+BoTm0OhysP86WJXyJI55silyhjFF+d/FV2l+5me8mVlXy2llYa1q0j5Lrr0CX55jHQE4TffRcIQf0rr1y2va68lfMna5l4bRIane/a/Q4EIQRTlo6kobKNcycur/LN2/kJ5uYmpg7CzJbe0OoNTF2+ivPHDlNXdmVswFLZSsveMgKnx6FL9M3fgVAJQpclY2tsx5TdeyX14cOH0Wg0ZGVleeS8mZmZ2O32i24XU6eFbjQoCn1ACCEcqYtd5f85bzncLeNWeOYEKpXDSi/aA1U9T9lZd2oderWeG1Ju6PF1b7E6fTUpoSn89sBvabddnhfbtP497C0tRNx7j09lGijauDhCli2jYe1a7K2fBn2PbS5CrVUx0U8dFd0lZUo0wZGGywqNpJQc/fA9okeNJmn8BD9K5zoTFy1DpdZw7OPLs5GklDSsP4vQaQhZ6ttiL31qGOoIAy0HenZttbe3c/LkSSZMmHBZN8WBkJiYSGho6EW3i9lUjEqlR6fzTWxn2Cp0gJERRoeFbrc73C2pi8AY5rkTTL4H1Loeg6NtljY2nNvA0lFLvT5lqDtalZbvz/g+JS0lvJT70sXtUkrqXnkFQ2YmBjfTs/xJxOfuw97cTMM77wDQ2thOwf4Kxs+Oxxik869wLqJSq5i0aAQVZxspP+PIxijKPk5N8QWmrrhxUGfq9ERgWDjjZs8j55MtdJg/jVuZc+toL2wgdOko1D5+j4RKEDg9lo5zjT3mpZ84cYKOjo4BB0MvO6cQZGZmcubMGUwmEyZzCQZDks/ez2Gt0EeEOwZdyJKD0FQCmR4unw6MgvE3wLHXoOPyD8zG8xtptbRy69hbPXtOJ5mdMJt5ifN4KfclTFbHH1jbgYN0FJ4h/O67h5zCADBOnoxhUhb1/3sJabdzYlsJdptk0mLfPM56mvFz4tEHaDj6saM30JEN72IMCSV9Tv9NoQYjk5ddT4epjbydjnFtUkqathWhjjQQONM/8Y3Aq+JABa0HL59nIKXk0KFDxMXFkZjo2ae7LrdLfn4+JlMxRqPvXJvDW6FHBGC22DEdWwtqPYy7zvMnmfYAtDc6MmguYd3pdYwOHc3UmKmeP6eTfGnil6gz1/FO4TsA1L/yCurQUEKu95DbyQ9E3Pc5Oi5coGHbDnJ2lJIyOZowJ/pnD0Z0Bg0Trknk3IkaLpw8w9mjh5i0ZAUa3dB62ugiPi2dmNEpHP3ofaSUtJ9pxFLSQvD8JITaPwaEOkSHIT2StsOVl3ViLC0tpbKy0iPB0O4kJCQQFhZGTk4OZnMxBh/5z2HYK3QjINHkv+eo8DSEeP4ko+ZC1NjLgqOF9YUcrz7OrWm3+tUSnhozlUnRk3gx50VMZSU0b9lC6G23DooWue4SsmwpmpgYcl7bQ3ublayFQ9M672LitY7H8V2vr0WlUjN56dC92QohmLJsJbUlRZTkZdO8vRhVkJbAqf5NjQ2cEYe91YIp79MhaocOHUKn0zFx4kSPn6/L7XLhQh5Wa7NioXuKEeEBJIkadG0VDv+5NxACpn0BSg9B+QnAYZ1rVBpWpfg3j1gIwRcnfJHSllKOPvdbsNsJv8v38yg9idBqCb/7bs62xRMeqRm0Zf7OEhiqZ1RmEBVn9jF29rxB0yLXXcbNnY8hKJiC9dtoP91A0LxEhNa/asYwNhx1qI7WzuCoyWQiOzubrKwsl7oqukJaWho6vaNVstHgu95Cw1qhJ4UHkCY606hivVNyD0DWnY52vDlv025rZ/3Z9SwauYgIg/9L6q8ZcQ1jA0ejfX8bgddcM6RSFXvDMnclzSGjGNmeNyRjAd3RG0+DtBA1cp6/RRkwWp2eCQuWEFBiBJ2KoFn+rw0QKkHAtDjaCxuw1jnGxVmtViZPnuy1c8bExGAwtAAoFrqnMOrUTDF0pixFe3GKfUAEJM+DvPVsvrCZxvZGbk3zTzC0Oyqh4pGGqwhqsVG2bOhltvRE3tEm1NgI2/ZfrPX1/hZnQNjtNs4f3YLWOIKSAu+Vw/uSrOmLSQoYS2N4PSrD4LimwGkOt0/roQry8vIICQkhIcF77WwDAgIICXEMjlZ86B5koq6MOlWkZ9MVe2L8Kqg9zbqcl0gMSmRm/Ezvns8FRm/OoypCzTN694YRDCba2yycPlhJ6sQQ1K0NNKxd62+RBsTZI4dorKokfe5yKs42UVPS7G+RBk5uOwjJ/vz3sFndGzbhaTThBgxjw2k4WEphYSHp6elutcl1hbAwKzabHq3WC7G7Xhj2Cj2FYgrxwSNP+vVc0Gg4WJfDbWNvQyUGx6/WlJOD+dhxzDcu4HD1EY5VHfO3SAMif18FVoudSasyCJg+nYY31yDtA5sj6U9ObNpAUHgE8+5chlqjInuH+yPUBgO25g5aD1dCip76hjJO7d/jb5EuEjg9jqLWCqxWK+PHj/f6+QKMrZjNQW7NxXWXwaF1vIXdTnxHEdmWBKw2L//RhySwLiEVtYQbUwZP2Xb9q68ijEbmfulHhOpDeSHbtT7ugwkpJTk7SolJDiF6ZDBhd9yBpbiYtn37/C2aWzRVV3Hu+BEmLFxKQIiB1GkxnNpfQYfZ6m/R3KZldynYJPE3ZREWF8+xj5zvz+9tDOMjuKCvwaDSDbgRlzNotI2Y2gJpbHSuja8nGN4KveECWruZAnsS5Y19d0UcKBabhXd1dq5payO63bVpKd7C1tBA0/sfELpqFUGRsdyVfhfbirdxpsG5Pu6DjbLTDdRXtDFhvqMQJHjZUtRhYdS/0XtTqMHMya0bAZi4cCngmDtqabdx6kBlX4cNWuxmKy17yzFOjEIbHcjkpSspO5VH5bnB8XmzSTtFqhpGWiKhxbs3TSntSFmN2RxEVVWVV891KcNboVc7eqyctide3hfdC3xS8gl1NjO3Nre4PJ7OWzSsewvZ3k74PXcDcHf63RjUhiFrpWfvKEUfoCFtmqP9qkqnI/Tmm2nesgVrdf9tUgcTdpuNk9s2MXryVYREOa4ndnQIUSOCyN5e6tPHdE/Rsq8c2W4j+BpHEDDz2kVo9HqObRwcfw/nzp2jw2Yh2RZD6yHv3jQ7OqqR0oLZHES1Dz+bw1uhV+UBcFom9TyOzoOsO7WOuMA45oak9NtS1xdIu53611/HOO0qDOPGARBuCOeWtFvYcHYDFa09NywarLQ1dXD2aDXps+Iv66oYdvvtYLXS8PY7/hPODc4cOUBrfR1Ziz+tXhZCkHl1IrWlLVSea/KjdK4jLXZadpeiTwu72FHREBhExrwF5O/ejrmlxc8SQl5eHjqdjtHJybQeqnBq+IW7dLXNFSJKsdA9RnU+MiSBdk0QZ6r7H8vmLuUt5ewp28PNqTejTl8FRXuhxXdvYk+07t2LpbiY8DtXX7b985mfRyJ5MedFP0nmHnl7yrDbJJnzL081048ZTcCMGTSsGVrB0ZObPyIoIpIxUy5vDDV2Rixag5rs7Vf2fR/MtB6pxN5suWiddzFp6QqsHe3kdvZ38RddLW3T0tIInZmIrb6d9jMNXjtfW5tjwExg0BjFQvcYVbmI6PGkxQSRX+G9dLCN5zcikY7K0PGrAOl3t0vDmrWoQ0MJXrrksu0JQQksH72ctwvfdmr26GDAbpfk7CwjcVwY4XFXznzsCo627h0aaZmNVZWOYOiCpajUl/dw1xk0jJsRR+Hhqn4HSQ8WpJS07C5FmxiEPuXyyt2Y5DHEjknj5NaNfnUjFRcX09rayvjx4zFmRCH0atqcmGbkLi0t+ahURiIjxlFdXY3dR8bG8FXodhvUnIaY8YyLC6agwnuPsBvPbyQzMpMRwSMcFanhoyHff9F9a22to2/LTTei6qG0+a70u2i1tLL+jP9dQ85QlFNLc62ZCfN7Tj8NXroEdVgYDUMkOHpy68cIBBMXLunx9QnXJGKz2snbW+5jydyj/Wwj1ioTQbMTeqzczVq0jJqi81QUnvKDdA7y8vJQq9WkpaUhtCqMGZGYcmova9jlSVpaCwgKTCM6OhaLxUJDQ4NXztOd4avQ68+D1QzR6YyPC6GyqZ361g6Pn6akuYTs2myWJS9zbBDCYaWf3Q6mBo+fzxka33kHLBaHf7kHsqKyyIjM4PX814dE8C1nRykBITpGT47q8fWLwdGtWwd9cNRmtZL9ySZGT/k0GNqdyMQg4lNCydlR6lU/r6do3VuGKkBDwKSe35/0ufPR6g2c2PKRjyVzIKUkLy+PlJSUi71bjBOjkCYrZi+4XaSUtLQUEBSUTkyM4z32ldtl+Cr0zoBol4UOeMXt8vGFjwFYmrz0043jbwC7BU5/7PHz9YeUkoY1azFOnYo+NbXHfYQQrB63mjONZzhUecjHErpGc52Z89m1jJ8bj1rd+8c17I7O4Ohbb/e6z2DgbGcwdOKi5X3ulzk/kcZqEyX5g7u1gbWxHVNuLQHT4xDankcA6owBpM+dT/6eHbS3+T6lt7y8nMbGxsuKiQxjwxF6NaYTvY+nc5eOjhosljoCg8YSHe2YVOSrwKhTCl0IsVwIUSCEKBRCPN7HfrcKIaQQwnMjQNylulOhR48jPb5LoXve7bLx/EYmRk0kMeiSJvmJV0FQHOS95/Hz9UfbwYN0nD/fq3XexXWjryNUH8pr+a/5SDL3yN3tqJzMmNd33w396NEEzJw56IOjJ7Zs7DEY2p2UqdHoAzXk7BrclaOt+8tBQlA/AywmLlqGtb2d/N1Xzrn1Nnl5jiZu4zqzvQCERoUxMxJTTo3H3S4tLY506aCgdAwGAyEhIYPHQhdCqIGngeuADOAuIURGD/sFA48B+z0tpFtU5UPoCNAHEx2kJyJQR4GHLfTipmJya3M/dbd0oVLB+JVwevMVk4y8TcOba1AFBxOyfFmf+xk0Bm5OvZmtRVsHbQqj3S7J31POyPERhET2P/Mx7I7bsZSU0LpncAZHG6sqOd9LMLQ7Gq2acTPjOHe8GlOz512FnkBa7bQeqMAwLgJNRN899uNSxhI9Mtkvbpe8vDySk5MJCLh8EIoxKxpptmEubPDo+VpaHQOigwIdN5Do6OhBZaHPAAqllGellB3A60BPte0/B34LeLck01mq8yHG8YglhCA9Lpg8Dyv0jRcclX5LRy298sXxq8BqgjNbPXrOvrA1NND88ceErlqFyomht3eMuwO7tLP21OBscFWUU0tLfXu/1nkXwUuWoA4Pp+GNN7wsmXv0FwztTsa8BOw2Sf6+wXnDNWXXYG+xEDS7/xa5QggmLl5O1bkzVJ4t9IF0Dqqrq6mpqemxd4shNQxh0GA64VnruaUlH50uBp3O0T47JiaGmpoan2S6OKPQE4HiS34u6dx2ESHEVGCElLLPXD0hxENCiENCiENefQSxWaHm1GUtc8fFBXOqohm7B4NMG89vZFL0JOKDevhAj5oLxnCfFhk1vvcesqPD4U92ghHBI7g66WrWnlqLxTb4UuRyd5VhDNaSnNVzsK07lwZHLT4s5nAGm9VK9raP+wyGdicyIYi4MSHk7ioblMHrlr3laCIN6NOcG8oxft61aHT6iy0PfEFensP1mp5+ZfvsT90uns12aW05RVDQp+6d6OhorFYr9T5o9TzgoKgQQgX8Cfh2f/tKKZ+TUk6TUk7rChZ4hfpzYOu4aKEDjI8LwWSxUeShFgDnG8+TX5d/pbulC7UWxq2AUx+C1fuPzFJK6t98E0NWFoYePry9sXrcamrNtWwu2uxF6VyntbGd8ydrSZ8dj1rj/Mc07PbbwGaj8a23vCid65w9coDWhnqyFvcdDO1OxrwEGirbKC/0XYMnZ+goa6HjQhOBs+IRKueGjBgCgxg7ay55uz6hw2zysoQO8vLySEpKIiSk5xa2AVlRyHYb5lOeUbZ2u5XWttOXKXRfZro485dSClxa/pXUua2LYGAC8IkQ4jwwC3jPr4HRrgyXbhY6eC7TpSu7ZcmoPh6f01eCuRHO7/TIOfvCdPQYHYVnHArNBeYmzmVE8Ahez3/dS5K5R/7ecqRdkjHXtSEEF4Oja9cNquBoVzB09GTX/ixSr4pFZ1CTO8iCo617yxFaFYFXuTYvNGvRcjpMJgr2ev9voqGhgfLy8h6t8y70qWEIowbTSc9ku5hM57HbOy76zwGfZro4o9APAmlCiNFCCB2wGriYviGlbJRSRkkpk6WUycA+4AYppf/y4TqbchH96S91bGwwQngu02Xj+Y1MiZlCXGBc7zulLABtoE+KjBrefBNVQAChK1wbMqwSKu4cdydHqo5QUFfgJelcQ9olubvKSBwbRlhsQP8HdCPs9s7g6CCpHG2qruoMhi7pNxjaHa1eTdqMOAqPVGFuHRxuMXubhbZjVQRMjkEVoHXp2IRx44lIHMHJzd53u+TnO/RAX73PhbrT7ZJbi7QM3AC4NMOlC71eT2ho6OCw0KWUVuBrwEYgD3hTSpkjhHhSCHGDtwV0i6o8CBsFuk/LxI06NcmRgR7JdDnbeJZT9ad6d7d0oTU6hlMXfAhetBZtTU00ffQRIStXogq8sjS+P25KvQmD2sDrBYPDSi85VU9TjZnxLlrnXQQvWYw6NJSGNYMj2Hty2yYAJi7oIXjuBBlz47FZ7IOmrW7r4SqkxU6gE8HQ7gghyFq0jPLCAqqLznteuEvIz88nOjqayMjIPvcLyIr2mNulpaUAIdQEBqZctj0mJmbQWOhIKTdIKcdKKVOklL/s3PaElPKKRGsp5bV+tc7hsgyXS0mPC/aIy+Xj845shcUjF/e/c/pKaC6HsqMDPm9vNL7/PtJs7jf3vDdC9aGsGLOCD85+QFOH/7v85e0qQx+gIWWqe3EWlV5P6E03Otrq1tV5WDrXsNtsZH+yieSsKYREOxcM7U7MKEdb3cEQHJV2Seu+MnSjQtAlBLm1xvirF6DWaDi5xXtWeltbGxcuXOjT3dKFPiUUVYCGtpMDt6BbWgsICBiDSnV5y43o6GifZLoMv0pRm8XRw6WHodDj4oI5X9uKqcM2oFN0uVtiA53wH6YtAaH2mttFSknDm2vQZ4zHMCHT7XVWj1uNyWri3cJ3PSid65haOjhzrJpxM+PQ9FJ56Axht98OFguNfm6re+7YYVpqa8jqpzK0PzLnJVBb2kLVBf/OHG0/XY+11uxUqmJvBISEkjZzLrk7t2LpaPegdJ9y6tQppJROKXShVmGcEIU5tw5pGZhuaGkpIDBw7BXbY2JisNls1HnZwBh+Cr32jKPsvkcLPQQp4VSl+38UZxrOUNhQ2L+7pYuACEie67Xui+bsbNrz8wm//fYeGyM5y/jI8UyKnsQbBW9gl/4LJhbsq8BulU7nnveGPjUV45QpNKxd61er9uTWjQSEhjHmqhkDWidtRhwancrvwdGWveWogrQYJziXStobExcuo721lVN7d3lIssvJz88nODiY+HjnbjzGiVHIDhvmAvfdLlZrM2ZzCcFBV95EfBUYHX4KvfrKDJcu0jszXQbiR994fiMC0Xd2yxUnXgk1BVDj+YKKhjffRBiNhKxcOeC1Vqev5kLTBfaX+6fYV0pHMDR2dAiRie49zl9K2O2303HuHKZD/vEAttTVcvbIQTKvXYxaoxnQWnqjhtSrYjh9sNJvM0et9WbMBXUETo9DuJBK2hMjMicSFhfvlZx0i8XCmTNnSE9PR6VyTk79mDBUgRraBlBk1NLq6CYZeEnKYhddCt3bgdHhp9Cr8gEBUVc+9oyMCMCoVZPnZqaLlJKN5zdyVexVRAe44N8d1zmVpsCzVrqtpYXGDzYQsuI61MHBA15v6ailhOvDebPAP21oK840Ul/RNmDrvIuQ5ctQBQVRv2aNR9ZzlexPNiPt9oszQwdKxjzHzNHCQ/4pmmo94KhYDZzZR2aXkziCo8spzc+ltqRowOtdytmzZ7FYLJf1bulXHrVwuF3y6rC76ZJtaekq+b/SmNTpdISFhSkWustU50F4MuiuTHdTqQRj44LdttALGwo523jWeXdLF2EjIS7L426Xpvc/QLa1EX7HHR5ZT6fWcVPaTWwr3kZlq+8zKnJ3laHVq0m9yr3gYXdUAQGErFpJ80cbsfmoH3UX0m4ne9vHjMjMIjzOMzeouDEhhMcF+KVhl7TaaT1YgSE9Ak1Y331bnCXzmkWo1BpOeDg4mp+fj16vJzk52aXjjBOjkRY75gL3/NwtLQWo1UEYDD2/3zExMYqF7jJVPWe4dJEe68h0ccevuunCJkd2yygnsluuOPFKKD7g0dF0DW++iX7cOAxZWR5b8/axt2OTNt467dtKy3aTlcLDVaTNiEVnGJh74lLCb78d2dFB43u+HeZxIfs4jVWVTFzk4s2/D4QQZMxLoOp8EzUlvp3Racqpxd5iIXCW+8HQ7gSEhpE6Yza527dg7fBMNfWlo+Y0Lrq59KNDUQVp3S4yamnJJyhobK+xrK5MF5ttYIHXvhheCt3aAXVnevSfd5EeH0xdawfVLa5H1zdd2MTU2KlEGd0ICKWvAKQjJ90DmLJzMOfmEnbHwIKh3RkRPIK5CXNZe3otVrvvfLWnD1RgtdjJ9JC7pQtDRgaGzExHW10fBkdPbtmIISiYtOmzPbpu+qx4VBrh8+Boy75y1OF6DE72bXGWrEXLMLe2cHr/bo+sV1xcTFtbm1PZLd0RaoExIxJzfr3LRUZSSlpbCy4rKOpOTEwMdrvdq5kuw0uh1xaC3dqnhX6xBUC5a26X843nKWwodC73vCdiJzhcLx5yuzS8+SbCYCB01SqPrHcpd4y7g6q2KraX+KZ3tZSS7B2lRI8MJnrkwGMB3Qm7/XbaT5/GfPy4x9fuibamRgoP7iNj/kI0Op1H1zYEaUmZEkPB/gos7d6z9C7FUtVGx7lGAmc637fFWUZmZhEWG+8xt0t+fj4qlYrUXoa79IdxQme2y2nXsl3a28uxWpsvK/nvji8yXYaXQu8jw6WL9DhHkx5X/ehbirYAsGjkIvdkE8Lhdjn7CbQP7HHZ1tJK0/vvE7JiBepemg4NhPlJ84kNiPVZcLTyXBO1pa1kXt3zTMqBErLyekRAgM+Coznbt2C3WcnyoLvlUibMT6TDZOX0Id/EOVr3lYNaEDjNtb4tziBUKiYuWkZJXja1pcX9H9AHUkry8/MZM2YMBoN7fn79mFCEQY0pp9al4y4GRPuw0KOiHE/23vSjDy+FXpUPQtVjhksXEYE6YoL1LleMbinawoTICT23ynWWcSvA1g5ntri/BtC04QPsbW2EO9km11U0Kg23jb2NPWV7KGrybAZCT2TvKEVrUJM23fMKA0AdFETIiuto2vAhthbv+p6llJzcspGEseOJTBrplXPEp4Y6gqM7ve92sXfYaD1SiXFCFOogzz5tdDHh2sWo1AOvHK2urqa+vt6l7JbuCI0K4/hIzHm1SJvzbpcuhd5TUVEXOp2O8PBwxUJ3muo8CB8N2r7vzunxIS416aporeBkzUkWjXLTOu9i5GxHj/QBul0a3lyDfuxYDJMmDUyePrgl7RbUQs2aU961as2tFgoPVzFuRpxHg6HdCb/9dqTJRNP73inw6qIkL5v68lKPBkO7I4Qgc34iVeebqC7ybuWo6Xg10mwjyIPB0O4EhIaROn0WOTu2Dig42tWMayAKHcA4IRJ7m5X2s863LG5pzcegT0Cr7fuJ2duZLsNLofeT4dJFelwwp6tasDp5B+5yt7jtP+9CrYGx18GpjY4WBW5gysnBnJ1N2B13eMU90UVMQAwLRy7kncJ3aLd5pzwbHJWhNoudzPmeDYZ2x5CVhX7sWBre9K4b6eSWjegDAhk3e55Xz+NojaAie2dp/zsPgJZ95WhiA9Ale961dylZi5Zjbm7i9EH3O2Tm5+eTmJjYa+9zZ9GnhSO0KpfcLi0tBT0WFHUnJiaG2tparFbvJBwMH4VubYe6s04r9A6rnfO1rU4tvfnCZlLDUkkOTR6gkDiyXcwNcGGPW4c3rFmD0OsJvcHzwdDu3DHuDhraG/j4/MdeWb8rGBo3JoSoJM8HQy9FCEHYnXdgzs3FdPKkV87R1tTIqX27GH/1tWj1nsnV7g1DoJbU6bGcOlBJh8k7yqGjpBlLaQtBs+K9ajwAjJyQRWhsHCc3uzdztLGxkbKyMreyW7qj0qkxjAt3DJB2YsKZ3d5BW9vZPv3nXURHR3s102X4KPSa0yBtfQZEu3Bl2EWtqZYjVUfcyz3viZSFoDG45Xaxt7bStP59Qq67zivB0O7MjJtJckiy14KjZacaaKhsI3N+Yv87e4DQG290BEdfedUr65/c+jE2q5XJS6/3yvrdmXB1ItZ2G6cOeGfmaMs+xxCLgCmeKfTqC6FSMXHhMopzT1JX5vpTR0GBw4ftCYUOjmwXe7OFjuL+dURr21mktBLUh/+8i67pRd7yow8fhd5wwfFvxJh+d02NCUKtEk6lLm4r3oZd2gfubulCF+hQ6gUbwMW86MYNG7C3thLmocrQ/hBCcNvY2zhWfcwrwy+yd5aiD9CQOtX7CgMcwdHQG1bRtGEDVg/Pd7TbbZzY/CEjMiZ6LRjanZjkYKJGBJG90/Ntde1tFkzHqwmYEoPKi7GNS3EER9Wc2OK6lV5QUEBkZOTFTJKBYkiPALVwqsiop6EWvREZGUlycjJarWuDQZxl+Cj0ps6If0j/vli9Rs2YqECnLPTNRZtJCkpibHj/d1+nSb8eGouh4oRLhzW8uQZ9WirGKZM9J0s/3JR6E3q13uNWeltTB2ePVpM+Kx6Nzv02ua4SftfdjspRD88cPXf0EE3VVUxe5hvrHDqDo1cnUlvSQuU5z/axbz3SOcRipveCod0JDAsnZdpMcrZvwWpxPsZkMpk4d+4c6enpHnMNqQwaDKlhDrdLPzfL1pYChNASEDC633W1Wi3333//gAO3vTF8FHpzuaPveKBzTbOcyXRp6mhif/l+Fo9a7Fkf4tjljvRKF9wu5rw8zCdPEna7d4Oh3QnVh7IseRnvn32flg7Ppfzl7SnDbpNeD4Z2xzBuLMZpV1H/2usenTl67OMNBIVHkDJtlsfWdIaxM2LR6tXk7PBccFRKSev+cnQjgtF5oOulK1wMjh5wPsZUWFiI3W73uJI0TojCVt+OpazvWFtLSz6BgamoVN6xul1h+Cj0pnIIjgOVc9ZeelwwJfUmms29WwI7SnZgtVs95z/vIjDKkcKY847Tbpe6V15xVIbe6Pupf6vHrabN2sa7Zzwz/OLSmaHhca6PzBsoEXff7Zg5utMzg4rrK8o4f+wwExctH3CbXFfRGTSMnRnH6cOemznaXtiAtdrk0b4tzjJq4mRCY+M4ttF5YycnJ4fAwECSkpI8KoshIxIEmHL6dru0tJ7qs0LUlwwfhd5cBsHOfwC7eqP3Nexi84XNxBhjmBg1ccDiXcHE2xw90suP9burtb6epvXvE3rDDahDQz0vSz9MjJ5IVlQWr+W/5pHhF8V5dTTVmH0WDO1O8OLFqKOiqH/1NY+sd3zTh6jUaq9VhvbHhPkJ2Cx2CvZ5JjjasrsMVZCWgEnujQAcCEKlYsqylZQV5FJ5tv/5AW1tbZw6dYqJEyc63fvcWdSBWvSjQzFl967QLZYG2tsrCHIiZdEXDB+F3lQOIc4r9P4yXdosbewu3c3CkQtRCS/8mjJvBrUOjr/R764Na9Yi29uJuO9ez8vhJPeMv4cLTRfYVTrwCTPZO0oxBmsZM9n3CgNA6HSE33E7LTt20FFSMqC1LO1mcrZtInX6bIIi+h5G7C2ikoKJHR1Czs7SAQdHLTUmzPl1jr4tAxxi4S4TFixBqzdw9KP+O2Tm5ORgt9uZ5KUiO+OEKKxVJixVbT2+/mnJv6LQPUtzOQQ7749NDDMSrNf0mumyp2wPZpvZ8+6WLozhDl969lqw9Z5HLK1W6l99lYDZs9CnpXlHFidYkryEGGMML+e+PKB1WurNnD9Zy/g5Caj9pDAAR6aQSkXD668PaJ2CPTsxt7YweekKD0nmHhPmJ1Jf0UbZ6YYBrdO6pwzUwquVof2hDwgk89pF5O/eTltjQ5/7njhxgujoaOLiBj50oyeMmY6bdG9uF1cyXHzB8FDo7S3Q3uSShS6EYEJiKEeKek5f23RhE2H6MK6KvcpTUl7JpNXQWg1ntva6S/PmLVgrKoi47z7vyeEEWpWWO9PvZG/5Xs40nHF7ndxdZUj7wGeGDhRtXBzBCxfSsHYd9nb3KmGllBz7+AMik0aSlOEFt5wLpF4Vgz5AQ/YAgqN2s5XWQ5UEZEWjDvZO3xZnmbxsJTarlRN9FBrV1dVRXFzMpEmTvJYooA7VoxsZjCm756rRxqaj6HTR6HS+Sb3tj+Gh0JvLHf+6YKEDzEmJJLe8ifrWy/tHdNg62FGygwUjFqBReTHIlboEjBFwvHdfbt3LL6FNSiLommu8J4eT3Db2NnQqHa/kveLW8VaLjewdpYzMjCQ02uhh6Vwn/J67sTU00PShez3qK86covJsIZOXXu/TzKOe0OjUpM+J58yRaprrzG6t0XqoEtlhI2iuf2+2AJGJI0ieNJVjmzZg66VM/sQJR9rvxInevZkaM6OwlLZg7fZ7lVJSX7+X8PDZfn//uxgeCv1iDrprj4lzUiOREvafu/zuu798Py2WFu+5W7rQ6GDCLY4iI/OVjYDMubmYDh0m/J57EGrf5Wr3RoQhguvHXM/6M+tpbHe+cVEXpw5UYmq2MHnJCC9I5zoBM2eiGzOG+tfcC44e/3gDWoOR8Vcv8LBk7pG1wJHlcWKb63EBaZe07ClDNyoEnZfbMDjLlOtW0Vpfx6kehl9IKTl+/DijR48m1MuJAsYJXW6Xy/VEa1shHR01RIR7dojJQBgeCv2ihe6aQs9KCiNAp2bPmcvfqM1FmwnUBjIr3gc5xVmrwWqG3PeueKnupZcRRiNht97ifTmc5J7x92C2mVl3ep1Lx0kpOba5mMikIJLGeXbqjbsIIQi/6y7Mx09gys5x6di2pkby9+wgY/5C9AFXzq/1ByGRRlKmRpO7s9Tl/i7m/DpsdeZBYZ13MXrSVYTFxXP0wyv/NkpKSqivryfLg+MXe0MTaUQbH3hFtkt9vaORWLii0D1Ml4XuokLXqlXMGB3B7sJP3yiLzcLmC5u5dsS16NQ+8CMmTYOIFDhxebaLtbaWpvffJ/SmG33St8VZxkWMY3rcdF7Lf82lEXVFOXXUl7cyZfGIQfN4ChB6U2d/l9dc6++S88lmbBaL34Oh3Zm8eCQdZhu5u13rld6yuxR1qO5iEHAwIFQqpixfRfnpAsoLL289cfz4cTQaDRkZGT6RxTghio4LTVgbPo231NftwWBIwmgcHE+cMFwUenM56ENA73pV25yUSM5Ut1LZ5PCP7S3fS1NHE8uTl3tayp4RArLuhPM7oeHTiS0Na9YgLRYi7vVfqmJv3DP+HipaK9ha1HswtzvHNhcRGKoj1QtTbwaCOjiY0FWraHr/A6f7u9htNo5v2kBSxgSiRozysoSuEZscQnxqKCe2lmB3sj20paKV9jONBM5OQKgHl0rIvGYxOqORox+9f3Gb1WolOzub9PR09Hq9T+Qwdubkm046eplLaaO+Yf+gss5huCj0JteKii5lToqjmc/eTrfLxvMbCdYGMydhjsfE65eszmZbJx39UqTFQv2rrxE4dy76lBTfyeEk1yZdS2JQotPB0eriZkry65m4IMmvqYq9EXHfvcj2dupfci4l89S+XTRWVTL1Ot9X7TrD5MUjaa4zc+aoc4MUWnaXIbQqAqd7J/VvIOgDAsi8djEFe3bS2uC44Z4+fRqz2ey13POe0EYZ0SYE0nbC8TTf3JyL1dpERLgP9YQTDL6/Lndodq2o6FIy4kMINWrZc6aGdls7W4u2snDkQt+4W7qIGO1oBXD8DZCS5k2bsFZVEe7HQqK+UKvU3J1+N0eqjpBbm9vv/se3FKPRq8m82j+Vof2hT00laNEi6l55BVtL3307pJQceGcNEYkjSPVx3xZnGZ0VRWiMkWObivotNLK1Wmg9WkXAlBjUgf7vRdITU5atxG6zcnyTIxvp+PHjBAYGMmZM/51VPYkxKxpLcTPWOvMl/vPB9RkYHgq9ybWioktRqQSzx0Sy50wtu0t302JpYfloH7lbLiXrzoutAOpeehntyJEEzZ/vezmc5Oa0mwnQBPRrpbc2tHP6YCXj58RjGKQKAyDqoQexNzb2O9Ho3NFDVBedZ8aNtyE8XGruKYRKMHnRCKouNFN+pu9spNYDFWC1D6pgaHfC4xMZPWUaxzdtoKW56WKpv9rHmV8BWQ63S9uJaurr9xIQkIpePzjyz7tw6hMphFguhCgQQhQKIR7v4fVvCSFyhRAnhBBbhBC+cyzabdBS6baFDo70xZJ6E28XbCBMH8bM+JkeFNBJMm8CtQ7T+mcwHT1KxL33DFqFARCsC+bG1Bv58NyH1Jh673VxYlsJ0i6ZtHDwBI56wjhpEgGzZlH3n/9g72WupZSS/W+/SXBUNOlz/V8X0BfjZjtuoMc29T7kW9rstO4tQ58ahjbW903SXGHq8lW0NTaw7f31Xi317wtNhAHtiGBas8upbzg4qNIVu+hXYwgh1MDTwHVABnCXEKJ7aPkoME1KmQWsBX7naUF7paXKManITR86OAKjCAt7KnawaOQitP5og9nZCqD2nW2oAgIIvflm38vgInen343Vbu3VSu8wW8nZWcqYydGDopCoP6IeehBrdTWNb7/T4+uleTmUncpj+qpbfN5V0VW0OjUTrknk3IkaGip77kPSdqwaW1PHoLbOuxiVNYWIhCSyc3O9WurfHwFZUTS3nMRuNw26gCg4Z6HPAAqllGellB3A68CNl+4gpdwmpez61OwDPNvHsi+anR9s0Rsp0UFERp+hw25iWbJ/OuYBmMOuofmcivDr56IOHhzFHX2RHJrMsuRlvJr3KvXmKzNE8veW095mZfIS30zwGSgBs2djmDCB2uefR/ZQnbj/3TUYQ0KZsGCJH6RznQnXJKJSC45vLb7iNWmTNG8tQhsfiGFchB+kcw2hUpG5bBXtai2J4WF+S301ToymLSIPEISH++FJvh+cUeiJwKWfiJLObb3xRaDHWmohxENCiENCiEPV1c5F4Pulyb2iom5yERadC7YgpsVO84xcblDzwQlUWohM9ex4NG/y8KSHMVlN/Dfnv5dtt9slx7cUEzcmhLgxvm/56w5CCCIfehBLURFNGzde9lrluTOcP3aYq1bc6PUB0J4iMFTPuBlx5O8px9xyea/0tqNVWGvNhCwehVANnrqAvmjVGUFKao/t9+hwElfQhOkxJ5zC0JaMVhvmFxn6wqNOWiHEvcA04Pc9vS6lfE5KOU1KOS062kOtU7uqRAdgobdZ2qiTx+lomsD5Gvf6YAwUc34+zR9vIvzasaiLNkJzpV/kcJWUsBSuG30dr+W/Rq3p04rbc8eqaaoxM3nx0LDOuwhevBjdmDHUPvevyzJEDry7Fp0xgEmDrJCoPyYtHoHVYr+saZe02WnaWoQ2MQhDxuC3zgFsNhvHjh8nNjKchgtnObXf+YlGnpXDRFvAKYxV43ptqetPnFHopcClEa2kzm2XIYRYDPwfcIOU0r32de7QVObS6Lme2F6yHatsx9qUdVnVqC+pefppVEFBRH7r52C3wP5/+kUOd3h40sO029ovWulSSo5uKiIkysBoP/U8dxehUhH54IO0FxTQsn07AHVlpZzat4vJS1dgCPTtSLaBEpkQxMjMCE58UoKlwwZA25EqbHVmQhaPHFRVu31x8uRJGhsbWbB0ORGJI9i79lW/WOkNjYeRWAioy6DtuIe8DB7EGYV+EEgTQowWQuiA1cBlzRWEEFOAZ3Eo8yrPi9kHza6NnuuJj859RLQxmnjD+Cv6uvgCc24uzZs2E/H5z6MePQkyboSDz/fYsGswMjp0NNePvp7X81+nxlTDuWM1VJ5rYuqyUaiGyOP8pYSuvB5NQjy1z/0LgIPvrUOj0TJ1xY39HDk4uWp5MqamDk5sLUZa7TRtKUKbFOSYbD8EsNvt7Nq1i5iYGMaNG8fs2+6itqSIgn0DH7biKvX1exFCQ2jINEwnqgc8UMTT9KvQpZRW4GvARiAPeFNKmSOEeFII0VUq93sgCFgjhDgmhLiym463GECVKEBLRwu7SnexNHkp81Ji2He2Fpvdt29S9d+fRhUSQsTnP+fYMO+bjv7uB//tUzkGwpcnfRmL3cILJ/7D3nfOEB4XwPg5/huSMBCEVkvkA1/AdOQIVdu2kLtjK5kLlhAYNjiairlKQloYyVlRHPnoAg17yrA1tBO6ZNSQsc4LCgqoqalh3rx5CCEYN2sekUkj2bvmVex2m09lqa/fS0jIJIKzRmCtNmGpGFxuF6d86FLKDVLKsVLKFCnlLzu3PSGlfK/z+8VSylgp5eTOL9/VRA+gShRgW/E2OuwdLE9ezuyUSJrMVnLLmjwoYN+YsnNo2bqViPs//2kTrvhJkLII9v0TLCafyTIQRoWMYuWYlRzfcYGGyjZm3ZSCapD1BXGFsNtuRR0Rwb4XnkNKO9NXDZ6Ol+4w+6YUbO02GjddQDcyGP3YoXFzklKya9cuwsPDyczMBBxusTm3301dWQkFezwz6NsZrNZmmppOEh4+G+OEKMcA6RODy+0ydP/iuhhAlSg4erfEBsSSFZ3F7BRHp7k9Z3znR6/5299QhYYS8bnPXf7C1d9yTDM6OrCRb77ki+kPMrloMdbYZkZPivK3OANCZTRiXH0nZ03NpGVOJjRmcDUVc5WIhEBmpIejsdhRT48bMtb5+fPnKS0tZc6cOZdVhqbNmEP0yGT2rn0Nu803Vnp9wwHATkT4bNRBOvQpYYPO7TK0FXp7M3Q0u22hN7Y3srtsN8uSl6ESKmKCDaTFBPnMj246cYKW7duJfOAB1EHdgm2j5kLSdNjzVJ8zRwcT1fvsBFhC+DDmRarafBtK8QY5woJdJRiVe3pQ/dG6g7TYiW1pp84mOXxscFmVfbFz504CAwOZPHnyZduFSsXs2+6mvryU/N3bfSJLff1eVCo9ISFTAEcrAGutGUtZ3/1/fMnQVuhN7o2e62Jr0VasdutlrXLnpERy4FwdHVbvR9Cr//Z31GFhhPfUIlcImPctaCiCnLe8LstAaWvq4OimIhImBlEZfI5/nxw6/v+eKC8sIGf3J2SOzUR75BhN77/f/0GDmNaDFchmC7asaE4frqbqgu/ciu5SVlbG2bNnmT17NlrtldXbqdNnEZ08hr3rfGOl19ftITT0KtRqR8te44RIUAnaBpHbZWgr9Gb3Rs918dH5j0gMSmRC1ISL22anRGGy2Dhe0uABAXun7ehRWnfuJOILX0Ad1EsfjbHLIXo87Poz+KmQwlkOvn8Ou8XOgtsmcFPaTaw7vY6K1gp/i+UW0m5n6wvPEBgaxjWPP4Fh4kSqfvf7fjsxDlakxUbTtmJ0o0PIuDUVQ5CWPesKB/1Tx65du9Dr9Uyb1nOxn1CpmHPb3TRUlJO7c5tXZenoqKGlteCy/i2qAC2GtDBMx6uRPk6k6I0hrtA7FYYbFnpZSxl7y/Zy/ZjLB/zOHhOJELCn0HtuFykl1X/+C+rwcCLuubv3HVUqmPcNqMqF0x97TZ6BUl/RSs6uMjKuTiAsNoCHJj6ERPL3o3/3t2hukb19MxVnTjP/ngcwBAUR9+MfYa2upuaf//C3aG7RsqcMe3MHoUtGoQ/QMv36ZEpPNXChl0n2g4Gamhpyc3OZPn06BkPvlbkp02YSMzqFvWtfw9LuvaLA+vr9AIR3638eMCUGW0M77WcavHZuVxjaCt3N4dDAxZmYt6bdetn20AAtExJC2e3FwGjjunW0HThA9GNfRxXYT5e7CbdC6EjY9ScYpBbVvnfPotGqmH79aADig+K5L+M+3j3zLvvL9/tZOtcwt7aw89UXSRiXcXH4szEri9Bbb6Huxf/RfvasnyV0DWutiabNRRjGR6AfEwZA5tWJhEQb2fv2GeyDxLLszu7du9FoNMya1Xe/cSEE1973RZqqK9mzxrUxgq5QV78HtTqI4OAJl203TohCFaBxtCEeBAxthd5cDvpQ0LnW+tNit/DW6beYlziPhKArrfsF46I5dL6O0gbPpwxaqqqo/O3vCJg2jbA77uj/ALUW5n4divfDBf+UO/dF+ZlGzh6tZsrSkQSEfDoU5KuTvsrI4JH8dM9PMVmHRuolwJ41r2BqbmLhA1++7Mkt5lvfQmU0UvmLXw56V0UXUkrq3zoNKkH4TakXt6s1KmbdOIa6slYK9pX7UcKeaWxs5Pjx40yZMoWg7skCPTAiM4uJi5Zx+P13qDhz2uPy2GztVFdvJDLialSqy7tsCo2KgKtiMeXUYmvuue2yLxnaCr2pzC3rfHvxdmpMNdwxrmeFesf0EUjgtf2995J2l8qf/wLZ3k7cz590vt/55HsgIMrhSx9ESCnZ+1YhASE6Ji26vN+5QWPgp3N+SklLCf84NjRcFdVF5zm28QMmLb6O2NGXj/7TREYS/eijtO7ZQ/PmzX6S0DXaDlXSfqaR0BWjUYdePnsz9aoYYkYFs/+9cxdbAgwW9u7di5SSOXOcH+82/54HCAgL4+Nn/oqth06ZA6Gq+kMslnoSE+/q8fXAGXFgl7Qe8r+VPrQVenO5W1Wia06tITYglnmJ83p8PSk8gIXjYnj9YLFHs12aPv6Y5k2biPra19CPHu38gboAmPUVKNwEF/Z6TJ6Bkr29lPIzjcxYNRqd4cr+4NPjpnNr2q38L/d/5NTk+EFC55FSsvU/z6APCGTunT2P/gu/+y70aWlU/fo32M3+aeLmLLamdho+OItudEiPs0KFEMy9LY3Whnb2vn3GDxL2TENDA4cPH2bixImEhztf/GQIDGLRF79CddF5Dq33bFZYaekrGI3JvfY/10YHoE8JpfVAhd+Do0NboTeVu9xlsbi5mD1le7g17VY0qt6HFNw7axQ1Le18nOuZu66tsZGKn/8c/fjxRD5wv+sLzPqKw5e+/jGw+q73WW/Ulbeye10hIzMjyJjX+3vwrWnfIsoQxRN7nsBit/S6n78p2LODktxs5q3+HMbgkB73ERoNsT/+EZayMmr/NbjTMuvfPYO0SsJvSeu1PW5CWhhZC5M4ua2ECzn+D5BKKfnggw8AWLBggcvHp02fzdhZ89i77jXqyko8IlNzSz6NjUdISrwbIXpXl4Ez47HVt2M+7d/W10NXoXeNnnPRQl93ah1qoeaWtL5LueePjSYp3MjL+y4MRMqLVP7+99jq6on/xc8RPeTU9osuEFb+2TF31M+uF5vVzqYXctDq1Sz83Pg+qw5DdCH836z/41T9Kf6T/R8fSuk8HWYT219+gZjRKUxctLTPfQNnzCBkxQpq//1vOko8ozQ8TdvJGsw5tYQsHok2OqDPfWffnEJEQiBbXszD5GcfcE5ODqdPn2bhwoUuWeeXsvCBL6PV6fn42ac80o2xtPQVVCo98fG39rmfMSMSVZCW1v3+dbsMXYXeNXrOBR+6xWbh7cK3mZ80n9jAvku51SrB3TNHsu9sHYVVzQMStXXvXhrXriPyCw9g7OxH4RZpi2Hi7bDzj1BdMCCZBsL+985SU9zCwvvSCezmm+2JhSMXsnTUUp45/gxnGwdflsi2/z5HS10tCx94GJUTXTtjvvddUKspf/wHSMvgeuqwt1loeLcQbUIgwVf3PzhMo1Wz5AuZtLdZ2PpSvt8Cvm1tbXz44YckJCQwc6b7k4ACw8K55nNfojQ/l+Obepyz4zRWawsVFe8SG3N9v8MshEZF4LRYzPm12Br99wQ9dBV6V1GRCznoW4q3UGeu4/axtzu1/x3TRqBVC17e535w1G4yUf7ET9CNGkXUI4+4vc5Flv3aYa2/93W/FBuVFtRzdFMRGVcnMHqS873OfzDzBxg1Rn6656fY5eApkjqxZSPZ2zYx8+Y7SRw33qljtHFxxP/0J7QdOkTVnwZXoLrhg3PY2yyE3zoWoXauX0tUUhCzb0rh/IkacneVeVnCntm0aRNtbW2sWrUK1QCHo2des4hRWVPY8ep/aapxv4qzouJdbLZWEhPvcWr/wOlxYHdU5fqLoavQu8r+XbDQ1xasJTEokTkJzkXPo4L0XDchnnVHSmjrcC9yXv3U37AUFxP38ydR9VEg4TRB0bD0l1C8Dw771oVhbrWw+b+5hMUEMO+2NJeOjTJG8b3p3+No1VHeKHjDSxK6RuXZQrb+5xlGZU1hzh19FHj1QOgNNxB+913U/ec/NH20sf8DfID5dD1thysJnp+ELtG1QRyTFo4gKT2cXWtO9zpU2lucO3eOo0ePMmfOHOLjB95yWQjBkge/hpR2tjz/D7eeOqSUlJa+QnBQJiEhk5w6RhNpRJ8W5mizYPPPk87QVejNrvVxudB0gf0V+7k17VbULgzDuHfWKJrNVtYfd91yafr4Y+r++1/C7ryTwBkzXD6+VybfDaOvgc0//bS4ystIKdn+WgFtjR0s+UIGWr3rA0VuSLmBuQlz+eOhP3K8+rgXpHQeU3MT7/3pVwSEhLHi0e845WrpTszjj2OYlEX5D3/o94Ija72ZujcK0EQZCVnk+tg/oRIsvj8DtVbFphdysNl88xRlsVhYv3494eHhXHPNNR5bNzQmlqtXf46zRw5y4N21Lh/f2HiYltYCEhPvdqkzZdDMeGyNHZgL6lw+pycYugq9qQxUGqdHz609tRaN0HBz2s0unWZ6cjhjY4NcdruYTpyg7Hvfx5iVRewPHnfp2H4RwhEgtXXAhu96du1eOHWgksJDVUxfNZqYUT1ngfSHEIJfXf0rYgJi+PrWr1PS7J+got1uY8Pf/0hrfR2rvvU4ASHuDbFW6XQk/eUvCL2ekke/jr3VP71e7GYrNf/NQVrtRH4uA6F1b3pXYJieBfemU3WhmYPrz3lYyp7Zvn07dXV1rFy5Ep1O1/8BLjDluhtIn3sNu157kYK9rvVNLy19FbU6iLg410Y7GMZHoArW+a1ydOgq9OZyCIpz9Dvph3ZbO+8UvsOCkQuIMrrWp1sIwb2zRnGytJHjxQ1OHdNRUkrxV76KJiqKpH887RlXS3ciU+DaxyH/fchb7/n1L6Ghso0drxUQnxrK1GWjBrRWhCGCpxc9jdVu5atbvkpju+/H7O1b9zrnjx1mwf0PEZ86bkBraePjSfzTH+k4d47yH//Y50FFabNT+0oe1moTkfdmoI3pO6ulP1KmxDB+TjyHN16gON+7VmZFRQV79uxh0qRJpKSk9H+AiwghWPbwYySmZ/Dh03+i7FSeU8d1dNRSWfUh8fE3o1a79vsUahWB02MxF9Rhrfd9rcLQVeguVIluvrCZhvYGp4Oh3bl5SiIBOrVTKYy2piaKH/4y0mJhxLPPoImMdOucTjH7axA70WGle2n+aFOtiXf/chS1VsXi+zM8MiN0dOho/rLgLxQ3F/PtT76Nxea7TJFzRw+xd93rZF6ziKzF13lkzcDZs4n+xjdo2vAh9S+95JE1nUFKScM7Z2g/3UD4LakYUsM8su68O9IIjwvkw3+epOKsdz5Xdrud9evXYzAYWLq071TRgaDR6bjh2/9HcGQU7/zu5zRU9m85l5evRcoOEhNci6t00VXI5Y/g6NBV6C5Uia45tYYRwSOYGe9eOlSwQcuNkxNZf6KMxrbelY+0WCj9xjfoOH+BpKeeQu8Fq+My1Fq44a+OFM4194PVs3nErQ3tvPuXY1jabdzw2GRCooweW3t63HSenPMk+yv28+S+J31i2TZWVbLhb38gemQyi774FY9O7Yl88EsELVpE5e9+T9uRIx5bty9adpTQerCC4AUjCJx2ZTWou+gMGm58bDLGEB3v//041cUDS9vtjpSSDRs2UFpayvLlywnsr0HdAAkICeWWx3+KlJK3fvNTzC0tfchmp7T0dcLCZhAUNNat82nCDRjGhtN6sBLpo1hEF0NXoTtZJXqw4iCHKw9zx9g7UPVR6dUf984aidliZ+2Rnv2+UkrKf/YzWvfsJf7JJwmc5X4urUskXgWr/gJntsK7j3gsldHU3MG7fz2GqamDlY9OIiop2CPrXsqqlFV8ZdJXeKfwHa8PxGisqmDNL/4PKSU3fOuHaPWedYMJIUj4za/RJiZQ/JWvYjp2zKPrd6ftZDWNH57HOCmakCUDc4P1RGCYnhu/MRmtXs36p45RV+65+MCOHTs4dOgQc+bMISsry2Pr9kV4fCI3fuf/aKqq4L0//hKbtWfDrK5uJyZzEYmJ7lnnXQTOTsDe3OFzK31oKvSu0XP9WOhWu5VfH/g1CYEJrE5fPaBTZiaEMmVkGK/sv9Bjy9Haf//bUTz0lYcJu8W1wOuAmfo5WPhjOPkmfPyjAbfZbW+z8N5Tx2iqMXH9I1nEjXYvaOgMX5n0FVaOWclTR5/iw3MDKwTpjdqSIl5/4nu0t7Rw6w+fJCxu4KlxPaEODmbUCy+gDgvlwhe+SOte7/TdaS9qou6NU+hGhRBx29heS/sHSkikkRu/MQWE4L2/HKWxeuDpjIcOHWLbtm1MmjSJxYsXe0BK50kaP4FlDz9Gce5JNj339x6fCktKX0WrjSQmetmAzmUYF45udChNH1/A3sdTvacZmgr9Yg563xb62lNrOV1/mu9O/y4GzcAtsgfmjuZsdSvP7fw0RU1KSc0zz1L9xz8RsmIF0V//+oDP4xZXfxtmfBn2Pe2YQ+omHWYr6/92nLqyVq57eCKJXp4OL4TgZ3N+xtSYqfxw1w95t/Bdj65fceY0r//0caSU3PnT3xCfNrAgaH9oExNJfvlldElJFD/0ZY93ZjQXNlDznxzUIToi7xuP0Hr3TzgsNoAbH5uM1Wrn3T8fo7nO/UBfXl4eH3zwAampqdxwww0DLiByh/FXL2D2bXeTs30LHz/7t8ss9erqTdTUbCYp8W5UqoFl3AghCLshBbvJSuMmz7QPcYahqdAvVon2bmk1mBv429G/MTNuJotGLvLIaVdlxbNiYhy/31jA4Qt12NvbKfve96n+y18IWbmS+F//yn/T1IWA5b+BzJth0xNw7DWXl7B22NjwzxNUXWhm2ZcmMCrTiwHdS9CpdTy18Cmuir2KH+3+EX86/Cds9oG3dC3OPcman/8QncHI6p/9jqiRyQMX1gk00dGM+t+LGDIyKHnsGzS+65mbVMv+cmpeyEYdrCP6SxNRB3k2za83IhODuOHrkx1Pbn89RluT67Ga8+fPs3btWhISErjjjjtQq91LrfQEs2+7i5k330n2to9Z+4sf09bUiMlUSm7e9wgOnkBy8lc8ch5dfCCBM+Np3VeOpcI3Ka1DU6E7YaH//djfabW08v0Z3/eYkhVC8Jtbs0gMM/J/z2/n7L2fo2n9eqK/8RgJv/8dKn3/fU28ikoFNz/rKDp69xE45fzYuoaqNt76wxFKTzWw6PPjGTPF+bJ+TxCqD+Wfi//JHWPv4D/Z/+Ebn3yDVov7fwRnjxzkrV/9hKCIKFY/+VuvuVl6Qx0WxsgXnidgxnTKvv84dS+/4vZa0iZpeO8MDW8XYkgLI+ark9BEeCEVtg9iRoVw/dcm0VJvZu1vDrmU/VJZWclrr71GeHg499xzj8fzzV1FCMG81fex4tHvUF5YwKs//ibHjj6MlHYmZD6FSuW5v+OQJaNQGTU0vHfGJ4H/oanQ+7HQ8+vyWXNqDavTV5MW7lqJen+EGLQ8PSOIH67/HW35+ST89S9EPfyw/yzz7mj0cOfLEJsJaz4P53f3e8ipAxW8+cuDNNWYuO7LExk303MZE66gVWn50awf8YMZP2BHyQ7u+/A+ylpcq4SVUpKzfQvv/uEXRI4YyZ0//Q3BEa7VHngKVWAgI555xpH98otfUP23vyNdnE5vN1mp+W82LXvKCJqXSOTnM1H10HveFySkhnHTt6YiVPDWH45w+KPz/fb/rqmp4eWXX0an03HvvfcSEDCwPHlPMn7etdz5k98QOvYUbeZcIg0PEhDg2QCzOlBLyNJRtJ9txHTSe2MtuxiaCr2pHAyhjsEP3ZBS8uv9vyZUF8pXJnnm0elSmjdvRvvNLxNqUPPNuV/lTaNnbxgewRAC965zPMG8uAq2/97RbrgblnYbW/+Xx6YXcolKCuLOH81gzGTfWubdEUJw9/i7+eeif1LRUsFdH9zFsapjTh3bUlfLe3/8JR/9488kjBvP7T/+ldtVoJ5CpdeT9Ne/EHrjjdQ8/TQX7r6H9tPOjUmz1pio+scx2s80En5rGmErx3gtAOossckh3PF/js/JvnfOsv5vPbtgpJQcO3aMZ599FqvVyr333ktYWJjvBe4HbXgpEePLaSkaxaY/f8zhD971uCUdOCMebXwgjR+cw+7l6VBDU6E3l/faw2Xj+Y0cqTrCo1MfJVTvuT9ma20t5T/7GSWPfh19WhoZ77xF2txp/PajfI4U+bepfY8ExcCDW2HCLbDtF/DfldBQfPHl2tIW1vz6IHl7y5m2IpmbvjWFYB8/xvfFnMQ5vHz9ywRpg/jCxi/w1JGnenXBSCk5seUj/vvtr3L+2BHm3/MAt//ol+gHiTUoNBrif/NrEn73WzouXODsLbdS/fenkR09+6KlzU7L7lIq/34Me6uF6C9N6HHqkL/QGzUsezCTa+8ZR1lhI6//4gDFeZ9WlZpMJtatW8c777xDQkICDz/8MLGxfber9gdmcxk5ud8lKCiD5Xe8Tcq0mXzyv3/x3h9/SX2F53okCZUgbFUKtsZ2mrd7t92F8Ff/42nTpslDhw65d/BzC8AYBve9fdnmNksbN7xzAxGGCF67/jWXmnD1hr29nboX/0fts89ib28n/K67iPn2t1AZDDSaLFz/1E6khA++Po+wAP/6Bnvl+OvwwbdBpcay/ClOVk3hwPpz6I0aFn8hgxHpEf6WsFca2xv51f5fseHcBiINkTwy5RFuTr354rSp+ooyNj37N4pzTzIiYyJLvvwo4XGuTbHyJda6Oip/+SuaPvgAfVoq8b/4BcZJjm5+UkrMuXU0fngOa40JfWoY4Tenoon0XEGXp6ktbWHjv3Oor2hl0sIRxE5U8f6H79HU1MSCBQuYN2+eX7JZ+sNut3Dk6N20tJxixvR3CAgYjbTbObj+Lfatex2b1crkZdcz69bVGIM8U4NR+2oeptw64r511YBiIEKIw1LKaT2+NiQV+h/TIWUR3PT0ZZv/dvRvPHfiOf533f+YEjNlQPJJu52mDzZQ9ec/YS0rJ2jhQmK+8x30Yy6fBXq8uIHbntnDNWNj+Nfnrho8vvRutJee5uTzL3G8fCpmGcKozDAWfn4CASGD9CbUjZPVJ/n9od9ztOooqWGpfCPjEQzZdexb9zpqrZb5936BiQuXDtrff3eaP/mEip89ibWigvB77yVk1T207G2k41wjmhgjoSvGYBgXPiSux9JhY+ebBRw6tp+2wAsYdIHccvMtjM3wcqX0ACgs/B0Xip5lQuZfiY1dedlrrQ317H7zZbK3bkIfEMCsW+9i8rIVqDVuTBq7BGtDO5V/PIRhXDiR92a4vc7wUug2K/wi2pF3vfBHFzfvKNnBN7d9kyXJS/jN1b9xWy57RwetO3dS88yzmE+exJCRQcz3v0/gzN7b3z6/6xw/fz+XGaMjeGJlBhMS/eu3vZS2pg6Obynm5PYSLGYbo+LrmNb+O+IiGuCq+x1fLs5l9Rd2u531u19hx/uvE1Mk0dhVRGSN4+Yvf5+wqBh/i+cy1uYWqv/wb8ynO9CMmAmyg4AsA+F3zkHlZsdEX2MymTh27BiHDh2itraWmMBR2M8noUZD+ux4pi4bSWg/Y/B8iclUQuGZ31JVtYHEhLtIT/9Fr/tWF51nx8svcP74EcLi4pl1y2pSp88ekCuvaUsRTZsuEPWlCRhS3avxGF4KvakM/jQerv8TTP8iNaYafnvgt3x0/iNSw1J5bslzRAe4FtiTHR207t1L04YPad6yBXtLC5rYWKK/+Q1Cb7gB0c8jo5SSVw8U8cePT1Hf1sFtU5P47rJxxIT4xyfdYbZSeqqB8ydrOLWvAqvVTurUGKYuH0X0iGC4sNcxxq5wMwgVjF8J0x+E5HmOfPZBRoepjbxd2zm++UOqz59FqzegnpDAB8HHKA6oJ8IQwZJRS1iWvIypMVM94mrzFlJKLGWtmE5U03ayBludGdSg0pXRsvlZbNXlaEeMIOyO2wm75RbvNncbAOXl5Rw8eJCTJ09isVhISkpizpw5ZGRk0FRj4ujHReTtKcdus5NyVQxjJkUzYnwEhqCBWbnuYrU2c/7CMxQXvwCoGTXqIZJHPexUAdG5Y4fZ/tLz1JYUodZqGT15GuNmzyPlqploXeykKi12ql/IJmTBCAxuFu0NWKELIZYDfwXUwL+llL/p9roe+B9wFVAL3CmlPN/Xmm4r9JLD8O+FyNWv8Y66nT8c+gMmq4mHsh7iixO+iFbd/wdG2u1YSkowFxTQ8sknNG/egr2xEVVwMMGLFxOy4joCZ81yeZhzo8nC09sK+c/uc2jVKr56bQpfunoMBi9bW9IuqSltoSinluLcOsrPNGK3STQ6FalXxTB12SjC43pogFR3Fg69AEdfBlM9RKfDlHshaQbETXCMuvMDppZmyk/nU34qn7JT+ZSdzsfa3k70yGQmLV1B+txr0QcEYLKa2FW6i4/OfcSOkh2YbWaijdEsGbWEuYlzSQtLIy4wzu9uC1tzB5bKVtrPOFLXrDUmUIE+NZyArCjHgOEALfaODpo3baLh9TdoO3gQtFqMmZkYJ092fE2ZjNZPwUWr1UpVVRVlZWUcP36c4uJiNBoNEydOZPr06SQkXPmU19rYzrHNxeTtKaO91QoCYkYGMzIzkhEZEcSNDkGl9q5/XUobZeVrOXv2T3R01BAXdxMpY76DweBaXYK02yk7lU/Bvp2c2reb1vo6NDo9Y6ZOJ3XaTKKTxxAen4ha4/2U0gEpdCGEGjgFLAFKgIPAXVLK3Ev2+SqQJaV8WAixGrhZSnlnX+u6rdDz1nNh3f08mbWIA/V5TI2Zyk/m/IQxoWMu7iI7OrA1N2NrbMLe3IStoYH2c+doP32a9lOnaS8sRJpMgCNXOGjRQkKuu47AuXNReaDo4XxNK7/+MI+NOZUkhhlZlhnHiAgjSeEBjIgwMiI8gEC9c2+8lBK7TWLtsNHeZqW51kxTrYmmGjNNNSaaakw0VJowtzpKmCOTghiZEcHIjAjiU8JQO1MabjFB9jo48C8oP+bYJlQQNRbiJ0H8ZIeCD4hypETqQ0AX5FQv+p6wWa20NTbQ2lB/yVcdjZUVlJ0uoL6spFMEFdEjR5MwLp3x8xYQnzauV+XcZmlje8l2Np7fyM6SnXTYHRkkwdpgUsNTSQ1LJS08jVHBowjRhxCsCyZEF0KQLgityn2rUdol0mzFbrJiN9uwmyzY6tqxVLRiqWzFUtGGvfO9QYA+JQxjVhTGzCjUgb2ft/3MGRrfeYe2w0cwZ2dfzIjRxMdjnDwJ/egxaGKi0URFoYmKQh0VjSY6yu3iNiklFosFs9mM2WzGZDJRVVVFeXk55eXlVFZWYu9s/BYREcH06dOZPHkyRmP/AVu7XVJ1oYni3DqKcuqoPNeIlKA1qAmPDSA40khotMHxb5SR4CgDhkAtGp0KtUbl9A3ZZmvHbC7BbC7BZCrBZC6mrm4nLS35hIZexdi0HxESMvBmYHa7jdL8XAr27OTU/t2YmhxFVmqNhoiEJCJHjCJqZDKRSSMxBodgCAxCHxiIITAIjQf0y0AV+mzgp1LKZZ0//wBASvnrS/bZ2LnPXiGEBqgAomUfi7ur0Nf+9X6MY066fNxnAU85zwaf08V9vOlQFP38pmTnf3T9XwxAGglCOt6brn972c01BEgEshelKaREZbc5vmw2VHY7qgEO+ZYI7Co9UqVDCjVSaJCir6dYCVIiOn+Xn15858+AStuBJuDyNr/SpqajMYrGk9fQeiETb3yypbRjl43Y7A3YZCN2eyM22YCUvTUyUyHQERwVw4NP/8Otc/al0J0xExOB4kt+LgG694a9uI+U0iqEaAQigctKo4QQDwEPAYwc6frcQwC13YClxdU0O3HZP37Bk5rF59che/hWuiZGDzuLfl73BrLHf698c/p/uz5V0pf9JyQSO3bh5T7YXQpegko6FG/Xzxdfv2TfLgRXbnQca+/8+vR7lc2K6pKCNAnYAJtHylc6Or86b1KAFFqk0HV+qXGUyaiQ4pJ/ZdcVXPKvBLtNg7UlGGtLSOdXMLa2wIv7CSo9IPOVCEAlQKM2AkbAUS8gpRWbbENKCxIrUlov+deCPsS1Id7O4tMaYinlc8Bz4LDQ3Vnj5m8+41GZFBQUFIYLztxqS4ERl/yc1Lmtx306XS6hOIKjCgoKCgo+whmFfhBIE0KMFkLogNXAe932eQ/4fOf3twFb+/KfKygoKCh4nn5dLp0+8a8BG3GkLb4gpcwRQjwJHJJSvgc8D7wkhCgE6nAofQUFBQUFH+KUD11KuQHY0G3bE5d8bwZu96xoCgoKCgquMPi65igoKCgouIWi0BUUFBSGCYpCV1BQUBgmKApdQUFBYZjgt26LQohq4IKbh0fRrQr1M8Jn9brhs3vtynV/tnDmukdJKXtsKes3hT4QhBCHeutlMJz5rF43fHavXbnuzxYDvW7F5aKgoKAwTFAUuoKCgsIwYagq9Of8LYCf+KxeN3x2r1257s8WA7ruIelDV1BQUFC4kqFqoSsoKCgodENR6AoKCgrDhEGt0IUQy4UQBUKIQiHE4z28rhdCvNH5+n4hRLIfxPQ4Tlz3t4QQuUKIE0KILUKIUf6Q09P0d92X7HerEEIKIYZFWpsz1y2EuKPzPc8RQrzqaxm9hROf9ZFCiG1CiKOdn/cV/pDTkwghXhBCVAkhsnt5XQghnur8nZwQQkx1enEp5aD8wtGq9wwwBtABx4GMbvt8FXim8/vVwBv+lttH170ACOj8/iuflevu3C8Y2AHsA6b5W24fvd9pwFEgvPPnGH/L7cNrfw74Suf3GcB5f8vtgeueD0wFsnt5fQXwIY4Jd7OA/c6uPZgt9BlAoZTyrJSyA3gduLHbPjcCL3Z+vxZYJJwdET546fe6pZTb5KdTaPfhmCI11HHm/Qb4OfBbwOxL4byIM9f9IPC0lLIeQEpZ5WMZvYUz1y6BkM7vQ4EyH8rnFaSUO3DMjeiNG4H/SQf7gDAhRLwzaw9mhd7TcOrE3vaRUlqBruHUQxlnrvtSvojjbj7U6fe6Ox89R0gpP/ClYF7Gmfd7LDBWCLFbCLFPCLHcZ9J5F2eu/afAvUKIEhwzGR71jWh+xVUdcBGfDolW8CxCiHuBacA1/pbF2wghVMCfgPv9LIo/0OBwu1yL42lshxBiopSywZ9C+Yi7gP9KKf8ohJiNYzLaBCml3d+CDUYGs4X+WR1O7cx1I4RYDPwfcIOUst1HsnmT/q47GJgAfCKEOI/Dt/jeMAiMOvN+lwDvSSktUspzwCkcCn6o48y1fxF4E0BKuRcw4GhgNZxxSgf0xGBW6J/V4dT9XrcQYgrwLA5lPlz8qX1et5SyUUoZJaVMllIm44gd3CClPOQfcT2GM5/zd3BY5wghonC4YM76UEZv4cy1FwGLAIQQ43Eo9GqfSul73gM+15ntMgtolFKWO3WkvyO+/USDV+CwRs4A/9e57Ukcf8jgeHPXAIXAAWCMv2X20XVvBiqBY51f7/lbZl9cd7d9P2EYZLk4+X4LHO6mXOAksNrfMvvw2jOA3TgyYI4BS/0tsweu+TWgHLDgePr6IvAw8PAl7/fTnb+Tk658zpXSfwUFBYVhwmB2uSgoKCgouICi0BUUFBSGCYpCV1BQUBgmKApdQUFBYZigKHQFBQWFYYKi0BUUFBSGCYpCV1BQUBgm/D+M4k1KpM8vwQAAAABJRU5ErkJggg==", - "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-31T15:45:02.696041\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.2, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 50, - "source": [ - "\r\n", - "ts = np.linspace(0,1)\r\n", - "points = []\r\n", - "for t in ts:\r\n", - " points.append(bs.DeBoor(t))\r\n", - "points = np.array(points)\r\n", - "plt.plot(points[:,0],points[:,1])\r\n", - "plt.plot(x,y,'k--',label='Control polygon',marker='o',markerfacecolor='red')\r\n", - "out = interpolate.splev(ts,[knots,[x,y],3])\r\n", - "# plt.plot(out[0],out[1],'b',linewidth=2.0,label='B-spline curve')" - ], - "outputs": [ - { - "output_type": "display_data", - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAABSF0lEQVR4nO3dd3hUxfrA8e+kF1IpCUlIQgst9NDLFUQE5apgQynyAwG9CggIoogKl4go2OUKCggaQEUEARHBhF5DSQIEQkujJEB6T3bn98eGCNLJ7p5sMp/n2SfZs7sz78LZdydzpggpJYqiKIrlstI6AEVRFKV8VCJXFEWxcCqRK4qiWDiVyBVFUSycSuSKoigWzkaLSmvUqCEDAwO1qFpRFMViHThw4LKUsuY/j2uSyAMDA4mMjNSiakVRFIslhEi42XHVtaIoimLhVCJXFEWxcCqRK4qiWDiVyBVFUSycSuSKoigWzmiJXAhhLYQ4JIRYZ6wytbA8LIzgwECsrawIDgxkeViY1iEpimJCleEzb8zhh+OAWMDViGWa1fKwMKaOGsXCvDy6AjsSEhgxahQAzw0apG1wiqIYXWX5zAtjLGMrhPADlgChwAQpZb/bPT8kJERWxHHkwYGBfJGQQI9rjkUAYwICOBIfr1FUiqKYiqV95oUQB6SUITccN1IiXwnMAlyA12+WyIUQo4BRAP7+/m0TEm46rl1T1lZWFEiJ7TXHigEHIdDp9VqFpSiKiVjaZ/5WibzcfeRCiH5AqpTywO2eJ6VcIKUMkVKG1Kx5wwzTCqGJvz87/nFsBxBYowZqAw5FqTwKCgqYOXMmznDTz3wTf38Norp/xrjY2QV4TAgRD6wAegohfjBCuWY3NTSUQUIQgeFbOQIYJARnLl2iT58+nD17VuMIFUUpr9WrV9O0aVOmTZtG03btGO7oeN1nfoSTE1NDQzWO8t6UO5FLKd+UUvpJKQOBgUC4lHJwuSPTwIMPPcQFKRnq7o6DEIwJCGD2d9/x2WefERMTg5WVGq2pKJZu0aJFODs7Ex4ezp69e3n/m28YExCAA/AYMPmjjyzqQieoceTX2bJlCwC/bNyITq/nSHw8Q4YOZezYscTHxxMQEICUksGDB7No0SL0FbAPTVGU62VkZDBhwgROnToFwOLFizl06BA9ehgucT43aBBH4uOJPnKEHEBngd2oRk3kUsotdxqxUpGFh4fj6upKmzZtbnjMzs4OgKysLOLj4xkxYgQdOnRg9+7d5g5TUZS7oNPp+PbbbwkKCuLTTz/lr7/+AqB69erY2Nw48rpZs2Y0a9aMH3/80dyhlptqkV9jx44ddO/e/ab/yVe5ubmxfft2wsLCOH/+PJ07d2bo0KFcuXLFjJEqinI7u3btokOHDowcOZJGjRpx4MABRo8efcfXvfjii9SvXx+dTmeGKI1Hk/XIK6q9e/feVUIWQvD888/z2GOP8f7777N8+fKyFruiKNr78ccfuXjxIsuXL+fZZ59FCHFXr3vttddMG5iJGGUc+b2qqBOC7ldhYSH29vYUFxfz5JNPMnr0aB599FGtw1KUKqOwsJBPPvmELl260K1bN7Kzs7GyssLZ2fmey5JScvLkSYKCgkwQafmYbBx5ZTF79mzmzJlzX6+1t7cHIDk5mbi4OPr168ejjz5KXFycMUNUFOUfpJSsXbuWZs2a8eabb7JunWGpJxcXl/tK4gALFiygUaNGnDlzxpihmpRK5BhOhnnz5rFnz55ylVO3bl2io6OZO3cuO3bsIDg4mMmTJ1NQUGCkSBVFuer48eP07duXxx57DDs7O/78809mz55d7nL79OkDwE8//VTussxFJXLg7NmzJCYmlg1HKg87OzsmTJhAXFwcQ4YMYfPmzdja2t75hYqi3JM//viD3bt388knnxAVFcVDDz1klHIDAgLo1KkTK1asMEp55qASOYZhhwA9e/Y0WpleXl4sXLiQXbt2YW1tTXp6Oo8++ij79+83Wh2KUpXo9XoWL17MypUrAXjllVc4efIkr732mtEbSwMHDiQqKorjx48btVxTUYkciIiIwNvbm8aNGxu9bAcHBwDi4uI4ePAg7du3Z8SIEaSkpBi9LkWprPbu3UunTp0YPnw4y5YtA8DW1pZatWqZpL6nnnoKIYTFjClXiRzDCfHvf//7roco3Y8OHToQFxfH5MmT+f777wkKCmLu3LlqMS5FuY0LFy4wbNgwOnbsSFJSEt9//z2//PKLyev18fFh48aNTJw40eR1GYMafqiBuLg4xo8fj62tLatXr9Y6HEWpsNasWcMzzzzDhAkTeOutt3BxcdE6JE2ZdD3ye1WRErlOp8Pa2lqTuvPz83F0dOTUqVO88cYbzJ49mwYNGmgSi6JUFBs2bCAhIYGXXnoJKSXnzp3Dz89Pk1g+/vhjnJyceOmllzSp/5/UOPJbGDhwIP36abM8jKOjIwAxMTH8+eefZWNhc3JyNIlHUbR08uRJ+vXrxyOPPMLXX3+NTqdDCKFZEgfDyJgPP/ywwneBVulErtfrCQ8PR+uNLvr3709cXBwDBw7kgw8+oFGjRixfvlzTmBTFXLKzs3njjTdo1qwZ27ZtY86cOezbt0+zv5SvNXDgQM6ePUtF6UG4lSqdyKOjo0lLSzPqsMP7Vbt2bZYsWcLu3bvx8fFh3759WoekKGZx6tQp5s6dy6BBg4iLi2PixIkVZu2i/v37Y2trW+HHlFfpRB4REQFglIlAxtKxY0f27t3L+++/D8DWrVsZOXIkqampGkemKMYTGRnJBx98AEDr1q05ffo0ixcvxtvbW+PIrufh4cHDDz/MTz/9VKH3H6jSiTw8PJyGDRtq2gd3M1ZWVmX951FRUXz33XcEBQXx2WefUVxcrHF0inL/UlNTefHFF2nfvj2fffYZGRkZgGE2ZUU1aNAgmjZtSlpamtah3JqUslw3wAHYB0QBR4Hpd3pN27ZtZUWwZMkS+c0332gdxh3FxsbK3r17S0A2bdpUhoeHax2SotyToqIi+fHHH0tXV1dpa2srX3/9dZmZmal1WBYHiJQ3yanGaJEXAj2llC2BVkAfIURHI5RrckOHDuXFF1/UOow7aty4MX/88Qdr1qyhoKCAmJgYrUNSlHty+fJl3nnnHTp37kxMTAwfffQRrq6uWod1Ty5cuEBJSYnWYdyUMTZfllLKq+PlbEtvFXusDoYhfwkJCVqHcdeEEDz22GMcPXqU//znPwCEhYUxbdo0cnNzNY5OUW505swZ3n77baSU1K5dm+joaH7//XcaNWqkdWj3LCIiAl9fX7Zu3ap1KDdllD5yIYS1EOIwkApsklLuvclzRgkhIoUQkZcuXTJGteUyceJEzcaPl4eDg0PZVnSRkZHMnDmTxo0b8+OPP1b4sa5K1ZCTk8PUqVNp2rQpn376KSdOnAAMyzybchkMU+rQoQNOTk4Vd+2Vm/W33O8NcAcigODbPU/rPvKCggLp6Ogox44dq2kcxrB9+3bZunVrCcju3bvL6OhorUNSqii9Xi/DwsKkr6+vBOSQIUPkuXPntA7LaJ5//nnp6ekpCwsLNYsBE/aRX/ulkFGayPsYs1xj27dvH/n5+WYbP15UoqdEZ5qhS127dmX//v0sWLCAY8eOER8fb5J6FOVOCgoKmDJlCt7e3uzatYulS5fi4+OjdVhGM3DgQNLS0ti8ebPWodyg3JsvCyFqAsVSygwhhCPwEFD+bTpMKDw8HCEE3bt3N3rZJTo9cSk5HE7KICopg8NJGZxMzUYvwdZa4GBjjYOdNY621jjYWuFoa4297d/3PZzsaOjlQmNvFxp5u1Cjmv0d67S2tmbkyJEMHDiQatWqATB37lzs7e156aWXyrpiFMXYLl++zMcff8w777yDo6MjW7duJSAgACsrK3R6yZWcQlKzC7mUXUhqdgGpWYb7qdkFhp9ZhaTnFeHmaIuXqwPerg54udrj5eaAl4sD3m4OeJUec3HQdoOW3r174+bmxooVK3jkkUc0jeWfjPEJrw0sEUJYY+hz/0lKuc4I5ZpMeHg4bdq0wcPDo9xlXcws4EBCOlHJGRxOzCDmXCb5xToA3J1saennzkNNvbCzsSK/WEdB2U1PfpGOghId+UU6MvKLKcjUsT8nnRX7k8rKr1HNviypN/I2JPiGtVxwtLtx+vLVleGklGzZsoV169Yxf/58Pv/88wo16UmxbHq9JPFKNl/N+x9fz51Ffl4ul10a4t6wTWnCTiY1u5ArOYXob3LZxs3Rllou9tRytad9XU88nOzIzC8mJauA05dy2Hn6MtkFN44Ocbazvi7B13K1x7s0+ddydcDX3RFvNweTvW97e3t+/PFHmjVrZrI67leVXP3w/PnzpKSk0Lp16/suIyWrgA//OMGqQ8lICXY2VjTzcaWlnzut/d1p6edOQHWne764I6XkUk4hJy5mc+JiNsdLf8alZFNYYuieEQICqzvTyMuFZj6uhAR60qqO+3XJXUrJ6tWrmTBhAvHx8Tz99NPMnTuXOnXq3Pd7VqoevV6SkJZHdHIGR85lEp2cyd4dWzn/x/8ovpyIQ2BrPB4ciUNNf6pXszckaBd7arkYEm0tF3tqlv5es5o9NV3scbC98xoqeUUlpGQVcjGzgJQsw+1ilqFFfzGrgIuZBaRmF1Csuz5/hQR4MKJrXXo388bayjIvrN6OWsbWSPKLdCzYdoavt55Gp5cM6xJIvxa1aeztip2N6SbK6vSShCu5Zck9LsWQ4M9eyUWWdtsE+7rRPtCTkEBP2gV64O5kR35+PnPnzuXDDz9k+/bttGzZ0mQxKpZNSklSWj7R5zKISc4k5pzhdrV1bGdjRRNvFw588QpFOemMfeu/PP7443i5OVDd2d7siVOvl6TnFZUl+LiUbH7Ym0BSWj51PB0Z1rkuz4T4Gb1LZtWqVZw+fZpJkyYZtdy7oRJ5qWXLlpGVlXXP6wvr9ZI1Uef48I8TXMgs4JHm3kzp0wT/6k4mivTuZOYVcyAxjX1n09kfn0Z0ckZZKyXIqxrtAj1pF+hJ4+o2NPb3AmDKlCmEhITw5JNPWuxwMKV8pJScy8gnJjmT6HOZZa3tzHzDEhC21oImtV1p7utGUHU7ItcuZcqEMfjW9iYxMZFatWqVbWNYkej0kk3HUli44wz749NxsbdhYPs6vNA5ED8P43xWX375ZZYuXUpqairOzs5GKfNuqUReqmPHjlhbW7Nz5867fk1kfBr/XXeMqORMmvu6Ma1fU9rX9TRhlPevoFhHVFIG++PT2BefzsGEdHIKDS0qX3dHWtV2YH3oSBJOHqNHjx589tlnNG/eXOOoFVOSUnIxq4Do5MzrEndabhEANlaCRt4utPBzI9jXjRa+7gR5V8PO2oqff/6Z119/naSkJBYsWMDIkSM1fjd373BSBgt3nOX3mAsA9An25sWudWntX75rY1u2bKFHjx78+OOPPPPMM8YI9a6pRA5kZWXh6enJlClTmDlz5h2fr9NL3l4dw/J9SXi52jP54cb0b+2LlQX1ven0ktgLWeyPTzMk97PpXMrKIydqI5nbv0dfmEfP/oOYMWMGHRv7W9R7U26uRKcn9kI2kQlpRCakcyA+nYtZBQBYWwka1qpGCz83mvu509zXjcbeLjf0W0dHRzN27Fi2bt1Kq1at+Pzzz+nWrZsWb6fczmfks2RXPMv2JZJdUEIbf3de7FaP3k29sLG+9+5QnU5HnTp16NixI6tWrTJBxLemEjmwfv16+vXrx19//XXHMeQ6vWTSz1GsOnSO0d3rMa5XQ5zsLH8Yn5SS+Ct57Dt7ha0xZ/n1m09IPbSZ2i/+D88atWgX6EmHep60r1udYB/X+zrRFfPKKijmUGIGB+INiftwUgZ5RYaRUz5uDrQN9KSNvzst67jTtLbrXV1sfO6559i0aROhoaG8+OKLFWKTh/LKLSzh58gkFu+KJ+FKHr7ujvxfl0CebVfnnvvRX3vtNb7++mtSU1PNumaMSuQYpuV/9dVXpKenly0TezN6veSNX6L5+UAyEx8KYsyDDc0YpfkdjT/PiTQ9e89c4fu509DX64JDnWCc7KxpG+BBh7qedKhXnRZ+btjbWP4H2pJJKUlOz+dAQrqhxR2fzomUbKQEKwFNarsSEuBB20BPQgI88HG/9Xl+rZKSEhYsWMC//vUvmjVrRkpKCnZ2dkYZolvR6PSSzbEpLNx+ln3xaVSzt+HZdnUY1jmQOp5314++e/duXnrpJcLCwggODjZxxH9TiRzDaofnz5+/7cwsvV4ydfURlu9LZOyDDZnwUJAZI9RWUlISXbp0ISkpiW59HqfVk69yItuOEynZANjbWNGyjjut6rjTws+Nln7u+Hk4qgumJlSs0xN7IYvI+PSy5J2SVQhANXsbWvu70zbAg5AAT1r5u1PN/t7/aty6dStjx44lOjqaKVOmMGvWLGO/jQorOtnQj74++gJ6KZnwUBCv9rxzw01Kqcl5rxJ5qZKSklvOdJRS8s6ao3y/J4H/PFCfSQ83qnJJKi8vj9mzZ/Phhx9iZWXFm2++yfCXxxJzMY+9Z9I4mJjOsfNZFJUuOeDpbEdLPzda+P2d4KvfxWxU5UZSSi5kFnDsfBZRyRlExhu6Sa5OMPN1dzQk7UAP2gZ40NjbtVxD/hITE5k0aRI//fQTAQEBzJ07lwEDBlS5cx7gQmY+7/9+nLVR53m9990lczB8XgCcnMwzek0l8juQUjJj3TEW74xnVPd6vNm3cZU8oa+Kj4/n9ddfZ//+/cTGxl53ohaV6DlxMZvDyRlEJ2UQlZzBydQcrp5Kfh6OtPRzp2UdQ4Jv7uuG8320FCuzohI9p1JziL2QxbELWRw7n0XsxSwy8gzD/6ytBE1quxAS4FmWvGu73V03yd2aOnUqn3zyCVOmTGHSpEm37W6sCnR6yes/R/HroXO80acxLz9Q/7bPT0hIoFmzZnz66adm29egyifyyZMnc/LkSX799debPj5rQyzzt57h/7oE8k6/plU6iV8rLS0NT09PCgoKePnll5k0aRJNmza94Xk5hSWlY5EziErOJCopg+T0fMDQd9ugVjVa+rnTpLYrgTWcCKjuTB0PJ5NOoqooMvOKDcn6QpYhcZ/P4mRqdtl4f3sbKxrXdqVpbVea1nahqY8rjb1djf7lJ6Xk119/xdPTkwceeICcnByuXLlSobdZMzedXjL+x8P8FnWeqY80YWT3erd8rpSSRo0a4e/vb7aFtG6VyKtMM2n9+vW3nJ4ecSKV+VvPMKiDv0ri/+DpaRgvHxMTw+rVq/n+++8ZM2YM7777Lu7u7mXPq2ZvQ8d61elYr3rZsSs5hUQnZxKVbFhALPx4Kj8fSC573EqAj7sjgdWdCaju9PfPGs74ezrd1eiKiuTqzMhj17ayL2RxLiO/7Dk1XexpUtuV7kE1aepjSN51azibfFbkkSNHGDduHOHh4Tz11FM88MADVKtWrWyRNcXA2krw8TMt0eklob/HYm0lGN617k2fK4Tg2Wef5f333yclJQUvLy8zR3tNLFWhRX7x4kVq167N7NmzmTx58nWPFRTr6P3JNmysBRvGdVOjMm7j0qVLvP3223zzzTfUqFGD999/n+HDh2NldXetaikl6XnFxF/JJf5yLvFX8ki48vfPq90KYFhPprarAwHVncta8IHVDT9rudjjbG+DvY2Vyb90pZTkFelIzysiI6+Y9Lwi0vOKybjmfkZeMefS84m9kEV26eQrKwH1alYztLJ9XGlS25UmtV2o5WLe2ZDp6em8++67zJs3D1dXV2bOnMmoUaPUiph3UKzTM2bZIf44epEZjzdjaKfAmz7v6NGjBAcH8+WXX/LKK6+YPK4q3bWyfPlynn/+efbv309IyPX/Bh//eYLPw0+x7MUOdG5Qw2wxWbKDBw8yduxYSkpK2LVr110n8jvJyCsi4UpeaaK/muRzSbiSx5XSWYjXshLgZGeDk501zvY2ONpa42xvXXbMyc4GZ3trHO2scf7HMSc7G/RSklGamNPzisj8R6JOzysmM6+47MLuzbjY2+DmZIu3qwNNSpN209quBHndfIVKc/v2228ZPXo0L730EjNmzKB69ep3fpECGK5jvLLsIJuOpRDaP5hBHW7eBRUcHIynpyfbtm0zeUxVOpGPGjWKn376iStXrlw3seHMpRz6fLqdR5p78+nA+18JsSqSUpKWlkb16tVJTU1l6tSpTJ8+3WQbCWQVFJN4JY+zl3NJyy0it6iE/CIduYU68opKyCsy/Mwt1JFXrCOv8JpjRTqKSm6/sYettcDdyQ4PJ9uynx5Odtf97lb68+pz3J1ssa2AE6Z27txJSkoKAwYMQKfTcfz48Qq59KolKCrR8/IPB/jreCqzn2zOs+38b3jOX3/9haenZ7lWU71bVbqPvE2bNnh5eV2XxK8ONbS3teKtR5toGJ1lEkKUte6u7gazfPly3n77bcaPH4+9vXGHILo62BLsa1gL5H6U6PSlCV5X9iUAhjXjPZzscLKztvhrI+fOnWPy5MksW7aMVq1a0b9/f6ytrVUSLwc7GyvmDW7DqKUHmLIqBisheDrk+mttDz74oEbRXeNm+7+Z+qb1np1SSrnm8DkZ8MY6uWTXWa1DqRROnTolH3/8cQnI+vXry99++03rkKqM/Px8GRoaKp2dnaW9vb185513ZG5urtZhVSr5RSVy8Ld7ZOCUdXLVwaQbHt+9e7ecPn26yePAVHt2CiHqCCEihBDHhBBHhRDjyv/1Yjznzp0jOzv7umNZBcX8d90xWvi53bLfS7k39evXZ/Xq1WzcuBFbW1vCwsK0DqnK2LVrF1OnTuXhhx8mNjaW6dOnm22CSlXhYGvNgiEhdKpXnYk/RbHm8LnrHt++fTvvvvsuZ86c0SbAm2X3e7lh2OqtTenvLkAc0PR2rzFni3zo0KGydu3aUq/Xlx17d80RGThlnYxKSjdbHFVJUVGRTEtLk1JKGRMTIydOnCgzMzM1jqpyOXbsmFy8eHHZ/UOHDmkWS1WSW1gsn/l6l6w7ZZ1cG3Wu7Hh8fLwE5KxZs0xaP6ZqkUspL0gpD5b+ng3EAr7lLdcYpJSEh4fTtWvXsv7PC5n5fL8ngUEd/Gnh565tgJWUra1t2WJLf/31Fx9//DFBQUEsXrwYvf72Fx2V28vMzGTChAm0aNGCN954g9zcXABatWqlbWBVhJOdDYuGtaNtgAfjVhxmQ+la5wEBAXTq1IkVK1ZoEpdRL7kLIQKB1sDemzw2SggRKYSIvHTpkjGrvaVTp06RnJx83ZK1P0cmo9NLRne//fRbxTjGjRvH3r17qVu3LsOHD6dTp07s3XvD6aHcgV6vZ9GiRQQFBfHpp58yfPhwjhw5YvYdahRwtrdh8f+1p6WfG2OWH+LPoxcBGDhwIFFRURw/ftzsMRktkQshqgG/AK9JKbP++biUcoGUMkRKGVKzZk1jVXtbERERAGWJXKeX/Lg/iW4Na9z1cpVK+bVr146dO3eydOlSEhMTWb16tdYhWZzTp08zevRoGjZsSGRkJPPnz8dcnyPlRtXsbVgyvD3Bvm68suwghxLTeeqpp/D19eXs2bNmj8coiVwIYYshiYdJKc27ZcZthIeH4+PjQ8OGhpXMtp28xLmMfJ5rf+NYUMW0rKysGDJkCHFxcbz99tsAbNq0iTlz5lBUdONkHwXOnz/PV199BUDDhg3Zu3cv27dvp02bNhpHpgC4ONiyZHh73Bzt+HhTHD4+PiQlJdG3b1+zx2KMUSsCWAjESik/Ln9IxjNt2jS+/fbbsv7xFfsSqVHNjl5NtFsToapzcXEp6w5Yu3YtkyZNonnz5mzYsEHjyCqOwsJCZs+eTaNGjZgwYQIJCQmAYT6EpY91r2zcHG0Z2a0u209e5lBiOkII9Hp92bULczFGi7wLMAToKYQ4XHp7xAjllluzZs3Kvh1TswrYHJvKk239qsSKe5bg888/Z/369UgpeeSRR+jXrx8nT57UOixNrV+/nuDgYKZMmULPnj05evSoWp2wghvcMQB3J1u+DD9FYWEh9evXJzQ01KwxGGPUyg4ppZBStpBStiq9/W6M4MojIiKCFStWlI2S+PmA4SLnwJtMsVW088gjj3DkyBE+/PBDtm7dypYtW7QOSTOZmZkMHjwYa2trNmzYwJo1a2jQoIHWYSl34Gxvw4gudfnreConLxfQqFEjVqxYcXV4tllU2rVW+vfvT1RUFGfOnEGvl/xrTgR1PJxYNrKjSetV7l9KSgo1atTA2tqaH374ASklgwYNMtqiXBVRVlYWixYtYuzYsVhZWXHo0CGaNWuGnZ2d1qEp9yCroJguH4TTtUEN2hdHM3z4cPbt20e7du2MWs+t1lqplJ8QnU7Hli1bykar7Dx9maS0fAaqi5wV2rXr4YSFhTF06FC6du1KRdtNyhj0ej1LliwhKCiI8ePHs3PnTgBat26tkrgFcnWwZVjnQDYcuUjzLr2wtbU165jySpnIo6KiyMjIoEePHgCs2JeEh5MtDzdTFzktxfr161m0aBGnT5+mffv2vPjii6SmpmodllHs37+fzp07M2zYMAIDA9m7dy/dunXTOiylnIZ3qYuTnTXfH7xM3759+emnn8w2Aa5SJvLw8HAAevToQYlOz9a4S/RtXlttGmFBrKys+L//+z/i4uKYMGECS5YsISoqSuuwyk2n0zF48GDi4+NZsmQJu3bton379lqHpRiBh7MdQzoGsDbqPENfGsf8+fPN1k9eKRN5dHQ0jRs3xsfHh5hzmeQUltC5vlpQ3xK5ubkxZ84czp49y0MPPQTAZ599xp9//qlxZHevqKiIr776itzcXKytrfnll1+Ii4tj6NChlbr/vyp6sVs9bK2t2JNTnUceeeS6pbNNqVKeRUuWLCnrc9x95grAdXtJKpbHz88PMCTF+fPn8/DDD/PEE09ot9rcXfrjjz9o0aIFr776KitXrgQMO8q4urpqHJliCjVd7HmuvT+/HjrH9gNHmDFjBiUlJSavt1ImciFE2abBu09fIcirGjWqGXejA0UbdnZ2HDp0iFmzZrF582aaNm3K1KlTycnJ0Tq065w6dYrHHnuMvn37otPpWLduHS+88ILWYSlmMPpf9bASgk9//JN3332XrVu3mrzOSpfI582bx+DBg9HpDNt7Rcan00m1xisVe3t7pkyZwokTJ3j66af56KOPSEpK0jqs67zyyitEREQwe/Zsjhw5wqOPPqp1SIqZ1HZz5KkQP6Koh3O1amYZvVLpEvmqVauIiYnB2tqa6OQM8ot1dFL945WSr68v33//PadOnaJJE8N2fTNmzODQoUNmj0VKyQ8//MC5c4YNB+bNm8eJEyeYPHmy0be9Uyq+l/9VH2ljR722/2LVqlUmX0+oUiXygoICdu7cWTZ+fPfpKwgBHeqqRF6Z+fsb5gekpqby5Zdf0rZtW0aPHo25lks+cOAAXbt2ZciQIcyfPx8w7Jhkqo2olYqvjqcT/Vv7csUrhLS0NDZv3mzS+ipVIt+zZw8FBQVliXzP2Ss09nbFw1lNsKgKatWqRVxcHOPGjWPhwoUEBQXxxRdfmOxi06VLlxg1ahTt2rXj1KlTLFy4kPfee88kdSmW5z8P1McuoBWu1WuZfGnbSpXIIyIisLKyonv37hSW6FT/eBXk7u7OJ598QnR0NCEhIbzzzjtkZGSYpK533nmHxYsXM378eOLi4hg+fLgaTqiUqVezGv9uHYDPS4t4fthIk9ZVqc66GjVqMHDgQNzc3DicmEFhiV71j1dRTZs25c8//+TQoUPUqFEDvV7PlClTiI+PL1e5mzdvJjo6GoD33nuP6Oho5s6di5ubmxGiViqbV3o0IL8EFu88S2FhocnqqVSJfMyYMWW7t+87m4YQ0D7QU+OoFK0IIQgMDAQgJiaGzz//nCZNmvDuu++Sl5d3T2WdPXuWAQMG8NBDD/HBBx8AhrVhrl5kVZSbaeTtQp9m3rz7ymCeHzzEZPVUmkSenZ19XV/oqUs5+Lo74uZkq2FUSkXRsmVLTpw4wRNPPMGMGTNo3LgxP/300x2nUOfm5jJt2jSaNGnCxo0bef/991m0aJGZolYqg1d7NgCXWqxbt85kG04Ya6u3RUKIVCHEEWOUdz9CQ0OpXbt22TCfM5dyqVtDbUyr/K1OnTosX76crVu34unpydtvv01xcTEAy8PCCA4MxNrKiuDAQJaX/mX3v//9j5kzZ/Lkk09y4sQJ3nzzTRwcHLR8G4qFCfZ1o1vvxygqyCc44MZzzBhsjFTOd8CXwFIjlXfPIiIiaNy4MXZ2dkgpOXs5l6fa+mkVjlKBde/enQMHDpCcnIydnR2LFy3indGjWVpSQldgR0IC/zdiBGCY2NO5c2c6d+6sbdCKRevsLTkILLpyuewcGzFqFADPDRpU7vKN0iKXUm4D0oxR1v3IzMwkMjKybNjhpZxCcgpLVItcuSVra+uyLdRmTpnC0pISegC2QA9gcWEhoW+9haOjo0riSrmt+PQDlsN159jCvDxCp041Svlm6yMXQowSQkQKISKNPVFj27Zt6PX6skR+9pKhH0olcuVuxF82tJKu1RWIrWDT/hXLFZuYePNzLDHRKOWbLZFLKRdIKUOklCE1a9Y0atkRERE4ODjQsaNhG7ezl1UiV+5eE39/dvzj2I7S44piDKY+xyrFqJVnnnmGL774omxNizOXc7GzscLH3VHjyBRLMDU0lBFOTkQAxUAEMMLJialm3gldqbxMfY4Z62Knpjp27FjWGofSESvVnbG2EhpGpViKqxebxkydSmxiIk38/QkNDTXKRShFAdOfY8IYWxEJIZYDDwA1gBTgXSnlwls9PyQkRBprQ90jR46QmppK9+7dsbExfC89OHcLDWu58PWQtkapQ1EUpSIQQhyQUob887hRWuRSyueMUc79+N///sfSpUtJSzMMminR6UlMy6N3M2+tQlIURTEri+8jDw8Pp1u3btjaGmZwJqfnU6yT6kKnoihVhkUn8vPnz3P8+PGyYYcAFzILAPBTFzoVRakiLDqRb9myBYAePXqUHcvMN0zRV2usKIpSVVh0It++fTvu7u60atWq7FhmvmHtDHcntZmEoihVg0Un8i+++IK9e/dibW1dduxqIndzVC1yRVGqBotO5DY2NgQFBV13LCOvGGsrgbOd9S1epSiKUrlYbCL/7bffeO21125Y3zczvxh3R1uEUJOBFEWpGiw2kf/8888sW7YMJyen645n5BerbhVFUaoUi0zkUkrCw8Pp2bPnDS3vrPxiNWJFUZQqxSIT+cmTJzl//vx1ww6vyshTLXJFUaoWi0zk4eHhANdNBLrqah+5oihKVWGRibywsJC2bdvSoEGDGx7LVH3kiqJUMRaZyMeNG0dkZOQN/eN6vSSrQCVyRVGqFotL5Dqd7paPFen0SAn2tmoMuaIoVYfFJfIvv/ySevXqkZmZecvnqCHkiqJUJRaXyMPDw7GyssLNzU3rUBRFUSoEoyRyIUQfIcQJIcQpIcQUY5T5T8vDwggOCGDtb7+Rm5LC8rAwU1SjKIpiccq9Q5AQwhr4CngISAb2CyF+k1IeK2/ZVy0PC2PqqFEszMujK7AjJ4cRo0YBqH0VFUWp8ozRIm8PnJJSnpFSFgErgMeNUG6Z0KlTWZiXRw/AFugBLMzLI3TqVGNWoyiKYpGMkch9gaRr7ieXHruOEGKUECJSCBF56dKle6ogNjGRrv841rX0uKIoSlVntoudUsoFUsoQKWVIzZo17+m1Tfz92fGPYztKjyuKolR1xkjk54A619z3Kz1mNFNDQxnh5EQEUAxEACOcnJgaGmrMahRFUSxSuS92AvuBhkKIuhgS+EDgeSOUW+bqBc0xU6dyLCEBd1tbvlqwQF3oVBRFwQgtcillCfAqsBGIBX6SUh4tb7n/9NygQRyJj2dmaCjpxcX06t3b2FUoiqJYJKP0kUspf5dSBkkp60spTdrfcXXFwy1btpiyGkVRFIthcTM7Q0JCcHFxKVvK9lo2Voa5+UUlenOHpSiKohmLS+Q2NjZ069aNiIiIGx+ztsLF3obM/GINIlMURdGGMS52mt0HH3yAs7PzTR9zdbQlM08lckVRqg6LTOTNmze/5WPuTraqRa4oSpVicV0rVy1btowFCxbccNzN0ZYMlcgVRalCLDaRr1y5klmzZt1wXLXIFUWpaiw2kffs2ZP4+HjOnj173XE3R5XIFUWpWiw6kQM3DEO8erFTSqlFWIqiKGZnsYm8SZMmeHl53TAM0d3RjiKdnoJiNZZcUZSqwWITuRCCnj17kpqaet1xN0dbADLyi7QIS1EUxewscvjhVUuXLsXG5vq34O5kSOSZ+cXUdnPUIixFURSzstgWOXBDEodrWuRqUpCiKFWERSdygNGjRzNixIiy+7Vc7AG4mFmgVUiKoihmZfGJvLCwkDVr1qDXGy5u+ld3wkrAmcu5GkemKIpiHhafyHv27MmVK1eIiYkBwN7GGj8PJ86qRK4oShVh8Ym8R48eANcNQ6xbw5mzl3O0CklRFMWsypXIhRBPCyGOCiH0QogQYwV1L+rUqUODBg2umxhUt4YzZy/lqklByl1bHhZGcGAg1lZWBAcGsjwsTOuQlErGlOdYeYcfHgEGAPONEMt9Gz16NCUlJWX369V0JrdIR2p2IV6uDhpGpliC5WFhTB01ioV5eXQFdiQkMGLUKAC1L6xiFKY+x4QxWq1CiC3A61LKyLt5fkhIiIyMvKun3pcdJy8zeOFelo/sSKf61U1Wj1I5BAcG8kVCAj2uORYBjAkI4Eh8vEZRKZWJsc4xIcQBKeUNvR9m6yMXQowSQkQKISIvXbpk9PLz8/NJTEwEoG5Nw6YT6oKnciclJSXEJiTQ9R/HuwKxpeeTopRXbGKiSc+xOyZyIcRmIcSRm9wev5eKpJQLpJQhUsqQmjVr3n/Et9ClSxdGjhwJQG1XB+xtrNQFT+W2tmzZQps2bXACdvzjsR2Ak5Q899xzJCUlaRCdUpk09PW76TnWxN/fKOXfMZFLKXtJKYNvcltjlAiMpGvXruzYsYOioiKsrAR1azhz5pJqkSs3SkxM5Nlnn6VHjx5kZWXx4rhxjHByIgIoxvAn7whHRx4eMIDVq1cze/ZsjSNWLF39J17meRv7688xJyemhoYapXyLH354VY8ePcjLy2Pfvn2A4YKn6lpRbiYmJoa1a9cyY8YMYmNj+eTTTwldsIAxAQE4CMGYgABCv/mGlb/8wvHjx5k+fToAkZGR/Prrr2o0lHJPEq/kEVutBV3Hzrj+HFuwwHgX06WU930D+gPJQCGQAmy8m9e1bdtWGtuVK1ekEEJOnz5dSinlR38cl/XeXC/zCkuMXpdiWfR6vVy5cqX87LPPyo5dvHjxnssZMmSIBGSvXr3k0aNHjRmiUom9sTJK2ns3kKEfflzusoBIeZOcWq4WuZTyVymln5TSXkrpJaV8uLxfLPfL09OT1q1bl40nbxvogU4vOZCQrlVISgVw5MgRevXqxVNPPUVYWBg6nQ4ALy+vey5r0aJFfPHFFxw4cIAWLVrw2muvkZGRYeSIlcrkfEY+YWs3U3jxFL61PE1WT6XpWgH46KOPmDNnDgDtAj2xthLsPnNZ46gULaSnpzN27FhatWrF4cOHmTdvHjt37sTa2vq+y7SxseHVV18lLi6OUaNG8cUXX7Bo0SIjRq1UNgu2nSH76Dbs7Ox44oknTFaPRa9H/k9Xt38DqGZvQws/N3afvqJhRIpWkpOTmT9/PqNHj2bGjBlUr268+QQ1atRg3rx5vPTSSzRq1AiAjRs3Uq1aNbp06WK0ehTLlppdwLI9Zyk5vYu+ffvi5uZmsroqVYscYN26daxbtw6ATvWqE52cSW5hyR1epVQGO3bsKLsw2bx5cxISEvjqq6+MmsSv1aJFC+zt7ZFSMn36dLp27crgwYM5d+6cSepTLMu328+SnXCE3PRLDBw40KR1VbpE/v777xNaOqSnU/3qlOgl++PTNI5KMaXk5GSef/55unXrxqJFi8jMzATA29vbLPULIdi0aRNvv/02K1eupFGjRsyaNYuCArUmflWVllvED3sS6N22EWPGjKFfv34mra/SJfIePXqwf/9+srOzCQnwxNZasPuM6l6pjAoKCggNDaVRo0b8+uuvvPPOO8TGxpr0T9hbcXZ25r///S/Hjh2jd+/evPXWW2zYsMHscSgVw6IdZ8kv1vH2oF58/vnnVKtWzaT1VbpE3rNnT3Q6Hdu3b8fRzppWddzZo/rJK6XMzEw+/PBD+vbtS2xsLNOnT8fJyUnTmOrVq8eqVavYs2dP2cWtn3/+mePHj2sal2I+mfnFLNkVTwePPC6djinb9MaUKl0i79y5M3Z2dmXDEDvVq07MuUyyCtQenpVBbGwsr7/+OlJKvLy8iI2NZeXKlQQGBmod2nU6dOiAEIKioiLGjx9P8+bNmThxYlm3j1J5LdkVT3ZhCSWH19KnTx+KiopMXmelS+SOjo506tSJ6OhoADrWr45ewv6zqp/ckmVkZDB+/HhatGjBwoULOXnyJAA+Pj4aR3Z7dnZ2HDx4kGHDhvHJJ58QFBTEokWLzNJKU8wvp7CERTvP0qOhB39tWMsTTzyBg4Ppl9KudIkcYNWqVWzcuBGANv4e2NlYqWGIFkqv17Nw4UKCgoL47LPPGDFiBHFxcQQFBWkd2l2rVasW33zzDfv376d+/fqMGDGirKGhVC4/7EkgI6+Y1laJZGRkmHy0ylWVMpF7enoihADAwdaajvWqs+HIRfR6tUaGpSksLGTmzJkEBQVx4MABvv76a0yxeqY5tG3blp07d7Jz505atWoFwHfffceFCxe0DUwxivwiHd9uP0O3hjXYH74eDw8PevXqZZa6K2UiBxgzZkzZMMRnQ+pwLiOf7afULE9LcP78ecaPH09+fj6Ojo5s376d7du307p1a61DKzchBJ07dwYgJSWFl19+maCgID766COz9KUqprN8XyKXc4p4tUd9tm3bxpNPPomdnZ1Z6q60iTwuLo4VK1YA8FBTL6o727F8r9oooCIrLCxk9uzZBAUFMW/ePPbs2QOAn59f2V9YlYmXlxcxMTH06NGDyZMnExwczO+//651WMp9KCzRMX/baTrU9aRDvRqcPHmSWbNmma3+SpvIe/bsyZEjR0hJScHOxoqn2vqxOTaF1Gw1SaOikVKybt06goODmTJlCr169eLYsWP06NHjzi+2cA0aNOC3335jw4YNWFlZ8dRTT5Gamqp1WMo9+jkymZSsQsY+2BAwXOSuUaOG2eqvtIn8ahLYsmULAM+2q0OJXrLyQLKGUSm3MmvWLGxsbNi4cSOrV6+mfv36WodkVn369CE6Opq//vqLWrVqIaVk/vz5ZGdnax2acgfFOj3/23Ka1v7utPCyp1WrVqxfv96sMVTaRN6mTRtcXV3LxpPXq1mNjvU8WbEvSV30rACysrJ48803uXjxIkIIfv75Z6Kjo+ndu7fWoWnGzs6OTp06AXDw4EFeeuklgoKCWLp0qRquWIH9eugc5zLyGduzIevWrSMqKgpXV1ezxlCuRC6E+EgIcVwIES2E+FUI4W6kuMrNxsaGwYMHU7t27bJjz7X3JzEtj11qKKJm9Ho93333HUFBQcyePZs//vgDMIwHt7W11Ti6iqNt27bs2bMHf39/XnjhBbp06cL+/fu1Dkv5h2KdnnkRpwj2deWBRjVZsWIFvr6+5l8F82a7TdztDegN2JT+PhuYfTevM8UOQXcjv6hEtpq+Uf4n7IAm9Vd1e/fule3bt5eA7NSpk9y/f7/WIVV4Op1Ofvfdd9LLy0v6+vrKwsJCrUNSShWX6OTLP0TKgDfWyU1HL8r09HRpa2srx48fb7I6MdEOQX9KKa+uEbsH8CtPeaag1+vJysoCDGPKB7Tx48+jF7mcU6hxZFXP559/TlJSEkuXLmXHjh2EhIRoHVKFZ2VlxQsvvEBcXByrV6/Gzs6OoqIivvnmG4qL1bITWinR6Rn/UxS/x1zk7Ueb0KupF6tXr6a4uNhsk4CuZcw+8uHALZd7E0KMEkJECiEiL126ZMRqby84OJhx48aV3X+ufR2KdZLvdyeYLYaqqqioiDlz5hATEwPAp59+yokTJxgyZAhWVpX28oxJuLq6ln3xrVmzhlGjRtGiRQv+/PNPjSOrenR6yes/R7E26jxv9m3Mi93qAVC/fn1Gjx5Nu3btzB/UzZrp8vruk83AkZvcHr/mOVOBXwFxp/KkmbtWnnzySenv7y/1en3Zsf/8cEAGTf1dJlzONVscVc3vv/8ug4KCJCCnTZumdTiVil6vl2vXrpX169eXgHzsscfkqVOntA6rStDp9HLCj4dlwBvr5JfhJ81eP7foWilXH7mhXIYBuwGnu32NORP5V199JYHrTvQLGfmy6bQNctiivdcleKX8Tp48Kfv16ycBGRQUJH///XetQ6q0CgoK5KxZs6Szs7Ps2LGj1uFUejqdXk7+OUoGvLFOfrop7rrHDhw4YJYv01sl8vKOWukDTAYek1LmlacsU7k6njwiIqLsmLebA+MfCiLixCU2Hr2oVWiV0pIlS9i6dSsfffQRMTEx9O3bV+uQKi17e3umTJlCXFwc3377LQBpaWksX778aiNLMRK9XjJ19RF+jExibM8GjOvV8LrHJ06caPJdgG6nvB2VXwIuwCYhxGEhxNdGiMmoGjdujLe3d9l48quGdQ6ksbcL09ceU3t6loOUkh9++IHNmzcDMGXKFE6cOMHrr79utnUm7pWUkvwiHQXFOq1DMQofHx+aNWsGwIIFC8q2vTt06JDGkVUOUkre/e0oy/cl8p8H6jP+oetX3rxw4QJbt27l2Wef1ShCsCnPi6WUDYwViKkIIfjoo49uWLfaxtqK0P7BPPm/3Xz210neeqSJRhFargMHDjBmzBh2797NwIED6dWrF87Ozjg7O5ukvryiEhKu5HElp4jcohLyi3TkFpWQV6gjr0hHXlGJ4X6RjrxC3TXPMTxmOF5CXrGOqw1WexsrPJzscHeyxd3JtvR3OzzKfre95nHDcTdHW2ysK+bF2kmTJlGjRg3eeust2rZty8iRI5k5c6bFrhipNSkl09ce4/s9CYzuXo9JDze6Yd2fn3/+GSmlpolcaPEnWEhIiIyMjDR7vTcz5Zdofj6QzPqxXWnsbd7ZWJYqNTWVqVOnsnDhQmrVqsUHH3zA0KFDjTISJbugmIQrecRfyTX8vJxbdj81+/ZDRu1trHC2t8HJzrr0ZoOzvTWOtoafTnaGx5ztrHGyt0EvJRl5xaTnFpGeV0xmvuFnRp7hp+42M4BdHWzwcDYkfXdHW2q7OdDY24WmPm40ru2Cq4O2k5syMjKYPn06X3zxBc8++yxhYWGaxmOJpJTMXB/Lwh1nGdG1Lm8/2uSmi7d16dKF3NxcDh8+bPKYhBAHpJQ3jNutEolcSsnu3buxtbW9YWhQem4RD368lXo1nPlpdCesrCrfKnvGtnjxYkaNGsVrr73GtGnT7nk6cmZeMfFXcv9O1qU/E67kcjnn+qVca7nYE1jdmYDqTgTWMPys5eJgSMj/SNrWRvy/k1KSXVhCRm4xGdcm+Ny/f8/ILy77PTk9n7Tcv2P393SiSW0XmtZ2o6mPK01qu+Dr7mj2VRyPHTuGs7MzAQEBnDp1ioSEBB588EGzxmCJpJR8sOE487edYVjnQN79d9Ob/t9dvnwZHx8fpk+fzptvvmnyuKp8Iq9bty5t27bll19+ueHxnyKTmLwymrceacyo7lVrsaa7tWnTJq5cucLAgQPR6/WcOXOGBg1u37MmpSQpLZ+o5AyikjKITs7kZGo26XnXT2Sp7eZgSNTVnQmo7kxgadL293TC2b5cvX9mI6UkNbuQY+ezOHbBcIs9n8XZK7ll3TiuDjalSd2VprVdaerjSsNaLtjZmKeb5sUXX2ThwoUMGDCAuXPnVrh9TisKKSUfbTzBvC2nGdzRn/8+HnzbL+ArV65gZWWFh4eHyWOr0okcYPjw4axZs4ZLly7d0AWg10v+E3aQP45e5L9PBDOkY4BZY6vIzpw5w8SJE1m9ejUhISHs27fvlif1pexCopMziErOLE3cGWVJ287GimAfVxrXdqXuNS1sf08nHGytzfmWzCqvqITjF7PLEnzshSyOX8gmv/RCq621oH7NajT1KU3utQ2J3sPZ+BeKCwoKmDt3Lu+//z56vZ5JkyYxZcoUnJycjF6XJft4Uxyf/3WS59r7E/pEcIX6K73KJ/Lvv/+eoUOHcujQobJttq5VVKLnP2EH2BybyqwBzXmuvb9Z46tocnNzmTVrFnPmzMHGxoa3336b8ePHY29vDxj6smPOZRJdlrQzOZeRD4CVgCAvF1r6udOijhst/dxp5O2CbQW9QGhuOr0k/koux84bEvuxC1kcO5913TUAPw9H2gZ4EBLgQdsATxp5uxit6yg5OZnJkyezfPlypk2bxowZM4xSbmXw+V8n+XhTHM+E+PHBgBa3TeInT55kxIgRfP755zfNKaZQ5RN5cnIyderUYe7cuUyYMOGmzyks0TH6+wNsjbvEh0+24OmQOmaNsSKJiIigZ8+eDB48mA8++IB8Wzf2nU3jQEI6UckZnL6UU9Zl4O/pRAs/N1rVcaeFnzvBvq442VlGl0hFcjmn0JDYz2cRlZxBZHx6WXJ3sbehlb87IQGehAR60KqOe7m7nbZv307z5s1xd3dn//792NnZ0bJlS2O8FYtTWKJjXsRpPvvrJE+28eOjp26fxAFmzpzJtGnTSExMpE4d8+SKKp/IARo1akSTJk1YvXr1LZ9TUKxj5NJIdpy6zMfPtKR/6wq3DpjJHDp0iH379jFy5CiOX8xmzZZ9JEkP9p1NK7sIWd3Zrixht6zjRgs/dzxN0A2gGPpqk9PziUxIIzI+nQMJ6ZxIyUZKsLYSNKntQkiAp6HlHuhBbTfH+66rZ8+ebN26ldGjR/Pf//6X6tWrG/GdVFxXcgoJ25vI0t0JXM4ppH9rX+Y83fKu/vq5+iW4fft2M0RqoBI5cOrUKerUqVPWPXAr+UU6hn+3n71nr/DpwNY81tLnts+3dBdTUhkz8Q1+WbYER7ca1P3PN+ToDK09HzcHOtSrToe6nrSv60ndGs6Vcv9MS5GZX8yhRENSj4xP53BSRll/u6+7Y1lSbxvgQWNv17vujklPT+fdd99l3rx5uLq6MnPmTEaNGoWNTeX8y+pkSjaLdp5l1cFzFJboeaBRTV7sWo8uDarf1fl99OhRgoOD+fLLL3nllVfMELGBSuT3KK+ohGGL93MgIZ1Z/ZvzdEjl2QC4sERHTHImu06l8sPibzmwaj76wjxc2v6bFv8eQZemAbSv60mHep74eagLYRVZsU5P7IWsshZ7ZEIaKVmG7phq9ja09nenbYAhsbfwdcfN6fbj22NiYhg3bhwRERF89913vPDCC+Z4G2YhpWTHqcss3HGWLScuYW9jxYA2fozoGkiDWi73VNY777xDaGgo58+fx8vLy0QR30glcgxrk7/11ls0bdqUoUOH3vH5OYUlDP9uP/vOptHG351p/ZrS2t/0Q4yMLaewhIMJ6eyPT2Pf2TQOJ2VQWKKnOP08Fxb+h8DgECa8M4une3XEy9VB63CVcrjaHXM1qUfG/90dA4brGc393Gjh60ZzXzea+brh5mh7Qxm///47Dz/8MDY2NkRERFC/fn38/S1zAEBBsY7fos6zaMdZjl/MpkY1e17oFMDzHfypXu32f53fyvLly9m3bx+ffPKJkaO9PZXIS7Vo0QIvLy82bdp0V8/X6SUrDyTx0cY4LucU8ngrHyb3aYyv+/33R5rapexCIuPT2Bdv+CAfPZ+JXhpGk9S1z8MmcR/jJ0ykXaAHKYmnadLk5jPWlMohq6CYqKQMYs5lEpOced0II4C6NZxp7utGCz83gn0Nt2qlF1J1Oh0NGjQgJSWFKVOmMGnSJBwdK+65f60rOYX8sCeR7/fEczmniMbeLozoWpfHWvlgb2OZQ15VIi/12muvsWDBAtLT0+/YV36tnMISvt5ymm+2nwFgZLd6vPxAfc0nrEgpSUzLY99ZQ9LeH5/Gmcu5gGHKemt/d9oFetLcy4GIn77l04/nIIQgNjaWgAA1Xr6qSsstKk3shqGjR85lcj6zAAAhoF4NZ1r4udPc140aZLHk05ms+mUlAQEBzJ07lwEDBlTYL/+4lGwW7TjLqkPnKCrR07NxLUZ0rUvn+nfX/30nkZGR1K9f3ywTgP5JJfJSa9as4YknnmDr1q107979nl9/LiOf2RuO81vUeWq62PN67yD6Nq9tlrU1inV6zl7O5fjFbOIuZnP8YjYx5zLK+kTdHG1pF+hBu0BPQgI9ae7rhq21YOXKlUycOJGkpCQGDhzIhx9+aLbhUorluJRdyJHSuQEx5wwt+KvnlpUAz6yTJKybx+XEk8z/cT19HnyAWq72mk/oKijWkZpVSFxKNkv3JLAt7hIOtlY82caP/+tSlwa1qhmtrquzxJs3b87atWuNVu7dUom8VEZGBtWrV2fatGm89957913OwcR0/rvuGIcSMwCoX9OZVnU8aOXvTis/dxrXvv8JMFJKLmQWcKI0WZ+4mMXxi9mcuZRLkU4PGIaf1avhTFMfV9oFetIu0JOGtardMPY1IyOD+vXrU6dOHT7//PP7+vJSqq6UrAJDd8w5Q6s9KuEKSVE7cGzYESEE+af3U71eMN61alDLxZ5aLg6Gn67X/17TxQFXB5t7ahHr9ZLLuYWkZBaSklXAxawCUkt/XswqLPs945olH2q6XO3/DjDJsNg9e/bQqVMnlixZclfX2YztVom8co4tug13d3cefPBBdLryrUXdxt+DVS93ZvfpK0QmpBOVlMGWE6n8cjAZMHRrNPNxpVUdD1r4uWFrbUV+sWEN7Ks3w339dccvZRdy4mI2WQV/r5Fe282BRt4u/KtRTRp7u9DIy5X6tZxv2c+XlpbG/PnzmTx5Mu7u7mzbto3GjRtjbW2Z/YKKdrxcHfBq6kCvpoaRGVJKLmb9ixMXszl7PpWXHnmGbFs7aj71MkVt+3I4KYPU7AIKivU3lGVvY0VNF/u/E76r4XdPZ3sy8otIySwgJauQi1kFpGQVcCm7kJJ/rEBpJQzJ2svVgTqeTrQL9MTL1XDfx92RkEAPk/Z/r1ixAnt7ex5//HGT1XE/qlyL3JSujhg4nJTB4aSMsgtMhSU3ntRgaFU72lrjYGuFg601DrbWuDvaEuTtUpqwXWjs7XrHIWNX6XQ6FixYwNtvv01GRgbbtm2jS5cuxnyLinKdqKgoxo4dy7Zt22jVqhVffPEFXbp0IbuwhNSsQlKzDQn5UnYhqdmGVnTqNb9f22BxcbDB29XB8OXh6oC3m/3fv5f+rFHNTrO14HU6HXXq1KFjx46sWrVKkxhu1SIv736d/wWigcPAn4DP3bzOnHt23k5JSYnJ6ygq0ckTF7Pk8QtZMuFyrkzJzJeZ+UWyqERn1Hq2bt0qW7ZsKQH5wAMPyKioKKOWryi3otfr5YoVK6Sfn5+0traWCQkJd/3a/KISeS49T+YWFpswQuPYu3evBOSKFSs0i4Fb7NlZrha5EMJVSplV+vtYoKmU8qU7vU7rFrlOp6N169b069eP999/X7M4jEWn09GsWTPy8/OZM2cOTz31VIUdUaBUXrm5uYSHh/Pvf/8bgNWrV9OnTx8cHCrP3IS4uDj8/Pw0WzHyVi3ycv2NcjWJl3IGLGLHV2tra1xdXW/Yx9OS5Ofn89FHH5GTk4O1tTVr1qwhNjaWp59+WiVxRRPOzs5lSfz48eP079+fZs2asWbNmkqzGXRQUFCFXPa33J1NQohQIUQSMAh45zbPGyWEiBRCRF66dKm81ZZbjx492L9/P5mZmVqHck+klPz66680bdqUyZMnly0A1qhRowp5gilVU+PGjdm0aRMODg488cQTPPzww8TGxmod1n0LDw/nmWee4fz581qHclN3TORCiM1CiCM3uT0OIKWcKqWsA4QBr96qHCnlAilliJQypCJsBNuzZ0/0er1ZVy4rr6NHj/LQQw8xYMAAnJ2d+euvvxg8eLDWYSnKTfXq1YvDhw/z2WefsW/fPrp27UpeXp7WYd2XH374gT/++ANPT0+tQ7m5m3Wc388N8AeO3M1zK8LFzvz8fGlvby8nTJigdSh3rXfv3tLd3V1+8cUXsri44l8cUpSrUlNT5caNG6WUhoujq1atMstgA2MoKCiQ7u7ucsiQIVqHcsuLneXqWhFCNLzm7uPA8fKUZ04ODg68++67PPDAA1qHcks6nY5vvvmGpKQkAObPn8/Jkyd59dVXK+3yokrlVLNmTXr37g3Ahg0bGDBgAB06dGDXrl0aR3Znf/75JxkZGQwcOFDrUG7tZtn9bm/AL8ARDEMQ1wK+d/O6itAir+h27NghW7duLQH53nvvaR2OohiNXq+XYWFh0sfHRwJy8ODB8ty5c1qHdUuDBg2Snp6esrCwUOtQbtkiL1ezTkr5ZDm/RzQlpeTUqVNYW1tTr149rcMB4Ny5c7zxxhuEhYXh6+vLsmXLKnZLQFHukRCC559/nscee4z333+fuXPncvjwYaKjoyvkiKumTZvSoEED7Owq7k5YVXpmZ3FxMR4eHgwbNowvv/xS63AAePnll1m8eDGvv/46b775Js7OzlqHpCgmdfr0aS5cuEDXrl0pKChgy5YtPPzwwxUyqWvNJOPILZ2trS3dunXTdDy5lJLffvuNgwcPAjBjxgyOHTvGzJkzVRJXqoT69evTtWtXAL755hv69u3Lo48+yokTJzSODA4ePEhRUZHWYdxRlU7kYBiGGBsby4ULF8xe9/Hjx+nbty+PP/542U4jNWvWrDDdPIpibqNHj2bu3Lns3LmT4OBgJk2aRFZW1p1faALZ2dl06dKFKVOmaFL/vajyibxHjx4AbNmyxWx1ZmZmMnHiRJo3b87u3bv55JNPWLRokdnqV5SKys7OjgkTJhAXF8fQoUOZM2eOJsvFAvz2228UFBQwYMAATeq/F1U+kbdu3Ro3Nzezdq8sWLCATz75hGHDhnHy5Elee+01bG1NvzGFolgKLy8vFi5cyL59+5gxYwYAqamp7N2712wx/Pjjj/j6+tK5c2ez1XnfbjaUxdS3ijb8cMeOHfLSpUsmrWP37t1y8+bNUkrDZKQDBw6YtD5FqWxee+01Cchhw4bJCxcumLSutLQ0aWtrW+EmDGKKCUGVRZcuXahRo4ZJyr5w4QIvvPACnTp1Ytq0aYBhMlKbNm1MUp+iVFYzZsxg8uTJhIWFERQUxNy5c012IXL9+vUUFxfz7LPPmqR8o7tZdjf1raK1yAsKCuScOXPkpk2bjFrm7NmzZbVq1aSdnZ2cMmWKzMrKMlr5ilJVnThxQj7yyCMSMFmLWafTyZ07d0q9Xm+S8u8XpliP/H5VlHHkV+n1ery9venTpw9Lly41SpmrVq3iySefpF+/fnz88cc0bNjwzi9SFOWurV+/npYtW+Ln58fJkycRQtCgQQOtwzIpNY78NqysrOjRowfh4eGU54vt5MmT/PrrrwD079+f7du3s3btWpXEFcUEHn30Ufz8/ACYOHEizZo148033yQnJ6dc5S5btoyxY8dSUFBgjDDNQiXyUj179uTcuXOcOnXqnl+bnZ3NG2+8QbNmzRgzZgxFRUUIIcomOSiKYlrz58/nueee44MPPqBRo0b88MMP990oW7BgAZs2bcLe3t7IUZqOSuSlro4nv5dhiHq9nqVLlxIUFMSHH37I4MGDiYyMrNBrMihKZVS7dm2+++47du/ejY+PD0OGDOF///vfPZdz/vx5tm3bxsCBAy1qiQC1Fmqphg0bEhgYSHJy8l2/JioqihdeeIH27duzevVqOnToYMIIFUW5k44dO7J3717CwsLo378/AIcPH8bHx4datWrd8fU///wzUkrLGa1SSl3svEZJSckd1/lOSUlh06ZNZTvzbNu2ja5du2Jlpf64UZSKRkpJ8+bNSU5O5r333uOVV1657eS7Tp06kZ+fz+HDh80X5D1QFzvvwu2SeFFRER9//DFBQUGMHDmS1NRUALp3766SuKJUUEIIVq5cSceOHRk/fjwtW7Zk06ZNN31uSUkJzZo148UXXzRzlOWnMtA1cnNz6d69+w19axs3bqRly5ZMnDiRzp07c/jw4bv6M01RFO01btyYDRs28Ntvv1FYWEjv3r3ZuHHjDc+zsbHh22+/5dVXb7n1cIVllEQuhJgohJBCCNNMjzQTZ2dnThw/znsTJ2JtZUVwYCBfz5vHE088QUlJCWvXruX333+nUaNGWoeqKMo9EELw73//m6NHjzJ//nx69eoFwJ49e1i8aBHBgYGGz3xAAMvDwjSO9j7cbJbQvdyAOsBGIAGocTevqWgzO69a9sMP0tfaWoaDLAIZDrKuk5N8d9o0WVBQoHV4iqIYUU5Ojqzm7Cy9hbjhM7/shx+0Du+mMOFaK58AkwHzXzU1stCpU/lep6MHYAv0ABbm5bFy6VKLGlOqKMqdOTs7412tGsukvOEzHzp1qsbR3ZtyjVoRQjwO9JRSjhNCxAMhUsrLt3juKGAUgL+/f9uEhIT7rtdUrK2sKJCSa69pFwMOQqDT67UKS1EUE7G0z/x9j1oRQmwWQhy5ye1x4C3gnbsJQEq5QEoZIqUMqVmz5r2/AzNo4u/Pjn8c21F6XFGUyqeyfObvmMillL2klMH/vAFngLpAVGlr3A84KITwNm3IpjM1NJQRTk5EYPhWjgBGODkxNTRU48gURTGFyvKZv++ZnVLKGKBsDN6dulYswXODBgEwZupUYhMTaeLvT2hoaNlxRVEql8rymTfazM57SeQVdWanoihKRXarPnKjrbUipQw0VlmKoijK3VMzOxVFUSycSuSKoigWTiVyRVEUC6cSuaIoioXTZD1yIcQlDGuz3I8agMUOcfwH9V4qnsryPkC9l4qqPO8lQEp5w4xKTRJ5eQghIm82/MYSqfdS8VSW9wHqvVRUpngvqmtFURTFwqlEriiKYuEsMZEv0DoAI1LvpeKpLO8D1HupqIz+Xiyuj1xRFEW5niW2yBVFUZRrqESuKIpi4SwykQsh/iuEiBZCHBZC/CmE8NE6pvslhPhICHG89P38KoRw1zqm+yGEeFoIcVQIoRdCWOQwMSFEHyHECSHEKSHEFK3juV9CiEVCiFQhxBGtYykPIUQdIUSEEOJY6bk1TuuY7pcQwkEIsU8IEVX6XqYbtXxL7CMXQrhKKbNKfx8LNJVSvqRxWPdFCNEbCJdSlgghZgNIKd/QOKx7JoRoAuiB+cDrUkqLWqdYCGENxAEPAcnAfuA5KeUxTQO7D0KI7kAOsLR0ExiLJISoDdSWUh4UQrgAB4AnLPT/RADOUsocIYQtho2Ixkkp9xijfItskV9N4qWcseCNn6WUf0opS0rv7sGw05LFkVLGSilPaB1HObQHTkkpz0gpi4AVwOMax3RfpJTbgDSt4ygvKeUFKeXB0t+zgVjAV9uo7o80yCm9a1t6M1resshEDiCECBVCJAGDuMt9Qy3AcGCD1kFUUb5A0jX3k7HQpFEZCSECgdbAXo1DuW9CCGshxGEgFdgkpTTae6mwifwOmz4jpZwqpawDhAGvahvt7d3pvZQ+ZypQguH9VEh38z4UxdiEENWAX4DX/vHXuEWRUuqklK0w/NXdXghhtG4vo+0QZGxSyl53+dQw4HfgXROGUy53ei9CiGFAP+BBWYEvWtzD/4klOgfUuea+X+kxRUOl/cm/AGFSylVax2MMUsoMIUQE0AcwygXpCtsivx0hRMNr7j4OHNcqlvISQvQBJgOPSSnztI6nCtsPNBRC1BVC2AEDgd80jqlKK71AuBCIlVJ+rHU85SGEqHl1RJoQwhHDRXWj5S1LHbXyC9AIwyiJBOAlKaVFtp6EEKcAe+BK6aE9ljgCRwjRH/gCqAlkAIellA9rGtQ9EkI8AnwKWAOLpJSh2kZ0f4QQy4EHMCyXmgK8K6VcqGlQ90EI0RXYDsRg+KwDvCWl/F27qO6PEKIFsATDuWUF/CSlnGG08i0xkSuKoih/s8iuFUVRFOVvKpEriqJYOJXIFUVRLJxK5IqiKBZOJXJFURQLpxK5oiiKhVOJXFEUxcL9PyQQwIB/hwR6AAAAAElFTkSuQmCC", - "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-31T15:56:58.313848\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.2, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 62, - "source": [ - "control_points = np.array([(3 , 1), (2.5, 4), (0, 1), (-2.5, 4),\r\n", - " (-3, 0), (-2.5, -4)])\r\n", - "clamped_knots = [0, 0, 0, 0, 1/3, 2/3, 1, 1, 1, 1]\r\n", - "clamped_bspline = interpolate.splev(np.linspace(0,1),[clamped_knots,[control_points[:,0],control_points[:,1]],3])\r\n", - "plt.plot(clamped_bspline[0],clamped_bspline[1],'b',linewidth=2.0,label='B-spline curve')\r\n", - "plt.plot(control_points[:,0],control_points[:,1],'k--',label='Control polygon',marker='o',markerfacecolor='red')" - ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "[]" - ] - }, - "metadata": {}, - "execution_count": 62 - }, - { - "output_type": "display_data", - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAyxElEQVR4nO3dd3gU5fr4//eTQhJASqSXAIqUgCIakSaYiOUIgg1BQTwfUcCvBQUP4olijYqI5dhRUPAXKVYUVBATBERKaCG0ECChQwBDCSSk3L8/JqEmIcmWye7er+uaa3dnZ2fu2ezeefaZpxgRQSmllOfyszsApZRSjtFErpRSHk4TuVJKeThN5Eop5eE0kSullIcLsOOgtWrVkqZNm9pxaKWU8lgrVqw4ICK1z11vSyJv2rQpCQkJdhxaKaU8ljEmraj1WrWilFIeThO5Ukp5OE3kSinl4TSRK6WUh9NErpRSHs5pidwY42+MWWWMmeWsfdphamwsbZs2xd/Pj7ZNmzI1NtbukJRSLuQN33lnNj8cDmwAqjlxn241NTaW6CFDmHj8OF2BRWlpDB4yBIB7BwywNzillNN5y3feOGMYW2NMI2AyEAOMEJFeJW0fEREhFbEdedumTXk/LY3IM9bFA483aUJSaqpNUSmlXMXTvvPGmBUiEnHeeicl8m+B14GLgKeLSuTGmCHAEICwsLCr09KKbNduK38/P7JECDxjXQ4QbAx5+fl2haWUchFP+84Xl8gdriM3xvQC9ovIipK2E5EJIhIhIhG1a5/Xw7RCaB0WxqJz1i0CmtaqhU7AoZT3yMrK4tVXX6UKFPmdbx0WZkNU5eeMi51dgN7GmFRgGhBljPn/nLBft4uOiWGAMcRj/VeOBwYYw9b0dG655Ra2bdtmc4RKKUf9+OOPhIeH8/zzzxN+zTU8GBJy1nd+cOXKRMfE2Bxl2TicyEXkWRFpJCJNgf5AnIgMdDgyG9xw443sEWFQjRoEG8PjTZow9ssvee+991i7di1+ftpaUylPN2nSJKpUqUJcXBxLli7ltc8+4/EmTQgGegOjxo3zqAudoO3IzzJ//nwAvpszh7z8fJJSU7l/0CCeeOIJUlNTadKkCSLCwIEDmTRpEvkVsA5NKXW2jIwMRowYQUpKCgBffPEFq1atIjLSusR574ABJKWmkpiUxDEgzwOrUZ2ayEVk/oVarFRkcXFxVKtWjauuuuq85ypVqgTAkSNHSE1NZfDgwVx77bX8/fff7g5TKVUKeXl5fP7557Ro0YJ3332XP/74A4CLL76YgIDzW163adOGNm3aMH36dHeH6jAtkZ9h0aJFdOvWrcg/cqHq1auzcOFCYmNj2b17N507d2bQoEEcPHjQjZEqpUqyePFirr32Wh5++GFatmzJihUrGDp06AVf99BDD3HppZeSl5fnhiidx5bxyCuqpUuXliohG2O477776N27N6+99hpTp049VWJXStlv+vTp7N27l6lTp9KvXz+MMaV63ZNPPunawFzEKe3Iy6qidggqr+zsbIKCgsjJyeGuu+5i6NCh9OzZ0+6wlPIZ2dnZvPPOO3Tp0oXrrruOo0eP4ufnR5UqVcq8LxFh8+bNtGjRwgWROsZl7ci9xdixY3nrrbfK9dqgoCAAdu7cSXJyMr169aJnz54kJyc7M0Sl1DlEhJ9//pk2bdrw7LPPMmuWNdTTRRddVK4kDjBhwgRatmzJ1q1bnRmqS2kix/owfPTRRyxZssSh/TRr1ozExETGjx/PokWLaNu2LaNGjSIrK8tJkSqlCm3cuJF//etf9O7dm0qVKjF37lzGjh3r8H5vueUWAGbMmOHwvtxFEzmwbds2tm/ffqo5kiMqVarEiBEjSE5O5v7772fevHkEBgZe+IVKqTL57bff+Pvvv3nnnXdYs2YNN954o1P226RJEzp16sS0adOcsj930ESO1ewQICoqymn7rFu3LhMnTmTx4sX4+/vzzz//0LNnT5YvX+60YyjlS/Lz8/niiy/49ttvAXj00UfZvHkzTz75pNMLS/3792fNmjVs3LjRqft1FU3kQHx8PPXq1aNVq1ZO33dwcDAAycnJrFy5kg4dOjB48GD27dvn9GMp5a2WLl1Kp06dePDBB/n6668BCAwMpE6dOi453t13340xxmPalGsix/pA3HbbbaVuolQe1157LcnJyYwaNYqvvvqKFi1aMH78eB2MS6kS7Nmzh3//+9907NiRHTt28NVXX/Hdd9+5/LgNGjRgzpw5jBw50uXHcgZtfmiD5ORknnrqKQIDA/nxxx/tDkepCmvmzJncc889jBgxgv/+979cdNFFdodkK5eOR15WFSmR5+Xl4e/vb8uxT5w4QUhICCkpKTzzzDOMHTuW5s2b2xKLUhXFr7/+SlpaGsOGDUNE2LVrF40aNbIllrfffpvKlSszbNgwW45/Lm1HXoz+/fvTq5c9w8OEhIQAsHbtWubOnXuqLeyxY8dsiUcpO23evJlevXpx66238sknn5CXl4cxxrYkDlbLmDfffLPCV4H6dCLPz88nLi4Ouye6uOOOO0hOTqZ///688cYbtGzZkqlTp9oak1LucvToUZ555hnatGnDggULeOutt1i2bJltv5TP1L9/f7Zt20ZFqUEojk8n8sTERA4dOuTUZoflVb9+fSZPnszff/9NgwYNWLZsmd0hKeUWKSkpjB8/ngEDBpCcnMzIkSMrzNhFd9xxB4GBgRW+TblPJ/L4+HgAp3QEcpaOHTuydOlSXnvtNQD+/PNPHn74Yfbv329zZEo5T0JCAm+88QYA7du3Z8uWLXzxxRfUq1fP5sjOVrNmTW6++WZmzJhRoecf8OlEHhcXx2WXXWZrHVxR/Pz8TtWfr1mzhi+//JIWLVrw3nvvkZOTY3N0SpXf/v37eeihh+jQoQPvvfceGRkZgNWbsqIaMGAA4eHhHDp0yO5QiiciDi1AMLAMWAOsA1660GuuvvpqqQgmT54sn332md1hXNCGDRvkpptuEkDCw8MlLi7O7pCUKpOTJ0/K22+/LdWqVZPAwEB5+umn5fDhw3aH5XGABCkipzqjRJ4NRIlIO+BK4BZjTEcn7NflBg0axEMPPWR3GBfUqlUrfvvtN2bOnElWVhZr1661OySlyuTAgQOMGTOGzp07s3btWsaNG0e1atXsDqtM9uzZQ25urt1hFMkZky+LiBS2lwssWCp2Wx2sJn9paWl2h1Fqxhh69+7NunXr+H//7/8BEBsby/PPP09mZqbN0Sl1vq1bt/Lcc88hItSvX5/ExER++eUXWrZsaXdoZRYfH0/Dhg35888/7Q6lSE6pIzfG+BtjVgP7gd9FZGkR2wwxxiQYYxLS09OdcViHjBw50rb2444IDg4+NRVdQkICr776Kq1atWL69OkVvq2r8g3Hjh0jOjqa8PBw3n33XTZt2gRYwzy7chgMV7r22mupXLlyxR17paj6lvIuQA0gHmhb0nZ215FnZWVJSEiIPPHEE7bG4QwLFy6U9u3bCyDdunWTxMREu0NSPio/P19iY2OlYcOGAsj9998vu3btsjssp7nvvvskNDRUsrOzbYsBF9aRn/lPIaMgkd/izP0627Jlyzhx4kSFaD/uqK5du7J8+XImTJjA+vXrSU1NtTsk5aOysrIYPXo09erVY/HixUyZMoUGDRqct50IZGbC7t2wYQMsWwarV0NyMuzaBf/8A9nZ1nYVSf/+/Tl06BDz5s2zO5TzODz5sjGmNpAjIhnGmBDgRsDxaTpcKC4uDmMM3bp1szsUp/D39+fhhx+mf//+VK1aFYDx48cTFBTEsGHDTlXFKOVsBw4c4O2332bMmDHk5ITw8cd/cuJEExYt8mPKFNizBw4fPn8pzTVDf3+oXPn00qQJtG0Lbdqcvq1Z0/XnWOimm26ievXqTJs2jVtvvdV9By4FhwfNMsZcAUwG/LHq3GeIyMslvcbuQbO6d+9OZmZmhe92W14iQu/evZk1axZt27blf//7X4Xq9KQ8V2YmJCVBYmIu33zzMfPnjyE39xgXXfQrR470KPV+goOhenVruegiyMmB48etJTPTui1Nl4kGDU4n9csvhxtvBFd2C5kzZw5t2rSxre+Jjn54ht27d7Nv3z7at29vWwyuJiL8+OOPjBgxgtTUVPr27cv48eNp3Lix3aEpDyBilaZXr4Y1a07fJieDyB/AcKxuIzcC7wLhhITAJZecvTRsCDVqnE7ahfdL0wM/JwdOnLAS+7FjsGWL9U8kKQnWrbOWEyfOf13XrtCvH9x9N1SwjqIO00Tuo06cOMH48eN58803WbhwIe3atbM7JFXBiMCOHbBkCSxfbiXt1avhwIHzt/X3F4KCOuHnt5+ePd/h1lt7c+mlhksusZKmOxul5OfDtm1WQk9Ksura58yBwrnO/fyge3e45x646y5w1th433//PVu2bOE///mPc3ZYBprIC3z99dccOXKkwowvXOjECTh61CqF5OZaS+H9wMDTpZmCmePK7MiRI6c6YIwePZqIiAjuuusuj20OpsovMxMSEqzEvWQJLF1qlb7PVaMGXHklhIcfZ8+e8Tz22FC6dKnDvn3bqVOnzqlpDCuSo0fh559h+nT47Tc4edJa7+8PUVEweDD07Wsl+fJ65JFHmDJlCvv376dKlSrOCbyUNJEX6NixI/7+/vz1119uP3ZWlvWlWbUKtm+HtLTTt6VtWh8UdDqp16wJjRtDWNj5S61aRZeOjh8/TpcuXVi9ejWRkZG89957XH755U49T1VxiEBKCixefDpxr10LeXlnb1ezJnTsCB06wFVXQbt20Lix8O233/D000+zY8cOJkyYwMMPP2zPiZRDRgbMnGkl9d9/P32BNSICxo+H8rZ1mD9/PpGRkUyfPp177rnHafGWRnGJ3KntyEu72NWO/PDhw+Lv7y/R0dFuOV5Wlsj8+SIvvihy/fUiQUEi1lfr/CUwUKR2bZEGDUTCwkQuuUSkZUuRNm1ELrtMpE4dkUqVin/9uUuVKiJXXSVy330iL78sMmOGSGKiyIkTIjk5OfLRRx9JaGio+Pv7y2OPPSaHDh1yy3uiXCs7W2TJEpG33hK54w7rM3XuZ8PfX6R9e5FHHhGZPFlk0yaR/Pyz97NmzRrp3r27AHLllVfKggUL7DkhJzl4UOSjj0Tq1z/9Ptx+u3XuZZWbmyv169eXO+64w/mBXgDFtCP3qRL57Nmz6dWrF3/88YdL25CvWwcffghffWVdpDnTFVdAp07WhaCwMKtJVZMmULeu9fOvJCJWqf7wYau0ceAA7NxplerPXNLSrOeLYox17CuugObND7F27RgWL45l3br1NGpU3xmnr9woIwP+/hsWLYK//rJ+8RXWEReqUwc6d7Y+dx07wtVXw4VqBO69915+//13YmJieOihhyrEJA/OkJlplcbffNO6HxAAw4bBCy9Yv2JL68knn+STTz5h//79bh0zRkvkIjJixAgJCgqS48ePO33fJ0+KfPONSPfuZ5d+2rYVefxxke+/FzlwwOmHLdbBgyKLF4tMmiQyapRI794iLVpYpbHzS/D/SEiISEREvrRqNVSGD18gCxaIZGS4L151Yfn5IikpIlOmiAwdKnL55SLGnP/3bNVKZPBgkS++EElOPr+0XZScnBz58MMPJSkpSURE9u7d69W/0nbvFnn4YRE/P+s9q1ZNZOxY6xdraSxevFiuuOIKWbt2rWsDPQfFlMh9KpHff//9csMNNzh1n/n5Il9/LdKo0dnVGo88IuLmv3GpZGdbccXGioweLXLrrWfGvl2gsQAC/QW2yyWXWD/RX3pJZOZMkdTU0iUG5bisLOuf8bhx1t+gbt2iq+Q6dxb5z3+sv096etmPM3/+fLniiisEkNGjRzv/RCqwxESRW245/X5ecYX1Gb+QfJu+BJrIC+Tk5DhtXykpIjfddHZJ6P33RTxxmOVDh0T+/FPkrbcypX37MWJMsEBlgVcETpyVPGrUEOnWzfql8dlnIsuWibjgR45Pyc8X2bJFZNo0kZEjRbp0KfqaSu3aIn36WKXHRYtKX4IsSlpamtxzzz0CSJMmTeTbb7+1LUHZbc4ckebNrfe4Th2Rv/8u3esyMzMlMzPTtcGdQRO5E2Vni8TEiAQHW+9gzZoin38ukpdnd2TOs23bNrnzzrukfv0wmTgxU55+WqRHj6IvnoH1E7VVK5G77xZ54QXr4ur69VaVkzrfrl0iP/4oEh1tFQZCQ4t+X9u0saoAvvyy9NUkpfXf//5XQkJC5KWXXnJJdaOnOXRI5IYbrPc9KMj61VqS1NRUqVKlilsnpykukfvMxc5Ro0axefNmfvjhB4f2k5YGvXtDYqL1eOBA6+JJnTpOCLICOnToEKGhoWRlZfHII4/w9NP/ITQ0nDVrOGvZtOn8Jm1gtYFv2dLqQt2mDbRqBZddBs2bQ8GwMF4tJwc2b4b1662L4KtWWZ1udu8+f9s6deCaa6ylQwfrwqQzxxIREX744QdCQ0O5/vrrOXbsGAcPHqzQ06y5W04OPPEEfPKJ9fj55+HFF4tudy4itGzZkrCwMLcNpOXzFzvDw8Pl5ptvdmgfCQki9epZ/7EvvVTk99+dFJwHWLZsmdSoUUP8/f3lySeflH/++ees50+csN6fyZOti6s9e4o0bVp0KbNwqVdP5LrrRP7v/0Ree826WLxypVXP62m/8LOzRZKSRKZPt36R9O0rEh4uEhBQ9LlXqyYSFSXyzDMi334rkpbm2nNeu3atREVFCSB333236w7kBfLzRf73v9MXQvv2FSmu9uS5554TPz8/2bt3r1tiw5dL5Hv37qV+/fqMHTuWUaNGlWsfv/xidfXNzITISPj+e6tTji9JT0/nueee47PPPqNWrVq89tprPPjgg/iV0E3u2DFrqNLCsTGSk60S6pYtp3vdFSUoyBr8qFEja7yOwvuNGlkl15o1Ty+u7mCYnW2VoHftOn/ZufP0bVEj+hkDzZpBePjpUfuuucb6VeJI78LS+ueff3jhhRf46KOPqFatGq+++ipDhgzRETFL4bffrDFbjhyxOhHNnGkN0nWmdevW0bZtWz744AMeffRRl8fk0z07p06dyn333cfy5cuJiDj/V8mFfPIJPPqoNbbD/ffD55+XbtAfb7Vy5UqeeOIJcnNzWbx4cYmJvDh5eVby27zZ6nm4ebO1bN1qJcbi2sEXJTj47MRes6bVTjog4OwlMPDsx3l5p0fbKxxx79z7R4/CwYMXjqGwfX6bNqeTdni4VZVUuXKZ3x6n+fzzzxk6dCjDhg3j5Zdf5uKLL7YvGA+0fj3cdpv1uQwLs8ZzqVv37G3atm1LaGgoCxYscHk8Pp3IhwwZwowZMzh48GCZOza8+y489ZR1//nn4aWX3DswUEUlIhw6dIiLL76Y/fv3Ex0dzUsvvVTkRALlcezY6ZLuuUt6ujX5QOHi6vlw/f2hfv3Tvw6KWho1gpAQ18ZRWn/99Rf79u3jzjvvJC8vj40bN9KmTRu7w/JYBw5Az55WEu/UCeLjrV+Mhf744w9CQ0PdMpqqTyfyTz75hF27dvHKK6+U6XU//wx9+li1mp99Bg895KIAPdyPP/5Iv379CAwM5LnnnuOpp54i6MxPuguJWCXnMxP7P/9YvRvPHXzs3MUYq+RepYpVai7qfpUqVo8/T+jYuGvXLkaNGsXXX3/NlVdeycqVK3VQNCfZt8+qEtuxAx54AL74wp4Cnc9f7Cyr1autjj0g8sordkdT8aWkpEifPn0EkEsvvVR++uknu0PyGSdOnJCYmBipUqWKBAUFyZgxY9zattlXrFwpUrmylRPeeuvs5/7++2956aWXXB4DrmpHDjTGmqdzPdZI88Mv9Bp3JvKdO3fKkSNHyvSa3btP93YcONDzWlDYac6cOdKqVSvp16+f3aH4jD/++EMAufPOO2Xr1q12h+PVvvlGTvWb+OWX0+vffPNNAWTLli0uPb4rE3l94KqC+xcByUB4Sa9xZyIfNGiQ1K9fv9Q91jIzRa65xnpnunSxukmrsjl58uSpcTrWrl0rI0eOlMOe2N21Alu/fr188cUXpx6vWrXKtlh8zYsvnm5Cun69tS41NVUAef311116bJcl8vN2CDOBG0vaxl2JPD8/Xxo1aiR9+/Yt9WuGD7felWbNRPbvd11svuLdd98VY4zUrVtXJk2aJHne1P3VBhkZGfLUU09JQECA1KlTR44dO2Z3SD4nL8/qwQxWt/6DB631nTp1knbt2rn02G5J5EBTYDtQrYjnhgAJQEJYWJhLT7ZQcnKyAPLxxx+XavulS63R5Pz9rfow5RzLli2Tjh07CiAdOnSQJUuW2B2Sx8nLy5OJEydKnTp1xBgjQ4YMkf1a0rDNsWMiV15pZdAbbrCGonjvvfcEkA0bNrjsuC5P5EBVYAVw54W2dVeJ/NNPPxVANpVi9PiTJ0XatbPekVGjXB+br8nLy5MpU6ZIvXr1fG6EPWdITk6WgIAA6dKli6xYscLucJRYvXELR6SMjhbZtWuXNGzYUH45s/LcyVyayIFAYA4wojTbuyuR9+vXTxo0aFCq+vGxY09XqegFf9c5cuTIqeqAuXPnyrhx4yQ7O9vmqCqmXbt2yQcffHDq8YoVK3x2dMKKasECK29UqiSyebPrh7d15cVOA0wB3i3ta9yVyJOSkkr13zElRSQkxHo35sxxQ2BKREQef/xxAaRFixYuLcV4mqysLHnjjTekatWqUqlSJUktzQDZyjYPPGDljj59rMd5eXkuu3bhykTeFRAgEVhdsNxa0msqWjvym2+23okBA+yOxPfMnj1bLrvsMgGkZ8+ekpycbHdItpo1a5Y0b95cAOndu7ds3rzZ7pDUBezeLVK1qpVDZs3KkqZNm8qzzz7rkmO5rdVKaRZ3JPK4uDiZOnXqBVtJLFwopyZL2LfP5WGpImRnZ8ubb74pVatWlQkTJtgdjm0yMjKkRo0a0rJlS/n111/tDkeVwRtvWHmkdWuRm266WZo1a+aSahafS+S33367NGvW7ILb3Xqr9S48/7zLQ1IXsHfvXsnNzRURka+++kqmTJni9c0VDx8+LO+8886p81y5cqVeM/BAWVmnZxi6995JAsiyZcucfpziErkbBtJ0v7y8PObPn09UVFSJ261ZYw1PW7myNZi8slfdunVPDWoWGxvLoEGD6Nq1K+6ehMQd8vPzmTx5Mi1atOCpp57ir7/+AqB9+/ZU8uWhNT1UUBC8/bZ1f/bsOwgMDGTatGluO75XJvI1a9aQkZFBZGRkiduNHWvdPvywNTCSqjhmz57NpEmT2LJlCx06dOChhx5i//79doflFMuXL6dz5878+9//pmnTpixdupTrrrvO7rCUg3r1gptugiNHatCgwb+YMWMG+fn57jl4UcV0Vy+urloZN26cALJr165it0lJscZLCAiw2oOqiikjI0NGjhwpAQEBMnfuXLvDcVhubq60aNFC6tatK5MnT/b6qiNfs3594axQi+V//5t9qqrQWfClqpXExERatWpV4tjY48ZZE0UMHGgNGK8qpurVq/PWW2+xbds2brzxRgDee+895s6da3NkpXfy5Ek+/PBDMjMz8ff357vvviM5OZlBgwaVa1IOVXG1bg2PPQbQiW+/vRU/PzeNf1xUdnf14uoSeX5+vhwsHAChCIcOWbNkGyPiwt60ygWys7OldevWAkifPn1cPtqco3799Vdp2bKlAPLll1/aHY5yg3/+EalVSwRSpF+/lyQnJ8dp+8aXSuTGGEJDQ4t9/ocfrHkYo6KsqbiU56hUqRKrVq3i9ddfZ968eYSHhxMdHc2xY8fsDu0sKSkp9O7dm3/961/k5eUxa9YsHnjgAbvDUm5QowaMGQOwmunTX+DPP/90+TG9LpF/9NFHDBw4kLy8vGK3mTrVur33XjcFpZwqKCiI0aNHs2nTJvr27cu4cePYsWOH3WGd5dFHHyU+Pp6xY8eSlJREz5497Q5JudEDD0DlyrcCVfn4Y9e3XvG6qd569OhBeno6a9asKfL5ffusmbD9/a37NWu6JAzlRtu3byes4ELHyy+/zG233eaW+RPPJCLExsYSGRlJw4YN2bJlCyEhIU6bw1R5nmHD4NNPBxIc/CuHD+9xSrPS4qZ686oSeVZWFn/99VeJ7ce//da6yHnLLZrEvUVhEt+/fz8ffPABV199NUOHDiU9Pd0tx1+xYgVdu3bl/vvv59NPPwXg0ksv1STu4x55BKA/WVmHmDVrnkuP5VWJfMmSJWRlZZWYyAvb6Pfv76aglNvUqVOH5ORkhg8fzsSJE2nRogXvv/8+ubm5Ljleeno6Q4YM4ZprriElJYWJEyfy4osvuuRYyvO0awfXXnsT0IDvvtvm2oMVdQXU1YurWq2MGTNG/Pz8JCMjo8jn09KsLrQhISJHj7okBFVBrFu3Tnr06CE1atSQ9PR0lxxj2LBhEhAQICNGjCj2M6d825QpIpAjV13lnLl/8YVWK7Vq1aJ///5Ur169yOdnzLBue/WCqlXdGJhyu/DwcObOncuqVauoVasW+fn5jB49mtTUVIf2O2/ePBITEwF48cUXSUxMZPz48cV+5pRv69sXQkMDWLkSFi/Odt2Bisrurl7sGsa2Rw+rRD5tmi2HVzZavXq1hISESHBwsIwZM0Yyyzh7yNatW+WOO+4QQO69914XRam80ciRInCLNGvWz+F94e0l8qNHj5ZYF5qTA4sXW/evv949MamKo127dmzatInbb7+dl19+mVatWjFjxgzkAq22MjMzef7552ndujVz5szhtddeY9KkSW6KWnmDoUMBmrFt28/s3JnpkmM4JZEbYyYZY/YbY5Kcsb/yiImJoX79+pw8ebLI51euhOPHoWVLqFvXzcGpCqFx48ZMnTqVP//8k9DQUJ577jlycnIAmBobS9umTfH386Nt06ZMjY0F4OOPP+bVV1/lrrvuYtOmTTz77LMEBwfbeRrKw1x2GVx9dT/gOBGtzv+MOUOAk/bzJfAB1pRvtoiPj6dVq1bFttVcsMC67dbNjUGpCqlbt26sWLGCnTt3UqlSJb6YNIkxQ4cyJTeXrsCitDT+b/BgwOrY07lzZzp37mxv0Mqjdem8nZ0rYGrmgVOfscFDhgBw74ABjh+gqPqW8ixAUyCpNNs6u448IyND/Pz8ZMyYMcVu06uXVT/+1VdOPbTyApfUri1xYH1ACpY4kDZhYXaHprxEm7AmRX/GmjQp036wu47cGDPEGJNgjElwdkeNBQsWkJ+fX2z78bw8WLjQuq8lcnWu1ANWKelMXYENFazbv/JcG3ZsL/oztn27U/bvtkQuIhNEJEJEImrXru3UfcfHxxMcHEzHjh2LfD4pCQ4fhiZNdMhadb7WYWEsOmfdooL1SjmDqz9jXtFq5Z577uH9998nKCioyOe1flyVJDomhsGVKxMP5ADxwODKlYmOibE5MuUtXP0Zc9bFTlt17Nix2NI4wJIl1m3Xc3/bKMXpi02PR0ezYft2WoeFERMT45yLUErh+s+YU0Y/NMZMBa4HagH7gBdEZGJx2ztz9MOkpCT2799Pt27dCAgo+v/SVVfBqlVWO/JOnZxyWKWUcrviRj90SolcRGwb2fvjjz9mypQpHDp0qMjn8/Nh0ybrvk4ioZTyRh5fRx4XF8d1111HYGBgkc/v3Gl1BKpbV4etVUp5J49O5Lt372bjxo0lDlu7caN1q6VxpZS38uhEPn/+fAAiIyOL3UYTuVLK23l0Il+4cCE1atTgyiuvLHYbTeRKKW/n0Yn8/fffZ+nSpfj7+xe7jSZypZS38+hEHhAQQIsWLUrcRhO5UsrbeWwi/+mnn3jyySfJzCx+fN8jR2DPHggO1q75Sinv5bGJ/JtvvuHrr7+mcuXKxW6zZ49127Ah+HnsmSqlVMk8Mr2JCHFxcURFRWGMKXa7/fut2zp13BSYUkrZwCMT+ebNm9m9e3eJzQ4BCkfLdfJgi0opVaF4ZCKPi4sDKLEjEGgiV0r5Bo9M5NnZ2Vx99dU0b968xO20akUp5Qs8MpEPHz6chISEEuvHQUvkSinf4HGJPC8vr9TbaiJXSvkCj0vkH3zwAZdccgmHDx++4LZataKU8gUel8jj4uLw8/OjevXqF9xWS+RKKV/glERujLnFGLPJGJNijBntjH2ea2psLG2bNOHnn34ic98+psbGXvA1msiVUr7A4RmCjDH+wIfAjcBOYLkx5icRWe/ovgtNjY0lesgQJh4/Tldg0bFjDB4yBKDEOe+OHLFuS1F4V0opj+WMEnkHIEVEtorISWAa0McJ+z0lJjqaicePEwkEApHAxOPHiYmOLvF1OTnWbaVKzoxGKaUqFmck8obAjjMe7yxYdxZjzBBjTIIxJiG9sM6jlDZs307Xc9Z1LVhfHJHTibyYWeCUUsoruO1ip4hMEJEIEYmoXcZK69ZhYSw6Z92igvXFyc21bv38dMAspZR3c0aK2wU0PuNxo4J1ThMdE8PgypWJB3KAeGBw5cpEx8QU+xqtVlFK+QqHL3YCy4HLjDHNsBJ4f+A+J+z3lMILmo9HR7M+LY0agYF8OGFCiRc6tVpFKeUrHC6Ri0gu8BgwB9gAzBCRdY7u91z3DhhAUmoqr8bE8E9ODj1uuqnE7TWRK6V8hVNqj0XkFxFpISKXikjx9R1OUDji4fz580vcThO5UspXeNxlwIiICC666KJTQ9kWRxO5UspXeFwiDwgI4LrrriM+Pr7E7TSRK6V8hTMudrrdG2+8QZUqVUrcRlutKKV8hUcm8ssvv/yC2xSOdqttyJVS3s5j09zXX3/NhAkTin0+ONi6zcpyU0BKKWUTj03k3377La+//nqxz4eEWLcnTrgpIKWUsonHJvKoqChSU1PZtm1bkc9rIldK+QqPTuRAsc0QK1e2bo8fd1dESillD49N5K1bt6Zu3brFNkOsVAmMsVqvlGGaT6WU8jgem8iNMURFRbG/cGLO857X6hWllG/wyOaHhaZMmUJAQPGnEBJiVa2cOAFVq7oxMKWUciOPLZEDJSZx0BK5Uso3eHQiBxg6dCiDBw8u8jlN5EopX+DxiTw7O5uZM2eSn59/3nOFLVc0kSulvJnHJ/KoqCgOHjzI2rVrz3uusESuTRCVUt7M4xN5ZGQkQJHNELUtuVLKFziUyI0xfY0x64wx+caYCGcFVRaNGzemefPmRXYMCg21bg8edHNQSinlRo42P0wC7gQ+dUIs5TZ06FByc3PPW1+njnWbnu7mgJRSyo0cSuQisgGszjl2evrpp4tcX7u2dVtMnyGllPIKbqsjN8YMMcYkGGMS0l1QRD5x4gTbt28/a11hiVwTuVLKm12wRG6MmQfUK+KpaBGZWdoDicgEYAJARESElDrCUurSpQu1a9dmzpw5p9ZpIldK+YILJnIR6eGOQBzVtWtXJk6cyMmTJ6lUML+b1pErpXyBxzc/LBQZGcnx48dZtmzZqXVaR66U8gWONj+8wxizE+gEzDbGzLnQa1yle/fuGGPOaoaoVStKKV/gUCIXkR9EpJGIBIlIXRG52VmBlVVoaCjt27c/K5HXrAn+/pCRASdP2hWZUkq5lkcPY3uucePGUa1atVOP/fys6pW9e6168oYNbQxOKaVcxKsSeeH0b2fSRK6U8nZec7Gz0KxZs5g1a9apx1pPrpTydl5VIgd47bXXEBF69eoFnE7k+/bZGJRSSrmQ15XIIyMjWb58OUePHgWgQQNr/c6dNgallFIu5HWJPCoqiry8PBYuXAhAs2bW+m3bbAxKKaVcyOsSeefOnalUqdKpZoiayJVS3s7rEnlISAidOnUiMTER0ESulPJ+XnexE+D777+nZs2aADRtaq3bvh3y8qwOQkop5U28rkQOVi/PwjHSQ0Kgfn3IyYFdu2wOTCmlXMArEznA448/TkxMDHC6emXrVhsDUkopF/HaRJ6cnMy0adMArSdXSnk3r03kUVFRJCUlsW/fPk3kSimv5rWJPDIyEoD58+drIldKeTWvTeRXXXUV1apVIy4uThO5UsqrOTqxxDhjzEZjTKIx5gdjTA0nxeWwgIAABg4cSP369bnkEmudJnKllDcyIuWfB9kYcxMQJyK5xpixACLyzIVeFxERIQkJCeU+blnl5UFwMOTmwokT1n2llPI0xpgVIhJx7npHZwiaKyK5BQ+XAI0c2Z8r5Ofnk5l5hLAw63Fqqq3hKKWU0zmzjvxB4NfinjTGDDHGJBhjEtLdOK1927ZtGT58+KnqlZQUtx1aKaXc4oKJ3BgzzxiTVMTS54xtooFcILa4/YjIBBGJEJGI2oXT27tBeHg4cXFxtG5tVSGtW+e2QyullFtccKwVEelR0vPGmH8DvYAbxJEKdxeJioriu+++o27drcClmsiVUl7H0VYrtwCjgN4ictw5ITlXYXvyo0fjAUhKsjMapZRyPkfryD8ALgJ+N8asNsZ84oSYnKpVq1bUq1ePLVus8ck3bLBasSillLdwaBhbEWnurEBcxRjDuHHjaNCgAUuWWFO+bd0Kl11md2RKKeUcXjke+bkGDhwIQNu2ViJft04TuVLKe3htF/0ziQiLFy/m4ouXA1pPrpTyLj5RIge47777qFXrauA7TeRKKa/iEyVyYwxRUVFs3jwfyNcmiEopr+ITiRysZohHjhwCEtm0yZr6TSmlvIFPJXKA0NA4cnJg82abA1JKKSfxmUTeqFEjWrRoQWDgAkAveCqlvIfPJHKA2bNnc//90wEdc0Up5T18ptUKQPPmzWnXzrqvJXKllLfwqRJ5fn4+f/wxGpiiiVwp5TV8KpH7+fmRkPALxnzF5s1w5IjdESmllON8KpED3HBDFMb8hUg2K1bYHY1SSjnO5xJ5ZGQk+fkngKUsX253NEop5TifS+Tdu3fHGD8gThO5Usor+Fwir1GjBh073gDkaSJXSnkFn2p+WGjhwrlUrw5paZCeDm6cQlQppZzO0aneXjHGJBbMDjTXGNPAWYG5kr8/XHUVaKlcKeUNHK1aGSciV4jIlcAsYIzjIbleXl4eGzZcATyviVwp5fEcSuQicmZL7CqAOBaOe/j7+xMaWg294KmU8gYOX+w0xsQYY3YAAyihRG6MGWKMSTDGJKSnpzt6WIf16BEJLGfp0sOIR/z7UUqpol0wkRtj5hljkopY+gCISLSINAZigceK24+ITBCRCBGJqF0Bri7edVcUkM+BAwvZscPuaJRSqvwu2GpFRHqUcl+xwC/ACw5F5CadO3fCzy+I/Px4li/vRViY3REppVT5ONpq5cy56PsAGx0Lx32Cg4Pp1u0F4HqtJ1dKeTRH25G/YYxpCeQDacAwx0Nyn+HDn2X+fEhIsDsSpZQqP4cSuYjc5axA7BARIUAKy5b5k59/CX4+189VKeUNfDp11a2bizHtOXr0bVJS7I5GKaXKx6cTeWBgILVrXwfE8fffdkejlFLl49OJHOCaa6KADcyZs8fuUJRSqlx8PpH37RsJQHz8fHsDUUqpcvL5RN6vX3ugOnv3xrF3r93RKKVU2fl8Ig8O9ueaa2YDr7Nwod3RKKVU2fl8Ige47bYuQC1N5Eopj6SJHOjYMRsYz+zZ8+wORSmlykwTOdC5cyAwlq1bp5CRYXc0SilVNprIgSpV/Lj44kggjkWLdExbpZRn0URewGpPvouZM7WLp1LKs2giL3DnnVZ78ri4OJsjUUqpstFEXqBv38uApmzbtpPjx+2ORimlSk8TeYEaNQxXXrkZkVdYssTuaJRSqvQ0kZ+he3drVF9tT66U8iSayM/QoUMm0I2pUz+xOxSllCo1pyRyY8xIY4wYY2o5Y3926dGjCrCRXZtG4O/nR9umTZkaG2t3WEopVSJHp3rDGNMYuAnY7ng49vrj91jqcoip5NFVYFFaGoOHDAHg3gEDbI5OKaWK5owS+TvAKMDje9LEREczlTwigUAgEph4/Dgx0dE2R6aUUsVzKJEbY/oAu0RkTSm2HWKMSTDGJKSnpztyWJfZsH07Xc9Z17VgvVJKVVQXrFoxxswD6hXxVDTwX6xqlQsSkQnABIAIa9bjCqd1WBiL0tKIPGPdooL1SilVUV2wRC4iPUSk7bkLsBVoBqwxxqQCjYCVxpiikr5HiI6JYXDlysQDOUA8MLhyZaJjYmyOTCmlilfui50ishaoU/i4IJlHiMgBJ8Rli8ILmo9HR7Nh+3Zah4URExOjFzqVUhWaEXFOLUdZEnlERIQkJCQ45bhKKeUrjDErRCTi3PUONz8sJCJNnbUvpZRSpac9O5VSysNpIldKKQ+niVwppTycJnKllPJwTmu1UqaDGpMOpJXz5bUAj23ieA49l4rHW84D9FwqKkfOpYmI1D53pS2J3BHGmISimt94Ij2XisdbzgP0XCoqV5yLVq0opZSH00SulFIezhMT+QS7A3AiPZeKx1vOA/RcKiqnn4vH1ZErpZQ6myeWyJVSSp1BE7lSSnk4j0zkxphXjDGJxpjVxpi5xpgGdsdUXsaYccaYjQXn84MxpobdMZWHMaavMWadMSbfGOORzcSMMbcYYzYZY1KMMaPtjqe8jDGTjDH7jTFJdsfiCGNMY2NMvDFmfcFna7jdMZWXMSbYGLPMGLOm4Fxecur+PbGO3BhTTUSOFNx/AggXkWE2h1UuxpibgDgRyTXGjAUQkWdsDqvMjDGtgXzgU+BpEfGocYqNMf5AMnAjsBNYDtwrIuttDawcjDHdgGPAlIJJYDySMaY+UF9EVhpjLgJWALd76N/EAFVE5JgxJhBr8rHhIrLEGfv3yBJ5YRIvUAUPnvhZROaKSG7BwyVYMy15HBHZICKb7I7DAR2AFBHZKiIngWlAH5tjKhcRWQAcsjsOR4nIHhFZWXD/KLABaGhvVOUjlmMFDwMLFqflLY9M5ADGmBhjzA5gADDG7nic5EHgV7uD8FENgR1nPN6JhyYNb2SMaQq0B5baHEq5GWP8jTGrgf3A7yLitHOpsIncGDPPGJNUxNIHQESiRaQxEAs8Zm+0JbvQuRRsEw3kYp1PhVSa81DK2YwxVYHvgCfP+TXuUUQkT0SuxPrV3cEY47RqL6fNEORsItKjlJvGAr8AL7gwHIdc6FyMMf8GegE3SAW+aFGGv4kn2gU0PuNxo4J1ykYF9cnfAbEi8r3d8TiDiGQYY+KBWwCnXJCusCXykhhjLjvjYR9go12xOMoYcwswCugtIsftjseHLQcuM8Y0M8ZUAvoDP9kck08ruEA4EdggIm/bHY8jjDG1C1ukGWNCsC6qOy1veWqrle+AllitJNKAYSLikaUnY0wKEAQcLFi1xBNb4Bhj7gDeB2oDGcBqEbnZ1qDKyBhzK/Au4A9MEpEYeyMqH2PMVOB6rOFS9wEviMhEW4MqB2NMV2AhsBbruw7wXxH5xb6oyscYcwUwGeuz5QfMEJGXnbZ/T0zkSimlTvPIqhWllFKnaSJXSikPp4lcKaU8nCZypZTycJrIlVLKw2kiV0opD6eJXCmlPNz/D7dmkmxNrnjjAAAAAElFTkSuQmCC", - "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-31T16:06:59.684125\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.2, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 73, - "source": [ - "control_points = np.array([(3 , 1), (2.5, 4), (0, 1), (-2.5, 4),\r\n", - " (-3, 0), (-2.5, -4)])\r\n", - "unclamped_knots = [-0.9, -0.6, -0.3, 0, 1/3, 2/3, 1, 1.3, 1.6, 1.9]\r\n", - "unclamped_bspline = interpolate.splev(np.linspace(0,1),[unclamped_knots,[control_points[:,0],control_points[:,1]],3])\r\n", - "plt.plot(unclamped_bspline[0],unclamped_bspline[1],'b',linewidth=2.0,label='B-spline curve')\r\n", - "plt.plot(control_points[:,0],control_points[:,1],'k--',label='Control polygon',marker='o',markerfacecolor='red')" - ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "[]" - ] - }, - "metadata": {}, - "execution_count": 73 - }, - { - "output_type": "display_data", - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAwy0lEQVR4nO3deVxVdf7H8deXRVRcSc0VsNxQsyxGcy0wbdGxbSonbZnRrH5TaTajJmXbUJlpNdWUNlpqqNlqWZkaaJq5oCZQKG64KyZpKqICn98fBxAUVLjn3sPlfp6Px3kg5957zufg5c253/M9368REZRSSnkvP6cLUEop5RoNcqWU8nIa5Eop5eU0yJVSystpkCullJcLcGKn9erVk/DwcCd2rZRSXmvNmjW/iUj9M9c7EuTh4eEkJiY6sWullPJaxpjtJa3XphWllPJyGuRKKeXlNMiVUsrLaZArpZSX0yBXSikvZ1uQG2P8jTHrjDHz7NqmE2bFxdE+PBx/Pz/ah4czKy7O6ZKUUm5UGX7n7ex+OAxIBWrZuE2PmhUXR8zQoUzJyqI7sGz7dgYPHQrAXwcOdLY4pZTtKsvvvLFjGFtjTFNgGhALjBCRfud6fmRkpFTEfuTtw8N5c/t2ooqsSwAeDQsjJT3doaqUUu7ibb/zxpg1IhJ51nqbgvwT4CWgJvDPkoLcGDMUGAoQGhp61fbtJfZrd5S/nx/ZIgQWWXcKqGoMuXl5TpWllHITb/udLy3IXW4jN8b0AzJEZM25nicik0UkUkQi69c/6w7TCiEiNJRlZ6xbBoTXq4dOwKFU5ZGdnc2///1vgqHE3/mI0FAHqio/Oy52dgP6G2PSgdlAtDHmQxu263ExsbEMNIYErL/KCcBAY9h64AA33HAD27Ztc7hCpZSrvvjiC9q2bcvTTz9N2z/9ib9Xq1bsd35w9erExMY6XGXZuBzkIvKkiDQVkXBgABAvIoNcrswBvXr3Zq8I99apQ1VjeDQsjHEffMAbb7xBcnIyfn7aW1Mpbzd16lSCg4OJj49nxcqVvPjeezwaFkZVoD8wcvx4r7rQCdqPvJjFixcD8Ol335Gbl0dKejr33Hsvjz32GOnp6YSFhSEiDBo0iKlTp5JXAdvQlFLFHTp0iBEjRrB582YA3n//fdatW0dUlHWJ868DB5KSnk5SSgpHgVwvbEa1NchFZPH5eqxUZPHx8dSqVYsrr7zyrMeqVKkCwB9//EF6ejqDBw+mc+fO/PTTT54uUyl1AXJzc/nf//5Hq1ateP311/n+++8BuOiiiwgIOLvndbt27WjXrh0fffSRp0t1mZ6RF7Fs2TJ69uxZ4n9ygdq1a7N06VLi4uLYs2cPXbt25d577+XgwYMerFQpdS7Lly+nc+fOPPDAA7Ru3Zo1a9bw4IMPnvd1Q4YM4dJLLyU3N9cDVdrHkfHIK6qVK1deUCAbY7j77rvp378/L774IrNmzSo8Y1dKOe+jjz5i3759zJo1i7vuugtjzAW9bvjw4e4tzE1s6UdeVhX1hqDyOnHiBEFBQZw6dYrbb7+dBx98kL59+zpdllI+48SJE7z22mt069aNHj16cOTIEfz8/AgODi7ztkSETZs20apVKzdU6hq39SOvLMaNG8err75artcGBQUBsGvXLtLS0ujXrx99+/YlLS3NzhKVUmcQEb766ivatWvHk08+ybx51lBPNWvWLFeIA0yePJnWrVuzdetWO0t1Kw1yrDfDf//7X1asWOHSdpo3b05SUhITJkxg2bJltG/fnpEjR5KdnW1TpUqpAhs2bODGG2+kf//+VKlShQULFjBu3DiXt3vDDTcAMGfOHJe35Ska5MC2bdvYsWNHYXckV1SpUoURI0aQlpbGPffcw6JFiwgMDDz/C5VSZTJ//nx++uknXnvtNdavX0/v3r1t2W5YWBhdunRh9uzZtmzPEzTIsbodAkRHR9u2zYsvvpgpU6awfPly/P39+f333+nbty+rV6+2bR9K+ZK8vDzef/99PvnkEwD+8Y9/sGnTJoYPH277ydKAAQNYv349GzZssHW77qJBDiQkJNCwYUPatGlj+7arVq0KQFpaGmvXrqVTp04MHjyY/fv3274vpSqrlStX0qVLF/7+978zc+ZMAAIDA2nQoIFb9veXv/wFY4zX9CnXIMd6Q/z5z3++4C5K5dG5c2fS0tIYOXIkM2bMoFWrVkyYMEEH41LqHPbu3cv999/P1Vdfzc6dO5kxYwaffvqp2/fbuHFjvvvuO5544gm378sO2v3QAWlpaTz++OMEBgbyxRdfOF2OUhXW3LlzufPOOxkxYgRjxoyhZs2aTpfkKLeOR15WFSnIc3Nz8ff3d2Tfx48fp1q1amzevJlRo0Yxbtw4WrRo4UgtSlUU3377Ldu3b+ehhx5CRNi9ezdNmzZ1pJaJEydSvXp1HnroIUf2fybtR16KAQMG0K+fM8PDVKtWDYDk5GQWLFhQ2Bf26NGjjtSjlJM2bdpEv379uOmmm3j33XfJzc3FGONYiIPVM+aVV16p8E2gPh3keXl5xMfH4/REF7feeitpaWkMGDCAl19+mdatWzNr1ixHa1LKU44cOcKoUaNo164dP/zwA6+++iqrVq1y7JNyUQMGDGDbtm1UlBaE0vh0kCclJZGZmWlrt8PyatSoEdOmTeOnn36icePGrFq1yumSlPKIzZs3M2HCBAYOHEhaWhpPPPFEhRm76NZbbyUwMLDC9yn36SBPSEgAsOVGILtcffXVrFy5khdffBGAJUuW8MADD5CRkeFwZUrZJzExkZdffhmAjh07smXLFt5//30aNmzocGXF1a1bl+uvv545c+ZU6PkHfDrI4+PjadmypaNtcCXx8/MrbD9fv349H3zwAa1ateKNN97g1KlTDlenVPllZGQwZMgQOnXqxBtvvMGhQ4cA627KimrgwIG0bduWzMxMp0spnYi4tABVgVXAeuAX4Lnzveaqq66SimDatGny3nvvOV3GeaWmpkqfPn0EkLZt20p8fLzTJSlVJidPnpSJEydKrVq1JDAwUP75z3/K4cOHnS7L6wCJUkKm2nFGfgKIFpHLgSuAG4wxV9uwXbe79957GTJkiNNlnFebNm2YP38+c+fOJTs7m+TkZKdLUqpMfvvtN8aOHUvXrl1JTk5m/Pjx1KpVy+myymTv3r3k5OQ4XUaJXJ5YIv+vREF/ucD8pWL31cHq8lerVq0K/ZGuKGMM/fv3p0+fPoUzGMXFxbFhwwZGjx5d7iE7lXKXrVu3MnXqVF544QUaNWpEUlIS4eHhZbqD+vhxSE2FlBTYsgX27YO9e09/PXgQjAE/v+LLrFnQp499x5KQkECvXr1YuHAhvXr1sm/DdinpNL2sC+AP/IwV6ONKec5QIBFIDA0N9cSnkHPq3bu3tG/f3ukyXDJ8+HABpGnTpjJ79mzJy8tzuiSl5MiRIzJmzBgJCgqS4OBgSU1NvaDXHTokMn++yLPPitx+u0irViJ+fiJQ9uXrr+09pmPHjklwcLA88MAD9m64jCilacWWIC/cGNQBEoD253qe023k2dnZUq1aNXnsscccrcMOS5culY4dOwogPXv2lKSkJKdLUj4qLy9P4uLipEmTJgLIPffcI7t37y71+enpIh9+KPLwwyIdOogYc3Yg+/uLtGkjcscdIjExIm+/LfLZZyLLl4ts2yZy5IjI0aMif/xh/SHIzBT57TeREyfsP767775bQkJC5IQ7Nn6BSgtyW+fsFJFDxpgE4AYgxc5t22nVqlUcP368QvQfd1X37t1ZvXo1U6dOZcyYMaSnp3PZZZc5XZbyQdnZ2YwePZqGDRvy8ccf06VLl2KPHzoECQmwYAEsXGg1lRQVGAhXXQVdu0LHjtC+PbRpA/kDiDpuwIABzJw5k0WLFnHTTTc5XU4xLge5MaY+cCo/xKsBvQHXp+lwo/j4eIwx9OzZ0/ZtnzgBmzZZ7XqpqbBhg/WGzcqyHitYTp6EmjXhoosgJOT010aNoFUra2nZ0nrO+fj7+/PAAw8wYMAAatSoAcCECRMICgrioYceKmxTV8puv/32GxMnTmTs2LFUq1aNJUuWEBYWhp+fH3l5sHo1fPutFd4rV0LRrth16kD37tCtm7VERkJ+r9sKqU+fPtSuXZvZs2dXuCC3ozmlA7AOSMI6Cx97vtc43bTSs2dPsbOGgwdFPvhApH9/kapVy9emV9rSqJHINdeIPPKItY+UFJGcnHPXk5eXJ/369RNA2rdvr90Vle1OnTol//nPf6ROnToSEBAgCxcuFBGriePTT0X+9jeRBg2Kv5cDAkR69BB54QWRFSvO/z6uiObPny87d+50bP+U0rTik6Mf7tmzh/3799OxY8dybyMvD774At55x/q4mJt7+rEWLSAiwvpYGBFhnVnXqgVBQaeXwED44w/IzLSWgwetZdcuSEuzls2brbP3MwUHw5VXWmcwXbpAz55w8cXFnyMifPHFF4wYMYL09HTuuOMOJkyYQLNmzcp9zEoBfP/99wwbNoxffvmF3r17M2rU66SmtuWrr2DxYuvTZoGwMOjXD66/Hq699sI+YarS6TC2NikI8Oeeg6Qka52/P0RFwW23wc03Q+PG9uwrNxd27oSNG2HdOkhMtJbt289+buvWVqBfc431tSCvjx8/zoQJE3jllVdYunQpl19+uT3FKZ8kInTp0oXduzO45prX2LChP2vWnO5OaIx1cvHnP1sB3q6dta4y+eyzz9iyZQv/+te/PL5vDfJ8M2fO5I8//ijX+MIJCTB8+OkAb9IERo+Gu++22rc95cABWLMGVq2CZctg+XI4dqz4cy65BK67zupLGx0N/v5/FN6AMXr0aCIjI7n99tvdOiuSqhyysrJ49dUJREY+yJIlDfj44x1s29YA66ZuqF4dbrjBOom58UZweDBRt3v44YeZPn06GRkZHr9/o7Qgt7X74YUuTraRd+7cWbp27Vqm12RnizzxxOm2viZNrG5Q2dluKrKMTp602hzHjRPp21ekVq3ibZN+fiKdO4s89ZTIggXH5PLLrxBAoqKitLuiKtXJk3ny9NMfSY0azQQQmFz4nrroIqsdfO5ckawspyv1rISEBAHko48+8vi+8UQ/8gtdnAryw4cPi7+/v8TExFzwa5KSRC67TAr7tD73XMUJ8NLk5IisWiUSG2tdKA0MLB7sNWqckssv/68EB4eIv7+/PPLII5KZmel02aoCOH5c5MsvRfr3Xy8BAdfkB/gVAj9Is2Yijz0mkpAgcuqU05U6JycnRxo1aiS33nqrx/etQS4i8+bNE0C+//77C3r+p5+KBAVZP6UWLayzXm905IjIvHkiw4aJREQUDfWDAv8QP7868vDDeyQ+3j03UqiK7dAhkZkzrZtuatQoeG8MELhILr74XRk9OkcSE0X0xuHThg0bJkFBQR4f+EuDXERGjBghQUFBknUBnwXff//07cF/+5sVhpVFerrIO+9Y3SWDg0Xg9/xf3jwJDHxQevb8Qf73P5Fz3JSnvNy+fSKTJonccEPBJ7ZTAm8LpEjHjiKjR++Tn37ST2mlWb58uXTo0EGSk5M9ul8NchG55557pFevXud93uuvnz5rffbZyn0mkp0tsmiRdQ2gRYsdAgXtoQMEdsgVV4iMGSOybJlvf5z2dnl5Iqmp1nWUbt2K3w5vzGIJDu4ggDz88GinS/UKTo1rpEGe79R50ujVV0+/wV9/3UNFVSC//npMbrpprPj5VRWoLvCCwHEBkTp1rI/fU6fq2bo3OHVKZPFikREjRFq2LNqkJlKlikh09HaJjLxTAAkLC5NPPvlEB14ro2PHjsmxY8c8tj8N8gswd+7pM5WpU52uxlnbtm2TW265XRo0CJWHHz4mLVoUDwIQufxykVGjrLA4edLpipWINWDUrFkigwaJ1K1b/P8rJETknntEPv7YugNzzJgxUq1aNXnuuecuqLlRFZeeni7BwcEenZymtCD3mX7kI0eOZNOmTXz++eclPp6cbA3Wc/QoxMbCmDEeLa/CyszMJCQkhOzsbAYOfJiIiH/x889tiY+3xoouUKOGdTNS797WEhFR+W4EqYjy8qybxL79FubPt+4tKDqeScuWVv/u/v3h6quFr776nJCQEK699lqOHj3KwYMHvWZM/opGRGjdujWhoaEsWrTII/v0+X7kbdu2leuvv77ExzIyRMLCrLOWu++u3G3i5bVq1SqpU6eO+Pv7y/Dhw2Xv3t9lwQLrY3vxnjDW0rixyL33ikyfLrJnj9PVVy67dlk/17vvFqlXr/jPPTBQJDpaZPx4kQ0bTr8mOTlZoqOjBZC//OUvzhVfyTz11FPi5+cn+/bt88j+8OWmlb179wog48aNO+uxvDzrJhoQ6dTJ925uKIuMjAwZOnSoGGOkfv368t5770lubq6IiOzcaQ3qNXCgyMUXnx3srVqJDBkiMmOGyI4dDh+Il9m/X+Sjj0Qeesj6OZ75sw0Lsx6bO9dqMikqMzNTHn30UfH395e6devK22+/fd7rROrCpaSkCCBvvfWWR/bn00E+c+ZMAWT16tVnPTZ9uhReyNu1y6Nlea01a9ZIt27dpHPnzoVBXlRennUj1cSJIjfeWNDFsfgSHi5y330iU6ZYZ44lbMZn7d4t8skn1s037duf/bOrUcP6uU6caPVEOdcnyPfee0/8/Pzk//7v/+S3337z3EH4kHbt2kmPHj08sq/Sgtwn2siHDh3KnDlzOHjwIP7+/oXr9+2Dtm3h99/h/ffh/vs9VpLXExEyMzO56KKLyMjIICYmhueee47GJYwYduqUNejXkiXWsmwZHD5c/Dl16sCf/gSdOp1eGjb0zLE46cQJWLsWVqyAn36yvu7cWfw5Vata43ZHRVlLZKQ1emZpfvzxR/bv389tt91Gbm4uGzZsoF27du49EB/2/fffExIS4tJoqhfKpwfNevfdd9m9ezcvvPBC4ToRuP12+Pxza4jNb7/Vi3Pl9cUXX3DXXXcRGBjIU089xeOPP05QUFCpz8/NtQYe++EHa1m5EnbvPvt5oaFWuHfoYM0Wc9ll1mBgRf4We5VDh6xJhJOSrIvr69ZZS9FhX8Ea8rhzZ+vie3S09e9z/DgL7d69m5EjRzJz5kyuuOIK1q5dq4OiVTI+HeQl+eYb6NvXGh85JcUKDVV+W7Zs4YknnmDu3LlceumlvPbaa/z5z3++4Nfv3m31uFi1ygr21autHkRnqlrV+hTVvr21RERA8+bWuNf5kyM5SgQyMiA93ZoZKjnZWpKSzj7TBuvkoW1ba+jXq6+2vrZpY80Ef6Gys7OZOHEiL774Ijk5OYwaNYpRo0ZRvXp1245LnduKFStYsGABY8eOdet+3BbkxphmwHTgYkCAySLyxrle48kg3717N7Vq1aJmkRHt8/KsiRnWr4dXX4UnnvBIKT5hwYIFDBs2jMsvv5zZs2eXezu5udY47ImJ1h/agqWkMCxw0UUQHm4tYWHW10aNoG7d00tIiPXHuyxBCZCTY51R//776SUzE3bssEK76JKdXfI2qla1xue+7DJr6dDB+sRRu3bZajlTfHw8vXr14rbbbuPVV1+lefPmrm1Qldn48eMZOXIkW7Zs4ZJLLnHbftwZ5I2ARiKy1hhTE1gD3CIiv5b2Gk8G+X333cfChQvZvXt34cfMWbOsMcSbNrXm16wok7tWFqdOneLo0aPUrVuXlJQUPvjgA8aOHVs4HrorDh+GX36xQj052ZpJaft2K0BLmk2pJH5+Vpt83brFmyyKtkIYY51dHzlihfaRIxdeY9E/KEWDu0UL+5qFUlNTWblyJffnX9j5+eefueKKK+zZuCqz7du3Ex4ezksvvcTo0aPdth+PNa0YY+YCb4nIwtKe46kgFxFCQ0Pp0qULc+bMAawLbxER1sfe996DIUPcXoZPe+ONN3j88cdp0KABL730Evfddx9+ZT0dvgB5eaebNNLTrXDfts1aV/QsuqyhXMCY0+FfdGnW7HRoF3wSsOHvVakOHz7Mc889x5tvvklISAhbt271+OQGqmRdu3YlKyuLn3/+2W378MgNQUA4sAOoVcJjQ4FEIDE0NNQdPXPOkpaWJoC88847hesmTz7dr1m703rGqlWr5OqrrxZAOnXqJCscHg/41CmRAwdE0tJEfvnFmtA6JUUkOdlakpJOL1u3ivz+u/PdI3Nzc2XKlCnSoEEDMcbI0KFDJSMjw9miVDFvvPGGAJKamuq2feDufuRADaxmldvO91xP9SOfNGmSALJx40YRsfrbtm5tHfXMmR4pQeXLzc2V6dOnS8OGDWX0aB1hr6zS0tIkICBAunXrJmvWrHG6HFWC3bt3S5MmTeSbb75x2z5KC3JbmlaMMYHAPOA7EZl4vud7qmllwIABLF26lF27dmGMYeFCaw7LJk2sj93n6our3OPIkSP4+fkRHBzMwoULWb9+PY899hhVqlRxurQKZ8+ePXz++ef84x//AGDt2rV07NhRuxRWYCLi1v+f0ppWXG6sNFbVU4DUCwlxT3r66af53//+V/iDfesta/3DD2uIO6VmzZqFbbpfffUV//rXv7jsssv49ttvHa6s4jhx4gTjxo2jdevWjBgxgu3btwNw5ZVXaohXcMYY8vLyOHbmbOjuVtJpelkWoDtWt8Mk4Of85aZzvcaJQbO2brWGqK1SxRq7QlUMX3/9tbRs2VIA6du3r6SlpTldkqPmzZsnLVq0EED69+8vmzZtcrokVQbZ2dkSHh4uTz75pFu2TylNKy6fkYvIMhExItJBRK7IX75xdbuuSkhIYPbs2eTlj+k5aZLVneyuu6BBA4eLU4VuuukmUlJSeOWVV1iyZAmLFy92uiTHHD58mEGDBuHv78+3337L3LlzadGihdNlqTIICgqidevWzJ49u+BE1zNKSnd3L544I7/lllukefPmImL1OGjWzLrIuWyZ23etymnfvn2Sk5MjIiIzZsyQ6dOnlzgoV2Vy+PBhee211wqPc+3atXJCZ8D2alOnThVAVq1aZfu2cdcZeUWUm5vL4sWLiY6OBk4PRNSsmXULtKqYLr744sJBzeLi4rj33nvp3r07Tg/n4A55eXlMmzaNVq1a8fjjj/Pjjz8C0LFjR73w6+VuvfVWAgMDXbqzuawqZZCvX7+eQ4cOERUVBcBHH1nr77yz7LdmK2d8/fXXTJ06lS1bttCpUyeGDBlCRkaG02XZYvXq1XTt2pX777+f8PBwVq5cSY8ePZwuS9mkTp063HjjjcyZM6ewadfdKmWsxcfHAxAVFUVuLuTf1MlddzlYlCoTPz8//va3v5GWlsaIESOYNm0a69evd7osl+Xm5jJo0CDS09OZNm0ay5cvp1OnTk6XpWw2evRoJk2a5LF28ko5+uG9997L6tWrSU1NZckSuPZaa/jTzZt1qFpvtWvXLpo2bQpYt/1HRETQp08fh6u6MCdPnuS9997j/vvvJzg4mJSUFEJDQ20Ze0b5Frf1I6+Ipk2bVtjm+PXX1rrbb9cQ92YFIX7y5EkmTZrE9ddfzy233MLWrVsdruzc5s+fT4cOHXjkkUf45JNPAGjfvr2GuA/YsmULzz//PDk5OW7fV6UMcmMMISEhACzMH7rLS07e1HlUqVKFdevW8dJLL7Fo0SLatm1LTEwMR0savNxBmzdvpn///tx4443k5uYyb9487rvvPqfLUh70888/88wzz7BkyRL376ykrizuXtzZ/fDtt9+WgQMHSk5OjuzbZ3U5rFpV5Phxt+1SOWTXrl0yaNAgCQwMlF9//dXpcorp06eP1KhRQ8aNGyfZ2dlOl6MckJWVJTVq1JAhQ4bYtk18pfvhZ599RnJyMv7+/nz/vbWuRw8dc7wyatKkCTNmzGDz5s1EREQA8Pzzz7Nu3TqP1yIifPjhh+zOn7Puv//9Lxs3bmTkyJHnnPZOVV7VqlXj5ptv5rPPPuPkmfP52axSBXl2djY//vhjYf9xbVbxDaH58/RlZGTw1ltvcdVVV/Hggw9y4MABj+x/zZo1dO/enXvuuYdJkyYBcOmll5Y4EbXyLQMGDCAzM5NFixa5dT+VKshXrFhBdnZ2YZAnJFjrr7vOwaKUxzRo0IC0tDSGDRvGlClTaNWqFW+++abbLjYdOHCAoUOH8qc//YnNmzczZcoUnn32WbfsS3mnPn360LhxY7Zt2+beHZXU3uLuxV1t5GPHjhU/Pz85dOhQYft4jRoi+Xd9Kx/yyy+/yHXXXSd16tSRAwcOuGUfDz30kAQEBMiIESPk0KFDbtmH8n6nbJzBBl9oI69Xrx4DBgygdu3arF5trYuMtG+eROU92rZty4IFC1i3bh316tUjLy+P0aNHk56e7tJ2Fy1aRFJSEgDPPvssSUlJTJgwgdquzqCsKq2AgADAGp7YXSpVkD/66KPExcUBsGqVtU5vmvNdxhjCw8MBSE5O5j//+Q8RERE888wzZGVllWlb27Zt47bbbqN37968/PLLgDU2TMFFVqXO5cYbb3Rr99NKE+RHjhwp1haqQa6Kuvzyy9m4cSO33HILzz//PG3atGHOnDnnvYX62LFjPP3000RERPDdd9/x4osvMnXqVA9VrSqL5s2b89VXX7ltwglbgtwYM9UYk2GMSbFje+URGxtLo0aNOHnyJCIa5OpszZo1Y9asWSxZsoSQkBCeeuopTp06BcCsuDjah4fj7+dH+/BwZuV/snvnnXf497//ze23387GjRt58sknqap9WVUZ3XXXXWRlZXFZCe8xW5TUcF7WBegJXAmkXMjz3XGxs1OnTtK9e3cREdm+3brQWb++NeGyUmfKycmR9PR0ERGZOmWKNA0IkHiQkyDxIGFBQTLzww8lKytLfvzxR4erVd7uw+nTpWH+e6vgPda8enWZ+eGHZdoOpVzstK0nChDuVJAfOnRI/Pz8ZOzYsSIiMn++dWTXXGPrblQldUn9+hJvTSBVuMSDtAsNdbo0VUm0Cwsr+T0WFlam7ZQW5B5rIzfGDDXGJBpjEu2+UeOHH34gLy+vsP94aqq1vk0bW3ejKqn0336j+xnrugOpO3c6UY6qhFJ37Cj5PbZjhy3b91iQi8hkEYkUkcj69evbuu2EhASqVq3K1VdfDcCGDdZ67VCgLkREaCjLzli3LH+9UnZw93usUvRaufPOO3nzzTcLx7QoOCPXIFcXIiY2lsHVq5MAnAISgMHVqxMTG+twZaqycPt7rKT2lvIsONhGfqb69a1mqO3b3bobVYnM/PBDaRcWJn7GSLuwsDJfhFLqfOx4j1FKG7ktMwQZY2YB1wL1gP3AMyIypbTn2zlDUEpKChkZGfTs2ZOAgACOHIFatSAoCLKydI5OpVTlUdoMQQF2bFxE/mrHdsrjnXfeYfr06WRmZgJQcH2qWTMNcaWUb/D6qIuPj6dHjx4EBgYCxYNcKaV8gVcH+Z49e9iwYUNht0OAXbusrxrkSilf4dVBvnjxYgCioqIK1+kZuVLK13h1kC9dupQ6depwxRVXFK7TIFdK+RqvDvI333yTlStX4l9kwPG9e62vOsuWUspXeHWQBwQE0KpVq2Lr8juvUK+eAwUppZQDvDbIv/zyS4YPH37W+L4FQR4S4kBRSinlAK8N8o8//piZM2dSvXr1YusPHrS+apArpXyFVwa5iBAfH090dDTGmML1eXnw++/Wv+vWdag4pZTyMK8M8k2bNrFnz55i3Q4BDh+2BvqtXRsCbLlnVSmlKj6vDPL4+HiAYjcCwemz8Tp1PFyQUko5yCuD/MSJE1x11VW0aNGi2Prjx62vwcEOFKWUUg7xyiAfNmwYiYmJxdrH4XSQ69y4Silf4nVBnpubW+pjBUFerZqHilFKqQrA64L8rbfe4pJLLuHw4cNnPZadbX3VIFdK+RKvC/L4+Hj8/PyoXbv2WY9p04pSyhfZEuTGmBuMMRuNMZuNMaPt2OaZZsXF0T4sjK++/JJj+/czKy7urOcUnJFrkCulfInLva2NMf7A20BvYBew2hjzpYj86uq2C8yKiyNm6FCmZGXRHVh29CiDhw4F4K8DBxY+Ly/P+lpkDC2llKr07Dgj7wRsFpGtInISmA3cbMN2C8XGxDAlK4soIBCIAqZkZREbE2PnbpRSyivZEeRNgJ1Fvt+Vv64YY8xQY0yiMSbxwIEDZdpB6o4ddD9jXff89Uop5es8drFTRCaLSKSIRNavX79Mr40IDWXZGeuW5a8veV/lq1EppbyRHUG+Gyg6H0/T/HW2iYmNZXD16iQAp4AEYHD16sTExhZ73hn3BymllE+wY2ip1UBLY0xzrAAfANxtw3YLFVzQfDQmhl+3b6dOYCBvT55c7EKnUkr5KpfPyEUkB3gE+A5IBeaIyC+ubvdMfx04kJT0dP4dG8vvp05xXZ8+du9CKaW8ki2DvYrIN8A3dmzrfApGPFy8eDF33HFHscf69oWtW3XQLKWUb/G6OzsjIyOpWbNm4VC2RdWoAc2bQ4MGDhSmlFIO8bogDwgIoEePHiQkJDhdilJKVQheOY/Oyy+/TLC2nyilFOClQX7ZZZc5XYJSSlUYXte0UmDmzJlMnjzZ6TKUUspxXhvkn3zyCS+99JLTZSillOO8Nsijo6NJT09n27ZtTpeilFKO8uogB0rshqiUUr7Ea4M8IiKCiy++WLshKqV8ntcGuTGG6OhoMjIynC5FKaUc5ZXdDwtMnz6dgACvPgSllHKZ156RAxriSimFlwc5wIMPPsjgwYOdLkMppRzj9UF+4sQJ5s6dS17BzMtKKeVjvD7Io6OjOXjwIMnJyU6XopRSjvD6II+KigLQbohKKZ/lUpAbY+4wxvxijMkzxkTaVVRZNGvWjBYtWuiNQUopn+Vqt48U4DZgkg21lNuDDz5ITk6OkyUopZRjXApyEUkF6+YcJ/3zn/90dP9KKeUkj7WRG2OGGmMSjTGJBw4csH37x48fZ8eOHbZvVymlKrrznpEbYxYBDUt4KEZE5l7ojkRkMjAZIDIyUi64wgvUrVs36tevz3fffWf3ppVSqkI7b5CLyHWeKMRV3bt3Z8qUKZw8eZIqVao4XY5SSnmM13c/LBAVFUVWVharVq1yuhSllPIoV7sf3mqM2QV0Ab42xjjWrnHNNddgjNFuiEopn+NSkIvI5yLSVESCRORiEbnersLKKiQkhI4dO2qQK6V8TqUaPnD8+PHUqlXL6TKUUsqjKlWQF0z/ppRSvqTSXOwsMG/ePObNm+d0GUop5TGV6owc4MUXX0RE6Nevn9OlKKWUR1S6M/KoqChWr17NkSNHnC5FKaU8otIFeXR0NLm5uSxdutTpUpRSyiMqXZB37dqVKlWqaDdEpZTPqHRBXq1aNbp06UJSUpLTpSillEdUuoudAJ999hl169Z1ugyllPKIShnkISEhTpeglFIeU+maVgo8+uijxMbGOl2GUkq5XaUN8rS0NGbPnu10GUop5XaVNsijo6NJSUlh//79TpeilFJuVWmDPCoqCoDFixc7W4hSSrlZpQ3yK6+8klq1aml/cqVUpefqxBLjjTEbjDFJxpjPjTF1bKrLZQEBAQwaNIhGjRo5XYpSSrmVESn/PMjGmD5AvIjkGGPGAYjIqPO9LjIyUhITE8u9X6WU8kXGmDUiEnnmeldnCFogIjn5364AmrqyPXfIy8vjjz/+cLoMpZRyGzvbyP8OfFvag8aYocaYRGNM4oEDB2zc7bm1b9+eYcOGeWx/SinlaecNcmPMImNMSgnLzUWeEwPkAHGlbUdEJotIpIhE1q9f357qL0Dbtm2Jj4/HlSYkpZSqyM57i76IXHeux40x9wP9gF5SAdMyOjqaTz/9lK1bt3LppZc6XY5SStnO1V4rNwAjgf4ikmVPSfYq6E+ekJDgcCVKKeUerraRvwXUBBYaY342xrxrQ022atOmDQ0bNtT+5EqpSsul0Q9FpIVdhbiLMYbx48fTuHFjp0tRSim3qJTD2J5p0KBBTpeglFJuU2lv0S9KRFi+fDmrV692uhSllLKdTwQ5wN13383LL7/sdBlKKWU7nwhyYwzR0dEsXryYvLw8p8tRSilb+USQg9UNMTMzUydlVkpVOj4V5IB2Q1RKVTo+E+RNmzalVatW/PDDD06XopRStvKJ7ocFvv76a5o1a+Z0GUopZSufCvIWLSr8/UtKKVVmPtO0AtbY5KNHj2b69OlOl6KUUrbxqSD38/Pjm2++YcaMGU6XopRStvGpIAdrWNsff/yREydOOF2KUkrZwueCPCoqiuPHj7Ny5UqnS1FKKVv4XJBfc801+Pn5aX9ypVSl4XNBXqdOHXr16kVubq7TpSillC18qvthgQULFjhdglJK2cbVqd5eMMYk5c8OtMAY41WzN+hZuVKqMnC1aWW8iHQQkSuAecBY10tyv9zcXDp06MDTTz/tdClKKeUyl4JcRP4o8m0wIK6V4xn+/v7UqlVLL3gqpSoFly92GmNijTE7gYGc44zcGDPUGJNojEk8cOCAq7t1WVRUFKtXr+bw4cNOl6KUUi45b5AbYxYZY1JKWG4GEJEYEWkGxAGPlLYdEZksIpEiElm/fn37jqCcoqOjycvLY+nSpU6XopRSLjlvkIvIdSLSvoRl7hlPjQNud0+Z9uvSpQtBQUEkJCQ4XYpSSrnEpe6HxpiWIrIp/9ubgQ2ul+QZVatW5ZlnnqF9+/ZOl6KUUi5xtR/5y8aY1kAesB14yPWSPOfJJ590ugSllHKZS0EuIl7TlFISEWHz5s34+/tzySWXOF2OUkqVi8/dol9UTk4OHTt2ZOLEiU6XopRS5ebTQR4YGEiPHj20P7lSyqv5dJCD1Q0xNTWVvXv3Ol2KUkqVi88HeVRUFACLFy92thCllConnw/yjh07Urt2bW1eUUp5LZ8cxrYof39/vv76a1q3bu10KUopVS4+H+QA3bp1c7oEpZQqN59vWgE4ceIEEyZMYNGiRU6XopRSZaZBjtUNcdy4cUyfPt3pUpRSqsw0yAE/Pz+ioqKIj49HxCuGVFdKqUIa5Pmio6PZvXs3mzdvdroUpZQqEw3yfAX9ybUbolLK22iQ52vZsiXh4eHs2rXL6VKUUqpMtPthPmMMmzZtIiBAfyRKKe+iZ+RFaIgrpbyRBnkRx44do2fPnrz77rtOl6KUUhfMliA3xjxhjBFjTD07tueU4OBgNm7YwDMjRuDv50f78HBmxcU5XZZSSp2Ty20JxphmQB9gh+vlOGtWXByBmZnMyM2lO7Bs+3YGDx0KwF8HDnS2OKWUKoUdZ+SvASMBr7+TJjYmhhm5uUQBgUAUMCUri9iYGIcrU0qp0rkU5MaYm4HdIrL+Ap471BiTaIxJPHDggCu7dZvUHTvofsa67vnrlVKqojpv04oxZhHQsISHYoAxWM0q5yUik4HJAJGRkRXy7D0iNJRl27cTVWTdsvz1SilVUZ33jFxErhOR9mcuwFagObDeGJMONAXWGmNKCn2vEBMby+Dq1UkATgEJwODq1YmJjXW4MqWUKl25L3aKSDLQoOD7/DCPFJHfbKjLEQUXNB+NiSF1xw4iQkOJjY3VC51KqQrN2DXaX1mCPDIyUhITE23Zr1JK+QpjzBoRiTxzvW23MopIuF3bUkopdeH0zk6llPJyGuRKKeXlNMiVUsrLaZArpZSXs63XSpl2aswBYHs5X14P8NoujmfQY6l4KstxgB5LReXKsYSJSP0zVzoS5K4wxiSW1P3GG+mxVDyV5ThAj6WicsexaNOKUkp5OQ1ypZTyct4Y5JOdLsBGeiwVT2U5DtBjqahsPxavayNXSilVnDeekSullCpCg1wppbycVwa5MeYFY0ySMeZnY8wCY0xjp2sqL2PMeGPMhvzj+dwYU8fpmsrDGHOHMeYXY0yeMcYru4kZY24wxmw0xmw2xox2up7yMsZMNcZkGGNSnK7FFcaYZsaYBGPMr/nvrWFO11RexpiqxphVxpj1+cfynK3b98Y2cmNMLRH5I//fjwFtReQhh8sqF2NMHyBeRHKMMeMARGSUw2WVmTEmAsgDJgH/FBGvGqfYGOMPpAG9gV3AauCvIvKro4WVgzGmJ3AUmJ4/CYxXMsY0AhqJyFpjTE1gDXCLl/6fGCBYRI4aYwKxJh8bJiIr7Ni+V56RF4R4vmC8eOJnEVkgIjn5367AmmnJ64hIqohsdLoOF3QCNovIVhE5CcwGbna4pnIRkR+ATKfrcJWI7BWRtfn/PgKkAk2crap8xHI0/9vA/MW23PLKIAcwxsQaY3YCA4GxTtdjk78D3zpdhI9qAuws8v0uvDQ0KiNjTDjQEVjpcCnlZozxN8b8DGQAC0XEtmOpsEFujFlkjEkpYbkZQERiRKQZEAc84my153a+Y8l/TgyQg3U8FdKFHIdSdjPG1AA+BYaf8Wncq4hIrohcgfWpu5MxxrZmL9tmCLKbiFx3gU+NA74BnnFjOS4537EYY+4H+gG9pAJftCjD/4k32g00K/J90/x1ykH57cmfAnEi8pnT9dhBRA4ZYxKAGwBbLkhX2DPyczHGtCzy7c3ABqdqcZUx5gZgJNBfRLKcrseHrQZaGmOaG2OqAAOALx2uyaflXyCcAqSKyESn63GFMaZ+QY80Y0w1rIvqtuWWt/Za+RRojdVLYjvwkIh45dmTMWYzEAQczF+1wht74BhjbgXeBOoDh4CfReR6R4sqI2PMTcDrgD8wVURina2ofIwxs4BrsYZL3Q88IyJTHC2qHIwx3YGlQDLW7zrAGBH5xrmqyscY0wGYhvXe8gPmiMjztm3fG4NcKaXUaV7ZtKKUUuo0DXKllPJyGuRKKeXlNMiVUsrLaZArpZSX0yBXSikvp0GulFJe7v8BiUo4jxnQZ3MAAAAASUVORK5CYII=", - "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-31T16:26:36.054788\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.2, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 69, - "source": [ - "control_points = np.array([(3 , 1), (2.5, 4), (0, 1), (-2.5, 4),\r\n", - " (-3, 0), (-2.5, -4)])\r\n", - "nonuniform_knots = [0, 0, 0, 0, 1/4, 4/5, 1, 1, 1, 1]\r\n", - "nonuniform_knots = interpolate.splev(np.linspace(0,1),[nonuniform_knots,[control_points[:,0],control_points[:,1]],3])\r\n", - "plt.plot(nonuniform_knots[0],nonuniform_knots[1],'b',linewidth=2.0,label='B-spline curve')\r\n", - "plt.plot(control_points[:,0],control_points[:,1],'k--',label='Control polygon',marker='o',markerfacecolor='red')" - ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "[]" - ] - }, - "metadata": {}, - "execution_count": 69 - }, - { - "output_type": "display_data", - "data": { - "image/png": "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6WoC08yZM6V169YCSO/evSUzM9Ppkhw1Y8YMadWqlQDSt29fWV8yqIeq1rKzS6aHK5AmTeLk8ccf98h+PBbkVVm8EeSpqakyZcqUk/aSWLlSpFYt619g+HCPl6NO4fDhw/Liiy9KrVq1/Hqm9tPZu3evREVFSdu2beWbb75xuhxVSY8+auVJvXpXS8uWLT3SDBZwQf6Xv/xFWrZsWeHPDhywrtIEkdtus67MUs77448/SsfD+eCDD2TSpEl+311x37598sorr5Qe54oVK/Q7Ax+1Z0/J9ScTBZClS5favo+TBbkD85J4XlFREXPnzj1pb5Xhw2HDBmt2nokTnZmdRZ2oUaNGBBcP3J6SksKAAQPo1q0b/jiblMvl4v3336dNmzY8+OCDLFy4EICOHTsSVl2miVKVEhUFTz4JcAMQyuTJH3lt334ZYatWrWLv3r306NHjhJ998YU1CUSNGpCSYk0koKqfmTNnMnHiRH777Tc6d+7MPffcw44dO5wuyxbLli2ja9eu3HXXXcTFxbFkyRK6d+/udFnKBv/4B8TGRgF/5sMPp+Ly0mzqfhnkqampACcE+R9/QMnUeqNHW2fkqnoKCgri73//O5mZmQwfPpz333+fVatWOV2W24qKirjjjjvIysri/fffZ9GiRXTu3NnpspRNwsJg0CCAx2jT5u2SDiEe55dTvQ0YMIBly5axdu3a0nUi1rRr33xjTdn07bfapOJLtmzZQvPmzQH473//S7t27ejVq5fDVZ2ZI0eO8M4773DXXXcRGRlJRkYGsbGx1KlTx+nSlAds22bN02oM5ORAkyb2bTugpnpzuVyye/fucutmzCj5Rtmapk35psOHD0u7du0EkOuvv97jo82565tvvpG2bdsKIO+9957T5SgvsWYS2iBXXvmMrVPrEUhfdhpjqF+/fuljERg50rr/xBPQrJlDhSm3hYWFsXLlSl544QXmzJlD+/btSUpK4uDBg06XVs6GDRvo27cvf/7znykqKmLGjBn87W9/c7os5SVW88pPfP/9U6Sl/eD5HVaU7p5ePHlG/vrrr0v//v3LTev2+efW2XjjxiL5+R7btfKyLVu2yB133CGhoaHyyy+/OF1OOb169ZJatWrJmDFjdMakAFRYKBITky9QS6655h7btkugnJF/9tlnrFmzprQbm8t17Gz83/+G8HAHi1O2atas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", - "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-31T16:10:03.055889\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.2, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 74, - "source": [ - "plt.plot(clamped_bspline[0],clamped_bspline[1],\"--\",linewidth=2.0,label='clamped B-spline curve')\r\n", - "plt.plot(unclamped_bspline[0],unclamped_bspline[1],\"-.\",linewidth=2.0,label='unclamped B-spline curve')\r\n", - "plt.plot(nonuniform_knots[0],nonuniform_knots[1],linewidth=2.0,label='nonuniform B-spline curve')\r\n", - "plt.plot(control_points[:,0],control_points[:,1],'k--',label='Control polygon',marker='o',markerfacecolor='red')\r\n", - "plt.legend()" - ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ] - }, - "metadata": {}, - "execution_count": 74 - }, - { - "output_type": "display_data", - "data": { - "image/png": "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", - "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-08-31T16:26:42.368875\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.2, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 105, - "source": [ - "from typing import List, Dict, Tuple\r\n", - "# https://hal.archives-ouvertes.fr/hal-03017566/document\r\n", - "def parameterizeToBspline(ts: float, point_set: List[List], start_end_derivative: List[List]):\r\n", - " \"\"\"\r\n", - " Args:\r\n", - " ts: time step between points\r\n", - " point_set: points to be fitted\r\n", - " start_end_derivative: [start_vel, end_vel, start_acc, end_acc]\r\n", - " \r\n", - " Returns:\r\n", - " ctrl_pts: control points of the uniform BSpline\r\n", - " \"\"\"\r\n", - " K = len(point_set)\r\n", - " \r\n", - " prow = np.array([1, 4, 1],dtype=float)\r\n", - "\r\n", - " A = np.zeros([K , K + 2]) # K pos, 2 vel, 2 acc constraints, K+2 control points\r\n", - " for i in range(K):\r\n", - " A[i:i+1, i:i+3] = (1 / 6.0) * prow\r\n", - " \r\n", - " # write b\r\n", - " bx = np.zeros(K)\r\n", - " by=np.zeros(K)\r\n", - "\r\n", - " for i in range(K):\r\n", - " bx[i] = point_set[i][0]\r\n", - " by[i] = point_set[i][1]\r\n", - " \r\n", - "\r\n", - " # solve Ax = b\r\n", - " px = np.linalg.lstsq(A,bx)[0]\r\n", - " py = np.linalg.lstsq(A,by)[0]\r\n", - "\r\n", - " # convert to control pts\r\n", - " ctrl_pts = np.zeros([K+2,2])\r\n", - " ctrl_pts[:,0] = px\r\n", - " ctrl_pts[:,1] = py\r\n", - " return ctrl_pts" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 107, - "source": [ - "points = control_points\r\n", - "ctrl_pts = parameterizeToBspline(0, points, [[0,0],[0,0],[0,0],[0,0]])\r\n", - "plt.plot(points[:,0], points[:,1],'x')\r\n", - "K = len(points)\r\n", - "\r\n", - "out=interpolate.splev(np.linspace(0,K-1,num=100),[list(range(-3,K+3)),[ctrl_pts[:,0],ctrl_pts[:,1]],3])\r\n", - "plt.plot(out[0], out[1])" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stderr", - "text": [ - ":31: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n", - "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n", - " px = np.linalg.lstsq(A,bx)[0]\n", - ":32: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n", - "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n", - " py = np.linalg.lstsq(A,by)[0]\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "[]" - ] - }, - "metadata": {}, - "execution_count": 107 - }, - { - "output_type": "display_data", - "data": { - "image/png": "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", - "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-09-01T15:31:05.408386\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.2, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 99, - "source": [], - "outputs": [ - { - "output_type": "display_data", - "data": { - "image/png": "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", - "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n 2021-09-01T15:20:02.096634\r\n image/svg+xml\r\n \r\n \r\n Matplotlib v3.3.2, https://matplotlib.org/\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [], - "outputs": [], - "metadata": {} - } - ], - "metadata": { - "orig_nbformat": 4, - "language_info": { - "name": "python", - "version": "3.8.3", - "mimetype": "text/x-python", - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "pygments_lexer": "ipython3", - "nbconvert_exporter": "python", - "file_extension": ".py" - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3.8.3 64-bit ('base': conda)" - }, - "interpreter": { - "hash": "a1e740b78198265db0292300f82c425afd34470f3408deee2169acb09f133a0a" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} \ No newline at end of file diff --git a/Planning/fast_planner.py b/Planning/fast_planner.py new file mode 100644 index 0000000..29a4570 --- /dev/null +++ b/Planning/fast_planner.py @@ -0,0 +1,883 @@ +"""Python implementation of Fast Planner kinodynamic trajectory generation +ref: https://github.com/HKUST-Aerial-Robotics/Fast-Planner +""" + +from queue import PriorityQueue +from matplotlib import patches +import numpy as np +import matplotlib.pyplot as plt +from scipy.optimize import minimize + + +class NonUniformBspline(object): + """An implementation of non-uniform B-spline with different dimensions. + It also represents uniform B-spline which is a special case of non-uniform + """ + + def __init__(self, points: np.ndarray, degree: int, interval: float): + self.control_points = None # numpy array dim (n, 3) + self.p = None # p degree + self.n = None # n control points + self.m = None # m+1 knots, m = n+1+p + self.u = None # knot vector + self.interval = None + self.limit_vel = None # physical limits + self.limit_acc = None + self.limit_ratio = None # and time adjustment ratio + + self.setUniformBspline(points, degree, interval) + + def setUniformBspline(self, control_points: np.ndarray, degree: int, interval: float): + self.control_points = np.array(control_points) + assert self.control_points.shape[0] >= 4 and self.control_points.shape[ + 1] == 2, f"control_points.shape: {self.control_points.shape}" + self.p = degree + self.interval = interval + + self.n = self.control_points.shape[0] - 1 + self.m = self.n + self.p + 1 + + self.u = np.zeros(self.m+1) + for i in range(len(self.u)): + if i <= self.p: + self.u[i] = (-self.p+i)*self.interval + elif self.p < i <= self.m-self.p: + self.u[i] = self.u[i-1]+self.interval + elif i > self.m-self.p: + self.u[i] = self.u[i-1]+self.interval + + def setKnot(self, knot: np.ndarray): + self.u = np.array(knot) + assert len(self.u) == self.m+1, f"u length: {len(self.u)}" + + def getKnot(self): + return np.array(self.u) + + def getTimeSpan(self): + um = self.u[self.p] + um_p = self.u[self.m-self.p] + return um, um_p + + def getControlPoint(self): + return np.array(self.control_points) + + def getHeadTailPts(self): + um, um_p = self.getTimeSpan() + head = self.evaluateDeBoor(um) + tail = self.evaluateDeBoor(um_p) + return head, tail + + def evaluateDeBoor(self, u): + um, um_p = self.getTimeSpan() + ub = np.clip(u, um, um_p) + + # determine which [ui,ui+1] lay in + k = self.p + while True: + if self.u[k+1] >= ub: + break + k += 1 + + # deBoor + d = [] + for i in range(self.p+1): + d.append(self.control_points[k - self.p + i]) + + for r in range(1, self.p+1): + for i in range(self.p, r-1, -1): + alpha = (ub-self.u[i+k-self.p]) / \ + (self.u[i+1+k-r]-self.u[i+k-self.p]) + d[i] = (1-alpha)*d[i-1]+alpha*d[i] + return d[self.p] + + def getDerivativeControlPoints(self): + """The derivative of a b-spline is also a b-spline, its degree become p-1 + control point Q_i = p*(P_{i+1}-P_i)/(u_{i+p+1}-u_{i+1}) + see also: https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-derv.html + """ + ctp = np.zeros([self.control_points.shape[0] - + 1, self.control_points.shape[1]]) + P = self.control_points + for i in range(ctp.shape[0]): + ctp[i] = self.p*(P[i+1]-P[i])/(self.u[i+self.p+1]-self.u[i+1]) + return ctp + + def getDerivative(self): + ctp = self.getDerivativeControlPoints() + derivative = NonUniformBspline(ctp, self.p - 1, self.interval) + derivative.setKnot(self.u[1:-1]) + return derivative + + def getInterval(self): + return self.interval + + def setPhysicalLimits(self, vel: float, acc: float): + self.limit_vel = vel + self.limit_acc = acc + self.limit_ratio = 1.1 + + def reallocateTime(self): + fea = True + P = self.control_points + dim = P.shape[1] + max_vel, max_acc = None, None + + # check vel feasibility and insert points + for i in range(P.shape[0]-1): + vel = self.p * (P[i + 1] - P[i]) / \ + (self.u[i + self.p + 1] - self.u[i + 1]) + if np.any(np.abs(vel) > self.limit_vel+1e-4): + fea = False + max_vel = np.max(np.abs(vel)) + ratio = min(self.limit_ratio, max_vel / self.limit_vel) + time_ori = self.u[i + self.p + 1] - self.u[i + 1] + time_new = ratio * time_ori + delta_t = time_new - time_ori + t_inc = delta_t / self.p + for j in range(i+2, i + self.p + 2): + self.u[j] += (j-i+1) * t_inc + for j in range(j+self.p+2, len(self.u)): + self.u[j] += delta_t + + # acc + for i in range(P.shape[0] - 2): + acc = self.p * (self.p - 1) * ((P[i + 2] - P[i + 1]) / (self.u[i + self.p + 2] - self.u[i + 2]) - ( + P[i + 1] - P[i]) / (self.u[i + self.p + 1] - self.u[i + 1])) / (self.u[i + self.p + 1] - self.u[i + 2]) + if np.any(np.abs(acc) > self.limit_acc+1e-4): + fea = False + max_acc = np.max(np.abs(acc)) + ratio = min(self.limit_ratio, np.sqrt( + max_acc / self.limit_acc)) + time_ori = self.u[i + self.p + 1] - self.u[i + 2] + time_new = ratio * time_ori + delta_t = time_new - time_ori + t_inc = delta_t / (self.p - 1) + for j in range(i + 3, i + self.p + 2): + self.u[j] += (j - i - 2) * t_inc + for j in range(i + self.p + 2, len(self.u)): + self.u[j] += delta_t + return fea + + @staticmethod + def parameterizeToBspline(ts: float, point_set: np.ndarray, start_end_derivative: np.ndarray): + """Given waypoints and derivative constraints, fit a uniform cubic Bspline, return the control point + Args: + ts: interval + point_set: 2D waypoints + start_end_derivative: [start_vel, end_vel, start_acc, end_acc] + """ + assert ts > 0, f"ts: {ts}" + assert len(point_set) >= 2, f"len(point_set): {len(point_set)}" + assert len( + start_end_derivative) >= 4, f"len(start_end_derivative): {len(start_end_derivative)}" + K = len(point_set) + + # construct A + prow = np.array([1, 4, 1], dtype=float) + vrow = np.array([-1, 0, 1], dtype=float) + arow = np.array([1, -2, 1], dtype=float) + + A = np.zeros((K + 4, K + 2)) + for i in range(K): + A[i, i:i+3] = (1 / 6.0) * prow + A[K, 0:3] = (1 / 2.0 / ts) * vrow + A[K+1, K - 1:K+2] = (1 / 2.0 / ts) * vrow + + A[K + 2, 0:3] = (1 / ts / ts) * arow + A[K + 3, K - 1:K+2] = (1 / ts / ts) * arow + + # construct b + bx = np.zeros(K + 4) + by = np.zeros(K + 4) + for i in range(K): + bx[i] = point_set[i][0] + by[i] = point_set[i][1] + + for i in range(4): + bx[K + i] = start_end_derivative[i][0] + by[K + i] = start_end_derivative[i][1] + + # solve Ax = b + W = np.eye(len(A)) # least square weight + px = np.linalg.lstsq(W@A, W@bx, rcond=None)[0] + py = np.linalg.lstsq(W@A, W@by, rcond=None)[0] + + # convert to control pts + ctrl_pts = np.zeros([K + 2, 2]) + ctrl_pts[:, 0] = px + ctrl_pts[:, 1] = py + return ctrl_pts + + +class BsplineOptimizer(object): + def __init__(self, env) -> None: + super().__init__() + self.env = env + self.control_points = None + self.bspline_interval = None + self.end_pt = None + self.dim = 2 + self.guide_pts = None + self.waypoints = None + self.waypt_ind = None + self.cost_function = None + + self.order = 3 + self.lambda1 = 1.0 # smoothness + self.lambda2 = 5.0 # distance weight + self.lambda3 = 0.00001 # feasibility weight + self.lambda4 = 0.01 # end point weight + self.lambda5 = 0.0 # guide cost weight + self.lambda6 = 0.0 # visibility cost weight + self.lambda7 = 100.0 # waypoint cost weight + + self.dist0 = 0.4 + self.max_vel = 3.0 + self.max_acc = 2.0 + self.visib_min = None + self.max_iteration_num = 300 + self.max_iteration_time = None + + self.variable_num = None + self.iter_num = None + self.best_variable = None + self.min_cost = None + self.block_pts = None + + self.SMOOTHNESS = (1 << 0) + self.DISTANCE = (1 << 1) + self.FEASIBILITY = (1 << 2) + self.ENDPOINT = (1 << 3) + self.GUIDE = (1 << 4) + self.WAYPOINTS = (1 << 6) + + def setEnv(self, env): + self.env = env + + def setControlPoints(self, points): + self.control_points = np.array(points) + self.dim = self.control_points.shape[1] + assert self.dim == 2, f"self.dim: {self.dim==2}" + assert len( + self.control_points) > 6, f"len(self.control_points)={len(self.control_points)}" + + def setInterval(self, ts): + self.bspline_interval = ts + + def setTerminatedCond(self, max_iteration_num, max_iteration_time): + self.max_iteration_num = max_iteration_num + self.max_iteration_time = max_iteration_time + + def setCostFunction(self, cost_code): + self.cost_function = cost_code + cost_str = "" + if self.cost_function & self.SMOOTHNESS: + cost_str += "smooth |" + if self.cost_function & self.DISTANCE: + cost_str += " distance |" + if self.cost_function & self.FEASIBILITY: + cost_str += " FEASIBILITY |" + if self.cost_function & self.ENDPOINT: + cost_str += " ENDPOINT |" + if self.cost_function & self.GUIDE: + cost_str += " GUIDE |" + if self.cost_function & self.WAYPOINTS: + cost_str += " WAYPOINTS |" + print(cost_str) + + def setGuidePath(self, guide_pts): + self.guide_pts = np.array(guide_pts) + assert guide_pts.shape[1] == self.dim + + def setWaypoints(self, waypoints, waypt_ind): + self.waypoints = np.array(waypoints) + self.waypt_ind = [ind for ind in waypt_ind] + assert self.waypoints.shape[1] == self.dim + + def BsplineOptimizeTraj(self, points, ts, cost_function, max_iteration_num, max_iteration_time): + self.setControlPoints(points) + self.setInterval(ts) + self.setCostFunction(cost_function) + self.setTerminatedCond(max_iteration_num, max_iteration_time) + self.optimize() + return self.control_points + + def optimize(self): + # init solver + self.iter_num = 0 + self.min_cost = np.inf + pt_num = len(self.control_points) + self.variable_num = self.dim * (pt_num - 2 * self.order) + x0 = np.zeros(self.variable_num) + for i in range(self.order, self.variable_num//self.dim+self.order): + for j in range(self.dim): + x0[self.dim*(i-self.order)+j] = self.control_points[i, j] + bound_upper = x0+10.0 + bound_lower = x0-10.0 + bound = [(lower, upper) + for lower, upper in zip(bound_lower, bound_upper)] + + result = minimize(self.costFunction, x0, jac=True, + bounds=bound, options={"maxiter":self.max_iteration_num}) + self.best_variable = result.x + print(result) + for i in range(self.order, self.variable_num//self.dim+self.order): + for j in range(self.dim): + self.control_points[i, + j] = self.best_variable[self.dim * (i - self.order) + j] + return self.control_points + + def costFunction(self, x): + """Callback of scipy minimize function + Args: + x: shape (variable_num,), current variable + + Returns: + f_combine: current cost + grad: current gradient + """ + cost, grad = self.combineCost(x) + self.iter_num += 1 + + # save the min cost result + if cost < self.min_cost: + self.min_cost = cost + self.best_variable = x + return cost, grad + + def combineCost(self, x): + """ + Args: + x: shape (variable_num,) current variable + + Returns: + f_combine: current cost + grad: shape (variable_num,), current gradient + """ + # convert the NLopt format vector to control points. + control_points = np.zeros_like(self.control_points) + control_points[:self.order, :] = self.control_points[:self.order, :] + for i in range(self.variable_num // self.dim): + for j in range(self.dim): + control_points[i + self.order, j] = x[self.dim * i + j] + control_points[self.order + self.variable_num // + self.dim:] = self.control_points[self.order + self.variable_num // self.dim:] + + f_combine = 0.0 + grad = np.zeros(self.variable_num) + f_smoothness = f_distance = f_feasibility = f_endpoint = f_guide = f_waypoints = 0.0 + if self.cost_function & self.SMOOTHNESS: + f_smoothness, g_smoothness = self.calcSmoothnessCost( + control_points) + f_combine += self.lambda1 * f_smoothness + for i in range(self.variable_num//self.dim): + for j in range(self.dim): + grad[self.dim*i+j] += self.lambda1 * \ + g_smoothness[i + self.order, j] + if self.cost_function & self.DISTANCE: + f_distance, g_distance = self.calcDistanceCost(control_points) + f_combine += self.lambda2 * f_distance + for i in range(self.variable_num//self.dim): + for j in range(self.dim): + grad[self.dim*i+j] += self.lambda2 * \ + g_distance[i + self.order, j] + if self.cost_function & self.FEASIBILITY: + f_feasibility, g_feasibility = self.calcFeasibilityCost( + control_points) + f_combine += self.lambda3 * f_feasibility + for i in range(self.variable_num//self.dim): + for j in range(self.dim): + grad[self.dim*i+j] += self.lambda3 * \ + g_feasibility[i + self.order, j] + if self.cost_function & self.ENDPOINT: + f_endpoint, g_endpoint = self.calcEndpointCost(control_points) + f_combine += self.lambda4 * f_endpoint + for i in range(self.variable_num//self.dim): + for j in range(self.dim): + grad[self.dim*i+j] += self.lambda4 * \ + g_endpoint[i + self.order, j] + if self.cost_function & self.GUIDE: + f_guide, g_guide = self.calcGuideCost(control_points) + f_combine += self.lambda5 * f_guide + for i in range(self.variable_num//self.dim): + for j in range(self.dim): + grad[self.dim*i+j] += self.lambda5 * \ + g_guide[i + self.order, j] + if self.cost_function & self.WAYPOINTS: + f_waypoints, g_waypoints = self.calcWaypointsCost(control_points) + f_combine += self.lambda7 * f_waypoints + for i in range(self.variable_num//self.dim): + for j in range(self.dim): + grad[self.dim*i+j] += self.lambda7 * \ + g_waypoints[i + self.order, j] + return f_combine, grad + + def calcEbandCost(self, x): + f = 0.0 + g = np.zeros_like(x) + + for i in range(len(x)-2): + # evaluate tensor + tensor = -x[i]+2*x[i+1]-x[i+2] + f += tensor@tensor + temp_t = 2*tensor + # tensor gradient + g[i] += -temp_t + g[i+1] += 2*temp_t + g[i+2] += -temp_t + return f, g + + def calcSmoothnessCost(self, x): + """ + Args: + x: shape==control_points.shape, variable + + Returns: + f: cost + g: shape==x.shape, gradient + """ + f = 0.0 + g = np.zeros_like(x) + + for i in range(len(x)-self.order): + # evaluate jerk + jerk = x[i + 3] - 3 * x[i + 2] + 3 * x[i + 1] - x[i] + f += jerk @ jerk + temp_j = 2.0 * jerk + # jerk gradient + g[i + 0] += -temp_j + g[i + 1] += 3.0 * temp_j + g[i + 2] += -3.0 * temp_j + g[i + 3] += temp_j + return f, g + + def calcDistanceCost(self, x): + f = 0.0 + g = np.zeros_like(x) + + end_idx = len(x) - self.order + + for i in range(self.order, end_idx): + dist, dist_grad = self.env.evaluateDistGrad(x[i]) + # if np.linalg.norm(dist_grad) > 1e-4: + # dist_grad /= np.linalg.norm(dist_grad) + + if dist < self.dist0: + f += (dist - self.dist0)**2 + g[i] += 2.0 * (dist - self.dist0) * dist_grad + return f, g + + def calcFeasibilityCost(self, x): + f = 0.0 + g = np.zeros_like(x) + + # abbreviation + vm2 = self.max_vel**2 + am2 = self.max_acc**2 + + ts = self.bspline_interval + ts_inv2 = 1 / ts / ts + ts_inv4 = ts_inv2 * ts_inv2 + + # velocity feasibility + for i in range(len(x)-1): + vi = x[i + 1] - x[i] + for j in range(self.dim): + vd = vi[j] * vi[j] * ts_inv2 - vm2 + if vd > 0.0: + f += vd ** 2 + + temp_v = 4.0 * vd * ts_inv2 + g[i + 0, j] += -temp_v * vi[j] + g[i + 1, j] += temp_v * vi[j] + + # acceleration feasibility + for i in range(len(x)-2): + ai = x[i + 2] - 2 * x[i + 1] + x[i] + + for j in range(self.dim): + ad = ai[j] * ai[j] * ts_inv4 - am2 + if ad > 0.0: + f += ad ** 2 + + temp_a = 4.0 * ad * ts_inv4 + g[i + 0, j] += temp_a * ai[j] + g[i + 1, j] += -2 * temp_a * ai[j] + g[i + 2, j] += temp_a * ai[j] + return f, g + + def calcEndpointCost(self, x): + f = 0.0 + g = np.zeros_like(x) + return f, g + + def calcGuideCost(self, x): + f = 0.0 + g = np.zeros_like(x) + return f, g + + def calcWaypointsCost(self, x): + f = 0.0 + g = np.zeros_like(x) + return f, g + + +class ComplexEnv(object): + def __init__(self) -> None: + super().__init__() + self.center = np.array([0, 0]) + self.length = np.array((8, 6)) + self.origin = self.center-self.length/2 + self.reso = 0.1 + self.size = np.array(self.length/self.reso, dtype=int) + + self.occ_map = np.zeros(self.size) + self.esdf_map = np.zeros(self.size) + + self.circles = [] + self.rectangles = [(-2, -1, 4, 2)] + + self.genOcc() + self.distanceTransform() + + def posToInd(self, pos: np.ndarray): + ind = np.round((np.array(pos)-self.origin)/self.reso) + ind = np.array(ind, dtype=int) + return ind + + def indToPos(self, ind: np.ndarray): + pos = np.array(ind, dtype=float)*self.reso+self.origin + return pos + + def boundIndex(self, ind): + return np.clip(ind, np.zeros(2, dtype=int), self.size-1, dtype=int) + + def isInside(self, pos): + ind = self.posToInd(pos) + return np.all(ind >= 0) and np.all(ind < self.size) + + def addCircle(self, o, r): + self.circles.append((o[0], o[1], r)) + + def addRectange(self, o, w, h): + self.rectangles.append((o[0], o[1], w, h)) + + def genOcc(self): + for ox, oy, r in self.circles: + lb = self.posToInd((ox-r, oy-r)) + rt = self.posToInd((ox+r, oy+r)) + for x_ind in range(lb[0], rt[0]): + for y_ind in range(lb[1], rt[1]): + x, y = self.indToPos((x_ind, y_ind)) + if not self.isInside((x, y)): + continue + if np.hypot(x-ox, y-oy) <= r: + self.occ_map[x_ind, y_ind] = 1 + + for ox, oy, w, h in self.rectangles: + lb = self.posToInd((ox, oy)) + rt = self.posToInd((ox+w, oy+h)) + for x_ind in range(lb[0], rt[0]): + for y_ind in range(lb[1], rt[1]): + x, y = self.indToPos((x_ind, y_ind)) + if not self.isInside((x, y)): + continue + self.occ_map[x_ind, y_ind] = 1 + + def distanceTransform(self): + """Get esdf from occmap, see also https://www.cs.cornell.edu/~dph/papers/dt.pdf + """ + tmp_buffer2 = tmp_buffer1 = np.zeros_like(self.esdf_map) + + def f_set_val(buf, x, y, val): + buf[x, y] = val + + # calculate positive distance + for x in range(self.occ_map.shape[0]): + self.FillESDF( + lambda y: 0 if self.occ_map[x, y] == 1 else 1000000, + lambda y, val: f_set_val(tmp_buffer1, x, y, val), + 0, self.occ_map.shape[1]-1, 1 + ) + + for y in range(self.occ_map.shape[1]): + self.FillESDF( + lambda x: tmp_buffer1[x, y], + lambda x, val: f_set_val(tmp_buffer2, x, y, val), + 0, self.occ_map.shape[0]-1, 0 + ) + dist_pos = np.sqrt(tmp_buffer2)*self.reso + + # calculate negative distance + tmp_buffer2 = tmp_buffer1 = np.zeros_like(self.esdf_map) + + # calculate positive distance + for x in range(self.occ_map.shape[0]): + self.FillESDF( + lambda y: 0 if self.occ_map[x, y] == 0 else 1000000, + lambda y, val: f_set_val(tmp_buffer1, x, y, val), + 0, self.occ_map.shape[1]-1, 1 + ) + + for y in range(self.occ_map.shape[1]): + self.FillESDF( + lambda x: tmp_buffer1[x, y], + lambda x, val: f_set_val(tmp_buffer2, x, y, val), + 0, self.occ_map.shape[0]-1, 0 + ) + dist_neg = np.sqrt(tmp_buffer2)*self.reso + self.esdf_map = dist_pos - dist_neg + + def FillESDF(self, f_get_val, f_set_val, start, end, dim): + v = np.zeros(self.esdf_map.shape[dim], dtype=int) + z = np.zeros(self.esdf_map.shape[dim]+1) + + k = start + v[start] = start + z[start] = -np.inf + z[start+1] = np.inf + + for q in range(start+1, end+1): + k += 1 + + s = -np.inf + while s <= z[k]: + k -= 1 + # if q==243 and k==242: + # print(f_get_val(q), f_get_val(v[k]), q, v[k]) + s = ((f_get_val(q) + q*q) - + (f_get_val(v[k]) + v[k]*v[k])) / (2*q - 2*v[k]) + + k += 1 + + v[k] = q + z[k] = s + z[k + 1] = np.inf + + k = start + for q in range(start, end+1): + while z[k + 1] < q: + k += 1 + val = (q - v[k]) * (q - v[k]) + f_get_val(v[k]) + f_set_val(q, val) + + def evaluateDistGrad(self, pos): + pos = np.array(pos) + pos_m = self.indToPos(self.posToInd(pos - self.reso / 2)) + diff = (pos - pos_m) / self.reso + values = np.zeros([2, 2]) + for x in range(2): + for y in range(2): + values[x, y] = self.getDistance( + pos_m+np.array([x*self.reso, y*self.reso])) + dist = (values[0, 0]*(1-diff[0])*(1-diff[1]) + + values[0, 1]*(1-diff[0])*(diff[1]) + + values[1, 0]*(diff[0])*(1-diff[1]) + + values[1, 1]*(diff[0])*(diff[1])) + grad = np.zeros(2) + grad[0] = (values[1, 0]-values[0, 0])*(1-diff[1]) + \ + (values[1, 1]-values[0, 1])*(diff[1]) + grad[1] = (values[0, 1]-values[0, 0])*(1-diff[0]) + \ + (values[1, 1]-values[1, 0])*(diff[0]) + grad = grad/self.reso + return dist, grad + + def getDistance(self, pos): + ind = self.posToInd(pos) + ind = self.boundIndex(ind) + return self.esdf_map[ind[0], ind[1]] + + def isValid(self, pos): + ind = self.posToInd(pos) + ind = self.boundIndex(ind) + return self.occ_map[ind[0], ind[1]] == 0 # check occ + + def getBbox(self): + """Return the bounding box + Returns: + origin: + length: + """ + return np.array(self.origin), np.array(self.length) + + +def plotEnv(env: ComplexEnv): + fig = plt.gcf() + ax = plt.gca() + for ox, oy, r in env.circles: + ax.add_patch(patches.Circle( + (ox, oy), r, edgecolor='black', facecolor='gray', fill=True)) + for ox, oy, w, h in env.rectangles: + ax.add_patch(patches.Rectangle((ox, oy), w, h, + edgecolor='black', facecolor='gray', fill=True)) + + +class AstarNode: + def __init__(self): + self.x = 0 + self.y = 0 + self.x_ind = 0 + self.y_ind = 0 + self.cost = np.inf + self.parent = None + + +def AstarSearch(reso, start, end, env: ComplexEnv): + """Astar search path + Args: + reso: float + start: [x,y] + end: [x,y] + env: ComplexEnv + Returns: + path: [[x,y]] + """ + + start = np.array(start) + end = np.array(end) + center = start + + def posToInd(x, y): + x_ind = round((x-center[0])/reso) + y_ind = round((y-center[1])/reso) + return x_ind, y_ind + + def indToPos(x_ind, y_ind): + x = center[0]+x_ind*reso + y = center[1]+y_ind*reso + return x, y + node_map = {} + open_set = PriorityQueue() + start_node = AstarNode() + start_node.x = start[0] + start_node.y = start[1] + start_node.x_ind, start_node.y_ind = posToInd(start[0], start[1]) + start_node.parent = None + start_node.cost = 0.0 + + def addNodeToOpen(node): + g = node.cost + h = np.hypot(end[0]-node.x, end[1]-node.y) + open_set.put((g+h, g, node.x_ind, node.y_ind, node)) + addNodeToOpen(start_node) + node_map[(start_node.x_ind, start_node.y_ind)] = start_node + cnt = 400 + while not open_set.empty() and cnt > 0: + cur_node = open_set.get()[-1] + + if np.hypot(cur_node.x-end[0], cur_node.y-end[1]) < reso: + break + for dx in [-1, 0, 1]: + for dy in [-1, 0, 1]: + if dx == 0 and dy == 0: + continue + pro_x = cur_node.x + dx*reso + pro_y = cur_node.y + dy*reso + if not env.isValid((pro_x, pro_y)): + continue + pro_x_ind, pro_y_ind = posToInd(pro_x, pro_y) + assert not ( + pro_x_ind == cur_node.x_ind and pro_y_ind == cur_node.y_ind) + if (pro_x_ind, pro_y_ind) not in node_map.keys(): + pro_node = AstarNode() + pro_node.x = pro_x + pro_node.y = pro_y + pro_node.x_ind = pro_x_ind + pro_node.y_ind = pro_y_ind + pro_node.parent = None + pro_node.cost = np.inf + node_map[(pro_x_ind, pro_y_ind)] = pro_node + pro_node = node_map[(pro_x_ind, pro_y_ind)] + if cur_node.cost + np.hypot(dx, dy)*reso < pro_node.cost: + pro_node.parent = cur_node + pro_node.cost = cur_node.cost + np.hypot(dx, dy)*reso + addNodeToOpen(pro_node) + + # extract course + cur_node = cur_node + path = [] + while cur_node != None: + path.append([cur_node.x, cur_node.y]) + cur_node = cur_node.parent + path.reverse() + return path + + +def calcVel(x, t): + assert len(x) == len(t) + x = np.array(x) + dx = np.diff(x, axis=0) + dt = np.diff(t) + v = np.array([_dx/_dt for _dx, _dt in zip(dx, dt)]) + return v + + +def calcAcc(x, t): + assert len(x) == len(t) + v = calcVel(x, t) + a = calcVel(v, t[:-1]) + return a + +start = (-2.5, 0.0) +end = (3.0, 0.0) +start_v = (0.0,0.0) +start_a = (0.0,0.0) +end_v = (0.0,0.0) +end_a = (0.0,0.0) +reso = 0.2 +ts = 0.1 + +figwidth = 6 +# A star search initial path +complex_env = ComplexEnv() +path = AstarSearch(reso, start, end, complex_env) +path = np.array(path) + +origin, length = complex_env.getBbox() +fig = plt.figure(figsize=(figwidth, figwidth/length[0]*length[1])) +plt.axis([origin[0], origin[0]+length[0], origin[1], origin[1]+length[1]]) +plotEnv(complex_env) +plt.plot(path[:,0],path[:,1]) +plt.title("Initial path") + +# convert path to B-spline trajectory +ctrl_pts = NonUniformBspline.parameterizeToBspline(ts, path, np.zeros([4,2])) +bs_raw = NonUniformBspline(ctrl_pts, 3, ts) +t_min, t_max = bs_raw.getTimeSpan() +traj_t = np.linspace(t_min,t_max,num=100) +traj_raw = np.array([bs_raw.evaluateDeBoor(t) for t in traj_t]) + +origin, length = complex_env.getBbox() +fig = plt.figure(figsize=(figwidth, figwidth/length[0]*length[1])) +plt.axis(np.array([origin[0], origin[0]+length[0], origin[1], origin[1]+length[1]])) +plotEnv(complex_env) +plt.plot(ctrl_pts[:,0],ctrl_pts[:,1],"--ok",linewidth=2) +plt.plot(traj_raw[:,0],traj_raw[:,1],linewidth=2) +plt.title("Initial Control Points") + +# B-spline control points optimization +opt = BsplineOptimizer(complex_env) +ctrl_pts_opt = opt.BsplineOptimizeTraj(ctrl_pts, ts, opt.SMOOTHNESS|opt.DISTANCE|opt.FEASIBILITY, 500, 500) +bspline_opt = NonUniformBspline(ctrl_pts_opt, 3, ts) +t_min, t_max = bspline_opt.getTimeSpan() +traj_t = np.linspace(t_min, t_max, num=100) +traj_opt = np.array([bspline_opt.evaluateDeBoor(t) for t in traj_t]) + +origin, length = complex_env.getBbox() +fig = plt.figure(figsize=(figwidth, figwidth/length[0]*length[1])) +plt.axis(np.array([origin[0], origin[0]+length[0], origin[1], origin[1]+length[1]])) +plotEnv(complex_env) +plt.plot(ctrl_pts_opt[:,0],ctrl_pts_opt[:,1], '--ok') +plt.plot(traj_opt[:,0],traj_opt[:,1], c='purple') +plt.title("Optimized Bspline") + +plt.figure(figsize=(figwidth, figwidth/length[0]*length[1])) +traj_opt_vel = calcVel(traj_opt, traj_t) +traj_opt_acc = calcAcc(traj_opt, traj_t) +plt.plot(traj_t[:-1], traj_opt_vel[:,0], "-", linewidth=2, label="vel_x") +plt.plot(traj_t[:-1], traj_opt_vel[:,1], "-", linewidth=2, label="vel_y") +plt.plot(traj_t[:-2], traj_opt_acc[:,0], "-", linewidth=2, label="acc_x") +plt.plot(traj_t[:-2], traj_opt_acc[:,1], "-", linewidth=2, label="acc_y") +plt.legend() +plt.title("Optimized Bspline Vel/Acc") +plt.show() diff --git a/Planning/figure/fast_planner.gif b/Planning/figure/fast_planner.gif new file mode 100644 index 0000000..482e129 Binary files /dev/null and b/Planning/figure/fast_planner.gif differ