From 48ab4aa4ba2b4037dd32435c7bc65932fa8853c0 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Nov 2018 22:07:25 +0800 Subject: [PATCH 1/2] test --- test.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test.txt diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..e69de29 From ab20546a4eb67e31506fa30d389e4b046a15cfb6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 18 Nov 2018 07:47:39 +0800 Subject: [PATCH 2/2] lecture1 --- ...01-An Introduction to AI-ustccheng02.ipynb | 571 ++++++++++++++++++ 1 file changed, 571 insertions(+) create mode 100644 2018-autumn/Lecture-01-An Introduction to AI-ustccheng02.ipynb diff --git a/2018-autumn/Lecture-01-An Introduction to AI-ustccheng02.ipynb b/2018-autumn/Lecture-01-An Introduction to AI-ustccheng02.ipynb new file mode 100644 index 0000000..27c7b3a --- /dev/null +++ b/2018-autumn/Lecture-01-An Introduction to AI-ustccheng02.ipynb @@ -0,0 +1,571 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "import networkx\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 最后一题" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "#定义语法内容\n", + "grammar = \"\"\"\n", + "sentence = adj noun verb adj noun2\n", + "adj = adj_single 和 adj_single 的 | null\n", + "adj_single = 漂亮 | 蓝色 | 好看\n", + "adv = 安静地 | 静静地\n", + "noun = 猫 | 女人 | 男人\n", + "verb = adv 看着 | adv 坐着 \n", + "noun2 = 桌子 | 皮球 \n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# 定义语法创建函数,将语法字符串转换为语法规则字典,键值为声明,值为表达式\n", + "def build_grammar(grammar_str,split=\"=\"):\n", + " grammar_dict = {}\n", + " l = []\n", + " for line in grammar.split(\"\\n\"):\n", + " if not line:\n", + " continue\n", + " stmt,expr = line.split(split)\n", + " stmt = stmt.strip()\n", + " expr = [e.split() for e in expr.split('|')]\n", + " grammar_dict[stmt] = expr\n", + " return grammar_dict" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'sentence': [['adj', 'noun', 'verb', 'adj', 'noun2']],\n", + " 'adj': [['adj_single', '和', 'adj_single', '的'], ['null']],\n", + " 'adj_single': [['漂亮'], ['蓝色'], ['好看']],\n", + " 'adv': [['安静地'], ['静静地']],\n", + " 'noun': [['猫'], ['女人'], ['男人']],\n", + " 'verb': [['adv', '看着'], ['adv', '坐着']],\n", + " 'noun2': [['桌子'], ['皮球']]}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grammar_dict = build_grammar(grammar)\n", + "grammar_dict" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# 定义语句生成函数,给定目标声明('sentence','adj'...)和语法规则字典,随机生成语句\n", + "def generate(targetStmt,grammar_dict):\n", + " if targetStmt == 'null': # null 应该返回空字符串,而不是'null'\n", + " return ''\n", + " if targetStmt not in grammar_dict: # 解析至最终单词,结束递归\n", + " return targetStmt\n", + " expr = random.choice(grammar_dict[targetStmt])\n", + " return ''.join([generate(e,grammar_dict) for e in expr])" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'蓝色和好看的女人安静地坐着蓝色和漂亮的皮球'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "generate('sentence',grammar_dict)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# BFS 广度优先搜索 DFS 深度优先搜索" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "#定义无向图\n", + "graph = {\n", + " 'A' :'B B B C', \n", + " 'B' : 'A C', \n", + " 'C' : 'A B D E',\n", + " 'D' : 'C',\n", + " 'E' : 'C F',\n", + " 'F' : 'E'\n", + "}\n", + "#去重\n", + "for k in graph:\n", + " graph[k] = set(graph[k].split())" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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/Xo99dRT2rNnjxo18o8+64EHHlBxcbFWrFjhdx18Q/nHTwgAUCv33nuvwsPD/ebhDsuXL1dqaqoWL14cdAEs0QkDQMDZvn27LMvSwYMH1axZM9PlVCszM1M///nP9eGHH6pHjx6myzGCThgAAsygQYPUo0cPW2/e8d1332nMmDFatGhR0AawRCcMAAEpMzNTt912my0f7uByuTR+/Hi1aNFCS5YsMV2OUXTCABCAoqOjNXz4cC1cuNB0KZd46aWXlJWVpX/84x+mSzGOThgAAtSXX36pn/70p/r000/Vtm1b0+VIktLS0nTnnXcqNTVVnTt3Nl2OcXTCABCgOnTooClTpuiZZ54xXYok9x7XY8eO1SuvvEIAf49OGAACWF5enrp166bU1FSjD3coLy/XPffco86dO+u5554zVofd0AkDQACLjIzUzJkz9fjjjxutY+HChcrNzdWCBQuM1mE3dMIAEOAKCwvVpUsXJSUlKTY21ufvv337do0dO1affPKJrr/+ep+/v53RCQNAgAsPD9ef//xnPfroo/J13/Xtt99qwoQJeu211wjgKhDCABAEpk2bpmPHjumdd97x2XuWlZVpwoQJmjJlioYPH+6z9/UnhDAABIHGjRtr3rx5evTRR1VeXu6T93zmmWfkcrn09NNP++T9/BEhDABBYtSoUQoNDdXq1au9/l7vvPOOli1bplWrVikkJMTr7+evWJgFAEFk27Ztmjp1qg4cOOC1hzt8/fXX6tu3r1avXq3Bgwd75T0CBZ0wAASRn/3sZ+revbsWL17sleufP39e48aN0+9+9zsCuBbohAEgyGRkZOj222/X4cOHFRER4dFrz5w5UwcPHtTGjRvVqBF93uXwJwQAQSYmJkbDhg3T3//+d49ed/369Vq7dq0SExMJ4FqiEwaAIHT06FH16dPHYw93OHLkiPr376+NGzeqX79+HqgwOBDCABCkHn74YZWUlOjFF19s0HWKi4sVFxenKVOmaMaMGR6qLjgQwgAQpHJzc3XjjTdq586dDXqq0UMPPaT8/HytWbNGDofDgxUGPgbtASBItWnTRn/4wx8a9HCHlStX6v3339eyZcsI4HqgEwaAIHb27Fl16dJFGzZsUN++fet07oEDBzRo0CC9++676tmzp5cqDGx0wgAQxK644op6Pdzh7NmzGjNmjObPn08ANwCdMAAEufPnz6tHjx564YUXdMcdd1z2eJfLpYSEBIWEhOi1115jGLoBGpsuAABgVpMmTTR37lw99thjuu2229QoN1davlzKyJAKCqQWLaSYGGnqVCkqSkuXLtXevXv18ccfE8ANRCcMAJDL5dLUm2/WX8LDdd3+/e4vFhf/eEBYmORy6fStt+r+3bv1wscfq1u3bmaKDSB0wgAAOV55Ra9+8YVUUlL1AUVFkqQrP/hAW5o2VeP335cI4QYjhAEg2L38sjRrlkKqC+BKQiTp3Dlp1iz3F6ZP92ppgY7haAAIZmlp0uDBUmHhJS8NlrRP0glJVT6EbKpHAAACaUlEQVT0MDxc2rZNquOtTfgRtygBQDCbN++HoebKjkr6SJJD0obqzi0qcp+PeqMTBoBglZMjdehw4QKs7z0jaaukfpKyJG2q7hqhoVJ2thQV5bUyAxmdMAAEq+XLq30pUdLE7z+2Svq2ugMdjhqvg5oRwgAQrDIyquyCkyV9KWmspD6SfiJpVXXXKCqSMjO9VWHAI4QBIFgVFFT5ZaekOyS1+f7zCd9/rVqnTnm0rGDCLUoAEKxatLjkS0WS/iWpTFLb779WIum03Culq9wlulUr79QXBOiEASBYxcS4F1ZVkiT3vcCfSdr7/ccBSQPlnie+RFiYFB3t3ToDGKujASBYVbE6+v9I6iHp7xcd+i9JMyR9rYuGUFkd3SCEMAAEs9GjpaQkqT5R4HBIo0ZJa9d6vq4gQQgDQDCrYcesy2LHrAZjThgAgllsrLRwoTtQ6yI83H0eAdwgrI4GgGBX8RCGWbPc9/3WNEDqcLgXYy1cyMMbPIDhaACAW3q6ey/ozZvdYVt5T+nvnyesESOkOXPogD2EEAYAXOjkSfdWlJmZ7o04WrVy34Y0ZQqroD2MEAYAwBAWZgEAYAghDACAIYQwAACGEMIAABhCCAMAYAghDACAIYQwAACGEMIAABhCCAMAYAghDACAIYQwAACGEMIAABhCCAMAYAghDACAIYQwAACGEMIAABhCCAMAYAghDACAIYQwAACGEMIAABhCCAMAYAghDACAIYQwAACGEMIAABhCCAMAYAghDACAIYQwAACGEMIAABhCCAMAYAghDACAIYQwAACGEMIAABhCCAMAYAghDACAIf8fQ21PvhZpmY8AAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Graph = networkx.Graph(graph)\n", + "networkx.draw(Graph, with_labels=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## BFS" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I am looking at C\n", + "I am looking at D\n", + "I am looking at B\n", + "I am looking at A\n", + "I am looking at E\n", + "I am looking at F\n" + ] + } + ], + "source": [ + "seen = set()\n", + "need_visit = ['C']\n", + "while need_visit:\n", + " node = need_visit.pop(0)\n", + " if node not in seen:\n", + " print (\"I am looking at %s\" % node)\n", + " seen.add(node)\n", + " need_visit = need_visit + list(graph[node])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## DFS" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "#定义无向长图\n", + "graph_long = {\n", + " '1': '2 7',\n", + " '2': '3', \n", + " '3': '4', \n", + " '4': '5', \n", + " '5': '6 10', \n", + " '7': '8',\n", + " '6': '5',\n", + " '8': '9',\n", + " '9': '10', \n", + " '10': '5 11', \n", + " '11': '12',\n", + " '12': '11',\n", + "}\n", + "for n in graph_long: graph_long[n] = graph_long[n].split()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeEAAAFCCAYAAADGwmVOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3XlclWXex/HPQVHALdzKXFBxwlxIc8mlx7SxJ7UscZKZMhHMDTXTGTMddbQ0zaWyxhEddUInfdJyaQNtymVMS3EFLS33UhMtxQxQgfv54xZFOOzncJ9z+L5fr/NKzr3ww4Qv13Vfi80wDAMREREpcV5WFyAiIlJaKYRFREQsohAWERGxiEJYRETEIgphERERiyiERURELKIQFhERsYhCWERExCIKYREREYsohEVERCyiEBYREbGIQlhERMQiCmERERGLKIRFREQsohAWERGxiEJYRETEIgphERERiyiERURELKIQFhERsYhCWERExCJlrS5APFhiIkRHQ3w8JCVBlSoQHAwREVCjhtXViYhYzmYYhmF1EeJh4uJgxgyIjTU/Tk29dczXFwwDuneH8eOhTRtrahQRcQEKYXGsqCgYMwZSUsywzY3NZgbynDkQGVly9YmIuBB1R4vjZAZwcnL+5xqGed6YMebHCmIRKYXUEhbHiIuDzp1zBPCzwBfAb8BdwFhgYPZr/fxgyxZo3boEChURcR0aHS2OMWOG2QWdzXjgBHAZ+AiYCOzOflJKinm9iEgpoxCW4ktMNAdh2elUaQqUv/Fn243X0ewnGQbExMD5804tU0TE1eiZsBRfdHSeh4cB0UAK0BLoYe8km828z4svOrY2EVelKXyCQlgcIT7+9mlI2cwH/g58BWzmVsv4NikpkJDgjOpEXEteU/jWrIHJkzWFrxRRd7QUX1JSvqeUAR4EfgSicjnn+7g4Vq1axe7du7l06ZIDCxRxEVFR5gDGdevM8M3+y2tKivneunXmeVG5fbeIp1BLWIqvSpUCn5qGnWfCN1z28uK9997j6NGjHD16lPLly9OwYUMCAwNvezVs2JDatWvj5aXfIcWNaAqf2KEpSlJ8s2aZXWjZfqtPBDYCjwO+wOdAb2AF8GT2e/j6wssv33wmbBgG58+fvxnIR48e5dixYzf/fOnSJerXr58jnAMDA2nQoAE+Pj5O/qKdTM8LPUsuU/gKRFP4PJpCWIrNOHeOjLp1KXP9+m3vnweeAvYDGUAAMBIYZO8mPj5w6lSBA+a3337j2LFjtwVz5uvUqVPUrFnztmDO+vL398dmsxXnS3YeLfnpmXr3NruYc/lx+x7wMnAKcz59NPA/mQdtNggJgdWrS6BQKWkKYSmWXbt28cILLzD14EG6XL6MrSj/nBz8QyYtLY0ff/wx11a0zWaz28UdGBhInTp1KFOmjEPqKDQt+emZEhMhICDXwYv/wVzAZiXQFjh74/3aWU8q5C+p4j4UwlIk586d469//SsxMTFMmzaN8KZNKfP737t8d5thGPz88885gjnz9fPPPxMQEGC3Fd2wYUN8fX2dU1hhnhdm8vNTELuDXB7XZOoAPHfjlatsj2vEc2hglhTKtWvX+Pvf/86MGTPo378/hw4dokrmwKw5c4oeJCX0vMtms1G9enWqV6/OAw88kON4SkoKx48fvy2Y//Of/3Ds2DFOnDhB1apVc7SiMwO6evXqRevmjovL8+/te6A5Ztf+u1kPZA7cadNGzwtdWR5T+NKBXcATQCMgFegFzMYcR3GTpvB5LIWwFFhMTAyjR48mMDCQbdu2ERQUdPsJmS0yN+5S9fX1pUmTJjRp0iTHsfT0dE6fPn1bF/eHH3548+P09HS7XdyBgYHUrVuXsmVz+XbLZcnPTMOBXJ/+Zi75qeeFriuPKXzngOvAB8BWwBtz0OI04NXsJ1+86Jz6xFLqjpZ8fffdd4wePZrvv/+eN998k8ceeyzvC3btMoMhJsYM26wBkzm4qEcPc3CRB7XgfvnlF7td3MeOHSMxMZG6devm6OK+5447uLdbN2xXr9q953vAGqAJcIRsLeFMel7o2p59FpYvt3voIlAVcyBW/xvvrcYM4b3ZT+7XD5Ytc06NYhm1hCVXly9fZurUqbzzzjuMGzeOtWvXUq5cufwvbN3abJmdP29Os0lIMH+L9/eH5s0hPNwjA6Nq1apUrVqV1nZ+sUhNTeXEiRO3BfPmzZt5aMcO6l+9ip+d+10G/oa5C9WSvD6xlvx0bcHB5veDnS5pf6AO5prqefL1Nb93xOOoJSw5ZGRkEB0dzYQJE+jevTvTp0/nrrvusrosz5RHK+kF4G7gJWAKebSEQa0kV5bP6Oi/AbHAp5jd0U8AnYGpWU9Sb4fHUktYbvPVV18xcuRIypYty0cffUQbzUV1rlyeF+7DXNwkR5dkbvS80HXVrGnO7c5lnvAk4AJwD+ADhAITsp5gs5mPbxTAHkkhLACcPn2acePGsWnTJl577TWeeeYZLQtZEnJZ8nMz5j7M9W58fAVzJO03wB57F/j7O7w0caDx42HDBrsj4L0xNzmZn9u1vr7m9eKR9FO2lEtNTWX69OkEBwdTt25dDh06xLPPPqsALinBwWZXYzaDMdfY3nfjNRR4DNhg7x56Xuj62rThwrhxJBd2ClsJT+GTkqeftKWUYRisW7eOpk2bEhcXx86dO5k+fToVK1a0urTSJTzc7tt+mMsXZr4qYnZV2u2QNIxc7yOu4fTp0zwQHc3O0FAzWPMLY5tNi7GUEhqYVQodPHiQF154gbNnz/LWW2/RtWtXq0sq3fJZVzgv6cCRZs1otG+fdcttSp7Onz9Pp06diIiIYOzYsaV2Cp/YpxAuRS5evMjkyZP5v//7PyZNmkRkZCTe3t5WlyXF2GEnw9eXoY0bc6hiRZYuXUqDBg0cX58U2aVLl+jSpQuPP/44U6dOvf1gKZvCJ/apO7oUSE9PJyoqisaNG3P9+nW+/fZbRo4cqQB2FW3amN2OfvZmC+fBzw+v118nKi6OJ554grZt27JkyRL0e7VruHLlCj169OChhx7ilVdeyXlCjRrm3O5ly+Djj83/vviiAriUUUvYw23ZsoWRI0dyxx138NZbb9GiRQurS5LcFHMXpQMHDvDss89Sr149Fi1axJ133lkCRYs9qampPPbYYzRo0IBFixa57taZYjm1hD3UyZMnCQ0NJSwsjAkTJrB582YFsKuLjDR3kwoJMUdMZ9+xydfXfD8kxDwv24CdZs2asXPnTpo3b859993HmjVrSrB4yXT9+nVCQ0OpWbMmCxcuVABLntQS9jDJycnMnDmTefPmMXLkSF588UX8CtvNKdYr5vPC7du3ExYWRseOHXn77bdv7XQlTpWenk7fvn1JTk5m9erVeuQj+VIIewjDMFi1ahVjx46lffv2zJo1i3r16uV/oXisK1eu8OKLLxITE8M777zDww8/bHVJHi0jI4NBgwZx8uRJPvnkE3zszP8WyU4h7AH27t3LCy+8wOXLl3n77bfp1KmT1SWJC4mNjWXgwIGEhoYyffp0fLN3c0uxGYbBqFGj2LVrFxs2bNB8eykwPRN2Y+fPn2fIkCF069aNvn37snv3bgWw5NC9e3fi4+M5c+YMrVq1Yvfu3VaX5HEmTZrE1q1b+fTTTxXAUigKYTd0/fp15s6dS5MmTfD19eXQoUMMGTJEizVIrqpVq8bKlSuZNGkS3bt355VXXiEtLc3qsjzCzJkzWbNmDRs2bOCOO+6wuhxxM+qOdjOfffYZo0aNok6dOjeDWKQwTp8+zYABA7h06RLLli0jKCjI6pLc1j/+8Q/eeOMN/vvf/1K7dm2ryxE3pJawmzh69ChPPvkkkZGRzJgxgw0bNiiApUhq167N+vXrb46enjdvHhkZGVaX5XaWLl3KzJkz+eKLLxTAUmQKYRf366+/Mn78eB544AHat2/PN998w5NPPqm5h1IsNpuN4cOHs337dv7973/TrVs3fvzxR6vLchsffPAB48eP57PPPqN+/fpWlyNuTCHsojIyMli2bBmNGzfmzJkzxMfHM27cOMqXL291aeJB7rnnHrZt20anTp24//77Wb58uZa9zEdMTAzDhw8nNjaWxo0bW12OuDk9E3aGxERzoYX4eEhKMjduDw6GiIgCLbSwc+dORo4cSUZGBm+//Tbt2rVzfs1S6u3evZt+/frRrFkzoqKiqFatmtUluZzNmzcTGhrKRx99pO9LcQxDHGfnTsMICTEMHx/zZa4AbL58fc33QkLM8+w4c+aM0b9/f6NWrVrGO++8Y6Snp5fwFyClXXJysjF69Gjj7rvvNmJiYqwux6V8/fXXRo0aNYyNGzdaXYp4EHVHO0pUlLkd3bp1kJpqvrJKSTHfW7fOPC8q6uahq1evMmvWLJo3b86dd97JoUOHCA8Px8tL/3ukZPn6+vLGG2/w7rvvMnToUIYOHcqVK1esLsty+/fv54knnuCdd96hS5cuVpcjHkQ/5R0hc/eb5OT8N2Y3DPO8MWMwoqL4+OOPadasGVu3buWrr75i5syZVK5cuWTqFslFly5diI+P5+rVq7Ro0YLt27dbXZJlDh8+TPfu3Zk3bx6PPfaY1eWIh9Ez4eIqxobsqV5ePFu3LgMXLKBbt26Or03EAdauXUtkZCQRERG8/PLLlCtXzuqSSsyJEyfo1KkTr7zyCuHh4VaXIx5ILeHimjHD7GrO4irwHBAAVAJaArF2Li1nGKxq2VIBLC4tJCSE/fv3c/DgQdq2bUtCQoLVJZWIM2fO0LVrV8aOHasAFqdRCBdHYiLExubogk4D6gJbgCRgKhAKnMh2uZdh4LV+vbltnYgLu/POO/nwww8ZOXIkDz/8MLNnzyY9Pd3qspzmwoULPPLIIwwcOJARI0ZYXY54MIVwcURH2327AjAFqI/5F/w40ACwu2y+zZbrfURcic1mY8CAAezcuZNPPvmELl26cPz4cavLcrikpCQeffRRevXqxbhx46wuRzycQrg44uNzjoK24xzwHdDU3sGUFHPjdhE30aBBAzZt2sSTTz5J27ZtWbJkiccs8PHbb7/x2GOP8eCDDzJt2jSry5FSQCFcHElJ+Z5yHegL9AdyXVvn4kXH1SRSAry8vPjLX/7Cpk2bmDdvHk8++STnzp2zuqxiSU1NpVevXtxzzz28+eabWhpWSoRCuDiqVMnzcAbQDygHzMvrRH9/x9UkUoKaNWvGjh07aN68Offddx9r1qyxuqQiuX79OqGhoVStWpVFixZpjr6UGP1LK47gYPDxsXvIwBwhfQ5YDXjndg9fX2je3CnliZSEcuXK8eqrr7J27Vpeeukl+vfvT1IBeolcRXp6OmFhYWRkZPDvf/9b+3JLiVIIF0ce0xYigW+BjwHfvO5hGHneR8RdtG/fnn379lGhQgWCg4PZuHGj1SXlyzAMhg4dyrlz53j//fdL1RxocQ0K4eKoWRO6dzdHOGdxElgI7APuAireeC3Pfr3NBj16FGhTBxF3UKFCBebPn8/ChQsJCwtj9OjRpGSbR+8qDMPgz3/+MwcOHOCjjz7C1zfPX5dFnEIhXFzjx5tdylkEYHZHpwJXsrz6Zr/W19e8XsTDdOvWjf3793PmzBlatWrF7t12J+hZavLkyWzevJmYmBgqVqxodTlSSpWZMmXKFKuLcGu1a0PVqrBpE1y/XvDr/Pxgzhx48knn1SZiIT8/P/r06UO1atXo168fKSkpdOzY0SUGPc2ePZvly5fzxRdfUL16davLkVJMa0c7yo1NHDJSUvDK66/UZjNbwHPmQGRkydUnYqHTp08zYMAALl26xLJlywgKCrKslqioKGbPns3WrVupXbu2ZXWIgLqjHScyErZsYXedOqSVLZujixpfX3MkdUgIbNmiAJZSpXbt2qxfv57+/fvz4IMPMm/ePDIyMkq8jmXLljF9+nS++OILBbC4BLWEHSg1NZVatWpxaOtW7oyNNVfCunjRnAfcvLk5ClqDsKSU++677wgLC6Ny5cr861//ok6dOiXyeVevXs2IESPYuHEj9957b4l8TpH8lLW6AE8SGxtLixYtuLNZM2jWzOpyRFzSPffcw5dffsnMmTO5//77mTt3Lk8//bRTV6iKjY1l2LBhrF+/XgEsLkUtYQf605/+ROfOnRk6dKjVpYi4hT179tCvXz+aNm1KVFQU1apVc/jn2LJlC3369OHDDz+kffv2Dr+/SHHombCDJCcnExsbyx/+8AerSxFxG/fffz+7d++mbt26BAcHExtrb+ftotu5cyd9+vThvffeUwCLS1JL2EHef/99Fi1axGeffWZ1KSJuafPmzYSHh9OtWzfmzJmT99zdxERzC9D4eHMjlSpVzGVkIyJujruIj4/nkUceYcmSJTz++OMl80WIFJJC2EGeeuopunXrxsCBA60uRcRtJSUlMWrUKLZu3cqyZcvo0KHD7SfExcGMGZDZYs66laivr7kMbPfunHzmGdqPHMmbb77JH//4x5L7AkQKSSHsAL/++it16tTh+PHjVK1a1epyRNzeunXriIyMJCIigilTpphrOt+Yi09Kihm2uTBsNlKAvX370vHf/y65okWKQM+EHeDjjz+mY8eOCmARB+nVqxf79+/n4MGDtG3blh8nTjQDODk5zwAGsBkGfoZBxzVrzOAWcWFqCTtAr169CAkJoX///laXIuJRDMPgk8mT+f3UqfhlO9YZ+Jpb8yxrA4ez38DPz1wcp3Vr5xYqUkRqCRdTUlISGzdu5EmtAS3icDabjZ4HDuCbyxziedzaICVHAIPZdT1jhvMKFCkmhXAxffjhh3Tu3Jk77rjD6lJEPE9iIsTGYitqh51hQEwMnD/v2LpEHEQhXEwrV67U6EsRZ4mOzvPweKA60BHYnNtJNlu+9xGxikK4GC5evMiXX37JE088YXUpIp4pPv72aUhZzASOAaeBwUBP4Ki9E1NSzHXcRVyQQrgY1q5dS9euXalUqZLVpYh4pqSkXA89AFQCygP9MVvDMbmdfPGioysTcQiFcDGsXLmS0NBQq8sQ8VxVqhT4VBuQ65Njf39HVCPicArhIjp//jxff/21lsMTcabgYHMf7mwuARuAVCANWA78F3jU3j18fc2tREVckEK4iNasWUO3bt2oUKGC1aWIeK7wcLtvXwcmAjUwB2b9HVgHBNk72TByvY+I1RTCRbRq1SqNihZxtpo1oXt3c4RzFjWAOOBXzFbx18Aj9q632aBHj5ubOoi4Gq2YVQTnzp0jKCiIs2fP4uvra3U5Ip4tLg46dzaXrCwsrZglLk4t4SL44IMPeOyxxxTAIiWhTRuYM8cM1MLw8zOvUwCLC1MIF4EW6BApYZGRt4I4lyUsb7LZbgVwZGTJ1CdSROqOLqTTp0/TrFkzfvrpJ8qXL291OSKly65d5lrQMTFm2Kak3DqWuZ9wjx4wfrxawOIWFMKF9NZbb7Fnzx6WLl1qdSkipdf58+ZSlAkJHNm1i0tA64gIcxS0BmGJG1EIF1KHDh2YOHEiPXr0sLoUEcEco7F8+XLWrl1rdSkihaZnwoVw6tQpDh8+TNeuXa0uRURuaNiwIceOHbO6DJEiUQgXwvvvv09ISAjlypWzuhQRuSEwMJCjR4+iTj1xRwrhQtCoaBHXU6VKFcqXL8957RksbkghXEDHjh3jxIkTdOnSxepSRCQbdUmLu1IIF9CqVavo3bs3ZcuWtboUEckms0taxN0ohAtIXdEirkstYXFXCuEC+O677zh79iydOnWyuhQRsUMhLO5KIVwAq1at4qmnnqJMmTJWlyIidqg7WtyVQrgA1BUt4trUEhZ3pRDOxzfffMPFixfp2LGj1aWISC7q1KnDhQsXSE1NtboUkUJRCOdj1apV9OnTBy8v/VWJuKoyZcpQr149jh8/bnUpIoWiZMmDYRisXLmS0NBQq0sRkXyoS1rckUI4DwkJCSQnJ9OuXTurSxGRfGhwlrgjhXAeMlvBtvw2ERcRy6klLO5IIZyLzK5ojYoWcQ8KYXFHCuFc7N27F8MwaNWqldWliEgBqDta3JFCOBfqihZxLw0aNOD48ePa0lDcikLYDsMwWLVqlbqiRdxIpUqVqFixIj/99JPVpYgUmELYjp07d1KuXDnuu+8+q0sRkUJQl7S4G4WwHZmtYHVFi7gXDc4Sd6PNcbPJyMhg1apVxMbGWl2KiBRSYGCgQljcilrC2Xz11VdUrlyZZs2aWV2KiBRSw4YN1R0tbkUhnI3mBou4L3VHi7tRd3QW6enpvP/++2zatMnqUkSkCDQwS9yNWsJZfPnll9SsWZPGjRtbXYqIFEGtWrVISkrit99+s7oUkQJRCGehrmgR9+bl5UX9+vW1paG4DYXwDWlpaaxevVohLOLm1CUt7kQhfMPmzZupW7cugYGBVpciIsWgwVniThTCN2iZShHPoBAWd6IQBq5fv86aNWvo06eP1aWISDGpO1rciUIY+OKLL2jUqBH169e3uhQRKSa1hMWdKITRqGgRT9KgQQNOnDhBRkaG1aWI5MtmlPLNN69du8Zdd91FfHw8derUsbocEXGAu+++mx07dlC3bl2rSxHJU+laMSsxEaKjIT4ekpKgShWOeHvT4Xe/UwCLeJDMLmmFsLi60hHCcXEwYwZk7oyUmnrzUGCZMqyz2aB3bxg/Htq0sahIEXGUzMFZDz30kNWliOTJ858JR0VB586wbp0ZvlkCGKB8ejpl09LM4507m+eLiFvT4CxxF54dwlFRMGYMJCdDfo++DcM8b8wYBbGIm1MIi7vw3BCOi7sVwIWRGcS7djmnLhFxOs0VFnfhuSE8YwakpOR4ex7QGigPhOd2bUqKeb2IuCW1hMVdeOYUpcRECAjI8fwXYA3mbx4bgBQgOrd7+PjAqVNQo4azqhQRJzEMg4oVK3L27FkqV65sdTkiufLMlnB0dK6HegO9gGr53cNmy/M+IuK6bDabWsPiFjwzhOPj7baCCyUlBRISHFOPiJQ4hbC4A88M4aQkx9zn4kXH3EdESpxCWNyBZ4ZwlSqOuY+/v2PuIyIlTiOkxR14ZggHB5sDq4rD1xeaN3dMPSJS4tQSFnfgmSEcHp7roTQgFUi/8Uq98V4OhpHnfUTEtaklLO7AM0O4Zk3o3t0c4ZzNNMAXeA1498afp2U/yWaDHj00PUnEjQUEBPDDDz+Qlmb312wRl+CZ84TBXDGrc+fCr5gF4OcHW7ZA69YOL0tESk7dunXZunUr9evXt7oUEbs8syUM5m5Ic+aYgVoYfn7mdQpgEbenLmlxdZ4bwgCRkbeC2E7XdFaGzXYrgCMjS6hAEXEmDc4SV+fZIQxmoG7ZAiEh5ohpX9/bj/v6ctVm46d27czzFMAiHkMhLK6urNUFlIjWrWH1ajh/3lyKMiHBXIjD3x+aN2etjw9LY2KIVRe0iEcJDAxk7dq1VpchkivPHZhVCKmpqdSrV49t27bxu9/9zupyRMRBduzYwfDhw9mlrUnFRXl+d3QB+Pj4MGDAAKKioqwuRUQcSN3R4urUEr7hxIkTtGrVilOnTlGhQgWryxERBzAMgypVqnDy5En8tQytuCC1hG+oX78+Dz74ICtWrLC6FBFxEG1pKK5OIZzF8OHDmTdvHuocEPEcgYGBCmFxWQrhLLp27Upqairbtm2zuhQRcZCGDRtqwQ5xWQrhLLy8vBg2bBj/+Mc/rC5FRBxE3dHiyhTC2fTv35/169dz9uxZq0sREQfQ0pXiyhTC2dxxxx388Y9/ZNGiRVaXIiIOoJawuDJNUbIjISGBbt26ceLECby9va0uR0SK4dq1a1SqVIkrV67o+1lcjlrCdjRv3pxGjRqxbt06q0sRkWIqV64cd999NydPnrS6FJEcFMK5GDFiBPPmzbO6DBFxAHVJi6tSCOeiV69eHDlyhISEBKtLEZFiUgiLq1II58Lb25shQ4ZoupKIB9AIaXFVCuE8DBo0iJUrV3Lp0iWrSxGRYlBLWFyVQjgPtWrVolu3bixdutTqUkSkGLR0pbgqTVHKx5dffslzzz3Ht99+i5eXfmcRcUcXL14kICCApKQkbDab1eWI3KRUyUfHjh3x9fXl888/t7oUESkif39/ypQpw88//2x1KSK3UQjnw2azMXz4cA3QEnFzGpwlrkghXADPPPMM27Zt48SJE1aXIiJFpMFZ4ooUwgVQoUIFwsLCWLBggdWliEgRKYTFFSmEC2jYsGH861//IjU11epSRKQI1B0trkghXECNGjWiVatWrFy50upSRKQI1BIWV6QQLgStJy3ivhTC4ooUwoXQrVs3fv75Z3bu3Gl1KSJSSHXr1uXcuXNcvXrV6lJEblIIF0KZMmUYNmyYWsMibqhs2bLUrVtXsxzEpSiEC2nAgAF8/PHHnD9/3upSRKSQtHyluBqFcCFVrVqV3r17s3jxYqtLEZFCatiwoUZIi0vR2tFFsGfPHkJCQjh69Chly5a1uhwRKYjERDZHRFDx2DFaN2oEVapAcDBERECNGlZXJ6WUQriIOnTowNixY+nVq5fVpYhIXuLiYMYMiI0lLSODsteu3Trm6wuGAd27w/jx0KaNdXVKqaQQLqLly5cTHR3Nf/7zH6tLEZHcREXBmDGQkmKGbW5sNjOQ58yByMiSq09KPYVwEV29epWAgAA2b95M48aNrS5HRLLLDODk5IJf4+enIJYSpYFZRVS+fHkGDhzI/PnzrS5FRLKLi4MxY5iXnExroDwQnu2UL4DGgB/QBTgJZmCPGQO7dpVktVKKqSVcDD/88AP33XcfJ0+epFKlSlaXIyKZeveGdetYYxh4ARuAFCD6xuELQCCwGOgJTAK2Al+D2TUdEgKrV5d42VL6qCVcDHXr1qVLly68++67VpciIpkSEyE2FgyD3kAvoFq2U9YATYE+gA8wBdgPHALz2XFMDGgtACkBCuFiylxPWh0KIi4iOjrfUw4C92X5uAJmy/hg5hs2W4HuI1JcCuFi6ty5MwBbtmyxthARMcXHQz5bjl4BqmR7rwrwa+YHKSmQkOD42kSyUQgXk81mY/jw4VpPWsRVJCXle0pF4HK29y4Dt43suHjRcTWJ5EIh7AD9+vVj48aN/PiU+izLAAAYGElEQVTjj1aXIiJVsrdxc2qK+Qw402/A0Rvv3+Tv79CyROxRCDtApUqVeOaZZ1i4cKHVpYhIcDD4+ACQBqQC6TdeqTfeCwEOAKtvvPcKEIw5ZQkwF+5o3rxEy5bSSVOUHOTbb7+lS5cunDx5kvLly1tdjkjplZiIUa8etqtXmQK8nO3wZMzR0J8DIzDnBz+AOX2pfuZJPj5w6pTWlBanU0vYQe69916aNm3Kas0tFLGMYRi8v2UL6202MjDD1sj2mnLj3K6YU5JSgM3cCuB04EqnTgpgKREKYQcaMWIE//jHP6wuQ6RUOnnyJD179mTKlCnUevttvPz8inSfDG9veu3YwYIFCzT1UJxOIexAPXv25IcffmDv3r1WlyJSaqSlpfHGG2/QqlUr2rdvz969e2kxaJC5BnRhg9jPD++33uLvX33FkiVL6NGjB6dPn3ZO4SIohB2qbNmyDB06VK1hkRKya9cu2rZty6effspXX33FhAkTKFeunHkwMvJWENtsed/IZrtt84Z7772X7du30759e+6//35WrFihVrE4hQZmOVhiYiJBQUEcPXqUqlWrWl2OiEf69ddfmTRpEu+99x6zZs2iX79+2HIL2l27zP2EY2LMsE1JuXUscz/hHj3M/YRbt85x+e7duwkLC6NJkyZERUVRvXp1J31VUhophJ2gX79+tGjRgr/85S9WlyLicT766CNGjBjB73//e2bPnl3wUDx/3lyKMiHBXIjD39+chhQenu8grNTUVCZOnMiKFStYuHAhPXv2LPbXIQIKYaf4+uuv6du3L99//z1eXurxF3GE06dPM3LkSBISEli4cCFdunQp8Rr++9//Eh4eTufOnZk7dy6VK1cu8RrEsyghnOCBBx7A39+f9evXW12KiNtLT09n3rx5tGjRgqZNmxIfH29JAAN06tSJ/fv34+3tTXBwMJs2bbKkDvEcagk7yTvvvMP7779PTEyM1aWIuK39+/czZMgQvL29WbhwIU2aNLG6pJtiYmIYPHgwTz31FDNmzMDX19fqksQNqSXsJH/605+Ii4vjyJEjVpci4naSk5N56aWXeOSRRxg4cCBbtmxxqQAG6NGjB/Hx8SQmJtKyZUt27txpdUnihspMmTJlitVFeCJvb28uXLjAzp07efTRR60uR8RtrF+/nscee4zKlSvz4Ycf0qlTp9xHPlvM19eXP/zhD9SsWZN+/frx66+/0rFjR8qUKWN1aeIm1B3tRMePH6dNmzacOnUKvyKu3iNSWpw7d45Ro0axY8cO5s+fT7du3awuqVDOnj3LoEGDOHPmDMuWLaNZs2ZWlyRuQN3RTtSgQQPat2/PihUrrC5FxGVlZGSwaNEimjdvTkBAAAcOHHC7AAaoVasWH3/8McOHD6dLly7Mnj2b9PR0q8sSF6eWsJNt2LCBcePGsWf9emxLl0J8vLnpeJUq5pZrERFaKF5KrW+++YYhQ4Zw/fp1/vnPfxIcHGx1SQ5x/PhxIiIiSE9PJzo6msDAQKtLEhelEHayjB07+Pz3v6fr9evmnOHU1FsHM1fr6d7dXK2nTRvrChUpQampqbz66qssWLCAl19+mSFDhnjcc9SMjAzeeustpk+fztSpUxkyZIjLPtsW6yiEnSkqCsaMISMlBa+8/pptNjOQb6xbK+LJNm7cyNChQwkODubtt9/m7rvvtrokp/r2228JCwujevXqLF68mNq1a1tdkrgQPRN2lhsBTHJy3gEMZms4Odk8PyqqZOoTKWEXLlwgPDyciIgIXn/9dT744AOPD2BAm0FIntQSdoa4OOjc2QzWGypmOyUFGAb8Pfu1fn6wZYvdheRF3JFhGCxbtoyxY8fyzDPPMHXqVCpWzP4dUTpoMwjJTi1hZ5gx4/adWoArWV7nAF+gj71rU1LM60U8wPfff0/Xrl15++23iYmJ4c033yy1AQzQqlUrdu/eTUBAAMHBwXz88cdWlyQWU0vY0RITISDg9gFY2SwFXgaOAnaHafj4wKlTGjUtbuvatWvMmjWLuXPnMmHCBJ5//nnKli1rdVkuRZtBCKgl7HjR0fmeshQII5cABnOgVgHuI+KKvvzyS1q0aMGOHTvYvXs3o0ePVgDboc0gBBTCjhcfn2cr+BSwBeif1z1SUsw9T0XcyMWLFxk8eDB//OMfeeWVV/joo48ICAiwuiyXVqlSJRYuXEhUVBT9+vVj1KhRpGR7lCWeTSHsaElJeR5eBjwINMjvPhcvOqggEecyDIP33nuPpk2b4u3tzTfffMNTTz2lObGF0L17d20GUUqpj8jRqlTJ8/AyYFxB7uPv74hqRJzq+PHjDBs2jB9//JHVq1fTvn17q0tyW1WrVmXFihWsWrWKnj17MnjwYCZNmkS5cuWsLk2cSC1hRwsONgdW2bEdOE0uo6Kz8vWF5s0dXJiI41y/fp1Zs2bRpk0bHnroIfbs2aMAdpDQ0FD27dvH3r17adeuHQcOHLC6JHEihbCjhYfnemgp0BuolM8trl29yh4PWUNXPM+OHTto3bo1n3/+OTt27GDcuHF4e3tbXZZH0WYQpYemKDlD796wbp25ElYhGTYbR4ODefiXX7j33nuZMGECnTp1ckKRIoVz+fJl/vrXv7J69Wpef/11nn76aT33LQHaDMKzqSXsDOPHm13KRWDz9aXR4sUcOXKE0NBQBgwYQKdOnfjss8+01J1YwjAM1qxZQ5MmTUhNTeXgwYM888wzCuAS0qBBAzZu3Ejv3r1p164dCxYs0M8CD6KWsLNkWTu6wPz8cmzikJaWxsqVK5k+fToVKlRg4sSJPP744+aOTCJO9sMPPzBixAi+++47Fi5cqF4Zi2VuBlGtWjWWLFmizSA8gH6SO0tkpBmofn7m4ht5sdnsBjBA2bJl6du3LwkJCYwbN44pU6bQokULVq5cqWdE4jTp6em89dZbtGzZklatWrFv3z4FsAvI3AyiQ4cOtGzZkuXLl6tV7ObUEna2XbvMtaBjYsywzToRP3M/4R49zC7sAmzaYBgGsbGxTJs2jZ9//pnx48fTt29fDYwRh9m7dy+DBg2iUqVKLFiwgKCgIKtLEju0GYRnUAiXlPPnzaUoExLMhTj8/c1pSOHhRVoj2jAMNm/ezLRp0zh69CgvvfQSERER+OQyPUokP1euXGHy5Mm8++67vPbaa4SHh+u5r4tLTU1l4sSJrFixgoULF9KzZ0+rS5JCUgh7gK+++opXX32VvXv3MmbMGAYPHkyFChWsLkvcyKeffsrw4cPp1KkTr7/+OjW0eYhb0WYQ7kvPhD1A+/bt+eSTT/jkk0/Ytm0bDRs2ZMaMGSTls4SmyNmzZwkNDeWFF15g8eLFLFu2TAHshrQZhPtSCHuQli1b8sEHH7Bp0ya++eYbAgMD+dvf/sbPP/9sdWniLImJMGsWPPss9Oxp/nfWLPPxRx4yMjKIiooiODiY3/3udyQkJNC1a9cSKlqcIftmEC+88ALJhZmdIZZQd7QHO3LkCDNnzmTNmjU899xz/PnPf+auu+6yuixxhLg4c8BfbKz5cdaduzIH/HXvbg74a9PmtksPHDjA4MGDsdlsLFy4kGbNmpVg4VISfvnlF0aMGMGePXtYtmwZbdu2tbokyYVCuBT44YcfmD17Nu+++y59+/blxRdfpF69elaXJUWVOQc9JSXvVdlsNjOQb0x9S0lJYerUqSxatIhp06YxaNAgzTf3cKtWreL5558v2GYQiYnm4NH4eHM3uCpVzLXwIyKKNHhUCkYhXIqcO3eON954g8WLFxMSEsK4ceNo1KiR1WVJYRRxEZhvn3uOnjExtGrVirlz51KrVi3n1Sgu5ezZswwaNIgzZ86wbNmynD0fxehVEQcwpNS5cOGC8be//c2oVq2a0bdvX+PgwYNWlyQFsXOnYfj5GYb5Y/Hm6xswuoBRGYxAMNZkO26A8ZvNZnw5d67VX4FYJCMjw1i8eLFRvXp1Y+bMmUZaWpp5YP5889+UzZbj38xtL5vNPG/+fGu/EA+klnApdvnyZebPn8+bb77Jgw8+yIQJE7j//vutLktyY2djkDSgCTAUeAHYAvQE9gL3ZLnUsNmwhYTA6tUlWLC4mhMnThAeHk5aWhpr/vd/qTlzZrGX1pXiUQgLv/32G4sWLWL27Nm0aNGCCRMm0KFDB6vLkqwSEyEg4PauQuAA0A74FchcVuN/gQeAqdnv4eMDp07p+V4pl5GRwcoxY3jyzTf5FxANJABP3/gzwDXgGWAXcBLYBHTOvIGfH2zZUqAV/iR/GpUhVKhQgVGjRnH06FF69uxJ3759efjhh9m4caPWpXUV0dF237b3f8fADOccbLZc7yOlh5eXF0+fOIGvzcbdwERggJ3zHgTeBXLMp0hJMZ8hi0MohOUmHx8fhg4dynfffUf//v0ZNmwYHTt25NNPP1UYWy0+PkcrGKAxUBOYDVwHPsPskrbbwZiSYi6bKqVbYiLExmIzDHoDvYBq2U4pB4zCDOIy2a83DHMt/HzmokvBKIQlB29vb/r378/BgwcZNWoU48ePp1WrVqxevZqMjAyryytVLly4wLZt2ziVS3h6A+uATzFbLK8DoUCd3G548aITqhS34ojeEPWqOExZqwsQ11WmTBlCQ0N56qmn+OSTT5g2bRqTJk3ir3/9K3/6058oW1b/fBzh+vXrHD16lMOHD3Po0CEOHz5885WWlkZQUBBv/Poruc3sDsZs/WbqAPTP7ZP5+zuydHFHufSqFIp6VRxGP0UlX15eXjzxxBP07NmTzz//nGnTpjF58mTGjx9PWFhY3gsACGDuenXhwoUcIXvo0CFOnTpFnTp1aNy4MUFBQbRr147w8HCCgoKoWbOmuZPRrFkwebLdH57xmCOhM4D5wFkg3F4Rvr7mzl1SujlqTXn1qjiERkdLkWzdupVXX32VgwcPMnbsWAYOHIivr2/hbuKBK/Rcu3aNI0eO5Ajaw4cPYxjGzaANCgq6+efAwEDKly+f941zGR0N8CKwGPOZ8P8AfwfsLsGi0dEC5vriy5ff9tZE4EdujY7Oqg7mAK3O2Q/06wfLljm+vlJGISzFEhcXx6uvvsqOHTsYPXo0kZGRVKpUKb+L3HqFHsMwSExMzBGyhw8f5ocffqBevXo5gjYoKIgaNWoUb39eO/OEC8xmA80TFritVyUNc675y5ghvAize7QscBVzpH0j4F9AJ6A8N6bC+frCyy/Diy9a8AV4FoWwOERCQgLTp0/n888/5/nnn+f555/H397zxyKue2yFq1ev3mzVZg3aQ4cOUaZMmRwhm9mqdVr3fFwcdO5cuMUVMmlup2TK0qsyBTOAs5oMTAHqY84Rzur4jffVq+I4CmFxqMOHD/Paa6/x0UcfMXjwYEaPHk3NmjXNg0Vc99iZQWwYBufOnbMbtKdPnyYgICBH0DZu3Jjq1as7pZ58ueDfobihYvSqZAD06oXX2rUOL6s0UgiLU5w4cYJZs2bx3nvv0b9/f8Z37UrN0FDLWnGpqal8//33dp/VlitXLkfIBgUF0bBhQ7y9vYv8OZ3GjXoTxEUVo1cl1cuLwUFBjF+9mnvvvdfxtZUyCmFxqjNnzjBnzhwenjePHtev55iYfgIYBnyF+bzpKWAu2YbtF/B5pmEYnD171u6z2jNnztCgQQO7z2qrVcu+VIEb2LXLfK4eE2P+/aSk3DqW+Vy9Rw/zubq6oMWeIvaqGHPmsNBmY+LEiUycOJGRI0dqS8xiUAiL8yUmYtSrh+3q1RyHemCu+LQAuAQ8AgwCRmY/McszqJSUlJut2uxTfnx8fOw+q23QoIFrtmqL6/x5c4R5QoI5ZcTf35yGFB6u53WSv2L0qhw5coT+/ftTrlw5oqOjCQgIKKGiPYtCWJwvjzmu92Ku8tTjxscvApeBhdnOu1amDEsDA3n16lV++uknGjZsaHe6j93BYCKSu2L0qqSnpzNnzhzmzJnDrFmzCA8PL94MgFJIISzOZ2deYqYFwPYb/70IPIq5+0+InXN/7NKF1H/+k/r162u1LhFHK0avSnx8PP369aN+/fr885//5M477yyRkj2BfpKJ8+WxQs9DmHMTKwPpmMst9srl3DoVKkAju8tQiEhx1ahR5Hm/wcHB7Ny5k5dffpkWLVowf/58QkLs/Sot2elpujhflSp2387AbPn2Bn4DLmC2hl/K7T7qahZxWeXLl2f69OmsXr2asWPH0r9/fy5dumR1WS5PISzOFxxsDqzK5hfgB2AE5sjoakAEEGPvHlr3WMQtdOjQgX379lGxYkWCg4P5/PPPrS7JpemZsDhfHuseNwQGA2OAK5gh7AfkeIKsFXpE3M6GDRsYOHAgISEhvPbaa/j5+VldkstRS1icr2ZNcy1oO6Mm1wDrgRqYa9SWBd7MfpLNZo7OVACLuJVHH32U+Ph4fvnlF1q2bMmOHTusLsnlqCUsJUPrHouUau+//z4jRoxg8ODBTJo0SVug3qCWsJSMNm3Mif6F7Y7KXPdYASzi1vr06cP+/fvZt28f7dq148CBA1aX5BLKTJkyZYrVRUgp0aYNVK0KmzZBWlre59ps2nhAxMNUrFiRp59+Gm9vb/r164eXlxcPPPBAqV72Ut3RUvK07rFIqXf8+HHCw8MxDIPo6GgaNmxodUmWUAiLdbTusUiplpGRwdy5c5kxYwbTp09n4MCBpW7ZS4WwiIhY6uDBg4SFhXHXXXexePFiatWqZXVJJab0dsSLiIhLaNq0KV9//TWtW7emRYsWrFq1yuqSSoxawiIi4jJ27txJWFgY999/P/PmzaNq1apWl+RUagmLiIjLaNu2LXv27KFmzZoEBwezYcMGq0tyKrWERUTEJW3cuJGIiAh69OjBnDlzqFChgtUlOZxawiIi4pIefvhh4uPjSUlJ4b777mP79u1Wl+RwagmLiIjLW7duHZGRkYSHhzNlyhTKly9vdUkOoZawiIi4vF69erF//34OHTpE27ZtiY+Pt7okh1AIi4iIW6hZsyZr1qzhL3/5C127duW1114jPT3d6rKKRd3RIiLidk6dOkVERASpqaksXbqURo0aWV1SkSiERUTELWVkZDBv3jxeeeUVpk6dytChQ/Ne9jIx0VwqNz4ekpKgShUIDoaICMuWylUIi4iIWzt06BBhYWFUrVqVJUuWULt27dtPiIszN42JjTU/Tk29dSxz05ju3c1NY9q0KbnC0TNhERFxc40bN2b79u107NiRli1bsmLFCm62L6OioHNnWLfODN+sAQzmLm6pqebxzp3N80uQWsIiIuIxdu/eTVhYGE2bNmVJmzZUmjIFkpMLfoMS3sdcLWEREfEYrVq1Yvfu3XQsV45FY8fSOjmZ8kB4lnO+Bh4BqgI1gD7A2cyDyckwZoy573kJUAiLiIhH8fHx4YXkZAKAicCAbMcvAoOBE8BJoBIQkfWElBTzGXIJUHe0iIh4lsRECAi4+fx3IvAjEJ3L6XuAh4Bfs77p4wOnTjl91LRawiIi4lmiowt1+n+BptnftNkKfZ+iKOv0zyAiIlKS4uNzjoLO7VTgFeDD7AdSUiAhwcGF5aSWsIiIeJakpAKddgToDrwF/I+9Ey5edFxNuVAIi4iIZ6lSJd9TTgJdgUlAv9xO8vd3XE25UAiLiIhnCQ4GHx/SgFQg/cYrFUgDTgMPA8OBobndw9cXmjd3eqkaHS0iIp7lxujoKampvJzt0GTABkwBKmQ7diXrByU0OlohLCIinqd3b3MpyqJEnM0GISGwerXj68r+qRTCIiLiceLizLWgC7NkZSY/P9iyBVq3dnhZ2emZsIiIeJ42bcw1oP38Cndd5trRJRDAoHnCIiLiqTI3YRgzxpz3m1fHr81mDsYqwc0bQN3RIiLi6XbtMteCjokxwzYl5daxzP2Ee/Qw9xMuoRZwJoWwiIiUDufPm0tRJiSYC3H4+5vTkMLDnT4KOjcKYREREYtoYJaIiIhFFMIiIiIWUQiLiIhYRCEsIiJiEYWwiIiIRRTCIiIiFlEIi4iIWEQhLCIiYhGFsIiIiEUUwiIiIhZRCIuIiFhEISwiImIRhbCIiIhFFMIiIiIWUQiLiIhYRCEsIiJiEYWwiIiIRRTCIiIiFlEIi4iIWEQhLCIiYhGFsIiIiEUUwiIiIhZRCIuIiFhEISwiImIRhbCIiIhFFMIiIiIWUQiLiIhYRCEsIiJiEYWwiIiIRRTCIiIiFlEIi4iIWEQhLCIiYhGFsIiIiEX+HxGLnSlicUqHAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Graph_long = networkx.Graph(graph_long)\n", + "networkx.draw(Graph_long, with_labels=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I am looking at 1\n", + "I am looking at 2\n", + "I am looking at 3\n", + "I am looking at 4\n", + "I am looking at 5\n", + "I am looking at 6\n", + "I am looking at 10\n", + "I am looking at 11\n", + "I am looking at 12\n", + "I am looking at 7\n", + "I am looking at 8\n", + "I am looking at 9\n" + ] + } + ], + "source": [ + "seen = set()\n", + "need_visit = ['1']\n", + "while need_visit:\n", + " node = need_visit.pop(0)\n", + " if node not in seen:\n", + " print (\"I am looking at %s\" % node)\n", + " seen.add(node)\n", + " need_visit = list(graph_long[node]) + need_visit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Repetition is the mother of evil." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "def search(graph,start,concat_func):\n", + " seen = set()\n", + " need_visit = [start]\n", + " while need_visit:\n", + " node = need_visit.pop(0)\n", + " if node not in seen:\n", + " print (\"I am looking at %s\" % node)\n", + " seen.add(node)\n", + " new_discovered = list(graph[node])\n", + " need_visit = concat_func(new_discovered,need_visit)\n", + "\n", + "def new_discovered_first(new_discovered,need_visit):\n", + " return new_discovered + need_visit\n", + "\n", + "def already_discovered_first(new_discovered,need_visit):\n", + " return need_visit + new_discovered" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "from functools import partial\n", + "dfs = partial(search,concat_func=new_discovered_first)\n", + "bfs = partial(search,concat_func=already_discovered_first)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I am looking at 1\n", + "I am looking at 2\n", + "I am looking at 3\n", + "I am looking at 4\n", + "I am looking at 5\n", + "I am looking at 6\n", + "I am looking at 10\n", + "I am looking at 11\n", + "I am looking at 12\n", + "I am looking at 7\n", + "I am looking at 8\n", + "I am looking at 9\n" + ] + } + ], + "source": [ + "dfs(graph_long,'1')" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I am looking at 1\n", + "I am looking at 2\n", + "I am looking at 7\n", + "I am looking at 3\n", + "I am looking at 8\n", + "I am looking at 4\n", + "I am looking at 9\n", + "I am looking at 5\n", + "I am looking at 10\n", + "I am looking at 6\n", + "I am looking at 11\n", + "I am looking at 12\n" + ] + } + ], + "source": [ + "bfs(graph_long,'1')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mapping" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "BJ = 'Beijing'\n", + "SZ = 'Shenzhen'\n", + "GZ = 'Guangzhou'\n", + "WH = 'Wuhan'\n", + "HLG = 'Heilongjiang'\n", + "NY = 'New York City'\n", + "CM = 'Chiangmai'\n", + "SG = 'Singapore'" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [], + "source": [ + "air_route = {\n", + " BJ : {SZ, GZ, WH, HLG, NY}, \n", + " GZ : {WH, BJ, CM, SG},\n", + " SZ : {BJ, SG},\n", + " WH : {BJ, GZ},\n", + " HLG : {BJ},\n", + " CM : {GZ},\n", + " NY : {BJ},\n", + " SG : {GZ,SZ} # 加上SG \n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAecAAAFCCAYAAADL3BUJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3XdUFFcbx/EvAgqIIiqKBRULdqzYUVFEIZbYW2wxiYkxiUajYgFLAmIhdo0NNLYYe28UA7ZojNheJfbeIiAIiMC8f6xswI4CswvP5xxOdnfmzj5DTvJj7ty510BRFAUhhBBC6IxcahcghBBCiLQknIUQQggdI+EshBBC6BgJZyGEEELHSDgLIYQQOkbCWQghhNAxEs5CCCGEjpFwFkIIIXSMhLMQQgihYySchRBCCB0j4SyEEELoGAlnIYQQQsdIOAshhBA6RsJZCCGE0DESzkIIIYSOkXAWQgghdIyEsxBCCKFjjNQuQAghhFDF/fvg7w+nTkFUFFhYgL09DBgAVlaqlmagKIqiagVCCCFEVjp2DLy9Ydcuzfv4+P+2mZqCooCrK7i7g4ODKiVKOAshhMg5FiyAESMgLk4Twq9jYKAJ6unT4auvsq6+5+SesxBCCL0wYcIEPvnkk9dur1q1KsHBwa8/QEowx8a+OZhBsz02VrP/ggXvV/AHkHAWQgihU1avXk3dunUxNzenWLFiuLq6Ehoa+tZ2Z8+epXnz5q/eeOzYf8GcHikBffx4+tp9IAlnIYQQOsPX15ehQ4cyZswY7t27x/Xr1xk8eDBbtmz5sAN7e2u6st9HXJymfRaScBZCCKEToqKi8PDwYN68eXTq1Im8efNibGxMu3btmDZtGgAJCQn07duXfPnyUbVqVY6nuqItU6YM+/fvB+DPP/+kYcOGFChQgGJFizJk61YSUnVlGwALgQqAJfA1kLI1CRgOFAZsgbmKgsHGjSTeuQNA8+bNGTduHI0aNcLc3Jx27drx77//0rt3b/Lnz4+DgwNXr17Vftd3332HjY0N+fPnf+ffhYSzEEIInXD48GHi4+Pp2LHja/fZunUrPXr0IDIykvbt2zNkyJBX7mdoaMjPP//Mw4cPOTxgAAHJycx/YZ/twDEgDFgH7Hn++WJgF3ASOAFsTmmwfLm27dq1a/n111+5desWly5domHDhgwYMIBHjx5RuXJlJk6cqN3XwcGBkydP8ujRo3f+XUg4CyGE0An//vsvhQsXxsjo9VNwNGnSBDc3NwwNDenTpw9hYWGv3K9OnTo0aNAAIyMjyty8ySBF4cAL+4wGCgClACc0YQyaoP4OKInmqnp0SoMzZ7RtBwwYQLly5bCwsMDV1ZVy5crh7OyMkZERXbt25e+//9bu+8knn1CoUKE3nteLJJyFEELohEKFCvHw4UMSExNfu4+1tbX2tZmZGfHx8a/cPzw8nLZt22JtbU3+335jDPDwxWOlem0GxDx/fRuwSbVN+zoiQvtZ0aJFta9NTU1feh8TE6N9P2PGDCpXroyFhcVrz+tFEs5CCCF0QsOGDTExMWHz5s1v3/ktvvrqKypVqsQ///zD4+7d8eK/e8pvUwy4mer9jZQXlpbpriMkJAQfHx/WrVtHRKpwfxuZvlMIIYROsLCwYNKkSXz99dcYGRnh4uKCsbEx+/fvJygoCDMzs3c+VnR0NPnz58fc3Jzz1tYsMDDA6h3n3OoGzAI+AvICPikbqlVL3wk9r8PIyAgrKysSExPJnTv3O7WTK2chhBA64/vvv8fX15cff/wRKysrbGxsmDt3Lh9//HG6jjN9+nRWr15Nvnz56LJtG53TMRnm54ALYA/UAtzQXMkafvppumoAaN26Na6urtjZ2VG6dOl3bifTdwohhMh2FEVh27ZtTJw4kaSkJHaamFDszz8xeI/I2wV8aWrKtfROYPIBpFtbCCFEtqEoClu3bmXixIkoioKnpyft27cn119/QfPm7zRDWBwQhObq+R4wMVcuOnbokLmFv0CunIUQQug9RVHYsmWL9vniCRMm0L59ewwMDP7bKfXc2m8QCzQDzgOmwEcNGjBrz550TSLyoSSchRBC6K3k5GS2bNnCpEmTMDAwYMKECbRr1y5tKKemJ6tSSTgLIYTQO8nJyWzevJlJkyZhaGiIp6fnm0M5tePHNXNl79ypCeHUc26nrOfs5qZZz7lu3cw7iTeQcBZCCKE3UkJ54sSJGBsb4+npSdu2bd8tlF/04AH4+8Pp05oJRiwtoXp16N8frKwyuvR0kXAWQgih85KTk9m0aRMTJ04kT548eHp68tFHH71fKOsBGa0thBBCZyUnJ7Nx40YmTpyIiYkJ3t7euLm5ZdtQTiHhLIQQQuckJyezYcMGJk2ahKmpKT4+Pri6umb7UE4h4SyEEEJnJCcns379eiZNmkTevHmZOnUqbdq0yTGhnELCWQghhOqSkpJYv349kydPxtzcnOnTp9O6descF8opJJyFEEKoJiWUJ02aRL58+XJ8KKeQcBZCCJHlkpKS+P3335k0aRIWFhb4+vri4uKS40M5hYSzEEKILJOUlMS6deuYNGkSlpaWzJw5k1atWkkov0DCWQghRKZLSkrit99+Y/LkyRQsWJDZs2fj7OwsofwaEs5CCCEyTVJSEmvXrmXy5MkULlyYOXPm0LJlSwnlt5BwFkIIkeESExNZu3YtP/74I4ULF2bevHm0aNFCQvkdSTiL9Ll/XzMX7alTEBUFFhZgbw8DBqg+F60QQn2JiYmsWbOGH3/8kSJFikgovyeZW1u8m2PHNKu47NqleR8f/9+2lFVcXF01q7g4OKhToxBCNSmhPHnyZKytrZkwYQJOTk4Syu9Jwlm8nZ6sfyqEyHqJiYmsXr2ayZMnU7x4cSZMmEDz5s0llD+QdGuLN0sJ5tjYt++rKJr9RozQvJeAFiLbSkxMZNWqVfz444+UKFGCxYsX07x5c7XLyjZyqV2AyFyrVq3CxcXl/RofO/buwZxaSkAfP/5+3yuE0FmJiYn4+/tTqVIl/P39Wbx4McHBwRLMGUzCOZsIDQ2lUaNGWFhYULBgQRo3bsyxY8fo3bs3e/fufb+DentrurLfR1ycpr0QIlt49uwZfn5+VKpUiRUrVrB06VKCgoIklDOJ3HPOBh4/fkypUqVYsGAB3bp1IyEhgZCQEKytrbG3t3+/g96/D6VLpx34lV4mJnD9erpHcScmJmJkJHdchNAFz54949dff+Wnn36idOnSeHp60qxZM7XLyvbkyjkbCA8PB6Bnz54YGhpiamqKi4sL9vb2+Pv706RJE+2+BgYGLFy4kAoVKmBpacnXX39Nyt9nSUlJDB8+nMKFC2NbqRJzExMxABKft/UDKgP5gLLAL6lqCAZKAl5AYaAMsCopSfPYFRAVFUXfvn2xsrKidOnS/PjjjyQnJwPg7+9P48aNGTZsGAULFmTChAkALFu2jMqVK2NpaUnr1q25du1aRv/qhBCv8ezZM5YtW0bFihVZtWoVfn5+BAYGSjBnEQnnbMDOzg5DQ0P69evHrl27iIiIeOP+27dv59ixY4SFhbFu3Tr27NkDwOLFi9m1axcnT57kRMuWbE5MTNOuCLAdeIwmqIcBJ1Jtvws8BG4By4Evnj3jQmgoAN988w1RUVFcvnyZAwcOsGLFCvz8/LRtjx49StmyZbl//z5jx45l8+bNeHl5sXHjRh48eICjoyM9e/b8oN+TEOLtnj17xtKlS6lYsSKrV69m+fLlBAQE0LRpU7VLy1kUkS2cO3dO6devn1KiRAnF0NBQadeunXL37l3Fz89Pady4sXY/QAkJCdG+79q1q+Lt7a0oiqI4OTkpCxcu1Gxo21bZBwqgPNOMw37ppwMoM5+/DgLFEJSYVNu7gjLJzk5JTExUcufOrZw9e1b7vQsXLlSaNWumKIqi+Pn5KTY2NmnOp02bNsqSJUu075OSkhRTU1Pl6tWrGf2rE0IoivL06VNl8eLFSpkyZRRnZ+c0/58QWU+unLOJypUr4+/vz82bNzlz5gy3b99m6NChr9zX2tpa+9rMzIyYmBgAbt++jY2NjWaDhQU2L7TbBTQACgIFgJ1orpRTWAJ5U70vDdwGHj58SEJCAqVLl/5vW+nS3Lp1S/te+73PXbt2je+++44CBQpQoEABChYsiKIoadoIIT5cQkICixcvxs7OjnXr1rFy5Ur27duX5naYyHoSztlQpUqV6N+/P2fOnElXu2LFinHz5k3NG3t7bhgba7c9BToDI4B7QCTghubSOkUE8CTV+yvAlVu38PDwwNDQkCNHjmi3Xb9+nRIlSmjfvzhhgY2NDb/88guRkZHan7i4OBo1apSucxJCvFpCQgKLFi3Czs6O9evXs3r1avbu3Uvjxo3VLk0g4ZwtnD9/nhkzZmiD9caNG6xZs4YGDRqk6zjdunVj1qxZ3Lp1i8iOHfFJStJuS0AT0FZoZq7ZBbzqAS3P5/uGPN/ni5kzqVSpEsWLF8fNzQ0bGxs+/vhjPDw8cHJy0g4Ke9GXX36Jt7c3Z8+eBTQDyn7//fd0nY8Q4mUJCQn88ssv2NnZsWHDBlavXs2ePXvkD18dI+GcDeTLl4+jR49Sv3598ubNS4MGDahWrRozZsxI13E+//xz7SjvWi4uuFWtihFgiGaE9mygG5ru69VA+xfaWz/fVhzoDSysW5dOn33GsGHDCAsLo2vXrjx58oQ//viDYsWKsXz5cqysrLR/EBw+fJiEhAQAOnbsyKhRo+jRowf58+enWrVq7EqZ11sIkW4poVyhQgU2bdrEmjVrJJR1mDznLF5r16xZfDl0KO/yAFMw8AlwM+UDMzM4cADq1n1ju9u3bxMaGkpoaCghISH8888/1K1bF0dHR5o0aULDhg3Jnz//B52HEDnZ06dP8fPzw8vLi6pVq+Lp6ZnuXjWR9SSchVZcXBxBQUG4uLhw7949WrduTZ7wcI7myoXR06dvbBtMqnA2M3vvxS+ioqI4fPgwISEhhIaG8tdff1GxYkWaNGmiDezUA9qEEK/29OlTli1bhre3N9WqVcPT05P69eurXZZ4RxLOQis2NpZmzZpx/vx5jIyMiIuLY9WqVXS+f/+tq1IF8zycPyCYX+Xp06f89ddf2rA+ePAghQoV0oa1o6Mj5cuXlxVwhHju6dOnLF26FG9vb+zt7fH09KRevXpqlyXSScJZvCQ0NJROnTrx66+/0rp1a82Hx49r5sreuVOzNGTqObdT1nN2c9Os5/yWruwPkZyczNmzZ7Xd4CEhITx79owmTZpoA7tGjRoy/afIceLj41m6dClTpkyhRo0aeHh4SCjrMQlnkUZISAidOnV6/WpWDx5opuQ8fRoiIsDSEqpXh/790z2Hdka5du2aNqxDQ0O5fv06DRo00HaD169fHzMzM1VqEyKzxcfHs2TJEnx8fKhZsyYeHh44ODioXZb4QBLOQuvAgQN06dKFNWvW4OzsrHY57+3ff//l4MGD2sA+deoU1atX14Z1kyZNKFSokNplCvFBUkJ5ypQp1KpVC09PT+pmYq+VyFoSzgKA4OBgunbtytq1a2nZsqXa5WSo2NhY/vzzT21YHzlyhJIlS6YZZFa6dGm5by30Qnx8PIsXL8bHx4fatWvj6elJnTp11C5LZDAJZ0FQUBDdu3fnt99+w8nJSe1yMl1iYiKnTp3SdoOHhIRgbGycJqyrVatGrlwyDYDQHXFxcdpQrlu3Lh4eHhLK2ZiEcw4XGBhIjx49WLduXY5dNF1RFC5duqQdYBYaGsrDhw9p1KiRNrDr1q1Lnjx51C5V5EBxcXEsWrQIHx8f6tWrh4eHB7Vr11a7LJHJJJxzsP3799OrVy/Wr18vy8G94O7duxw8eFAb1ufPn6d27drasG7UqBEWFhZqlymysbi4OH755RemTp1K/fr18fDwoFatWmqXJbKIhHMOtW/fPnr16sXGjRtxdHRUuxydFx0dzeHDh7Xd4MeOHaN8+fLabnBHR0eKFy+udpkiG4iNjeWXX35h2rRpNGjQAA8PD2rWrKl2WSKLSTjnQHv27KFPnz5s3LhRloV7TwkJCZw4cSLNI1wWFhbaiVGaNGlCxYoVZZCZeGexsbEsXLiQadOm0bBhQwnlHE7COYfZvXs3ffv2ZdOmTbI0XAZKTk7m/PnzaQaZPXnyJM0gs1q1amGcahlOISBtKDdq1AgPDw9q1KihdllCZRLOOcjOnTvp378/mzdvlpVossCNGzfSXFlfuXKF+vXrawO7fv36mJubq12mUMmTJ09YuHAh06dPp3Hjxnh4eGBvb692WUJHSDjnEDt27GDAgAFs3bpVVqRRSUREBIcOHdKG9cmTJ6lSpUqaq2srlWZZE1nnyZMnLFiwgOnTp+Po6Mj48eMllMVLJJxzgG3btjFw4EC2bdsmq9LokLi4OI4dO6a9uj58+DDW1tZpBpnZ2trKfets4smTJ8yfP58ZM2bQtGlTxo8fT/Xq1dUuS+goCedsbuvWrXz22Wds375dJsHXcUlJSZw+fTrNoh4GBgZprqyrV6+OoaGh2qWKdIiJiWH+/Pn4+vrSrFkzxo8fT7Vq1dQuS+g4CedsbMuWLXzxxRfs2LFD5tzVQ4qicOXKlTSDzO7evUvDhg21YV2vXj1MTEzULlW8QkxMDPPmzcPX15fmzZtLKIt0kXDOpjZt2sSXX37Jzp07ZYq/bOTBgweEhoZqw/rcuXPUrFkzzeQolpaWapeZo6UOZScnJ8aPH0/VqlXVLkvoGQnnbGjjxo0MHjyYnTt3yjR/2dyTJ084cuSI9ur66NGj2NraasPa0dGRkiVLql1mjhAdHa0N5ZYtWzJ+/HiqVKmidllCT0k4ZzPr169nyJAh7Nq1S6b6y4GePXvGyZMn03SF582bN80gs0qVKsmiHhkoOjqauXPn8vPPP+Ps7My4ceMklMUHk3DORn7//Xe++eYbdu/eLTMLCUBz3/rChQtpnreOioqicePG2sCuXbs2uXPnVrtUvfP48WPmzp3LzJkzadWqFePGjaNy5cpqlyWyCQnnbOK3337ju+++Y8+ePTK7kHijW7duaRf1CAkJ4eLFizg4OGjDumHDhuTLl0/tMnXW48ePmTNnDrNmzcLFxYVx48ZRqVIltcsS2YyEczawZs0avv/+e/bs2SOTGYh0i4qK4tChQ9qr6xMnTlCpUqU0j3AVLVpU7TJV9/jxY2bPns2sWbNo3bq1hLLIVBLOem716tUMHz6cffv2yWMaIkM8ffqU48ePa7vBDx48iJWVVZqwLl++fI6ZHCUqKkp7pdymTRvGjRtHxYoV1S5LZHMSznps5cqVjBw5kn379smjGiLTJCcnc/bs2TSDzBITE2nSpIk2sO3t7TEyMlK71AwVFRXF7NmzmT17Nq6urowbNw47Ozu1yxI5hISznlqxYgWjR49m//79MjJUZClFUbh+/br2nnVoaCg3b96kQYMGaRb1MDU1zdrC7t8Hf384dQqiosDCAuztYcAASMec5ZGRkcyePZs5c+bg5ubGuHHjqFChQubVLcQrSDjroeXLlzNmzBj2798vo0OFTnj48GGaRT1OnTqFvb29thu8cePGFCpUKHO+/Ngx8PaGXbs07+Pj/9tmagqKAq6u4O4ODg6vPUxkZCSzZs1izpw5tG3blrFjx0ooC9VIOOsZPz8/xo8fz/79+2UwitBZsbGxHD16VNsNfuTIEWxsbLQTozRp0oTSpUt/+BctWAAjRkBcnCaEX8fAQBPU06fDV1+l2RQZGcnMmTOZO3cu7dq1Y+zYsZQvX/7DaxPiA0g465Fly5bh4eFBQECADEgReiUxMZGwsLA0i3rkyZMnzSCzqlWrpm9ylJRgjo199zZmZtqAjoiIYObMmcybN4/27dvj5+fHP//8I8EsdIJME6QnlixZgqenJ4GBgRLMQi+sXbuW+vXrkzdvXooXL87gwYMxNjbm999/5+7duwQEBODs7MyxY8fo1KkThQsXpl27dvj4+HDo0CGePn36+oMfO5b+YAaIjUUZPpxfPv+cChUqcOPGDY4ePcqyZcs+7GSFyGBy5awHFi1axOTJkwkMDJR7YEIvzJgxg6lTpzJv3jxat26Nubk5J0+eZPr06Sxbtow8efK81Obu3btpZjK7cOECderUSbOoR/78+TU7d+oEmze/uSv7NZKAk6VLYxkYSNmyZbWfGxgYyJWz0B2K0GkLFy5UbGxslH/++UftUoR4J5GRkYqZmZmyfv361+7TrFkzZfHixdr3fn5+SuPGjbXvv/32W6VEiRKKmZmZYm1trdSsWVPJmzevUrNmTaVJrVpKFwMDpQ8o5qBUAeWYJqYVBZS/QKn5fFsXULqBMvb5trag5E35MTNTDAwMFD8/P0VRFAVQFixYoJQvX14pUKCAMnjwYCU5OVlRFEVJSkpSJk+erJQqVUqxsrJS+vTpo0RGRiqKoihBQUFKiRIl0pxf6dKllX379mXUr1TkQNKtrcMWLFiAl5cXQUFB8te80BuHDx/m6dOndOjQ4b2P4eDgQFhYGFFRUYwYMYI7d+5w+/Zt5s+fT7noaLYpCj2ASKA9MOR5uwSgI9AfeAT0BDalOu42IAaIMTVlfc+eWFtb07JlS+327du3c+zYMcLCwli3bh179uwBwN/fH39/f4KCgrh8+TIxMTEMGTIEITKLhLOOmjdvHj4+PgQFBVGuXDm1yxHinT18+JDChQunmZSkUaNGFChQAFNTU/7444+3HuOTTz6hUKFCGBkZMXz4cJ4+fcqVK1do2LAhZUxNaQK4AYZAHyDsebsjQCLwLWAMdALqveL44XFx9F25kt9++w0bGxvt56NHj6ZAgQKUKlUKJycnTp48CcCqVav4/vvvKVu2LObm5nh7e7N27VoSExPf4zckxNtJOOugOXPmMG3aNIKCgtLcExNCHxQqVIiHDx+mCa5Dhw4RGRlJoUKFSE5OfusxZsyYQeXKlbGwsKBAgQJERUXx8OFDzcb4eKxT7WsGxKMJ5dtACSD1xKI2pBUFdAAm29nh6OiYZpu19X9HNjMzIyYmBoDbt2+nefSrdOnSJCYmcu/evbeeixDvQ8JZx8yaNQtfX1+Cg4OxtbVVuxwh0q1hw4bkyZOHLVu2vHafvHnzEptqpPXdu3e1r0NCQvDx8WHdunVEREQQGRmJhYUFSsrgLxOT1x63GHALSD1M7Eaq18lAL8AJGJSOZVWLFy/OtWvXtO+vX7+OkZERRYsWfelckpKSePDgwTsfW4hXkXDWIT///DOzZs0iODiYMmXKqF2OEO+lQIECeHp6MnjwYNavX09MTAzJycmcPHmSJ0+eAFCzZk02btxIbGwsFy9eZOnSpdr20dHRGBkZYWVlRWJiIpMmTeLx48f/fUHRovCa56EbounqnovmSnoL8Geq7WOBJ8AsExOoXv2dz6lnz578/PPPXLlyhZiYGMaMGUP37t0xMjLCzs6O+Ph4duzYwbNnz/jxxx/f/BiYEO9AwllH+Pr6MnfuXIKDgzNm5iQhVDRy5Eh8fX2ZOnUqRYoUoWjRogwaNAgfHx8aNWrEsGHDyJ07N0WLFqVfv3707t1b27Z169a4urpiZ2dH6dKlMTExSXNfmDdc8eYGNgJLgQLASqAtkPLg1ho096Ut4+MxnzABc3NzVq1a9dbz+fTTT+nTpw9NmzbF1tYWExMT5syZA4CFhQXz58/ns88+o0SJEuTNm5eSJUum6/clxIvkOWcdMH36dBYuXEhQUFDa/wkJIV4tHc851we+BAakfGBgAB07woYNmVigEB9GrpxVNnXqVBYuXEhwcLAEsxDvyt0d5TX3ng8Ad9F0ay8HTgFtUm1XTE01i2AIocMknFXk4+PD4sWLCQ4Olm4wIdLhSZUqzCxZkqeGhi9tuwDUACyAGcB6NAPFAOIMDNji6IhSp06W1SrE+5BwVom3tzdLly6VYBYinWJiYnBzc+NU48YYz5qlWczC4L+Hp74A7qEZ+HUK+Ag0283MSPTxweP2bcaPH4/c0RO6zOjtu4iM9tNPP7FixQqCg4MpXry42uUIoTeio6Nxc3OjYsWKLFq0SLOKVf36mvWcd+7UhHBc3H8NUtZzdnMDd3fy1a1LQP/+tGjRAkNDQyZOnKjeyQjxBjIgLItNnjyZVatWERQURLFixd7eQAgBwOPHj2nTpg3Vq1dnwYIFLy8v+eAB+PvD6dMQEQGWlprHpfr3ByurNLvev38fJycnunfvjoeHR5adgxDvSsI5C02cOJG1a9cSFBSUZiYiIcSbRUVF0bp1a+rUqcOcOXPSt+7za9y7d4/mzZvzySefMHbs2AyoUoiMI93aWUBRFCZMmMD69esJDg6maNGiapckhN6IiIigdevWNGjQgFmzZmFgYPD2Ru+gaNGiBAYG4uTkRK5cuXCXEdxCh0g4ZzJFUfD09GTjxo0EBgZKMAuRDo8ePaJVq1Y0bdoUX1/fDAvmFMWKFSMwMJDmzZtjaGjIyJEjM/T4QrwvCedMpCgK48ePZ8uWLQQGBlKkSBG1SxJCb/z77784Ozvj7OzM1KlTMzyYUxQvXpygoCBtQA8fPjxTvkeI9JBwziSKojB27Fi2b99OYGAgVi8MSBFCvN6DBw9wdnbG1dUVb2/vTAvmFCVKlNAGdK5cuRg2bFimfp8QbyPhnAkURcHd3Z1du3YRGBhI4cKF1S5JCL1x//59WrZsSYcOHZg8eXKmB3OKkiVLau9BGxoa8u2332bJ9wrxKhLOGUxRFEaNGsXevXsJCAiQYBYiHe7evUvLli3p2rUrnp6eWRbMKUqVKqW9B50rVy6GDBmSpd8vRAoJ5wykKAo//PADAQEBBAQEUKhQIbVLEkJv3LlzhxYtWtCzZ09Vnz0uXbp0mnvQX331lWq1iJxLwjmDKIrCiBEjCAoKIiAggIIFC6pdkhB649atW7Ro0YJ+/foxZswYtcuhTJkyabq4v/jiC7VLEjmMhPOb3L+vmXHo1CmIigILC7C3hwED0sw4pCgK33//PSEhIezfv1+CWYh0uHHjBi1atOCzzz5j1KhRapejVbZs2TTPQX/22WdqlyRyEJkh7FWOHdPM1btrl+Z9fPx/21Lm6nV11SxPi6yoAAAgAElEQVRbV7cuQ4cO5dChQ+zduxdLS0t1ahZCD12/fh0nJycGDx6ss48wXbx4EScnJyZOnMinn36qdjkih5BwftGCBTBihGby/Df9agwMUExN+c3BAd/YWPbu3UuBAgWyrk4h9NzVq1dxcnLiu+++Y+jQoWqX80bh4eG0aNGCn376iX79+qldjsgBpFs7tZRgjo19+76KgkFsLB1CQmg/bRpmEsxCvLPLly/TokULRowYoRcjou3s7Ni/fz8tW7YkV65c9OnTR+2SRDaXLa+c/f39WbJkCaGhoe/e6NgxaN783YL5RWZmTOjdm4uxsaxcuTL97YXIQS5evEjLli0ZPXq03o2E/t///kfLli2ZNm0avXv3VrsckY19+NIuKgoNDaVRo0ZYWFhQsGBBGjduzLFjx97vYN7eadeBTY+4OAgJeb+2QuQg4eHhODk5MXbsWL0LZoDKlSuzf/9+fvjhB9asWaN2OSIb09tu7cePH9O2bVsWLFhAt27dSEhIICQkhDx58qT/YPfvawZ/vW8ngqLAP/9A1arv116IHOD8+fM4OzszadIkvR5YVaVKFfbu3UurVq0wNDSkW7duapcksiG9vXIODw8HoGfPnhgaGmJqaoqLiwv29vbafUaMGIGlpSW2trbsShl5jWZt2IEDB1KsWDFKlCjBuJ49SXoezP5AE2AEYAnYAiktDwPmqX5MgDIpBzUwIOGff+jbty/58uWjatWqHD9+XPudt2/fpnPnzlhZWWFra8vs2bO12yZMmEC3bt1e21YIfXfu3DlatmzJTz/9pNfBnKJatWrs2bOHb7/9lvXr16tdjsiG9Dac7ezsMDQ0pF+/fuzatYuIiIg0248ePUrFihV5+PAhI0eOZODAgaTcXu/Xrx9GRkZcvHiRv//+m71hYSx5+vS/tkBF4CEwEhgIKEBDIOb5TwTQAOiZ0igxka1nztCjRw8iIyNp3769dqBLcnIy7dq1o0aNGty6dYuAgABmzpzJnj17tN+5devWV7YVQt+dOXMGZ2dnfHx8stVIZ3t7e3bv3s2QIUPYuHGj2uWI7EbRY+fOnVP69eunlChRQjE0NFTatWun3L17V/Hz81PKlSun3e/JkycKoNy5c0e5e/eukjt3biU2Nla7fXWtWkpzTee04gdKueevFVCeaHJZuZPqMwWUL0FxAyXp+XtPUFoWLqw95tmzZxUTExNFURTlyJEjio2NTZravby8lP79+yuKoiienp5Ky5YtX9lWCH0WFhamWFtbK6tWrVK7lExz4sQJpUiRIsqmTZvULkVkI3p7zxk0gzP8/f0Bzf2sTz75hKFDh9K6dWusra21+5mZmQEQExPDo0ePePbsGcWKFdNuT37yBJtUx7VO9drs+T9jUn32CxAMHCFt14N1vnxpvjM+Pp7ExESuXbvG7du30zwHnZSUhKOj439tX6g3pa2RkV7/KxI52MmTJ2nTpg2zZs2ie/fuapeTaWrVqsXOnTtxc3PD0NCQdu3aqV2SyAb0tlv7RZUqVaJ///6cOXPmjfvZ2NiQJ08eHj58SGRkJJGRkTz+6SfOmpi80/eEAOOBLYBF6g1GRvCaZ51tbGywtbXVfl9kZCTR0dHs3Lnznb5TCH1z4sQJ2rRpw7x587J1MKeoU6cO27dvZ+DAgezYsUPtckQ2oLfhfP78eWbMmMHNmzcBzfy8a9asoUGDBm9sV6xYMVxcXBg+fDiPHz8mOTmZS82bcyA5+a3feQPoDqwA7F7YlpycjGJr+8p29erVI3/+/Pj4+BAXF0dSUhJnzpx5/8e+hNBhx48fx9XVlQULFtC5c2e1y8kyDg4ObNu2jQEDBqQZgCrE+9DbcM6XLx9Hjx6lfv365M2blwYNGlCtWjVmzJjx1rYrVqwgISGBKlWqYGlpSZdBg7hTowa8Ze3YAOAu0IX/RmxXBZINDLieOzdb9+5lyZIlPE01uAzA0NCQbdu2cfLkSWxtbSlcuDCfffYZUVFR73n2Quimo0eP4ubmxuLFi+nYsaPa5WS5+vXrs3XrVvr165dmwKcQ6ZUtZwh7Lx84Q5gSHExIXBxeXl6cOXOG4cOH8/nnn2Nubp7hpQqhiw4fPkyHDh3w8/Pjo48+UrscVR06dIiPP/6YVatW0apVK7XLEXpIb6+cM5yDA0yfDmZmb983NTMzmD4dAwcHmjZtyu7du9myZQuHDh2ibNmyTJo0iUePHmVOzULoiNDQUDp06MDy5ctzfDADNGrUiI0bN9KrVy8CAgLULkfoIQnn1L766r+AfksXNwYG2mDmhWkI69Spw++//05ISAhXr16lfPny/PDDD9y5cycTixdCHX/88QedOnVi5cqVuLq6ql2OzmjSpAkbNmygZ8+eBAUFqV2O0DMSzi/66is4cAA6dgQTE836zamZmmo+79hRs98b5geuWLEiy5Yt4+TJk9p73F9++SWXL1/O5JMQImsEBwfTuXNn1qxZg4uLi9rl6JymTZuybt06unXrxoEDB9QuR+gRuef8Jg8egL8/nD4NERFgaQnVq0P//mBl9R6He8CsWbNYuHAhrVu3ZvTo0VSvXj3DyxYiKwQEBNCjRw/WrVuHk5OT2uXotMDAQLp3787GjRvTzG8gxOtIOKvg8ePHLFiwgJ9//pl69erh7u5Ow4YN1S5LiHe2d+9ePvnkE9avX0/Tpk3VLkcv7N+/n549e7J582YaN26sdjlCx0k4qyguLg4/Pz+mTZtGmTJlcHd3p1WrVhi87X63ECravXs3ffv2ZePGjTRp0kTtcvRKyh81mzdvplGjRmqXI3SYhLMOePbsGWvXrmXKlCmYmpri7u5Ox44dyZVLhgQI3bJjxw4GDBjAli1bpLfnPaX8cbN169a3Tpokci4JZx2SnJzM1q1b8fb25vHjx4waNYrevXtjbGysdmlCsG3bNgYOHMi2bduoX7++2uXotZ07d9K/f3+2b99OvXr11C5H6CAJZx2kKAqBgYF4e3sTHh7ODz/8wMCBA7ULeAiR1TZv3sygQYPYvn07Dg4OapeTLaSei7tu3bpqlyN0jPSb6iADAwNatmzJ/v37Wb9+PYGBgdja2uLl5UVkZKTa5YkcZsOGDQwaNIhdu3ZJMGegtm3bsnjxYj766CNOnDihdjlCx0g467h69eqxadMmAgMDOX/+POXKlcPd3Z179+6pXZrIAdatW8fXX3/Nnj17qF27ttrlZDvt27fnl19+wdXVlb///lvtcoQOkXDWE1WrVmXFihUcP36cx48fU6lSJYYMGcK1a9fULk1kU2vWrOG7775j79691KxZU+1ysq2PP/6Y+fPn4+rqSlhYmNrlCB0h4axnbG1tmTdvHv/73/8wNzendu3a9OvXj3PnzqldmshGVq5cyfDhw9m3bx/29vZql5Ptde7cmTlz5tCmTRtOnz6tdjlCB0g46ylra2umTJnCpUuXsLOzw8nJiU6dOska0eKDLV++nFGjRrF//36qVaumdjk5RteuXZk5cyYuLi6cOXNG7XKEyiSc9VyBAgUYO3Ysly9fpnnz5nTu3JlWrVoRGBiIDMQX6bVs2TLGjh1LQEAAVapUUbucHKd79+74+vri4uIivWE5nDxKlc0kJCSwatUqpkyZgqWlJe7u7rRr104mNBFvtWjRIiZPnkxAQAB2dnZql5OjrVy5klGjRhEQEEClSpXULkeoQMI5m0pKSmLTpk14eXmRkJDA6NGj6dGjB0ZGRmqXJnTQggULmDJlCgEBAZQvX17tcgSwYsUKxowZQ0BAABUrVlS7HJHFJJyzOUVR2Lt3L15eXty4cYMffviBAQMGYGJionZpQkfMnTuX6dOnExgYSNmyZdUuR6Ti7+/PuHHjCAwMlN6MHEbCOQc5ePAg3t7enDhxgqFDh/Lll1+SP39+tcsSKpo1axYzZ84kKCiIMmXKqF2OeIVly5bh6elJUFCQ9GrkIHIjMgdp3Lgx27dvZ9euXfz999+ULVuW8ePH8/DhQ7VLEyrw9fVl9uzZBAcHSzDrsE8//RQPDw9atGjBpUuX1C5HZBEJ5xyoRo0arFmzhiNHjnDv3j3s7OwYOnQoN27cULs0kUWmTp3K/PnzCQ4OpnTp0mqXI97i888/Z8yYMbRo0YIrV66oXY7IAhLOOVj58uVZtGgRp0+fxtDQkBo1ajBw4EDCw8PVLk1kIi8vL5YsWcKBAwewsbFRuxzxjr788ktGjRpFixYtuHr1qtrliEwm95yF1r///svcuXOZO3cuTk5OuLu7U6tWLbXLEhlo8uTJrFq1iqCgIIoVK6Z2OeI9zJ07F19fX4KCgl7u9bh/H/z94dQpiIoCCwuwt4cBA8DKSpV6xfuRcBYviY6OZtGiRfj6+mJvb8+YMWNwdHRUuyzxARRFYeLEiaxbt47AwECsra3VLkl8gFmzZmnHC9jY2MCxY+DtDbt2aXaIj/9vZ1NTUBRwdQV3d5CVxfSChLN4radPn7J8+XKmTp2KtbU1Y8aMwdXVFQMDA7VLE+mgKAoeHh7a1c2KFCmidkkiA/j6+jJ//nyOffoplj/9BHFxmhB+HQMDTVBPnw5ffZV1hYr3IuEs3ioxMZHff/8db29vcuXKxejRo+natSuGhoZqlybeQlEUxowZw44dOwgICMBKujazlb2dOuG4eTOm6fnfuJmZBLQekHAW70xRFHbs2IG3tzf3799n1KhR9OnThzx58qhdmngFRVEYOXIk+/fvZ9++fRQuXFjtkkRGOnYMmjeH2Ng0H/sDS4DQN7U1M4MDB6Bu3UwrT3wYGa0t3pmBgQFt27YlNDSUpUuXsn79esqVK4evry8xMTFqlydSURSF4cOHExgYSEBAgASzjvP29sbNzS3NZxUqVHjlZ2vXrk1ppOnKfh9xcZr2QmdJOIt0MzAwoGnTpuzevZstW7Zw+PBhypYty8SJE3n06JHa5eV4iqIwdOhQQkJC2L9/PwULFlS7JPEWTZs25eDBgyQlJQFw9+5dnj17xokTJ9J8dvHiRZo2baoZlb1r15vvMb+JosDOnfDgQUadgshgEs7ig9SpU4fff/+dkJAQrl27Rvny5fnhhx+4c+eO2qXlSMnJyQwZMoSjR4+yb98+LC0t1S5JvAMHBweePXvGyZMnAfjjjz9wcnKiYsWKaT4rV64cCQkJGBQtSmKqYG6Opis7tRGAJWAL7Er1uR9QGcgXH0/ZSpX45ZdftNuCg4MpWbIkM2bMoEiRIhQrVgw/P78MP1/xdhLOIkNUrFiRZcuWcfLkSRISEqhSpQqDBg2S6QazUHJyMoMHD+bvv/9mz549FChQQO2SxDvKnTs39evX548//gA0Qezo6EiTJk3SfNa0adP/Gj19+trjHQUqAg+BkcBAICXKiwDbgceAX926DBs2jBMnTmjb3r17l6ioKG7dusXSpUv5+uuviYiIyLBzFe9GwllkqFKlSjFr1izCw8OxsrKifv369OrVi9OnT6tdWraWnJzMoEGDOHv2LHv27MHCwkLtkkQ6NWvWTBvEISEhODo64ujomOazZs2avdOxSgOfA4ZAP+AOcO/5to+AcoAB0Cx3blxcXAgJCdG2NTY2xsPDA2NjY9zc3DA3N+fChQsZco7i3Uk4i0xhZWXFjz/+yOXLl6lRowatWrWiXbt2HD58WO3Ssp2kpCTttKu7du0iX758apck3kPTpk0JDQ0lIiKCBw8eUKFCBRo1asShQ4f4559/OHPmDBcuXOD7779/67FSTzFj9vyfKUM2dwENgIJAgT172LlzZ5rFbwoVKpRm3XczMzMZ8KkCCWeRqfLnz8+oUaO4cuUKrq6u9OrVi+bNm7N3717kKb4Pl5SUxIABA7h27Ro7d+7E3Nxc7ZLEe2rYsCFRUVH8+OOPlCpVijFjxtCjRw8ePXqEvb09RkZGxMTEaLu2n6R6hPHuO37HU6AzmvvR90xMiPzpJ9zc3OS/RR0k4SyyhKmpKYMHDyY8PJyBAwcybNgwHBwc2LBhA8nJyWqXp5cSExPp27cvt2/fZvv27eTNm1ftkkQ6REdHc/DgQebNm8cXX3xB8+bNSUpKYubMmcTFxZEnTx6++OILevXqRf78+enSpQuzZ89m6NChlChWjFVJSSQBy4B3HdmRgCagrQAjRWGXjQ179+7NrFMUH8Do7bsIkXGMjY3p06cPvXv3ZuvWrXh7ezN27FhGjx5N7969MTY2VrtEvZCYmEifPn149OgR27Ztw9TUVO2SxGsoisK1a9cICwvT/pw8eZK7d+9StWpVatSoQc2aNenbty8bN27k559/xs/Pj9q1awOQkJDAihUr0gwGW7x0KYO7dGFMYiIDgUbvWEs+YDbQDXianEy7HTto3759Bp+xyAgyQ5hQlaIoBAYG4u3tTXh4OD/88AMDBw7EzMzs7Y1zqGfPntG7d2+io6PZtGkTJiYmapcknouPj+fs2bPaAA4LC+PUqVOYmppqQ7hGjRrUqFGDChUqpLm3m26vmSHsncgMYTpPwlnojD///BNvb28OHTrEd999x+DBg+VxoBckJCTQo0cPEhIS2LBhg0ydqqJ79+6lCeGwsDAuXbpEhQoVtAGc8pNpi40sWAAjRqQvoGVubb0g4Sx0ztmzZ/Hx8WHHjh188cUXDB06lKJFi6pdluoSEhLo1q0biqKwbt06CeYskpiYSHh4eJoQTnmePyV8U66Iq1SpkvX/XlICWlalylYknIXOunLlCtOnT2f16tX07t2bESNGUKZMGbXLUsXTp0/p0qULxsbGrF27lty5c6tdUrYUGRnJqVOn0lwRnzt3jhIlSrzULW1jY6M7y6ceP66ZK3vnTk0Ip55zO2U9Zzc3zXrO0pWtFySchc67e/cuM2fOZPHixbRt25ZRo0ZRpUoVtcvKMvHx8XTq1AkzMzPWrFkjg+YyQHJyMlevXn2pW/rBgwdUr149zRVx9erV9ecRtQcPwN8fTp+GiAiwtITq1aF/f5DlQvWKhLPQG5GRkcybN4/Zs2fTuHFj3N3dcXBwULusTBUXF0fHjh0pUKAAv/76qwTze4iNjeXMmTNpRkufOnWK/Pnzv9QtXa5cOVmnXOgECWehd548ecLSpUuZNm0alSpVwt3dHScnJ93pYswgsbGxdOjQgSJFirB8+fIPG9mbAyiKwp07d9LcFw4LC+Pq1atUrFgxTZd0jRo1KFSokNolC/FaEs5CbyUkJLBq1SqmTJmCpaUl7u7utGvXjly59H9unSdPntCuXTtKliyJn5+fXM294NmzZ5w/f/6lbunk5OQ0IVyzZk0qVaok9+iF3pFwFnovKSmJTZs24eXlRUJCAqNHj6ZHjx56e6UZExND27ZtsbW1ZcmSJTk+mB89evTSBB4XLlygVKlSL3VLFy9ePNv1oIicScJZZBuKorB37168vLy4ceMGP/zwAwMGDNCrSTqio6Nxc3OjYsWKLFq0KFv0Aryr5ORkLl269FK3dGRkJNWrV09zRVytWjWZrlRkaxLOIls6ePAg3t7e/PXXXwwbNowvv/yS/Pnzq13WGz1+/BhXV1eqVavGggULsnUwP3nyhNOnT6cJ4dOnT1OwYMGXuqVtbW2z9e9CiFeRcBbZWlhYGFOmTGHfvn189dVXfPfddxQuXFjtsl4SFRVF69atqV27NnPnzs02YaQoCrdu3XppAo+bN29SuXLlNF3S9vb2WFpaql2yEDpBwlnkCBcvXmTq1KmsX7+evn37Mnz4cGxsbNQuC9A8Iubi4kKDBg2YNWuW3t4zTUhI4Ny5cy91SxsZGb00gUfFihXlsTAh3kDCWeQot27dwtfXFz8/Pzp27MioUaOws7NTrZ5Hjx7h4uKCo6Mjvr6+ehPMDx8+fGmkdHh4OLa2ti91S1tbW6tdrhB6R8JZ5Ej//vsvc+fOZe7cuTg5OeHu7k6tWrWyvAZnZ2datmzJtGnTdDKYk5KSuHjx4kvd0jExMS+NlK5ataosXSlEBpFwFjladHQ0ixYtwtfXF3t7e8aMGYOjo2Omf++DBw9wdnbG1dUVb29vnQjm6Oho7bzSKSF89uxZihQp8lK3dJkyZXSiZiGyKwlnIdAsLLFixQp8fHywtrbG3d0dNze39AXQ/fuaeY1PnYKoKLCwAHt7GDAgzbzG9+/fp2XLlnTo0IHJkydnecgpisL169df6pa+c+cOVatWfWleaQsLiyytTwgh4SxEGomJifz+++94e3uTK1cuRo8eTdeuXd88EcixY5oVgXbt0ryPj/9vW8qKQK6u4O7OvVKlaNGiBV26dGHChAmZHszx8fGcO3cuTQiHhYVhamr6Urd0hQoV9HbiFiGyGwlnIV5BURR27NiBt7c39+/fZ+TIkfTt2/fltXrTsZZusokJk/LnJ9fgwXh4eGR4zffu3XtpJq1Lly5Rvnz5l7qlixQpkuHfL4TIOBLOQryBoiiEhITg5eXFmTNn+P777/niiy80Swg+D+aQ2Fg+Ay48b1MVmAc0B7yAy8CS59sSjI3JPWvWBy12n5iYSHh4+Evd0vHx8S+NlK5SpcrLf1AIIXSehLMQz5UpU4Z79+5haGiIsbExjRo1YuHChdrnof/66y+mTJnCgQMH+Onjj/ls5UoMUi9q/67MzODAgXda9D4qKopTp06lCeGzZ89SokSJl7qlbWxsZJCWENmEhLMQz5UpU4YlS5bg7OxMfHw8gwcP5tGjR2zevDnNfhcuXCDGxYWa16/zXktSGBhAx46wYYP2I0VRuHLlyksTeDx48IBq1aqlCeHq1auTL1++DztZIYROk9EfQryCiYkJXbp0YejQoYBmNPfYsWNZt24dT+Pi6BgRwc+AKRAMfALcfN62DJpubGdgAnARWAlcBWwBf0Vh/MaNRJibU7VaNYyNjTl16hTm5uYYGBjw77//UrBgQXr16sWaNWs4cuRI1p24EEInZI8JfIXIYLGxsfz22280aNAAgFGjRhEeHs7Jkye5+O233FIUJr3nsUOBk8A4GxuOHz/Op59+yuXLl+nTpw/lypXj9u3bHD16lD179mTU6Qgh9IxcOQuRyscff4yRkRExMTEUKVKEPXv2oCgKixcv5tSpUxQsWBAuXGBMcjK9AO/3+A5PoCAwysGBDfnyYWpqSqFChVi3bh0LFizA0tISS0tLvv32WyZMmJCh5yeE0A8SzkKksnnzZpydnUlKSmLLli00a9aMkydPEhsbS506dTQ7PXmCAiS953doZ5qOiMDMzIyYmBgAbt++nWYxDl1ZmEMIkfWkW1uIVzA0NKRTp04YGhpy5MgRTE1NOXv2LJGRkUR2704UEPOhX/LC8ojFihXj5s2b2vc3btz40G8QQugpCWchXkFRFLZs2UJERARVq1bl888/Z9iwYdy/fx/s7bmZJw8fdEfY1BSqV0/zUbdu3fD29iYiIoJbt24xd+7cDzoHIYT+knAWIpV27dphbm5O/vz5GTt2LMuXL6dq1ar4+PhQvnx56tWrh8n48Tg/faqddOS9KAr075/mIw8PD0qWLImtrS3Ozs506dJFJhARIoeSe85CPHf16tXXbnv8+DGKohAdHU3PXr2YffMm+QICQFFozn+PUQEkA7mfv56Q6vMygAKa55zd3MDKiuDgYO32vHnz8uuvv2rfL1iwgJIlS37IKQkh9JRcOQvxBjdu3ODbb7+lUqVKREdHc+LECfz8/Mjn5aXpmn7Bg+c/Zd50UFNTcHd/6eM7d+5w8OBBkpOTuXDhAjNmzKBjx44ZdCZCCH0i4SzEK1y8eJHPPvuMmjVrYmJiwrlz55g7dy6lS5fW7ODgANOna6bifO4YUAH4Bij1muM+NTLStHvF1J0JCQkMGjSIfPny0aJFCzp06MDgwYMz+tSEEHpAurWFSOX06dN4e3uzb98+vv76a/755x/Ns82vkrJ4xfNVqRwUhcjXHdjAAMXEBK98+ShpZMTnr9ildOnSnDlzJgPOQgih7+TKWQjgzz//pEOHDri4uFCrVi0uX77MhAkTXh/MKb76SrOIRceOYGLycle3qanm844dMfjjD3qHhDBu3DgOHDiQeScjhNB7svCFyLEURdGsMPXTT4SHhzNy5Eg+/fRTTF9xL/mdPHgA/v5w+jRERGieY65eXTMq28pKu9u+ffvo06cPhw8fxtbWNkPORQiRvUg4ixxHURR27tyJl5cXDx8+ZPTo0fTu3ZvcuXO/vXEGmT17NosXL+bQoUOywpQQ4iUSziLHSEpKYuPGjXh5eZGcnMzYsWPp3LkzhobvtfDjB1EUhUGDBnHv3j02bdpErlxyh0kI8R8JZ5HtPXv2jNWrV+Pt7Y2lpSVjx47lo48+wsDAQNW6EhISaNWqFY0bN8bLy0vVWoQQukVGa4tsKz4+nmXLljF16lTKlSvH/PnzcXJyUj2UU+TOnZv169dTv359qlatSu/evdUuSQihIyScRbYTExPDwoUL8fX1pW7duqxdu1a7LrOusbKyYsuWLbRo0YIKFSpQr149tUsSQugAudElso1Hjx4xadIkypYty/Hjx9m9ezdbt27V2WBOUb16dZYuXUqnTp24deuW2uUIIXSAhLPQe/fu3WPUqFFUqFCBq1evEhoaytq1a7G3t1e7tHfWvn17vv76az7++GNiY2PVLkcIoTIJZ6G3rl+/zjfffEPlypWJjY3l77//ZtmyZdjZ2ald2nsZPXo0dnZ2DBw4EBmnKUTOJuEs9E54eDiffvoptWrVwszMjP/973/MmTOHUqVeN6O1fjAwMGDJkiVcunRJRm8LkcPJgDChN06dOoWXlxeBgYEMGTLkzfNe6ylTU1M2b95M/fr1qVKliqxKJUQOJVfOQucdPXqU9u3b06ZNG+rWrculS5fw8PDIdsGconjx4mzatIkvvviCU6dOqV2OEEIFEs5CJymKQmBgIM7OznTv3p02bdpw+fJlRowYkSOmu6xbty5z5syhQ4cO3L9/XyeTlx0AABYHSURBVO1yhBBZTGYIEzpFURR27NjBTz/9xKNHj3B3d6d3794YGxurXZoqUlawCggIyNK5v4UQ6pJwFjohKSmJDRs2aAdCjR07lk6dOqky77UuSU5OpnPnzhQsWJAlS5bozOxmQojMJeEsVPXs2TNWrlzJlClTKFSoEGPHjsXNzU1CKJWYmBgaN27MgAEDGDp0qNrlCCGygIzWFqqIi4vTznttZ2fHwoULad68uYTyK5ibm7NlyxYaNmxI5cqVad26tdolCSEymVw5iywVHR3NwoUL+fnnn3FwcGDMmDHUr19f7bL0QkhICJ07dyYkJISKFSuqXY4QIhPJaG2RJR49esSECRMoW7YsJ06cYPfu3WzZskWCOR0cHR3x9vamXbt2REREqF2OECITSTiLTHX37l1GjhxJhQoVuHHjBocOHWLNmjV6Ne+1Lhk4cCAfffQR3bp1IzExUe1yhBCZRMJZZIpr167x9ddfU6VKFeLj4/n7779ZunQpFSpUULs0vTdt2jQMDQ0ZPny42qUIITKJhLPIUBcuXGDAgAHUrl2bfPny8b///Y/Zs2fr/bzXusTIyIi1a9eye/duFi9erHY5QohMIKO1RYYICwvDy8uLoKAgvvnmGy5evIilpaXaZWVbBQoUYNu2bTg6OmJnZ0ezZs3ULkkIkYHkyll8kMOHD9O2bVtcXV2pV68ely9fZvz48RLMWcDOzo6VK1fSvXt3rlz5f3v3H1Rlmfdx/I0gCYMIiKGoCaSkK9q6/l4SqJYtlVVR8yellEa6jfU82Kjg5o9nAVnZUaHUR3Cmx1+ZYhirkD8o0dIMN01yMpuANCiQEhFFj8B5/jiKmKjYAucAn9eMM537vu77+sI0fryvc93XlWvuckSkHulVKnlgN9e9joqKIicnh3nz5hEaGkqbNm3MXVqLFB8fT2JiIocPH24R646LtAQKZ6kzo9HIrl27iIqKoqSkhAULFjBlypQWu+61pTAajYSFhVFYWEhKSgqtWmlATKSpUzjLfVVWVrJ9+3ZiYmJo1aoVkZGRBAcHt/h1ry2JwWAgMDAQX1/f6vXJRaTp0oQwuSuDwVC97nWHDh2IiYlh+PDhWmLTAtna2pKcnMzgwYPp3bs3U6dONXdJIvIfUDjLHcrLy0lKSmL58uX07NmTxMRE/Pz8FMoWrkOHDnzwwQc89dRT9OjRg0GDBpm7JBH5jfTllFQrLS0lNjYWLy8vMjIySE5OZu/evfj7+yuYm4g+ffqwfv16xo4dS35+vrnLEZHfSE/Ows8//0x8fDyrV68mMDCQvXv30qdPH3OXJb/RqFGjOHXqFGPGjOHgwYPY2dmZuyQReUB6cm7BfvzxR9544w28vb0pKCjgyJEjbNmyRcHcDMyfPx9vb29efPFFNOdTpOlROLdAeXl5zJ49m969e2MwGDhx4gSJiYl0797d3KVJPbGysiIpKYnvvvtOs7dFmiCFcwty+vRppk+fTv/+/WnXrh2nT59m1apVdO3a1dylSQOws7Nj586drF27lpSUFHOXIyIPQN85twDHjx8nOjqazMxM5syZw3fffYeTk5O5y5JG4O7uTkpKCsOHD+fRRx/VVp0iTYSenJuxw4cPM3LkSIKCghg6dCg5OTksXLhQwdzCDBgwgISEBEaPHk1RUZG5yxGROtAKYc2M0WgkIyODqKgo8vLymDdvHtOnT9e618LChQvJzMwkIyMDW1tbc5cjIvegcG4mqqqq+Ne//kV0dDSXLl1iwYIFTJo0SeteS7WqqirGjRuHi4sLSUlJenddxIIpnJu4yspKtm3bRnR0NK1bt65e91qbH0htysrK8PX1JTQ0lNdff93c5YjIXWhCWBNlMBjYuHEjy5Ytw83NjX/84x88++yzehqSe3JwcCA1NZUhQ4bQq1cvnnnmGXOXJCK10JNzE3PlyhWSkpKIi4ujV69eREZG4ufnZ+6ypIn55JNPGDt2LIcOHeKxxx4zdzki8isa+2wiSktLWbZsGV5eXnz88cfs2LGDPXv2KJjlN3niiSeIiYnhL3/5CxcuXDB3OSLyKwpnC1dcXMzf/vY3vLy8yM7OZv/+/aSkpDBw4EBzlyZN3EsvvcTIkSOZMGECFRUV5i5HRGpQOFuogoICwsPD8fb2prCwkM8++4zNmzfj4+Nj7tKkGVm+fDnW1taEh4ebuxQRqUHhbGFyc3OZNWsWPj4+VFZWcvLkSdatW6d1r6VB2NjYsHXrVvbs2UNiYqK5yxGRGzRb20J8/fXXLFu2jF27dhEWFsbp06d5+OGHzV2WtABOTk6kpqYybNgwvL298ff3N3dJIi2enpzN7Pjx44wfP56AgAC8vb2rdxFSMEtj8vb2ZtOmTUycOJHc3FxzlyPS4imczeTTTz9lxIgRBAUF4evrS05ODpGRkVr3WswmMDCQyMhIRo0axaVLl8xdjkiLpvecG5HRaGTfvn1ERUVx7tw55s+fz7Rp03jooYfMXZoIYPp/NCwsjMLCQlJSUrTSnIiZKJwbQVVVFampqURFRXH58mUiIiKYNGkSNjb6yl8sj8FgIDAwEF9fX6Kjo81djkiLpHRoQBUVFbz33nvExMTw0EMPERkZyZgxY/Q0IhbN1taW5ORkBg8ejI+PD1OmTDF3SSItjp6cayoqgnfegZMn4eJFaNcO+vaF0FDo0KHOt7l27RobNmwgNjaWTp06ERkZyTPPPKN1r6VJyc7O5qmnnmL37t0MGjTI3OWItCgKZ4CsLIiJgfR00+erV2+ds7MDoxGGD4cFC+AeK3NduXKFxMRE4uLi6N27N5GRkQwbNqyBixdpOKmpqcyePZujR4/SuXNnc5cj0mIonNesgblzobzcFMJ3Y2VlCuq4OJg167ZTFy9e5O2332bVqlX4+voSERHBgAEDGrhwkcYRExPD+++/z8GDB7GzszN3OSItQrMI5+joaHJyckhKSiIvLw9PT0+uX79+/wlXN4P5ypW6d2ZvD3FxHPLxITQ0lEmTJrF27VoqKipYsWIFoaGh/9kPI2JhjEYjISEhVFVVsWXLFn09I9IImkU411TncM7KgoCABwvmG6rs7Fg5Zgx///BDnnvuOebNm4eXl9dvL1rEwpWXl+Pv78/o0aOJjIw0dzkizV7Lna0dE2Mayv4NjOXlPP3550zMztb3cNIi2NnZsXPnTgYPHszvfvc7goODzV2SSLPWJN/p8fT0JD4+vvrz4sWLCQkJqbVtQUEBo0aNwsXFhe7du5sW9y8qgvR0FhuNTABeANoCvYFjNa79Auh349xzwERgIWANXDh7lsE1Jod5eHiwf/9+AD7//HOGDh2Kk5MTnTp14tVXX8VgMFS3tbKyYu3atfTo0QNnZ2f++te/cnMAo7KykvDwcFxdXfH09OStt97CyspKW/qJ2bm7u5OSksLLL7/MyZMnzV2OSLPWJMM5IyODlStXsmfPnvu2nTx5Ml26dKGgoIDk5GQiIiLIWLiw+nwqMAkoAUYBr944bgCCgenAL8BkIKXmja2s7jokbm1tzYoVKyguLubIkSNkZGSwevXq29rs2rWLrKwsvvzyS7Zt21b9syQmJpKens6JEyf44osv2Llz5/1/ISKNZMCAASQkJDB69GiKiorMXY5Is9Ukw9nLy4uZM2eydevWe7Y7d+4cn3zyCbGxsbRp04bf//73zJgxg40ZGdWvSz0BjMD0NPw88OWNaz8DKoA5QGtgLHDbm54GA1y/Xmu//fv3Z8iQIdjY2ODh4UFYWBiZmZm3tZk/fz5OTk488sgjPPnkk5w4cQKAbdu28dprr9GlSxecnZ2ZP3/+A/xmRBrepEmTmDp1KuPGjbttREhE6k+TDGcnJyeio6MpLCy8Z7uCggJcXFxo27Zt9bFu3bqRX1pa/bljjfb2wFVMoVwAdAZqzkvt+usOqqpq7ffMmTMEBQXRsWNHHB0diYiIoLi4+LY2HTve6tne3p6ysrLqmrt2vdVTzf8WsRRLly7F1dWVWbNm0czmlIpYhCYZziUlJVy6dIm0tLR7tnN3d+eXX365bYeds2fP0tnR8b59dALygZp/7Zz7daO7LMM5a9YsevbsybfffktpaSnR0dF1/gusU6dO/PDDD7f6PHdHryJm16pVKzZu3MixY8dYtWqVucsRaXaaZDhXVlby1VdfkZWVdc92Xbt25Y9//CMLFizg6tWrnDx5kvXr1zP1ySehTZt7XjsU01D3W5iepD8APq/ZwNYWWreu9dpLly7h6OiIg4MDp0+fZs2aNXX+2SZMmMCqVavIz8+npKSE2NjYOl8r0pgcHBxITU0lNja2TvM/RKTummQ4u7q6MmPGDC5evHjftu+++y55eXm4u7sTHBzMkiVLCKzDTju2wPvAesAJ2AQEAdWbOxqNpgVJahEXF8eWLVto27YtM2fOZOLEiXX6uQBmzpzJn//8Z/r27Uu/fv0YMWIENjY2WFtb1/keIo2lW7dubN++neeff55vvvnG3OWINBvNbhGSOhs7FnbuvPeSnb8yGHgFCLWy4iNfX2bk55OTk9NgJQKkp6fzyiuv8P333zdoPyL/ifXr1xMbG8vRo0dxdnY2dzkiTV6TfHKuFwsWmNbKvodM4CdMw9r/B5wEngWws+OrwYPx9PSs97LKy8tJS0ujoqKC/Px8lixZogUfxOK99NJLjBw5kgkTJuidfJF60HLDeeBA0yYWdxmaBvgGeBxoB/wTSAY62dvz2qBBrNixg0WLFtV7WUajkUWLFuHs7Ey/fv3o1asXS5curfd+ROrb8uXLsba2Jjw83NyliDR5LXdY+6Z62JVKRExKSkoYMmQI4eHhzJw509zliDRZCmeAY8dMa22npZlCuOaa2zf3cx4xwjQUrq0gRe7pzJkzDBs2jO3bt+Pn52fuckSaJIVzTefPwzvvQHY2XLgAzs7Qpw9Mnw4dOpi7OpEmY9++fbzwwgscPny4QeZmiDR3CmcRaRAJCQmsW7eOw4cP37ZKn4jcn8JZRBqE0WgkLCyMwsJCUlJSaHVzRb2iItMI1cmTcPEitGsHfftCaKhGqERuUDiLSIMxGAwEBgbi6+tLdHCwaW5Herrp5I3NZ4BbczuGDzfN7aixHatIS6RwFpEGVVxczMqePVl86RI216/rrQiROmi57zmLSKNw3b6dpZcvY2Mw3H9FPqPRtE/63LmwZg379+/Hw8OjXuqorKzEwcGBs2fP1sv9RBqSwlmkmfLw8MDNzY3Lly9XH0tKSiIgIKDB+pw6dSovvvjirQNZWWT+13/R4epVfnyQG90M6Adcrzs/P5/Q0NDq7Vp79erFkiVLKC8vx9ramrKyMh555BEAQkJCWLx48QPdX6SxKJxFmrGKiopG3dIxPj6etLQ09u3bB8DVv/+dmdeu8U9M27A+iIorV2Dr1jq3Ly4uZujQoVRUVHD06FFKS0v58MMPOX/+fIOvgS9S3xTOIs3YG2+8QVxcHCUlJbWeP336NIGBgbi4uPDYY4+xbds2AHJzc3FycqKqqgqAGTNm8PDDD1dfFxISwsqVK++4X/v27UlISODll1/mcm4uS3bv5lFg+o3zV4E5mIK6M/DfgOHGuf2ABxANdARmAhw9CjdqAFixYgU+Pj4UFBTc0XdcXBwuLi5s2LCBbt26AaZds9566y169+5NRUUFVlZW5OXlsXr1at577z2io6NxcHAgODiYmJiYO3aQmzVrFnPnzr3Lb1ek4SicRZqxAQMGEBAQQFxc3B3nLl++TGBgIFOmTKGoqIh3332X2bNnc+rUKTw9PXF0dOT48eMAHDp0CAcHB77++msADh48iL+/f619Pvfcc/Tv35/JI0eyrrKS/61xbilwDNMmMseBT4GYGud/AMqAs8BqME0QKysDYNGiRWzevJkDBw7g7u5+R7/79+9n3LhxWFlZ3ff3Mnv2bCZOnEhERARlZWWkpKTw/PPPs3v3bkpLSwHTTPOb22GKNDaFs0gzt3TpUhISEjh//vxtx3ft2oWHhwehoaHY2Njwhz/8gXHjxpGcnAyAv78/mZmZ/PTTTwCMHz+ezMxMcnNzKS0t5fHHH79rn2+//TYfffstbwKP1Di+GVgMdAAeBt4ENtY4b3PjvC1gB2AwYDQYeO211/j444/56KOPcHV1rbXPn3/+mU6dHnTw/JYuXbowdOhQduzYAUBaWhru7u73/DlFGorCWaSZ8/HxISgoiGXLlt12/Pvvv+fo0aM4OTlV/9m8eXN1GPv7+3PgwAEOHjyIn58fAQEBZGZmkpmZybBhw24tKlILNzc3XFu3pvevjv8IdKvxuRuQX/M6TMFc089Xr5KUlMTChQtxdHS8a5/t27fnxx8faNrZHaZNm8amTZsA2LRpk56axWwUziItwJIlS0hMTCQ//1YUdu3aFX9/f0pKSqr/lJWVsWbNGsAUzocOHeLAgQP4+/vzxBNP8Omnn5KZmXnXIe3b1BLenYDva3w+i+m755tqG5B2bdOG1NRUQkJC+Oyzz+7a3Z/+9CdSUlKo69INtQ1/jx07ln//+9+cOnWK9PR0pkyZUqd7idQ3hbNIC9C9e3cmTpxIfHx89bGgoCDOnDnDxo0buX79OtevXycrK6v6e+UePXpgZ2fHpk2b8PPzw9HRETc3N3bs2FG3cLa1hdatbzs0GdP3zsXAeeB/gJD73cPWlqeffpoNGzYwevRojh07VmvTuXPnUlxcTGhoaPW7zD/88AOvv/46p06duqO9m5vbHbO47e3tCQ4OZvLkyfj6+tK5c+c7rhNpDApnkRbizTffvO2d57Zt27J37162bt2Ku7s7HTt2ZN68eVy7dq26jb+/P+3bt69+N9jf3x+j0Ui/fv3u36GDwx2HFgGPA32AvsBgYMG97mE0Vt/n2WefJTExkaCgIE6cOHFHU1dXV44cOQLAwIEDadu2LYGBgbRv3x4vL6872s+YMYMvv/wSZ2dnxo8fX3182rRpZGdna0hbzErLd4pIwxk7FnbuvP/KYLWxsoLgYLgxQaux5OTk0LdvX3766SccavkHhkhjUDiLSMPJyoKAANOKXw/K3h4yM2HAgHov626qqqqYM2cOBoOBdevWNVq/Ir+mYW0RaTgDB5o2sbC3f7Dr7O1N1zViMF+8eBFHR0cOHDjAokWLGq1fkdroyVlEGt6aNaa1ssvLtSuVSB0onEWkcRw7ZtrPOS3NFMLl5bfO3dzPecQI037OjfjELGKJFM4i0rjOn4d33oHsbLhwAZydoU8fmD4dOnQwd3UiFkHhLCIiYmE0IUxERMTCKJxFREQsjMJZRETEwiicRURELIzCWURExMIonEVERCyMwllERMTCKJxFREQsjMJZRETEwiicRURELIzCWURExMIonEVERCyMwllERMTCKJxFREQsjMJZRETEwiicRURELIzCWURExMIonEVERCyMwllERMTCKJxFREQsjMJZRETEwiicRURELIzCWURExMIonEVERCyMwllERMTCKJxFREQsjMJZRETEwiicRURELIzCWURExMIonEVERCzM/wMkDD6c5iOUlQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "air_route = networkx.Graph(air_route)\n", + "networkx.draw(air_route, with_labels=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": {}, + "outputs": [], + "source": [ + "def search_pathes(graph,start,destination,all_path=True):\n", + " seen = set()\n", + " pathes = [[start]]\n", + " chosen_pathes = []\n", + " while pathes:\n", + " path = pathes.pop(0)\n", + " frontier = path[-1]\n", + " if (not all_path) and (frontier in seen): continue # all_path为False时,只会得到最短路径\n", + " seen.add(frontier)\n", + " for city in graph[frontier]:\n", + " if city in path: continue # 避免搜索到 类似NY-BJ-NY 的path\n", + " new_path = path + [city]\n", + " pathes.append(new_path)\n", + " if city == destination:\n", + " chosen_pathes.append(new_path)\n", + " return chosen_pathes" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [], + "source": [ + "def draw_route(pathes): return '\\n'.join(' ✈️ -> '.join(path) for path in pathes)" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [], + "source": [ + "pathes = search_pathes(air_route,SZ,CM,all_path=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Shenzhen ✈️ -> Beijing ✈️ -> Guangzhou ✈️ -> Chiangmai\n", + "Shenzhen ✈️ -> Singapore ✈️ -> Guangzhou ✈️ -> Chiangmai\n", + "Shenzhen ✈️ -> Beijing ✈️ -> Wuhan ✈️ -> Guangzhou ✈️ -> Chiangmai\n" + ] + } + ], + "source": [ + "print (draw_route(pathes))" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [], + "source": [ + "pathes = search_pathes(air_route,SZ,CM,all_path=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Shenzhen ✈️ -> Beijing ✈️ -> Guangzhou ✈️ -> Chiangmai\n" + ] + } + ], + "source": [ + "print (draw_route(pathes))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "hide_input": false, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}