Skip to content

Instantly share code, notes, and snippets.

@tristandahn
Created June 7, 2015 21:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tristandahn/3b7bcac142a6a4f2a443 to your computer and use it in GitHub Desktop.
Save tristandahn/3b7bcac142a6a4f2a443 to your computer and use it in GitHub Desktop.
Development of a (Semi-)Automatic Character Network Tool
{
"metadata": {
"name": "",
"signature": "sha256:a459a671d6f9a0c86cce4ea7c0afd117b165e62713402350a8554947bf2f7275"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"(Semi-)Automatic Character Network Tool"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook will take you step by step through the creation, and testing of the Character Network tool. The test text used in this example is the first two chapters (approx. 7,500 words) of Kazuo Ishiguro's *Never Let Me Go*."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For the purposes of this script, an interaction, which constitutes a connection between characters and contributes to edge width, is represented by a co-occurrence of character names within a given paragraph. A block of code for parsing on the sentence level is provided after the main script, and can be substituted where the paragraph level parsing occurs in the name matching script."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**NOTE:** These scripts were written and tested using Mac OSX 10.7.5 and Python 3.4.2. Certain differences may exist across platforms, which can cause errors. These scripts will be unable to run in some earlier versions of Python, such as 2.7, and without installing the necessary libraries. Intructions for these installations are including within the explanatory text provided. If you have issues, please feel free to contact me with questions at [tristandahn@gmail.com](mailto:tristandahn@gmail.com)."
]
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Importing the Necessary Libraries"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First the necessary libraries need to be imported."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"OS is used in this script to iterate over files within folders to extract the characters from the texts to create character dictionaries, csv files which list the characters as well as assigning them a unique identifier, and again to put them back out from the dictionaries from the dictionaries to match the character names against the texts, which are iterated over concurrently."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import os"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"String is used in this script for the express purpose of assigning a list of punctuation marks to a variable for the purposes of stripping the punctuation from the character names and individual token entities of the text in order to maximize matches."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import string"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"CSV is important, as it has a function that allows me to read csv files (character dictionaries) into a [dictionary object](https://docs.python.org/2/tutorial/datastructures.html#dictionaries) (different from \"character dictionary,\" this is a data structure in python), using column headings as the key. Since the hand coded CSV character dictionaries have information in them unimportant to my purposes, this is essential in isolating the two pieces of information I am interested in using, namely the character names and their identifiers."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import csv"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"NLTK (Natural Language Took Kit) provides me with the tools I will need for extracting character names from texts for the creation of the algorithmically generated character dictionaries (explained in detail below). Please note that NLTK is not native to iPython and must be installed: http://www.nltk.org/install.html"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import nltk"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"RE is the regular expressions library for Python. It will be used in the context of first person perspective texts, allowing me to create an alias for the first person narrator pronouns (\"I\", \"I've\", \"I'd\" etc.). Additionally it is used to ensure that only exact matches of a character name are captured, which is particularly important for texts such as The Brothers Karamazov, in which there are characters with overlapping names, such as \"Ivan\" and \"Ivanovna.\""
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import re"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pandas is used in this context because of its ability to create dataframes that can be written to csv files. Since the character dictionaries provided to me are in csv form, in order to make the network building scripts work for both the computer generated dictionaries and the hand coded, they must be in the same format. Please note that Pandas is also not a native library, installation instructions are here: http://pandas.pydata.org/pandas-docs/stable/install.html I found that trying to install from the terminal using \"pip install pandas\" causes errors, and would suggest using Anaconda to install them. To do this, you must first [install Anaconda](http://docs.continuum.io/anaconda/install.html) and then follow the instructions for the install from the previous link (or try running \"conda install pandas\" from the terminal)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import pandas as pd"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 6
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The networkx and matplotlib libraries are what allow for the character network visualization. Matplotlib is fairly powerful, but a little cumbersome, allowing for robust visualization in iPython notebook, but at a steep learning curve. You may also need to [install networkx](https://networkx.github.io/documentation/latest/install.html)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import networkx as nx\n",
"import matplotlib.pyplot as plt\n",
"#the next line is important for displaying the image, trying to generate a graph without it will cause the notebook to freeze\n",
"%matplotlib inline"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Create directories for the .csv dictionary and for reading the text"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#set the directory to where you wish to save the files generated by these scripts\n",
"directory = \"NLMGDict\"\n",
"if not os.path.exists(directory):\n",
" os.makedirs(directory)\n",
"\n",
"directory = \"NLMGText\"\n",
"if not os.path.exists(directory):\n",
" os.makedirs(directory)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 48
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Removing .DS_Store files"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you are running these scripts in a Mac OSX environment, it may be necessary to remove hidden [.DS_Store](https://en.wikipedia.org/wiki/.DS_Store) files from the directories where you're texts and character dictionaries are. Common errors you may see while running these scripts that can be the result of this hidden file which is automatically created by OSX's Finder when it accesses folders are a UTF-8 encoding error or an iteration that creates a value that is outside of the range of the dictionary objects created by the scripts. The following script will remove these files from your Character Dictionary and Text folders.\n",
"\n",
"If a .DS_Store file is found in the directory, you will see a message indicating which directory it has been found and removed from. Running the script a second time should remove this message, confirming that it has been removed and printing just a list of the files in that directory.\n",
"\n",
"**NOTE:** You may need to run this block of code again after creating and editiing the .csv Character Dictionaries."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"dictDir = \"NLMGDict\"\n",
"textDir = \"NLMGText\"\n",
"\n",
"print('Character Dictionary Folder'+'\\n')\n",
"\n",
"for filename in os.listdir(dictDir):\n",
" if filename == '.DS_Store':\n",
" print('Found and removed .DS_Store in dictDir!')\n",
" os.remove(dictDir+\"/.DS_Store\")\n",
" else:\n",
" print(filename)\n",
"\n",
"print('\\n'+'Text File Folder'+\"\\n\") \n",
" \n",
"for filename in os.listdir(textDir):\n",
" if filename == '.DS_Store':\n",
" print('Found and removed .DS_Store in textDir!')\n",
" os.remove(textDir+\"/.DS_Store\")\n",
" else:\n",
" print(filename)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Character Dictionary Folder\n",
"\n",
"Never Let Me Go - Kazuo Ishiguro Chapter 1 and 2_Dictionary.csv\n",
"\n",
"Text File Folder\n",
"\n",
"Never Let Me Go - Kazuo Ishiguro Chapter 1 and 2.txt\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Set directory for reading texts"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we need to make a dictionary object which will hold our file names, which we will iterate over in order to make a unique character dictionary for each text in the corpus. We will use this dictionary again when we look for interactions in our text. The dictionary object is important here, since we can both use a key to look up the results from specific stories, as well as pass that key to new dictionaries when we move the data around in order to ensure that the correct dictionaries are matched with the correct stories when mapping interactions."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#set textDir equal to the folder where the text(s) you wish to create networks out of are stored\n",
"textDir = \"NLMGText\"\n",
"textDirDict = {}\n",
"textDictCount = 0\n",
"for filename in os.listdir(textDir):\n",
" #adds only .txt files\n",
" if filename.find(\".txt\") == -1:\n",
" continue\n",
" textDirDict[textDictCount] = (textDir + \"/\" + filename)\n",
" textDictCount = textDictCount + 1"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 9
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"Finding Names"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, let's looks at the process of extracting character names from text using named entity recognition (NER). These characters will act as the vertices of the network maps created by the algorithm. NER is a form of information extraction that, through the use of hand built as well as computer trained algorithms, seeks to identify specific units of text, such as people, dates, geographic locations [4]. Early versions were specifically built to fine specific entities, such as company names in Lisa Rau's 1991 paper, which used exclusively a process of heuristics and hand built rules [4]. More recent versions rely on supervised machine learning, in which positive and negative instances of entity recognition are evaluated and fed back into the algorithm in order to refine its thinking [4]. Unfortunately, a relatively small amount of genre or domain specific research exists, resulting in dramatically different results in precision and recall across types of text [4]. The NER used in this project was selected for the sake of convenience, as it exists as part of the Natural Language Took Kit available for use with Python. The relative inaccuracy of the NER was at first problematic, but certain steps were taken to mitigate this, and will be described below."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def nerTagger(textString, characters):\n",
" #tokenize textFile\n",
" textTokens = nltk.word_tokenize(textString)\n",
" #tag for parts of speech\n",
" textPos = nltk.pos_tag(textTokens)\n",
" #tag for PERSON, ORG, or LOC, NER tagger\n",
" textNE = nltk.ne_chunk(textPos)\n",
" \n",
" #call findPeople from above to extract the PERSON entities from the chunked text\n",
" findPeople(textNE, characters)\n",
" \n",
" #eliminate duplicates\n",
" uniqueCharacters = set(characters)\n",
" \n",
" characters = uniqueCharacters\n",
" \n",
" #remove punction from Characters, this will be done with the text as well\n",
" characterList = []\n",
" punct = set(string.punctuation)\n",
"\n",
" for character in uniqueCharacters:\n",
" character = \"\".join(ch for ch in character if ch not in punct)\n",
" characterList.append(character)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 50
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, since the NLTK NER algorithm (used below in the nerTagger function) provides us with its output in the [nltk.tree](http://www.nltk.org/_modules/nltk/tree.html) structure with branches labeled as \"PEOPLE\", \"LOC\" or \"ORG\", we must define a function that extracts the branches which are labeled as \"PEOPLE\", as these are our potential characters within the text.\n",
"\n",
"The following function is taken from a [notebook by Stefan Sinclair](http://nbviewer.ipython.org/gist/sgsinclair/bf112f84f130c8bac96c), which provides us with a \"quick and dirty\" corpus level look look at character networks in Sherlock Holmes [8]."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def findPeople(tree, people):\n",
" if type(tree) is nltk.tree.Tree and tree.label() == \"PERSON\":\n",
" people.append(\" \".join([word for word, pos in tree]))\n",
" elif (type(tree) is nltk.tree.Tree) or (type(tree) is list):\n",
" [findPeople(branch, people) for branch in tree]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 51
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This next step creates a list of English words from an online wordlist, which has the alphabet appended to it. This list is used by checking the results of the NER against it in order to exclude mistagged entities, such as place names."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import urllib.request\n",
"enDictURL = \"http://www-01.sil.org/linguistics/wordlists/english/wordlist/wordsEn.txt\"\n",
"enDictString = urllib.request.urlopen(enDictURL).read().decode()\n",
"enDictTokens = nltk.word_tokenize(enDictString)\n",
"\n",
"alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']\n",
"for ch in alphabet:\n",
" enDictTokens.append(ch)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 10
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This step creates a list of names from the name lists contained in NLTK in order to ensure that names which are also english words are not excluded by the list above. Additionally there is a line where you can add any other words you believe should be included for the particular text(s) you are working with, such as titles."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#get the location of the names list in the NLTK corpera\n",
"maleNamesFile = nltk.data.find(\"corpora/names/male.txt\")\n",
"femaleNamesFile = nltk.data.find(\"corpora/names/female.txt\")\n",
"\n",
"#create a list of these file locations for iterating over\n",
"namesFileList = [maleNamesFile, femaleNamesFile]\n",
"\n",
"#create an empty inclusion list that we will add our names to\n",
"inclusionList = []\n",
"\n",
"#iterate over the lists, open the files and add their words as tokens to our inclusion list one at a time\n",
"for filename in namesFileList:\n",
" f = open(filename, \"r\")\n",
" nameString = f.read()\n",
" f.close()\n",
" nameTokens = nltk.word_tokenize(nameString)\n",
" for token in nameTokens:\n",
" inclusionList.append(token.lower())\n",
"\n",
"#use the line below to add any other words you think may occur in character names\n",
"inclusionListAdditions = ['miss', 'mr', 'mrs', 'dr', 'doctor', 'general', 'colonel', 'mister',\n",
" 'inspector', 'herr', 'lady', 'sir', 'duke', 'duchess', 'm', 'count', 'de',\n",
" 'captain', 'st', 'lord', 'madam', 'madame']\n",
"\n",
"#iterate over this list and add them to our inclusion list one at a time\n",
"for word in inclusionListAdditions:\n",
" inclusionList.append(word)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 11
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This function is used to clean up the list of extracted named entities by using the two lists created above."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def nerCleanUp(cleanCharacterList, characterList, inclusionList):\n",
" \n",
" #iterate over character list\n",
" for name in characterList:\n",
" \n",
" #create a boolean check, if a word in the name is found to be a common word\n",
" #this will be switched, and the word will not be included in our final characterList\n",
" wordCheck = False\n",
" \n",
" #splits the name in the case that it is more than one word\n",
" nameList = name.split()\n",
" \n",
" #check each word in the nameList against the word list, and the inclusion list\n",
" #any name containing a word in the english word list and not in the inclusion list\n",
" for token in nameList:\n",
" for word in enDictTokens:\n",
" if token.lower() == word and token.lower() not in inclusionList:\n",
" wordCheck = True\n",
" if wordCheck == False:\n",
" cleanCharacterList.append(name)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This function is necessary only if the text has a first person narrator. Using regular expressions, it replaces all instances of the first person pronoun that exists outside of speech (quotations) with the word NARRATOR. This can be aliased to the name of the narrator in the character dictionary that is generated in order to ensure that the narrators presense in the text is represented as accurately as possible."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def narratorAlias(textString):\n",
" textString = textString.replace(\"\u201c\", '\"')\n",
" textString = textString.replace(\"\u201d\", '\"')\n",
" textString = textString.replace(\"\u2019\", \"'\")\n",
" textString = textString.replace(\"'\", \"\")\n",
"\n",
" patternList = [r'(\\bId\\b)(?=(?:[^\"]|\"[^\"]*\")*$)', r'(\\bIve\\b)(?=(?:[^\"]|\"[^\"]*\")*$)', r'(\\bIll\\b)(?=(?:[^\"]|\"[^\"]*\")*$)',\n",
" r'(\\bI\\b)(?=(?:[^\"]|\"[^\"]*\")*$)', r'(\\bme\\b)(?=(?:[^\"]|\"[^\"]*\")*$)', r'(\\bmy\\b)(?=(?:[^\"]|\"[^\"]*\")*$)']\n",
"\n",
" pattern = r'(\\bIm\\b)(?=(?:[^\"]|\"[^\"]*\")*$)'\n",
" narratorAliasString = re.sub(pattern, 'NARRATOR', textString)\n",
"\n",
" for pattern in patternList:\n",
" textString = narratorAliasString\n",
" narratorAliasString = re.sub(pattern, 'NARRATOR', textString)\n",
" \n",
" return(narratorAliasString)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 13
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since text files are not always perfect and the narratorAlias function relies on the sequence of quotation marks in the text to be even, this next block of code can be used to view the results of the above function on particular texts in your corpus."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#test NARRATOR alias by key, change textDirDict[#] to view different texts\n",
"f = open(textDirDict[0], \"r\")\n",
"textString = f.read()\n",
"f.close()\n",
"\n",
"textTest = narratorAlias(textString)\n",
"\n",
"#first 1000 characters, change the value or remove the bracketed part to view more or all of the text\n",
"textTest[:1000]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 14,
"text": [
"'England, late 1990s\\n\\nPart One\\n\\nChapter One\\n\\nMy name is Kathy H. NARRATOR thirty-one years old, and NARRATOR been a carer now for over eleven years. That sounds long enough, NARRATOR know, but actually they want NARRATOR to go on for another eight months, until the end of this year. Thatll make it almost exactly twelve years. Now NARRATOR know NARRATOR being a carer so long isnt necessarily because they think NARRATOR fantastic at what NARRATOR do. There are some really good carers whove been told to stop after just two or three years. And NARRATOR can think of one carer at least who went on for all of fourteen years despite being a complete waste of space. So NARRATOR not trying to boast. But then NARRATOR do know for a fact theyve been pleased with NARRATOR work, and by and large, NARRATOR have too. My donors have always tended to do much better than expected. Their recovery times have been impressive, and hardly any of them have been classified as \"agitated,\" even before fourth donat'"
]
}
],
"prompt_number": 14
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Create .csv character dictionary"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's put it all together and write our character dictionaries as csv files. The .csv character dictionaries generated consist of three columns, the first assigns a unique identifier to each and is called \"id\", the next is the characters name in this instance and is called \"name\", and the last allows you to indicate which are proper names and which are aliases using a boolean operator in case you which to use that information for a later analysis, and is called \"identification.\" (\"Identification\" is set as True in all cases when this file is generated, and must be changed to False manually when aliasing the character dictionary.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here we go! (This script may take some time to run depending on the size of your corpus, as there are many processes running, and POS tagging in particular is processor heavy.)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"textCount = 0\n",
"\n",
"for filename in textDirDict:\n",
" f = open(textDirDict[textCount], \"r\")\n",
" textString = f.read()\n",
" f.close()\n",
" \n",
" characterList = []\n",
" \n",
" #call the NE tagger\n",
" nerTagger(textString, characterList)\n",
" \n",
" #remove duplicates\n",
" uniqueCharacterList = set(characterList)\n",
" \n",
" cleanCharacterList = []\n",
" \n",
" #create a variable outof the inclusionList generated above\n",
" localInclusionList = inclusionList\n",
"\n",
" #call the NE list clean up method from above\n",
" nerCleanUp(cleanCharacterList, uniqueCharacterList, localInclusionList)\n",
" \n",
" #create the header for the csv files\n",
" csvCharacterList = []\n",
" csvCharacterList.append(['id', 'name', 'identification'])\n",
" characterCount = 1\n",
"\n",
" #add characters from the cleanCharacterList into the list to be turned into a csv file\n",
" for character in cleanCharacterList:\n",
" characterEntry = [str(characterCount), character, 'True']\n",
" csvCharacterList.append(characterEntry)\n",
" characterCount += 1\n",
" \n",
" #turn the csvCharacterList into a matrix in order to write it to file\n",
" charcterMatrix = pd.DataFrame(csvCharacterList)\n",
" csvFile = charcterMatrix.to_csv(index=False, header=False)\n",
" \n",
" #from the textDirDict extract the filename and clean the beginning and end off for writing the csv filenames\n",
" removeDir = len('NLMGText/')\n",
" removeTxt = textDirDict[textCount].find('.txt')\n",
" filename = textDirDict[textCount][removeDir:removeTxt]\n",
" \n",
" #create a new csv file and write the matrix to it\n",
" f = open(\"NLMGDict/\" + filename + \"_Dictionary.csv\", \"w\")\n",
" f.write(csvFile)\n",
" f.close()\n",
" \n",
" textCount += 1"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 144
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"IMPORTANT!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The reason I'm calling this process \"(Semi-)Automatic\" is because the character dictionary should be opened in a text editor and \"aliased\" before matching it against the text. To do this, the same unique identifier (\"id\") should be applied to all instances of the same character, including aliasing the \"NARRATOR\" instance to the name of the narrator in the case of a first person narrated text. Additionally, it may be beneficial to add the characters first or last name as an entry as well, provided there are not more than one character with the same first or last name. At this point as well, you can make sure the \"identification\" column is accurate, with the proper instance of the name being set to \"True\" and any alias as \"False.\""
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Building Character Networks"
]
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Choose directory to load character dictionary from"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#this is the same as where you have just written the file\n",
"csvDir = \"NLMGDict\""
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 15
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Create the \"hit dictionary,\" a dictionary object of found names indexed by text"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The next block of code is where the bulk of the work is being done. The tricky part of this process is that the iterating over the files (both character dictionaries and stories) must occur at once in order for it to be a fully automated process. Since it all occurs in a single for loop, exposition/explanation will occur as comments in the script for the next section."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The result of this action is to iterate over the csv character dictionaries and check them against the text files in the txtDirDict created above. In the end a dictionary object of {key : [text, para, name and id]} (key = text) is created."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Note:** There is a line here marked by the \"!!!!!\" comment which should be included for first person narrated texts, but excluded for third person texts and possibly first person omniscent texts in the case that you are not interested in the narrator as part of the character network."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"textCount = 0\n",
"hitDict = {}\n",
"hitDictCount = 0\n",
"\n",
"for filename in os.listdir(csvDir):\n",
" \n",
" #if the file is not a csv file move onto the next iteration in the loop\n",
" #this is necessary as system generated hidden files (DSStore in OSX for example) will cause an error\n",
" #(thanks Stefan Sinclair for this snippet) \n",
" if filename.find(\".csv\") == -1:\n",
" continue\n",
" \n",
" #create temporary dictionary under the headings in the character dictionary for each csv\n",
" d = {}\n",
" d['character'] = []\n",
" d['value'] = []\n",
" d['identification'] = []\n",
" \n",
" #read csv into dictionary, field names match the names of the column headers\n",
" csvDict = csv.DictReader(open((csvDir + \"/\" + filename), 'rt', encoding=\"utf-8\"), \n",
" fieldnames = ['character', 'value', 'identification'], \n",
" delimiter = ',', quotechar = '\"')\n",
" \n",
" #skip over header column (fieldnames)\n",
" next(csvDict)\n",
" \n",
" #these two variables are needed for removing the punctuation in the next step\n",
" emptyString = \"\"\n",
" exclude = set(string.punctuation)\n",
" \n",
" #create character dictionary with id and name, strip punctuation and make lowercase\n",
" characterDict = {}\n",
" for row in csvDict:\n",
" charNameString = row['value']\n",
" charNameStringClean = emptyString.join(ch for ch in charNameString if ch not in exclude)\n",
" characterDict[charNameStringClean.lower()] = row['character']\n",
" \n",
" #open text from textDirDict and read to a string\n",
" f = open(textDirDict[textCount], \"r\")\n",
" textString = f.read()\n",
" f.close()\n",
" \n",
" #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",
" #if the text is first person include the following line to alias the first person pronoun within the text\n",
" #be sure to comment out this line if the text has a third person narrator\n",
" textString = narratorAlias(textString)\n",
" \n",
" #strip punctuation and make lowercase\n",
" cleanTextString = emptyString.join(ch for ch in textString if ch not in exclude).lower()\n",
" \n",
" #split text string on paragraphs\n",
" textParagraphs = cleanTextString.split(\"\\n\")\n",
" textParagraphs\n",
" \n",
" #these counters are used for keeping track of what paragraph an instance is found in\n",
" #this is essential for validating the results\n",
" paraCount = 0\n",
" hitCount = 0\n",
" paraHits = {}\n",
" \n",
" #iterate over paragraphs, iterate over characterDict, match name in para and add instance to paraHits\n",
" #this creates a temporary paragraph level dictionary, from which a list of all hits for the current paragraph is created\n",
" for para in textParagraphs:\n",
" for name, id in characterDict.items():\n",
" #if name in para:\n",
" #if (\" \" + name + \" \") in para:\n",
" if re.search('\\\\b'+name+'\\\\b', para) is not None or (name+\"s \") in para:\n",
" paraHits[hitCount] = [textCount, paraCount, name, id]\n",
" hitCount = hitCount + 1\n",
" paraCount = paraCount + 1\n",
"\n",
" #add paraHits into text level list called hitList\n",
" hitList = []\n",
"\n",
" for hitCount, instance in paraHits.items():\n",
" hitList.append(instance)\n",
" \n",
" #add hitList to hitDict indexed by number as string\n",
" #index must be a string if you want to iterate over this dictionary, otherwise you receive the error\n",
" #\"cannot iterate over integer\"\n",
" hitDict[str(hitDictCount)] = hitList\n",
" \n",
" #increment counters\n",
" textCount = textCount + 1\n",
" hitDictCount = hitDictCount + 1"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now check that this hit dictionary is populated correctly. The keys are simply numbers corresponding to the texts in the txtDir. This is the first value in the lists you see below. The next value is the paragraph number, the one after the character name, and the last that characters unique identifier."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"hitDict['0'][:20] #first twenty for legibility, change value or remove brackets to view more"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 18,
"text": [
"[[0, 6, 'kathy h', '5'],\n",
" [0, 6, 'kathy', '5'],\n",
" [0, 6, 'narrator', '5'],\n",
" [0, 8, 'kathy h', '5'],\n",
" [0, 8, 'kathy', '5'],\n",
" [0, 8, 'narrator', '5'],\n",
" [0, 10, 'tommy', '8'],\n",
" [0, 10, 'ruth', '13'],\n",
" [0, 10, 'narrator', '5'],\n",
" [0, 12, 'narrator', '5'],\n",
" [0, 14, 'ruth', '13'],\n",
" [0, 14, 'narrator', '5'],\n",
" [0, 16, 'narrator', '5'],\n",
" [0, 18, 'tommy', '8'],\n",
" [0, 18, 'ruth', '13'],\n",
" [0, 18, 'narrator', '5'],\n",
" [0, 24, 'narrator', '5'],\n",
" [0, 26, 'narrator', '5'],\n",
" [0, 28, 'ruth', '13'],\n",
" [0, 28, 'narrator', '5']]"
]
}
],
"prompt_number": 18
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Create interaction dictionary, character id by paragraph by text"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now that we have a dictionary of all the \"hits\", or occurrences of a character name, for all of the paragraphs in all of the texts we need to combine those hits into paragraph entries in order to map specific interactions, as we have defined them as co-occurrence in a paragraph. This is done by creating a dictionary, checking if the paragraph exists as a key, and if it doesn't, creating it and assigning to it a list containing the id of the character in the hit we are looking at, and if it does exist, appending that list and adding the current character. A second if statement is used to check if an id has already been found in a paragraph in order to avoid passing duplicates into the id list for the paragraphs."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"interactionDict = {}\n",
"\n",
"for key in hitDict:\n",
" paraHitDict = {}\n",
" for text, para, name, id in hitDict[key]:\n",
" #check if paragraph exists as ket in paraHitDict\n",
" if para in paraHitDict:\n",
" #check if id already exists in the id list, if so pass, if not append\n",
" if id in paraHitDict[para]:\n",
" pass\n",
" else:\n",
" paraHitDict[para].append(id)\n",
" else:\n",
" #if para does not exists as a key, as it and assign the id as a list\n",
" paraHitDict[para] = [id]\n",
" interactionDict[key] = paraHitDict"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 19
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And to test the results:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print(interactionDict['0'])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{6: ['5'], 8: ['5'], 10: ['8', '13', '5'], 12: ['5'], 14: ['13', '5'], 16: ['5'], 18: ['8', '13', '5'], 24: ['5'], 26: ['5'], 28: ['13', '5'], 30: ['24'], 32: ['5'], 34: ['13'], 36: ['8', '13', '5'], 38: ['8', '13', '5'], 40: ['8', '5'], 42: ['8', '1', '13', '5'], 44: ['8'], 46: ['5'], 48: ['8'], 50: ['8', '1', '13', '5'], 54: ['8'], 56: ['8'], 58: ['8', '1', '5'], 60: ['13'], 62: ['8', '14'], 64: ['8', '13', '5'], 66: ['8', '13', '5'], 68: ['8', '5'], 70: ['5'], 72: ['8', '5'], 74: ['8', '5'], 76: ['5'], 78: ['5'], 82: ['5'], 84: ['13', '5'], 95: ['8', '5'], 97: ['5'], 99: ['8', '5'], 101: ['5'], 103: ['5'], 105: ['8', '5'], 115: ['5'], 117: ['8', '5'], 119: ['5'], 121: ['8', '5'], 123: ['8', '4', '2', '5'], 125: ['8', '13', '5'], 127: ['5'], 129: ['5'], 131: ['8', '5'], 133: ['13', '5'], 137: ['5'], 141: ['19', '15'], 143: ['19', '13'], 145: ['13', '5'], 147: ['17', '13', '5'], 149: ['13', '5'], 151: ['17'], 153: ['8', '13', '5'], 155: ['8', '12', '5'], 157: ['12', '5'], 159: ['8', '3', '9', '12'], 161: ['8'], 163: ['8'], 165: ['11'], 167: ['8', '5'], 169: ['8', '5'], 171: ['8', '10', '23', '11', '5'], 173: ['8', '5'], 175: ['5'], 177: ['5'], 179: ['8', '5'], 181: ['8'], 183: ['5'], 187: ['8'], 189: ['8'], 191: ['8'], 193: ['5'], 197: ['5', '7'], 205: ['8', '5'], 207: ['8'], 209: ['8', '5'], 211: ['8', '5'], 213: ['5'], 215: ['8'], 217: ['5'], 219: ['7', '5']}\n"
]
}
],
"prompt_number": 21
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Create edges dictionary"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Great! We have exactly what we want, a dictionary object containing the paragraph numbers with a list of the id numbers for the characters that are found within that paragraph. This is great, but it's not quite in the form of interactions yet. Interactions occur between two characters, so let's pretend we have a paragraph with three characters, 1, 2, 3 and 4. That means in that paragraph the possible interactions to be mapped are:\n",
"\n",
"* 1-2\n",
"* 1-3\n",
"* 1-4\n",
"* 2-3\n",
"* 2-4\n",
"* 3-4"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following script, again taken from [Stefan Sinclair's notebook](http://nbviewer.ipython.org/gist/sgsinclair/bf112f84f130c8bac96c), on networks in Holmes will iterate through the occurrence lists above and count the number of times each character occurs with another in a paragraph [8]. This count is very important, as it determines the weight of our edges in our network map. The more times a character interacts with another particular character, the stronger their relationship is, and the thicker the edges of the network graph will be."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from collections import defaultdict\n",
"\n",
"textEdgesDict = {}\n",
"\n",
"for key in interactionDict:\n",
" edgesDictionary = defaultdict(int)\n",
" for para, people in interactionDict[key].items():\n",
" for personA in people:\n",
" for personB in people:\n",
" if personA < personB:\n",
" edgesDictionary[personA + \" -- \" + personB] += 1\n",
" textEdgesDict[key] = edgesDictionary"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 22
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And test!"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"textEdgesDict['0']"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 23,
"text": [
"defaultdict(<class 'int'>, {'1 -- 5': 3, '13 -- 17': 1, '5 -- 8': 31, '10 -- 23': 1, '1 -- 13': 2, '2 -- 5': 1, '13 -- 5': 17, '2 -- 4': 1, '11 -- 8': 1, '13 -- 8': 10, '2 -- 8': 1, '17 -- 5': 1, '23 -- 5': 1, '12 -- 8': 2, '3 -- 8': 1, '12 -- 9': 1, '10 -- 8': 1, '4 -- 5': 1, '5 -- 7': 2, '10 -- 5': 1, '13 -- 19': 1, '11 -- 23': 1, '12 -- 5': 2, '12 -- 3': 1, '8 -- 9': 1, '14 -- 8': 1, '3 -- 9': 1, '1 -- 8': 3, '11 -- 5': 1, '4 -- 8': 1, '23 -- 8': 1, '10 -- 11': 1, '15 -- 19': 1})"
]
}
],
"prompt_number": 23
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, in order to plot this, we need to turn it into a frequency distribution."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"edgesFreqsDict = {}\n",
"\n",
"for key in textEdgesDict:\n",
" edgesFreqs = nltk.FreqDist(textEdgesDict[key])\n",
" edgesFreqsDict[key] = edgesFreqs"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 29
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Select text to plot"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"edgesFreqs = edgesFreqsDict['0']"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 30
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Plot by character id"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"G = nx.Graph()\n",
"plt.figure(figsize=(10,10))\n",
"\n",
"# create graph edges (node pairs) and keep track of edges for each count \n",
"edges = defaultdict(list)\n",
"for names, count in edgesFreqs.most_common():\n",
" if count > 0:\n",
" parts = names.split(\" -- \")\n",
" G.add_edge(parts[0], parts[1], width=count)\n",
" edges[count].append((parts[0], parts[1]))\n",
" else:\n",
" break\n",
"\n",
"# draw labels (nx.draw(G) doesn't really work)\n",
"pos = nx.spring_layout(G)\n",
"nx.draw_networkx_labels(G, pos)\n",
"\n",
"# draw edges with different widths\n",
"for count, edgelist in edges.items():\n",
" g = G.subgraph(pos)\n",
" nx.draw_networkx_edges(g, pos, edgelist=edgelist, width=count, alpha=0.1)\n",
"\n",
"plt.axis('off')\n",
"plt.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAl0AAAJPCAYAAABGnGG7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XmMbXt2H/TvqjpVp+rWfKf3GrXTaVndwYlFO3IrQSaJ\nEUbYAskojE5ieUDC/JFHRCADwW6n7Q6QxAkJJhYiUruNrcbGQ1oQlEgxAWJhKUPHA7LBUzy03e73\n7r01z+Pij7V+dX61a59z9t5nz+f7ka7eu7emXXVO1f7W+q3f+omqgoiIiIiqtdD0BRARERHNA4Yu\nIiIiohowdBERERHVgKGLiIiIqAYMXUREREQ1YOgiIiIiqgFDFxEREVENGLqIiIiIasDQRURERFQD\nhi4iIiKiGjB0EREREdWAoYuIiIioBgxdRERERDVg6CIiIiKqAUMXERERUQ0YuoiIiIhqwNBFRERE\nVAOGLiIiIqIaMHQRERER1YChi4iIiKgGDF1ERERENWDoIiIiIqoBQxcRERFRDRi6iIiIiGrA0EVE\nRERUA4YuIiIiohowdBERERHVgKGLiIiIqAYMXUREREQ1YOgiIiIiqgFDFxEREVENGLqIiIiIasDQ\nRURERFQDhi4iIiKiGjB0EREREdWAoYuIiIioBgxdRERERDVg6CIiIiKqAUMXERERUQ0YuoiIiIhq\nwNBFREREVAOGLiIiIqIaMHQRERER1YChi4iIiKgGDF1ERERENWDoIiIiIqoBQxcRERFRDRi6iIiI\niGrA0EVERERUA4YuIiIiohowdBERERHVgKGLiIiIqAYMXUREREQ1YOgiIiIiqgFDFxEREVENGLqI\niIiIasDQRURERFQDhi4iIiKiGjB0EREREdWAoYuIiIioBgxdRERERDVg6CIiIiKqAUMXERERUQ0Y\nuoiIiIhqwNBFREREVAOGLiIiIqIaMHQRERER1YChi4iIiKgGDF1ERERENWDoIiIiIqoBQxcRERFR\nDRi6iIiIiGrA0EVERERUA4YuIiIiohowdBERERHVgKGLiIiIqAYMXUREREQ1YOgiIiIiqgFDFxER\nEVENGLqIiIiIasDQRURERFQDhi4iIiKiGjB0EREREdWAoYuIiIioBgxdRERERDVg6CIiIiKqAUMX\nERERUQ0YuoiIiIhqwNBFREREVAOGLiIiIqIaMHQRERER1YChi4h6S0TeEZHPisiFiHwq+vc/JiLH\n0Z9TEbkTkd/b5PUSUb+JqjZ9DURElRCRPwzgDsBXA1hV1W8e83rfCODbVPVDdV4fEc2XQdMXQERU\nFVX9DACIyEcBvH/Cq34TgO+v45qIaH5xeZGI5oGMfYHIBwD8QTB0EVHFGLqIaB5M6qP4BgA/oaq/\nUdfFENF8YugionlwX+kSkRUR+aCIhJ9/3wDgf2zmsohonrCni4jmQVzp2gBwCuCJiHwEwPsA/Ggj\nV0VEc4WVLiLqLRFZFJEV2C+YiyKyCat67QFYA/CNAH5UVU8bvEwimhMMXUTUZx8DcAbgzwL4egAH\nAP64qt7Agti/Cy4tElFNOKeLiOaCiKwCeKKqu2l/JyKqGitdRD0hIieJKes3IvLdTV9Xi2wAOA5/\nUdVzAAMRYW8rEdWCP2yIekJV18P/i8gagHcB/HBzV9QeIvIEwK2qXiVedAbgCYCj+q+KiOYNK11E\n/fTvAHhPVf/vpi+kJTaQHqzOYLsYxw5PJSIqC0MXUT99IzhhHcB91e9aVa+TL1PVWwBXAFZrvzAi\nmjtspCfqGT/W5p8B+OJ5n7LuFayXAPbSQpe/zhDApqq+rvXiiGjusNJF1D//IYB/BOC9pi+kBZ4A\nuBoXuABAVS9h+WypvssionnE0EXUP18H4EcA7Phg0LnkVa51RDsWJziFDUslIqoMQxdRj4jIVwB4\nG8APwSavz3PwWgNw6YNQpzkHsBKdx0hEVDr+gCHql28A8GOq+i6swjOXwStnlQuqegfgAmyoJ6IK\nsZGeqMdEZAM2LkEB7KvqRcOXVAv/vBdV9SDH2ywB2FHVV9VdGRHNM1a6iHpMVY8xZxUvXyJcQ8Yq\nV+DN9ne+m5GIqHQMXUQ9N4fBax3Auc/gyusMbKgnooowdBHNgXkJXl7leoKcVa7IOYBlEVks76qI\niAxDF9GcmJPgtQHgzBvjc1Nrcg3nMRIRlYqhi2iO9Dl4eXVqFcDJjO+KoYuIKsHQRTRnehy81gGc\nFq1yBT7X60ZEOD6CiErF0EU0h/oWvEqscgWcUE9EpWPoIppTPQteGwBOtKTBgz7PbFFEBmW8PyIi\ngKGLaK71IXh5MBrCqlNlYrWLiErF0EU053oQvDZgvVxlH69xBmDVjxQiIpoZQxcRdTZ4eZVrGeVX\nucJ5jJfgTkYiKglDFxEBSA1eXdi9t4kSe7lSnIKhi4hKwtBFRPcSwWu7zcHLD6heUtXSq1yBql75\nx1qu6mMQ0fxg6CKiBzoUvDZQ/LifPNhQT0SlYOgiokfaHry88jRQ1bMaPtw5gKGf60hEVBh/iBBR\nqpYHr7qqXOE8xnOw2kVEM2LoIqKx2hi8RGQIYFFVz2v8sGyoJ6KZMXQR0UQtDF61VbmC6DzGTozS\nIKJ2YugioqnaEry8yiU1V7mCM3CJkYhmwNBFRJm0JHhtouYqV+BBb8DzGImoKIYuIsrMg9cRGghe\nvrSnfhh1U87A3i4iKoihi4hyUdUTNBO8au/lSnEG4AnPYySiIhi6iCi3uoOXv39V1csqP840qnoL\n4ApA05sJiKiDGLqIqJCag9eGf6w24IR6IiqEoYuICqsjeInIEwC34RzEpnm1TfzsRyKizBi6iGgm\nNQSvdbSnyhWw2kVEuTF0EdHMqgpeXuW6UdXrMt5fic4BrPA8RiLKgz8wiKgUZQcv3yHYhh2Lj6jq\nHYALcHwEEeXA0EVEpSk5eD0BcNXCKlfA8xiJKBeGLiIqVRnBy6tc62hhlSvwMHjnRxMREU3F0EVE\npSsheK3Bqlw3pV9cudhQT0SZMXQRUSWKBi+vcq2hxVWuyAWAZRFZbPpCiKj9GLqIqDIFg9c6gMsO\nVLmgqgo7GojVLiKaiqGLiCqVJ3j5CIauVLmCU/BYICLKgKGLiCqXErzG7fpbA3DuZxx2gl/rdY0H\nfxNRRzF0EVEtEsFrKxm8OlrlCrjE2AAR+ZCIXIjIDzR9LURZMHQRUW2mBK91AGc+eLRTVPUCwCLP\nY6zd9wD4xwC06QshyoKhi4hqlRa8fPffEwAnjV7cbDgstUYi8nUA9gH8fdhziaj1GLqIqHbJHi8A\nLwCcdrHKFTkDsOojL6hCIrIJ4DsA/EkwcFGHMHQRUSM8eB3Cfg69BaDLgSucx3gJVrvq8AkAnwTw\nHri0SB3C0EVEjVHVU1jYOkNKc30HcUJ9xUTkywB8FYD/C1YhHTR6QUQ58MlKRI0RkQGAWwC/DWAL\nNk4CqnrW7JUVo6pXIqIisqyqV01fT099JYAPAvjbsMC+AWBBRL5EVT/a6JURTSE2UJmIqH4isgPg\nWlVPRGQNFrwA4KCrwcurdUNV3W/6WvpIRJ4DeD+sJ/AUwJ8C8CEAfxrAr3ZpxhvNHy4vElEjvMq1\nDLtxhqXGQ3/xpAGqbXcOYOhzx6hE/pwZAPg8gN9W1fdgO16PAHwBwHMRGTZ4iUQTsdJFRI3wKteV\nh6343ztf8RKRLQB3qtrFQa+tJSLPYIeMbwB4TxM3MBFZBrADm/fGrz21Dn8TI6La+RDRZVgD/QM9\nqXhxZlfJ/HkgAK4B3CQDF2A9dQBeA1gSkWesNlLb8AlJRE3YAHCcduMEuh+8VPUGwI2IrDR9LX3g\n4WkDwAGAIWw0RypVvVPVPX+dF1xupDZh6CKiWvkS0GDasmHXgxc4PqJMW7AlwxtMCV2Bz4Hbhz13\nNiq+PqJMGLqIqG4byHjcT5eDl5/HOPDmbyrIq4VLqnrs0/4HWcdxRMuNy1xupDbgE5CIauNVrsU8\nzfFdDl6wnjVWuwrykLUFW1YErMqVa/6ZLzfu+tu98OcgUSMYuoioTpsAcu8q63Dw4nmMs9kEcBFV\ntjItLabx3YwHAHZEZL2k6yPKhaGLiGrhDc2iqudF3r6LwcsHdV4CWG36WrrGK1IrsBlcQeHQBQCq\neglbbhyKyFMuN1Ld+IQjorpsoECVK9bF4AUuMRa1BeAw7HAVkUVYaL+Z5Z1Gy43X4HIj1Yyhi4gq\n583Q4s3lM+la8PLqivDmnp3vNrxNPF9y93NNwuVGagJDFxHVYQMPl4lm0rXgBQ5Lzcx3e65h1Dwf\nLGOGpcU0HojfAFjhciPVgU8wIqqUiKwCUL/BlaZjwesMdmPnz9zptgEcqepd4t9n6ucaR1VvVfUN\ngBvY2Y1LZX8MooA/AIioajP3co3TleDlfUkXYLVrovD4JUeKePVLfWNCJVT1CPZceurnfxKVjqGL\niCrjVa7bsqtcsa4EL3CJcaLEUT9JlVS5kqLlxlVfbuSoDyoVQxcRVamyKlesC8FLVa8B3PEswLG2\nMTrqJ6mW0AU8Wm58weVGKhNDFxFVwoPPTdYjW2aVErzauETE8xhT+O7WRd9RmGYZJe5czMKXG4/A\n5UYqEUMXEVWllipXLBG8tlp4s7wAsOQzpwgPjvo5HPPyZVh4TzbWV85HVoTlxh0uN9KsGLqIqHQe\ndq58Sa1WHrxCX1Crgpc31J+D1a5Y8qifpNqWFtNEy4134HIjzYihi4hK5dWAddRc5Yr57rdWBi/Y\nEiPPY8TYo36SSh2KWpSqHmK03Ni6nkHqBoYuIipbqHLNdFzLrNoavHzswTUsbMy7bURH/SR5MB2g\nBaELeLDcuMblRiqCoYuISuM3oTU0WOWKtTV4gQ314aif6ylHQy3766SGsib4cuNrjJYbB01fE3UH\nQxcRlWkNwGXTVa5YG4OXz4NamNf+IA8qTzCmeT7SaD/XJL7ceAzgGZcbKSuGLiIqRRt6ucZpY/CC\nHQ00rzfrbQDHGXYktjZ0AYCqngPYhS03bnO5kaZh6CKisqwDOK/yqJZZtDB4nWEOG+r9667Jo35S\nXm8BNrur9h2weXhV9w0ABZcbaQqGLiKamd8g1wCcNH0tk7QpeHmVZ67OY/T5ZBuYvqwItLzKFVMT\nLzeuNn1N1E4MXURUhnXYES6trHLF2hS8YNWupituddoCcJKx568zoSuIlhvXudxIaRi6iGgmXuV6\ngpZXuWJtCV4+EFTn4TxGr/4sqmrW50nnQhfwYLkRAJ5zuZFiDF1ENKsNWJWr9mNaZtGW4AUbH9Hr\nJUYP5psYfb2nvf4AtmrX+sppGl9uPIA9tlxupHsMXURUmPforKJDVa5YS4LXOYChB5O+2oRtssja\nFN+KKfSz8ufXLoANEdniciP1+ZuciKq3AeC0a1WuWNPBq+/nMfrS6TLyjRJZRgeXFtP4cuNrAILE\ncqOILIvIJ0Xk10XkSER+WkS+prGLpcoxdBFRIV7lGqKjVa5Y08ELPV1i9MrOFiYc9TNGJ/u5xpmw\n3DgA8DkAf0hVNwF8G4AfFpEPNHSpVDFp0ekKRNQhIrIN4CZHY3Tr+WTxbf/roaqe1vixn8GqhpOO\nxekUEdmENc/v53ibJQDbftRO7/jntwM7ueHR6AwR+VkAH1fVz9R+cVQ5VrqIKDdfIhnCfnPvjYYr\nXr06j9HDxSqyzeSK9arKleR9ba9hx0C98IoxAEBE3gLwYQA/39T1UbUYuoioiA3YvKXelcqbCl5e\n4Rr0aMTAFoCjAv1+vQ5dwP1y4z4saD8XkaGH1E8D+D5V/aVmr5CqwtBFRLn4zWEZNtizlxqsePVi\nWGp01M95zrcTAEvowc7FafxzXYD9AvMMwA/ATih4p8nromoxdBFRXr2tcsUaCl6n6Ph5jNFRP5lm\nciUsA7ju83NLRBa91+0tWFXvHMB/BeAFgH+7q7PJKBuGLiLKzKtcgzobzJtUd/DypbhLWC9UV4Wj\nfoqEh94uLYrIkojswMKVAngFuwd/B4DfBeBrVbWXnzuNMHQRUR6b6MGIiDyi4KWw4LVe8YfsbEN9\ngaN+knoXukRkxXem7sCWTd9T1WPYY/w+AP8BgI8AeFdEjv3PH2nuiqlKfWnYJKKKicgy7Iba216u\ncVT1zFf8tgBsigiqGpWhqldilv1sxk6IjvrZm+HtF3NMrW8tXx5ehR0Efwer/F1EL1+GzWX7OVVl\n8WOOMHQRUVYbyDdVvFfqDF4YDUvtTOhC/qN+kpbRrc/3kejw9zUA1wAOksHZA9k2bA5cZ09yoGIY\nuohoKj/KZSHvbrS+qTF4nQF4S0QWunBjjo76mWWgaWeXFn3zwDqsunUOYNeP/0mzBRuM2pshuJQd\nQxcRZTHXVa6YBy+FVSsqCV6qqiJyDquatLqHboajfpI6N2zXN5asYzRC5dWkkCwiK5g9nFKHMXQR\n0UR+oxD+Zj6iqude8aoseMFu4k/R8tAFC+RXs+y880qRTKgOtYp/T6zDNqOdwpYRJwZOX3rcArDX\n55EYNBlDFxFNswHgqOmLaJuqg5eqXovIrYistDXwRkf9zFq5af3S4rTm+Ay2AZz1YaMAFcfQRURj\n+W/0yvlB6WqoeIWG+laGLtjnXeSon6QhWvo5eoVqDfY4pDbHZ3gfT2A9kVyin3PcqkpEk7CXawrf\nXBDmeG2WOcfL3/dSfChyW/jneVvS5orWVbp8cvwWgJewe+Wuqu4VCFwD2M7OIhP6qWdY6SKiVD7o\n8o5VrukqrnidwyotrVnijXbrzdwQ7kuUd23ZpekztNaQsTk+g1AN7ES/GlWLoYuIxil6ft5cqjB4\nnQJ4LiLHLWrA3gZwXNI5ga2ociWa40+QoTk+w/vcgAXKuRsoTOkYuojoEe9BuenSRPQ2qCJ4qeqt\niFwDWIFVvRrlzw0p8fzNUFGqXQnN8ZPe9xKsD4zjIegeQxcRpdlAweNc5l1FFa9T2GPSaOjypvIN\nALslvttlAPslvr+pEs3xVyjQHD/l/QvsrEVOnacHGLqI6AERWQNwza3txZUdvFT1UkS2RGSp4cdl\nCzb2oJT+JO+fuqlr2dSb2tcwmhz/pqQl0qRN2OyyVu7IpOZw9yIR3fPf0NfBHYszq2BX4xksMDTC\nj/pZQrnDWmvp5xKRZRF5CuAZbBnxlaoeVhG4vDdsCOCw7PdN3cdKFxHFnsB+Q2eVqwQlV7zOALwU\nEam7oT46pHm/5I89RIW7MlOa48u+/uTHC1PnK/041F0MXUQE4EGVq8x+nblXVvBS1TsRuYAF47rP\nKNyAHdJcdt/ToOzNGv5+n8CqgqU2x2cQps5zAwqlYugiomANdmPlPKGSlVjxOoU1aNcWuqKjfl6V\n/K6HsCb2UqQ0x+/XWbHl1HnKgqGLiOIqF7e3V6SM4OXnMaqIDGscWhuGe5a9XFZKP5c3x69jNFKj\nqub4SdewCGuef1Pnx6XuYegiIsBuWud136zmTUrwkgKVkXAeYx0N6GUe9ZM0xAzzuXzn4zqsuf8U\ns0+On8UObFgsq8Q0EUMX0ZyLlmVY5apBInhteMUrT/A6hwW2xSpDclRBKv154ZWhhSLLf3481Rq8\nOV5VG50nF02dr7vPjjqIoYtoDkVn593CqibXsNEGVINZgpeqqoicwR63KvuHtlDeUT9Jy8hRqUs0\nx9/6dbXh6CBOnadcGLqI5tMS7AYmAJ7DelHeFhGF3dRu/L+38d85Xbs8M1a8zmAzpyoJXRUc9ZOU\nqZ8rqsKu+evX2hw/CafOUxEMXUTzadH/uw5brgpVLoH9XEj92cBQVq6iwUtVb0TkRkRWy+63quio\nn6QhJgTGRHP8GYDXLew35NR5yo2hi2g+DWA9MSvIt+OKoaxkM1S8TmEVoLKb3Es96ifJA5WmhaiU\n5vj32jhk1KfzD8FlRcqJoYuop0TkHQDfBOBLAfygqn6z//vvBvBpAB+EBa9fAPBfAvgnZXxYMJTl\nViR4qeqFn8c4KPEsxBUAS6pa5QHUj5YWvTk+HJN02nRz/CReCaxiOj/NAeFzhqifROQPwyZyfzWA\n1Sh0bQH4MGyA5DmAbwDwLQC+rKFLjc11KPPwsQ0Lr8fTgpfvnFtQ1ZnP+fMepZewMFHZRHU/A/EM\nFryewMLWDWwnYuPN8dOIyA7suVjZ8UXUX6x0EfWUqn4GAETkowDeH/37oYgcwpZwNmH9XbuwG33T\nv4XNdaWsQMXrFHYeYxnDSzcBXNRwhM0Q9phtw4LXXlua46fxDQaDiiuB1GMMXUT9Jw/+Ytvc1wH8\nA1hP12sA/xFsN9wBLMC0Ve9DmQcvhe2Mmxi8/DzGS9gxPbMOGl1B+Uf9xB9jAPucnsLCYhub48fy\nMStVbzCgnmPoIuq/+wqI3/jeB1vW+UOwG+23APjLAP4o7IZ4BKCrO7J6Ecq8X2sfGYIXLMBsYYbQ\n5W9/WEWPkjedr8EqqwLgNzu6NLcDWwJt8y8l1HILTV8AlU9E3hGRz4rIhYh8Kvr33ykidyJyHP35\n1iavlWohsJadHdhMri+ChS3AwtV3A/gAgA/5627BbpJ9FELZCuxz3ITdTF/A5pS9T0ReishTb1Jf\nF5FVEVnyBura+CiCfVho3vD+rbTXu4I9vstFPo6/35uyRx/41+0F7Gt8rqrvwYbwtr5vK8mPQ1JO\nnadZsdLVT58H8Al4A3XKyze562Y+eGUrbG8PvTo3sF+4FmCN9ouwMBLfdMO2/YPaLrYdWlUpy1Hx\nCuMjcvVj+fOjtInq0eT40Bx/FJrj/WVLea+xab4cz2OyqBQMXT00roE6sgC7UVBP+c00VKwEVmFY\ngd0QvxwWtk5gz4U/DuA3APxm4t0MYcuNB/761EAoyxi8zvxlCzk/xjZsl+RMj6/3O63Bnl8XSG+O\nXwZw3aVf+KKp80dtWXqmbmPo6jcZ8++/4TeHHwfwp1WVjaE94WFrA3aD+xMA/lz04q8H8Fdhv7G/\nA1tqPAXwTwH8J2Pe5RJGDfad2GHWsEpC2bTg5ecxnsNCz0mmC7WdeFDVWRrwQxUoy+T4TEf/tEyY\nOl/2AFqaU5zT1WMi8gkA71fVb/ab8RqALwbwM7Ab7vcA2FDVr2nwMqkEibB1ApsoronXCTOg3gd7\n/K8AZJ3vpOh2g31XTAxlsMd3BylzvPw58Mx7pybyytQLAG+KNIZ7c/w6LFymPt9S3uYFgIMOjYcY\nwr5fXnWpOkftxkpXv8WVrhUAd6r6U/73Vz6x/AsissYG0W5KCVsH424QPorgBha4gHzf/6HBfgkV\nHbJMAKZUymChLJxLuOHz1g4RhTQRWcnQFL8Fm/yeK3AlJsefZK0A+SaExQ4FLk6dp0owdPVb/MNi\ngPGlfe5i7Zg8YSvhFsAe7IayCmuiz9Pf9wT2XDpA84NU55HAHq8LWHB6AnsehF+ahgB2RGQXoyrZ\ndTzp3Y/6Wcx61I73Na35n2tEzfE5dG1pcQu247JTTf/UfgxdPeRLB0uwx3cxOpz1S0RkD8Avw5Yo\nvhvA/5nxcF1qgRnCVrAIC0tvYMtLA+TfVLGMUYM9N2Q04xJW4dpCdGah//sGLIyF/rAL//cQoLZg\noygmSmmO351hRlVnQpdX8zh1nirB0NVPHwPw7dHfvx7AXwHw07CDjl/C+nP+HoA/UvvVUW4lhK3g\nBjZR+xoWmBZhlc5F/5PVABa8DtGxEQA9Mi54JRvq42A89aif6MSCIaw5/lUJO/eGyNjg3yQPmpvg\n1HmqCBvp54D3J7xU1XebvhbKJ0uDfMH3u4xRM/0JbLkxDl8L8EopJocyDdc16zVRYUNY8BLYY3EO\n23Ea5kodqeqJP+Y7GNMYXqQ5PgsPMs+zNPg3TUSewUIpe1ypEqx0zYcB2n2eHiUkwtYpile2xgkN\nzUs+juANrHIFTF4yTAtlQ9gNnzeqZqRVvK4B/C0AHwFw44dofwHAv5Cyq/UJRicQZG6Oz6ETS4s+\ndR4MXFQlhq75wNDVETWELQD3c51uAAxEZElVrz147cBukuOE5uw0YQRFqIyFUBb/oWokg9clLAh/\nK4D/DrZ7eRB2NaY0xx9W2DQ+RMtHjUTzxt40fS3Ubwxd84Ghq+XqClsJV7DnxhJsh9sdgF0RKXr2\nYmiw30vb3eY3+jiAMZSVKw5eQ4y+voAf9VNyc3xWQ2SfB1c7f15uw5ZhuTGEKsWerjkgIk9h/Rmt\n/m1zHqWErdO65gKJyBpG85oOU162ifGnGkyisPlGuZ5vDGWlCT1enwTwQdguxl8G8Bdgpw+E59nE\n5vgCRwqlvY8lANuq2tpzC0VkEzZCg7sVqXKsdM0HVrpapqHKVlLo61pOvkBVT335cQf557gJgKci\n8mBi+jT++d9gzHOVoSyzS1gz/Sdhu/B+EcC/BOAHYedu7gEY+gabtD/hAHQRkTczLju2up/LNw+s\nAnjV9LXQfGDomg+LNSwhUAYetsJ2/KbCVnCN0YTzR1T1UkRew3bCFflZseGfbymfI0PZI4JRSFrw\nvw9hYX4I4Ldgy72/B1bh+lnY+Jjvgy0tZ3lMZv2atXZURLSs2OT3IM0Zhq6e85se+xQalhK2Dpv+\nQR810y+FZvqU17n14LUDa8bOaxXWrL9Xdb9Mj0PZiv8JISv8iS1gdPB0sAwbgvp5PKxircKCGWDB\n+8r/m/Z1K3xahX+9l9DeOW7bsKnzra3EUf8wdPUflxYb1MawlXANuzEuYbTc+IBf7573vqynvc4U\nSwCei8h+k8eqdDiULWH8jtKwCzGEsmAdwJcC+PsA3oMNQf69sL4ugZ0mcAcLZksYHQl1A3sehD+z\nHBG2DOCmZc93AKOp87CvA1FtGLr6j6GrAR0IW8EVbCfbMqYMOFXVI6+MhUGceSwCeCYih6raykGq\nLQ5l45rZV2GPXTIYncOed18H4E/BPp9fBvAfA/gl2LLiNkaDceMNDyGAr8CqYSv+XL6C7XDNE5pb\n2c8VTZ3fa+n3JPUYdy/2nIhsA7hq642ub1LCVm27EYvw3WUvYDfUTDvMosnmRUPGiaoeFXzb1qow\nlK3CQkIwhFW3ku8vhKhbWB/eAixsheCzAOvxCkErjI44w/jBtpf+8lARC7/EhSXJq3HLxiLyHDaG\noVXLiz7TDj4vAAAgAElEQVR1/lJVW9lrRv3GSlf/DcAjWirXocrWAz4UVWF9V5LlmlX1Kppgv1Tg\nw67712u/C1+jrCqslIWvUXiOJb/m17DnXFgeHsIC1hUe9lPdwXq8dmDBLJzTuA47EipZ9Qqf17m/\nXtyntQyrhm36tPvwscKypMCGsbYtcK0BAAMXNYWhq/+4vFihroathBuMlpUy3SS9wf4NbJlqtcDH\nXAHwwhvs5+L5OWMoW8fjr3MITsklvND/dYHHOxRvMRqguu9/P/KPtYHRQdnhefBg6dI/hwdhzpfr\n4t6wcN0D750aWw2rU/S9yqnz1BiGrh7zOTyYdcAhPdaTsBVcIWfoAu5vwPve57Ux7fVTDDBqsG9d\n70/dkqHMv383MDpU/ASjGVoXsLCVPJB8ARaAwtukuQZwDKt47cEqYDewEBZGTtz660z92eGBKlkN\newZ7LiWrYfe7JRv4ftkBp85Twxi6+o1VrpL1LGwF94dfF3ljVT0WkWvYTS1vg/0CbJDqEQ8aNh5a\n1mE9VwsYVatCkDrG+BlbG7DwdY3JbQWX/r5D8NLo3y9hFasdABci8irPL24+imQB1qgeAmRcDduE\nVcHCTskrVFwN8523NxUc5k2UC0NXvzF0lcRvGmHoZF/CVjB2Mn1WqnoR9XnlbRgXAFs+K2yut/CL\nyBOMglOgsCB0jOkz95Zhj+c+plctz/3jbPvrJ192AQt/b+UJxf69IvGycbIa5q+X1ht2H8JQUjXM\nN36sAmjtUUQ0Pxi6+o2ha0Y9D1sAijXTT3g/r2HBq0iAe+KVxL15WxL342g2kd4kfwRb5ps2Myvs\nLrxF9mXiE/+423g8s0phQW8PwJo3oR9lOFMz06gIH8YbNgGE77UQxEI1LHwuhaphXjXcgU2dn6vn\nFLUTQ1e/LaK906BbbR7CVsI1Rss/hZ8zfmN746NKnhR4F8sYNdinDmvtE6/2bOLx8NNbWMAJfVJZ\nQldotM+7hHYEC10bsJCVpKq6F4JhFL7GPT5DpOyCnMYD1W38tiVUw7YAXLBnkNqCoavfWOnKaQ7D\nVhBC1zJKCOqqeuB9XpsoPkj1IENVpZOi51kymN7Bqk/J+W5ZqjTxrsW8DmAVyjC3KxY25FwCeO1L\noE9F5BLAcUr1aRkW5GaWUg0LGwWmVsN85+QSuFuRWoShq9947mJGcxy2gitY43ahZvo0qnrqzdI7\nyH+cTGiwP1bVtOpLJ0VN8ut4GEYVFnaOxyyDTQtdKxjN5ir6Pb8PC153eBjckmMjzkQkzPd6ISKn\nsIG36svDWlVTvH9tLjC5GiawXzY3YEcgEbUGQ1dPeYi4nbPgkBvD1r2ZdjCOo6qXUYN9kZ83G34j\nP+j64+LLcut4vNHgArZcN6kqPS3EFF1ajCkeBq9Q8Xy0McIfi2MROYN9/7wUkWNYkKx1KW9MNext\n2Nf1CSyIxdWw63mZDUftw9DVX1xanIBh6yFVvfG+oYGILJTZdOzvOzTYjzu4eZJVv669Ls5YEpEV\n+FJY4kVXyH5MzqTHI57NNety7B1sqTE01t9gQpXSH48DrzZtwaqa7854DbMKA1nvlxUT1bAND2bx\nFP2ref7+p/owdPUXQ1eKKGytwHpn5jpsJVzDQtESSq5W+Nd4V0S2YMuYeS3BBql2psE+CiLJnZw3\nsGXEPFWpSaErVLnK6n+7wai5fg8Zlob9MXnj1bxV/9ynVe9KN27q/JTesHUAS6yGUR0YuvprgNGS\n0dxLCVvvMWw9UlnoClT10Bvst1Cswf65N9i3dsilP9c28fjYnjtY2CoyBHZS6Frx/5b5NQmHZ+8g\nY5jzeVinqvpGRNZhj9UZrN+rrnENO0hv7n9gSm/YEKyGUUUYuvprgHJ/CHdSImydgmFrkpmHpGbh\njdg3sOXGvA32AmDHB6mWskOuLH6TDpPkk03yodm8aPgY93ZhNleY7l6mC9jj81xEdjN839zP51LV\nk6jf64WInFR94kA0dX7SJP6xompYeH+TqmEhhLEaRrkwdPXXXC8vMmwVEnqLSm2mT6OqV1GfV5GP\nt+5LSftteFx9WW0Dj0PkOco5729c6Cp7aTHpDNaM/hTA7pTXHSIaFeEB89B3N8bzvUq/1iqmzk+o\nhoWK2HpUDYuPM2r8+UjtxdDVQ75lWuZxAjPDVnGqeuvN9ItlN9NP+HhvYEtCK9NeP8UKRn1ejTTY\n+yyoDaQ3yR+W2H827rGoYmkx6RTAnYhsjzumyX/mDNI2BXg1KM9w1Vz8Y2+jhqnzUTXszD92qIYt\n4WE1LA5hc/vLLz3G0NVPczefi2GrNKGvaxnVVU/u+WO0JyIbsMcvryXY8tV+nVPHvbKyifQm+dKr\nOR5Qk/+8AlvGvEK24alFCYBD2Ny0zTHLukNMGao7ZrjqUQlBaQvAZRNT51kNo7zy9lNQN8zN0qKI\nLPqRMy9gQfM9VT3mD7XCaltijPkA1H1Y/1NeYZBqkV2RuYjIQESeAniOh4HrFlbZelXhFP1kOClj\nNldWC7DlxeGYr3Pmkwy85+oV7Gv2UkQ2JCVRZuHjOEqbgF8GVb1W1TNVPVDVV7DPNfSzhQPEX4jI\ntoiE80YzE5F3ROSzInIhIp+K/n1JRH5URH5NRO5E5CvL+6yoLKx09VPvQxcrW5WpZEhqFqp6HjXY\nPxrIOYUA2BKRgaoeln1tXq0Ix/Ykm+RP4BPZy/64CfH5i4uwsJGcHl+VBZ+3tgdb0r1NhMshHh+Y\nPVZiuOomLHzdnzWZhT8mW7AD0lv7ve/VsEtEO4I9aN036fvnEp8pOaka9nkAnwDw1Xi8Q/YnAPw1\nAD+CYr/AUMUYuvppgHp+ENeOYatyjYUuwKoEUYN9kV2Ua1GD/cxLbl6BCZPk45UBhVWYpo4nKFH8\n+YRerrq+z8P5i7cisgs7G/PON0QsAFgs0qPlX7v9MNMs6vfKUjXbho2o6NxoHO/zusHD3rD7JUlY\nb1g4FeBBb5iqfsbf5qMA3h+9z2sA3+0vm6v2ki5h6Oqn3lW6GLbq4TfVW1gz/WITDeqqeuc39i08\nPhA6iyFGDfaFvw+8SX4Tj6tuoRep7pt9HLqq3rWYdB84veK1DxvdsYsS5rpFw1VXAWz7LLexuz49\nnC2o6sksH7ctClbDCi3JUrMYuvqpN6HLw9Y67CbDsFWPa1jQWEJDGzL8MT7w5cYN5L/BDDAapJor\nmIRddnhc7QtBoPaGbRdC1zLs8aliNtc4yUOvr0TkEMAzv4ZSwp8vMV/AqosvfPnxQY+mh5ENlDge\noo0yVMOeAFjxntarovPJqF5spO8ZDyl3XQ8m3iC/BWuQvwMb5OvU6BJjzCsZeyi2Oy802K9neeWo\nSf4ZHn7ut7BxBK8bDFzhOoB6G+iDtEOvL2D9bG+jxBMM1JzAGtAF1u8VN+/voJzZZ52iqneqeuk/\nB3dhYewSVtn9Pf7cpZZjpat/Ol3lYmWrFWqZTJ+Vql76PK+nKPYza9OrI6nnbHoFIRzbE1fU7jCa\nJN+G5+Ad7PqGGPWU1WXcL+iXsCrXTsap9ZmNGa56B+CWVR0A9r0whH39P4+WfL/SZKx09U8nQxcr\nW63SyNiISXyp5Q2KV1SewJq/73/midkA8BYe7koMx/a8atlz8A4PZ3PVeV3j7hVD2CiJG1hje+lU\n9UZV92CVnZcAFvKOWegTEVkVkffDvvY3eDgjbOhjNAAb71Fk6DBVSNrz84TK4MHlRis+56wsKZWt\ntlQV5pqIvAVbUnqvbcs4/hwvOpPrFrZcuQTrC0oum13Alq5a94uL95p9CHbtB6joUPIxrlX1UQ+V\nL2mdqeqFiDyD/eypYmSHwH4hO4Q9ZhsYbWiYi5M3PGhuAvhzAP6zxIu/C8BfBvBTAL4IFsjF//tB\nVf1cjZdKEzB09Yz/4DtpuPdkqpSwdTovPzy7wG+mK7DRC607ON2nmm8hf4P9EFbVOsfD5u9r2PJj\npgGfTfCqxZfAKl51N5Hfqup7Kdf0NqwieOfB6DmA87J3FXqzuIZA5x8rzE07gf386OXNLJoRtwL7\n2X6aePkQ9kvIFWxHZ2sGxdJjc1ui7bFWLy+mhK1XDFutdAX7Ib+EenuHMlHVs2iQapY2ibDjLfS9\nhB2AR7BqSes+xxR1z+aKPfoa+2yt2/D9q6rqIyTC8NRSvqbR1Pn7oOkB6yj0e6HAcNUu8D62ddhj\n/nrMz8ol2M/8S1S0xEvlYejqEf/tb6Fty0EAw1YHtWYH4zg+tiAMUh13nQsYPe9id7Cll9LGHdRg\n6P9tIliIiEiimjREYonTK157GA1PnaniPm3qfDRcdRkPD9NubcUyC69ebcHC1O6U5e4BbGTEtffG\nVn5YPRXH0NUvratyMWx1VutDF3A/zPUNbIxAsmk4zDJKHttzDluSUn+bMEi1db+sBF7tWYRVIJv6\nHg+zwYIh7Ov4gI6OC3rqX9dZZoltw3rGJr4PD1lhuOqOiFyhg2MlvG9rC/bLwmHG0DrA6GzHMEKi\nVxW/PmHo6pfWhC6GrW7zisUNgIHYeYateF6l8QrInohsYvScSx7bA1hF6xiPZ34twQZx7rW4QhIm\n8ze5QebBzk/Y1y316+VVlwNY8HpTJPx4396C2mHomWQZrtpG0/q2poh/7l+BoavVODKiXxoPXSmj\nH8K2ewau7ulEtStyhVHv1kLi3/dgO9/GPQ8XYEtiRY4dqpTfkMNsrlaELliP1fWkMONVmmMkRnVk\nEU2dz3yIdvRx04artu5xDXxJ9AXs8X2VJ3D5L7caPQ6X4LyuVmOlq18aO+iala1euoY9nsto8W/O\noZ8Hdp03sIC1DbuJnSD7aAWBnfu3VMXYgxmEoa3he7upEBwHp0f9XGl8w8MirOKVZ3jqNqxCVfiX\nyMRw1fgw7Vbs7PYl401k69sa58Ev2r60K9LQuak0HUNXv9Re6WLY6rXWDUmN+XMvTJKPXQH4NVgw\nKPJb/5pXWvZb8lwOVZozPO5bq1MydGWqQqnqsVe6dmCBeCIfWHtX1tR5DzO7oTld7ED3w6aWzAv2\nbY0zwOPzN0NfF6f2txCXF/sl2ehaGS4jzoVWLi+KyIL3b73Ew8AVKlvveR/QLopX6IawBvtGfzH1\nsQxhNMMFip1BWZYFv6YFAIt5GuSj+VoTRxr45/sEBZYVM1zDpaq+glUMn4nIVt5lz1n483YLdrbn\nuZZzlmcYFxELoYtaiKGrJ/yHh+Yo3xf9OAxbc8KfSzewvunGq+K+bLIOC1vreLgr8Qz2XDwK3wPe\n27MPm8VVxAAWvJq8gYUqVwiPTS4Zhen9Q4xpoJ9iH7YxYyPthd6cvwOr/lT288R7pl7BQvpLEVn3\nj12Z6Hkb+rbKqkKlrW5cgX1drdX4D1IqTaVLi1xGnFuhOT30SzXCRwFs4vGxPeEomLFVF1U98Z2Y\n28j/i+YCrB/puOwp6xmFSl64STde6YI9F3JXaHx46h4syN6lNIxvwuZNVd6XmjJc9YU/xqX2Lib6\ntl5X0Gf16Oe+j1HRtu86nlcMXf1RSehi2Jp7jS4xJprkYzewsJXpBq12NuAb2CDVvD/3BDZ4c6Cq\npS97jf2gFjQXYEEkfG+3IXQNUXAXpY8iiafWXwD34WSImo83GjNc9XDG2WJhmXQT5fRtjfsYYXUj\n7TkRlhgZulqGoas/Sg1dDFvkGgldMjrcN9k4fgvb1ZZ7ecZ3doVBqkWWDJ/4de3V9L0Qqlxx9aXR\n0OU/F2TGXYW3Hryeicgd7OfWFmzjQiPztBLDVZ8WHa7qQWgT9vwq9DzNIa2fK7iELU03OWKEUjB0\n9ccABUr+SYmwFfpkGLbm1zWsD6WW0BUNiUybJH8CGxxZ+Mbsz+Vdb+guMrtpGaNBqjNVQybx78Mw\nmyu+cTdd6co0KmIaD8D7sAB8B5s63/hg2lmGq3rf1jpGPzerDpCTftG+As9hbCU20vfHTJWuaGdN\nPKTviIFrviWa6SsLXt4kvwFrNl7DKHCF0PGeb9go5Ubmy4SH/v7zWoQtj1U5vuF+Nlfic27y+1FQ\nUugC7qtL1wCeo0XjDRLDVRcwZbiqiKyIyEvYLyav480cFUsbFwHg/peLW182pRZhpasHfOdNoWF4\nUWWBlS0a5xp2Q1nCmB/ys/Ab2gYeN8lfwJZ4KulLUdVTb7DfQf5fQAWjBvvMx9TkEM/muufN6IqH\nVcA6rcLC6sy8mrcE4PMYHRfUmuN6/OfgQejPSg5XTfRtHTRQqVvC5JEoYTp94xVEGmHo6ofc87kY\ntiiHELSWUWJFwkcxbOLx0uU1apocrqqXMzTYA8CG93kdlBUYvDoxgM3mSvsa3KKZn90DADcl/pzY\ngZ8z6HPXnsJmq7WKLyPvemUzDFcF7OtRdd/WJNNWNy5hy51N7LqlMRi6+iHz0iLDFhVQ6mT6qEKQ\nbGa/hYWtWo8c8v6i17AQUGTJcBU2f2qvpJEAqVWuSFPfr6UdBxVNnT8FAFU9EpEdEdnx2WptdAl7\nTF7AKo27aO7YtUk7F4MrAEsiIm2qIM479nT1wwBThiZGPVvxgD72bFEWN7DnzGCWIZI+WHcb1sMT\nB6472ADTV3UHrsD7ePZQvCqwBOvzmqmHxr++IfiN+1o09T1bygiCcVPnPWyFn1Ot4rsaX8Ae58/B\njpm6H67awCVN/UXbg9Y1OCi1VRi6OkRE3hGRz4rIhYh8KnrRAMDXi8gvi8ixiPxdEXmfvw3DFs0k\nbqZHgWpXokk+3pWoGI0jmWlXYllU9QgWBoo22D+b1HSdwQoez+ZKaup7d2zjdlYZps7vAVhuKMg8\nIiJLIvIctkx3oKr7qnrrIf0INldsSUReVryxImnSuIjYFXgkUKswdHXL5wF8AsD3Jv79KwH8eQBf\nC+uL+DUAPyij8+kYtmhWhZYYvfn4JWxJO66SXcB2elV65EsR3qOzi2JH7giAbf/eK2La0iLQTOgK\nN/lZ7xkTp8578N6FzURLHmReG/9ldRv28/RU7ZzERw3pHsD2YUF9Q0SeV7nLN5K1pSQ001NLsKer\nQ1T1MwAgIh8F8P7oRV8N4EdU9f/ztf6/BuAXAXwAwM+37aZGnZRrSGp0/EnyZ0wYOtnqHVWqehU1\n2Be5ia57g33mgZ+J2VyTllmb+H4Ou+AKhy7fODF16rza1Po9+PDUOjZUBF6JW4NVtkIVdurj58/n\n19Fw1UtYk31VZ2UOkKG/zp/HA/Z1tQcrXd10XzEIDZX2v/eVrfC4/k4GLipJvINxLF+OeYbHuwFv\nYAHkTdsDV+A3zDco3jy+AhuwmfWX2/vDrafcIDsXuvzn1DYy7vL0pdU9WNWwrsG8q7Cfn2HeVu65\ncN6T+ApWJX0hIhuz9EFOkHV5EeASY6swdHVT/INgAOAnAfz7AH43rCH5P/XXmaW3hOieb5sf20zv\nTfI7sGbjZJP8oao21iQ/C+/d2QdQdBbXANZgn+WmlzzcepyqqieThH6u5Cy1rLaRc+q8P+cOYZWj\noh93qqhvaw32i8H+LBUqf84cw8LXIqYMV83LAyxy/EIdzmGkFmDo6qb4pncN4H+B9XR9P4BfhfV0\nHQP4rfovjfpIRN4B8Hdhz6/vi/49rrDGPTjh2J5XYSxAl/lNdA/FGuwXYMFhbdwrRLO5bjIEk7or\nXUOMKp257xkeOBaLDJH13q9j2FJjqferaDdt6NsqtQqrqndqJx/sAVgVkRcZw/c0eU8fYehqEYau\nbrr/we+/VZ2q6veo6odV9W0Afwv2jflzjV0h9c3nAfwlAD8E/7nhIeItWP9L/IvAOXq4ccMDwBsU\nb7Df8pt8mvulxQzvq+6v6TJGR//kumd4hWoDQOHZW76x4RwWXGdeqot2076APZaVVmFV9VpVd2Hh\ncUtEnuZYck6TaxepL9VK2aGVimEjfYfI6NiMAYBF/63pxv/+IQA/D+CLAPxNAH9dVUs5roNIVT/j\nPS+/D8D7xM6aS2uSP9QKD4Jumqpe+yDVpyi2K+yJ33D3QiD1IJF1aRFoJnSF65KcTdlh6vxM871U\n9dhDww6sclSIP4c3YSHydYWN7o94aL/wX1aeiR2sfVzgF5M8/VxB6Ovq3BJ/3zD5dsvHYD/8/iyA\nr4d9A30rrGH307DfpP4RrMfrYw1dI/VXOINxDdajE0LHDSxEvOlz4Ap82egNih+JtIyHDfbhcOvL\nLCHAA09dO9EWYNd2m/i3qXzWlpa1vBx+iZxQLZx0LXHf1p6qHtQZuGL+9XgNewxfTFp2HiPv8iLA\nJcbWYKWrQ1T14wA+PubFH6nvSmgeqR2XE35TXoOFhSPYzK0FESl06HpXqeqBiFzDKid5l70WYQ32\nB8g2myvpDsWb2vNYxuOlrAVMPwEjhPOJ4yEK2IdViTay9Ij56sAm7POo/Yipcby6dSQiZ3h4mHaW\nY4WKDKm9hC3zUsMYuogojytYyDqBzTECrNK6AgAeQi5hVZva5is1Re2w5hvYslfelYMFjHZ7niDf\nOX51hq7k47iICTf9DFPnC1NV9Rlez32GV2oVza9hHRb8TlHigeRlCqMxvFUkDl+pX19fYpW8X1dV\nvRURFZHBrEu9NBuGLiLK4w5WkXkPFrSSP0OW/M+6iNxhFNIyLZ11kapeRoNU8/5MXYGFg7yVi1uU\ndAD5FMt4fB7ltHA5cer8rHx46i4seN0mP06ib+tVFzZz+C8or32n56ThqkWWFoMr2OPJ0NUghi4i\nmiqxiUNgN7S40hWmjcfLbAt4WAW7wSiA9aoK5kuvocE+T+9MPGbjuYjsZQyndQSJRVjfUfJjjQ1d\nWafOz8orN3uwgHLnk9eXYWELsL6tzvUXquqZL+Gvw/q9TmEbEUKVbpbzLy9h34tFexGpBNLCiisR\ntYyIfBzAtyf++eOq+p3R6wjsN+kh0qtgMYUvQwK46FMVTOyA+SzN0cuwZbgb2HmDgFWwpgYGn41W\n9aHQq7DHMNk7daJ22HPymsJy6X5dpw54yHsKCyILsOpQK/q2ZhWN2xjCPq8zf9xvi2xO8Mfnpaq+\nW/KlUg4MXURUCb9pjKuCJd1XwWBLU53+weTLRFuY/Dlvwb4+x3hYfVBYD9LY8OA7A4seqp3VNmyH\ndLIqeeZDP5PXtAMLBI8CWRWivq1n/k+f68JSYl6+KSE8lxZhobZQpVhEXsCeW52rAvYFlxeJqBJe\nvTr1P/HSU1oVbAC7ga4DUO9p6WwVzKsSN7AqTNpynGD84dYCYEdEliYEmDrCxRLsGJ6kR5+P91EN\n/Mikynmo3YA9Rz4Hq8o9E5E3XQ/sSR6Q3ogdIv/FAG68l61Ib1YYHcHQ1RCGLiKqhf92fgnbKr+I\nUQBbxsMbuWDUC7bl4eUSVgnrTBXM+4xCn1ey6X0Fo964cZ/Pus/y2k/5nKsOXWEAZ9q1PQhd0ViG\n3ZTXLZX3bW35dcXLsKd+HU/ruI6GXMI+t3NY/98ZbKk3z3PhCjyTt1FcXiSixkVVsCEm78rrXC9Y\nNEJhJfrnHVjYPMDj5buka1jAuP9cfcnpRcmXGgs9aWm9Q7eq+l50Lc8BnFd5xmYU7JYwYZ6VL3Gi\nropbncIyo6q+8f6sDdhz6iTr196fi2+xr6s5DF1E1CpTqmBJnamC+Xl/G/DBqLBqVdZdfnew4HXl\n72sRdu5lVXZggSutIV5V9Qt+HesAhn62YOk8JGzAqjMnsIOpJz7GIvIMwHVdvWV18SXV5bifziuh\nm7BVq0zDVT0kH9W12YEe4vIiEbWKV3TO/M+0KtjA/6zhYS/YZduGQPr5gTcA3u//lGeO1QKsZ+nI\nqxpVLy8OkB64AD9/EaOv+5sqLiDRt5Vn3lYYnrquqskZY132aFxE3uGqLvR1MXQ1gKGLiFot6gWb\nVgWLe8HCXLBWVcFU9dx7cVaR//BhgfW4DVT1UEQU+Y8fyiLLAM0F2O7Go7KXeKO+rVDdy9X07VPr\n4+GpvRghAbtfpy5FjxmuejQmqF7CqmNTj1Gi8vHAayLqDFW9VdUzVd3zvpQ3sGWntBtzqMQ8A/C2\niDwTkbXooOna+Q40BfAuig+pXPMltKpCZNrRP0lbAG7KDDQisug9WduwuVS7RUcbeNjYg1V/+nLQ\nc9jcMJaqngF4BZv39lJENkTkHRH5rIhciMinYN8rAzFfJSK/ICKnIvJ/iMjvqP7TmG8MXUTUWap6\npapHqvoadjTRAayClPwNP4xo2ILdjF6KyJaIrPhSWV3CzrFT2E60osFrCOu7quL8xWVMXnpahoXZ\nR7O6ivCb/yZsY8C1qr4q4wghX3rbB7DtTeid5c9RyVJVVHMM6xccwH4p+UsAvje8HBa83gfgxwB8\nK+y59FkA/3MlnwDd4/IiEfVCSi/YMkbDWaf1gsVnRFbSC+Y7zu5nc/nN78CXQTeQf6lwATYi4QjT\nK1OZLxMW5CZ9DTYB/HoZy7VR39YFKjgn0cd2HMKW3N50YbfrGLnPXPTPdV9EPg37ZeP3Y7Qr9RLA\nHwPwc6r6Y8D9qRNvROTDqvpLZV04PcTQRUS95Luz4t1+cUN+shcs/HvcCxYa8staxlv1j3URhwtV\nPfGPuY18qw+3sKrTFqyaUcaZetMarLdgAWmmcBQav/397Fa56UFVLzzwhuGpXZxaP3VpcZxouOo1\ngGVfwj0D8KUAfjZ6vTMR+RX/d4auijB0EVHvtaQKFpYWH4UjDwZvYJWrrD+XQ3gIYxUGsKrXLCb1\nc63AqmCHKNiaUmTEQRk8UCzCKl67bdhUkVPuSleKcNTWNWwpdwfAryRe5wjVn+k51xi6iGjuJKpg\nC3h4RuSkKtgtRmdEZq6CeU/REmywaGrQUNUbD1474eNNkazYrMJC0QGKN9kvw6pmSQuwm/F+9PfM\nEvO2jlV1r+D1FeYjOxZhX9/aP/6MBshYyfSv9aL/GUT/vwZ7jqzDAtg5Hp/fuQXuaqwUQxcRzTVf\nbkpWwcJYimQVLNy84ipYmI4/qRIRqlwTd/v5teyKyBZG/TfjpC2TLcN2ax4gf2VkERbW0t7vFuzr\nE2+XxSMAACAASURBVHqiMoeuqvu28lDVAxF5KiLbmnJod4s9mNHl4TEOVPH/L8Ae+1v/cwP7BeMc\n1kv4ru9+/ccAvi56n2uwsx1/vobPZ24xdBERRaIq2HGOKtjmlCrYqv83U7XC53Bdw8LOuAb7cdWs\ncAbhEfINYF1C+uiNtGufGrrq7NvKaR/W37Xhu/xax0NVHKh2ANz68uwCHgaq8Ly7gVVS71Le15K/\n3aIH+kUAPwTgL4jIvwXg7wD48wB+hk301eIxQEREGU2pgsUUFtxCf9QmbEBrrunt/vGeIj3kLPnL\nJjlB+vmJabYwGiYbxMtx8c38RlVfjbnmuG/r0Ad3toqH6eewcwvL2IBQ5ONPqlbdYRSoBLYk+B4s\nVOXagem7Er898c/fqaofF5GvAvA3AHwAwD8E8E2q+rmCnxZlwNBFRFRANAIiVMLGVX+2YTfU17Aq\nS64dkaEBHI9D3gKyHXp9iWwztV7Ahs3G1/YUVuFKVszuz1+MrjP0fa0ixyHMTfGv63NYMCy1oT8K\nVclAFf57h8fVqltYmL1NvK9V2PmWMy+H+s7Fm7ZW+OYBlxeJiArwZZxz/zOuCiawPqvw/0+RrxcM\nqnobNdivRC/K2hs19I97MOFtBrCbfhy41jFaukoSEZEQHr0faN1f93UXxjL413UPtqPxLs8B0FGz\nelydiv8OPAxUYefgLaxalafaUXhcROKaw/OyS71svcPQRURUgpResCGsqT0sNQZpvWBhWS+1Cub/\ntueT2+Mt/VnPX1zCqME+rW8rOYV+CRbwdie8zwVfStyChYI29W1loqrXInIAYMdHSdxfv39uaUt/\nA9jXPK1ZPVSrylxCyrxzcRwPiVsA9js4LqNXuLxIRFQREXkJ722CLQcOMap8pYl7wS7Tzh705aZt\n2I3/OfIdBaRIb7DfgfV+heD13F9vXPVnEaN+tVb2bU0TNauHmWxbGD1Oac3q9/9fZyXPn0O7s0zT\n9+Z5qOphaRdGhbDSRURUAV9uHMBu0qG/Ka6CpfWCpc0Fe1AFU9Vzn2D/FLZcmCd0hYrHEh7OYxpg\nFLA2/eOlBa7Q1D0E8Juqup/yOq3gX+dx1apks/oFLJAuA3ivLccFhWXMGQNXGAScuvGB6sXQRURU\njdQJ9Cm9YGEpL60Ktujv5wmsF+wao7EUbzAKUEWubQBr7F/GqGdoxf89bXjoKqwidAFbdqxlmvw4\niWb1tHCVbFaPl//SQsyxL99uY/Kyap1mmkTvoW0bVo3kslYLMHQREZXMb3ah6X3aQNRrWJ9VXAUL\nlbBkFWwZo2AWqmBPkP+wbGA0SDWcNRl2HyYbrZdhw01vYSEt94DUIsY0q8f/D5TXrA4AUNUjEdkR\nkZ2WVPFmPf5nHcB1Xcct0XQMXURE5QuB6SpPc/mUKtgSHoarcIi3RK8TmvmnLUe9BPBfAPiIv+7/\nBuCvwKpy4XoXYUuNAluKTC435lnWTDWlWR0YVaqqbla/p6r7IvJMRDZVddazLGf1YBJ9Hv7ceQIb\nVUItwdBFRFS+sYdb55GhChYaui/8/zcwGvVw5W97hcfT6/8MrKL1rwH4HQD+IoB3Afy3eNi3dYLx\ny4hZptJPWv4Lzepxo/o1GmhWT7EH4LmIrDU8b2yAKZXSCbZhh4q3fnzHPGHoIiIqkQeNISzoFL1h\nPjKmChYOx16ChasDjKbBr/ofxSh8hUrRFwP4LljA2gXwTwD8cxgdiHwO6xmbZCFns3pYDj1Dgcnq\ndVJVFZFdWPC6U9XSHseckhseMhGRddjXuKnrpjEYuoiIynV/uHWVzcs+Y+oIo7lRoRH/GhbG4qGs\nyV6wzwL4NwD8AoC3AHw57DiYIazKcxu97eKYP3ewUBBXq6Y1q3eGqt758NRnHryaGIuxmHf2mYf+\ndXBZsZU4p4uIqETRbK43eaacF/xYy7CZWkkD//dNPO4FA2wZ8i8C+CBsme9vA/jPYYFpEL1+mBsW\nlv3iJctc/Wpd5V/jHQB7aXPTKvy4AwA7qporPInIM9hJB60+hmleMXQREZUkCkFjD4Qu+eMNYE3x\n46xiFLwGGAWq/wFW7fqHsGrXnwHwi7Dm+rivijcI3B+hswUL0rVU8HwI7kqeXZQi8gTAk7wHq1N9\nuLxIRFSe+6XFmj5eGOwZZlLdpfwZwCo1ofH9bQAfBvBxAL8G4P8F8CkAH4Nd/1X0Phm6AKjqhfev\nPRORNzU1p+caF+HXt4H2zBijFAxdREQl8LlSq/7XmXYtZhXOZJzyauHA7Kewitc17Mb8+wD8Pf/3\nfw/AT8Ga58PuyK1oIv4lbDlxbkOYqp55v9RTP6ex6q9F3p2LWwDO5mHJt8sqHW5HRDRHVmFLd5dt\nayL3G/EbWCVrA8C3APgKAP8MwD+Fhao/qaq3qnqmqvuq+i5sN+QdrDH7LZ9fte7LmnNHVY9h1aed\nGj7cEjJWunz5c+DXRy3Gni4iohKIyHPYDsH9tm3V9yrcc1g1ZADgcwCGPgj0KWyn5cRr9vcxjP4I\nRlWwy3maB+Vfs9sqD5AWkfep6hcyvJ7A+vpqbfSnYubytxUiojJ55WcZVhVq1ZErflN+Bjs3cRnW\nMB8OtQZsCWsV048rUn+bC3+/YR7Zo6XIhsYr1Gkf1t+1UUV1yZ9PWZcJt2C7FRm4OoChi4hodqGX\n66JNfU9R4FqBha5fgQXDIYBQpbmAhaaFPNUqX0I98z/xkUUbIrIDa8gPIaxXfUY+PDVMrb9V1bJ7\n+DKFLhEJs9k4k6sjGLqIiGZXyrE/ZfLA9RSjA6t/Q1Uv/UZ9HQKWB4hLWGAqfP2JI4vipcg1/3uv\nliJ9eGo8tb7MCufUfi7/mm4BOGxT0KfJGLqIiGbgIWYRNpur0mGoOYUjgtYBvKuqJ/7vK3i8BHrm\nr1dKaJywFLkKq6rdYBTA2vQ1y0VVb73i9dQrXmUt8Q0wfZl6A7ajtO9Lub3C0EVENJs2VrmewsLV\nEFYJiQdsriBxrqJXwHZEZLGKnZcpS5HLfm2b3r/U2aVIP47pAKNREmVc/wBWNUzlS7mr4LJi5zB0\nEREV5Es8K7Ahoq0IXd5PtQL7+X6J6MbsN+u7McEqNNSfpLysVF7duoItRS7AlkCHANZFRPFwKbL1\nS2ceWo9gwauM4amDKeFtG8BRH5Zp5w1DFxFRcU9goxMu2nADFJFtjJr6b2HH1sTXtYrxy1bnsB6h\nykNXzK8vLEUeeuVrCPvabndlKVJVz30ZNUytLxQW/fMfW20UkXXYuIpWjSWhbBi6iIiKCwGn8Rug\niGzBgsodLAgepISUFdi4g0dU9UpEFkRkWpWlUv6xbwCcAqlLkXEVrG1DaE/C1HoUP45n7NKif/7r\n4LJiZzF0EREVEM/marrqICKbsJEQCgtdl8kxBn69MqXZOywxtmayecpSZNgVudHGpUhVPfT+uJ08\nh1VHJo2LCMuKrQqblB1DFxFRMXUfbp3KA9c6LHBdAlgYMyl9iOk74s5gVZrWhK6YL0We+x+MWYq8\ngAWwxoaF+qT/ZyKyqapHOd98CSmPk4is+ftuRe8gFcPQRURUTK2HW6cRkQ2MAtcpJu9om1rBUtUb\nEVERWW5z/1QQL0X6poawFLnty3xNLkWG4alrqnqa4+0eVbr8c9lAYtcpdQ9DFxFRTn7A8CJsyGgj\nFRVvqN6ABa5D///9tIZ+X5YbZJzpFJYYWx+6Yr60GEIWJixFXsDmW1W6FJmYWp9nCTpteXELwEnX\nxmnQYwxdRET5NTqby5eaNmGB6wBW7TqeUJ1agYeRDM5hh2NXdphzHVKWIpcwGha7JCLXGFXBKgnO\nPjx1F7aj8XZa9dArWrdxIBSRVQCL0XBb6jCGLiKiHKIKiqKBfi4ReQKrfAAWjFZglZtJAXAFGa/V\ng8KtiAz7NO08OqboZMJSZOgHK238hy/Z7gPYyTA89cHxP/5c24QtVVIPMHQREeWzioZmc3nVIw5c\nC7AqyNhdclHAyLOT7gz2efYmdMVSliLDMUUrsGOKbqOXz7wU6eM4DjGa4TWuvyy5tLgJ4LzJTQFU\nLoYuIqJ8Glla9D6ybVjgO4LdnLcxfWZTOOA6T3C4gM3FkjaMYahayjFF45YiL4r2VanqRWJ4alpg\nD3PIwpmey+BMrl5h6CIiyshvxkuwvptp4xfK/LgrsAOsBbYDMfRdpTbOJ6QdcD2Rqt6JyBVyLEv2\nScpSZGjIf+p/j3dFZq52quqpLxmGcxqTgXYJo52Y27ABt70PvfOEoYuIKLvaZ3N5xSMOXCewwDWp\ncT42RLG5W2EX49yFrpiHnnBM0cSlyCw9cKp67O9jB497tcLy4mbW90fdstD0BRARdUits7n8CJyn\nsMB1oqrHsArItMb5+O3HHXA9zQWAZa/MkFPVW1U9U9V9VX0XtntUYWMp3haRpyKy5oNbH/HH5K8C\n+BkRORKRnxaRr/Eg9sUAPgvg1wH8uoj8pIj8gXo+M6oDK11ERBn4Et8CLPBUPi8pEbhOVfXIZ3NN\nbJxPyL20GPicqQt/H5yCPka0FHmcWIpcG7MUOQDwOQB/APZ1/ZcB/DCAjwL4TQDfAuDn/W3eAfCj\nAN6u8VOiCjF0ERFlU9vSoveOPYWFvDM/z28IO18xT2P12AOuMzqHDV1l6MpgwlLkKmwp8gYWpv7r\ncMA4gJ+AVba+HMA/APCr3nQ/gJ2j+YXaPxGqDEMXEdEUdc7m8pvtM1jgOlfVA795byNb43z8fqYd\ncD2Rql6KyLaILPKQ5fxSdkWG2WCb/vhcwXZIfghW/VoC8K6IHMAC9m8D+FcauHSqCNfqiYime4Ia\nZnMlAteFH5ws8EOoc56HWHhpMeECo142moGqXqnqsaq+AfAKFro+CeBHYBWwPVW9U9Vt2Dy2HwLw\nI/4coB4Q7kYlIppMRF7CVgZ2q9pR5tWs57AzHS9Udc//fQfWDJ/rWB4RCTscZ7per85sqSrnRZXI\nq6f/E6zS9W/CHmNNvE7YsfoVqvr/1H+VVDYuLxIRTeChYwCbzVVH4LqE92EVaJwP7y/PAdcTee+R\niMiABy6Xw8PUJwG8APCvT1i6XYT39dV1bVQtLi8SEU1W6ZgID0jPYDfYK9gSk0aN80XO3ctzwHUW\nYWYXleO/B/DPA/jaOBiLyL8qIl8mIosisgngvwHwi6r6K01dKJWLoYuIaAyvSISwUXoDvQeu57BK\n2hVs+VKLNM4nlNXPFTB0lUREPgAbC/ERWNP8sf/5o7DH/Adhs79+EVYJ+9rGLpZKx54uIqIx/IDp\nHdhsrjclv+9Q4VqCzXl644FLYEHsNMsA1JT3KwDeAvBemUfIiMgLAIc5m/mJKMJKFxHReJUcbh3t\nSAyBKz6HL/PE+TGKHHCdBatdRDNi6CIiShENtix1NpcHrmcAlmHn7O2GJcSocT7XTsWEspcWg3N/\n30RUEEMXEVG6+wn0ZVWNogpXWuCapXE+Vkno8h12t36dRFQAQxcRUboqdi3uwKpnt7DAdQvcV9Vm\naZyHv59l2GiLqqbHn4FLjESFMXQRESVEs7luymocF5GnsCpUMnAVnTifpqqlxeACwAonpBMVw9BF\nRPRYqYdb+1T5FdgBxruJIaOzNs7HKg1dXoW7Anu7iAph6CIiiiRmc80chERk29/fo8BVUuN8eF8D\nAJjlgOuMuIuRqCCGLiKih1Zhh1tfztobJSJbsKpZCFzX0cvKapwPyp5CP84FgGWfM0ZEOfCbhojo\noVJmc3ngWoONnNhLBK5SGucTqu7nAgD4Ts4LcImRKDeGLiIi50t0y7DKVOEA4+fmxYHrKnpZmY3z\n4X2WdsB1RucYhVMiyoihi4hoJPQqXRSdzSUiGwDWMQpcySBUZuN8UEuVK/DPadErdkSUEUMXEdHI\nTEuL3hi/AQtc+8nAVWbjfEKtoctdgA31RLkwdBER4b6xfREFZ3OJyBqATVjgOlDVi8TLy26cD+9X\nYEuidS0tBtzFSJQTQxcRkSlc5RKRJwC2/K+HqnqeeHkVjfPBELZcWfYB1xN5MJUwqoKIpmPoIqK5\n59WiFRQ43FpEVmGBCrAK11ni5aU3zic0sbQYsNpFlANDFxGRVblyz+ZKBK7DMc3xVTTOx5oOXdzF\nSJQRQxcR0ahak7nKJSIrsEAlAI5U9TTldapqnA/vfxnWg1b2kmUmPl3/zq+DiKZg6CKiuRbP5kr2\nYk14myGAHVjgOlbVkzGvU3rjfEKTVa6AS4xEGTF0EdG8y3W4tVd1nsIC14mqHqe8Tmic36u4CtWW\n0MXp9EQZMHQR0bzLfLh1InCdqupRyuvEjfOVHT4dHXB9M+11q+Q9cDde2SOiCRi6iGhueV/WIoDr\naQFJRJZgYWoBwNmEPq2qG+eDNlS5AjbUE2XA0EVE8yzTbC6vKj2D/cw8V9WDMa9XaeN8QptC1wWA\noVf5iGgMhi4imkt+SPQQU2ZzpQSu/TGvV0fjfPhY4YDrKuZ+5eZ9a1dgbxfRRAxdRDSvVjGazZXa\n7O4N8c9gS5AXEwJXXY3zQZuqXAF3MRJNwdBFRPNq4tKiB6nnsMB1CWBc4KqlcT6hjaHrAsCyV+GI\nKAW/OYho7nhT/BKA2+TB1P7yBYwqXFewCta4sw3rapwP19bUAdcT+dfnAlxiJBqLoYuI5tHY2Vwe\nuJ4DGMAC1+64wFVz43zQyAHXGXEXI9EEDF1ENI9SZ3NFFa4BgGtMDly1Nc4ntHFpEQCgqpcAFn1p\nlogSGLqIaK74bK4F2Gyum+jfBRa4ljA9cNXdOB9rbehyF2BDPVEqhi4imjePGugTgesGFrjG7Whs\nonE+fOxGD7jOiLsYicZg6CKiuZE2mysKUcuYErhcrY3zCW2vcsFnh0k4poiIRhi6iGiePIHN5rqI\ngtVTWBC7hQWu23Fv3FDjfKz1ocuxoZ4oBUMXEc2TB0uLIhIHrjdTAldTjfPh47figOuMuMRIlIKh\ni4jmgvdDDWCzuS5FZAdWObrD9ApXk43zwSq6UeUKwfDOv+ZE5Bi6iGhe3I+JEJFt/3sIXGOrR002\nzid0ZWkxYLWLKIGhi4h6Q0TeEZHPisiFiHwq+vd/EcD/CuDnAPwqgO+H7VbczRCkmmycB3BfaVts\nywHXGTF0ESUwdBFRn3wewCcAfG/i318C+AEAfxDA7wdwAuC7pgWuFjTOB12rcsGXa6+9F46IYP0N\nRES9oKqfAQAR+SiA90cv+klYZesGVoH56wD+90nvK2qcf13JxeazAuC06YsoIOxibNU5kURNYaWL\niPpI7v/Hluaewm7+57Ddh18BW2pMf+N2NM6HaxHY0NYuBpcLAEP/HIjmHitdRNRH8fE9q7CK1TmA\nfQC/C8DHAHxt2hu2qHE+WEF7D7ieSFXvROQK9jk8OlycaN6w0kVEfSSJ/78G8FuwJce/A+BPqOpP\njnnbxhvnEzrXz5XAhnoix9BFRH2kwP1A0Sewvqy3Afw4gO9U1U+nvVGLGudjQ3Q7dF0AWPYjmIjm\nGr8JiKg3RGRRRFZgrROLsF2Lp7Dlwh8H8DdU9W+OedtGJ86n8Wtq+wHXE/my6AWsYkc016SDbQJE\nRKlE5OMAvj3xz98BC2Dfhoc7AFVVN/3tFgE8hzXOt6GPCwAgIluwCfonTV/LLDw8bqjqm6avhahJ\nDF1E1Dseol4AeK2qtyFUqep7Ka8rsMB12qI+LgCAiLyFKRPzu8I/l4nnWxL1HZcXiej/b+9+XixL\nzzqAf9/+3T12d2EQEXEh4kKIEf0DAiZx4UJwYXYGV4oLRQKRgGAWkeDChRvRhWAUxo2goiK6cmmQ\nEXcqKIgoZkgyTiYzbXd1dXe9Ls57J9VVp27dqrr3veee+/lAMbfurak+1VV0fXme5zzvHB1kuPvw\nVfLhos66ODR65GOnNDifJCml3M5Qjdv5wNUcxkA9e07oAmallPIgQxX/9DLRoyR3Tn3sFAfnF3b9\nrsXT3MXI3hO6gNlod8g9TPLeyMuvha4pDs6fMqvQ1c6NLOdUG2EvCF3AnBwkeXpOS+7D0DWljfNj\n2vXd2LEDrlexOBYI9pLQBcxCWxVxs9b6wdjrLYiVE8cCTWXj/Jh72c1jfy6ixcheE7qAndfaio8z\n3lY86SjD7q7JDc6fMqvW4kILvsellDsXfjDMkNAFzMGjJM9WqFzdTnJvooPzSXb+gOtVqHaxt4Qu\nYKe1gfg7SUbbiqc+7nZeX5A6RTt7wPWKhC72ltAF7KxWFXqc5FvLQsqJwfmvJ7kx8XMAZ9laXGg7\n0160EAx7Zcr/8ABc5GGGqtC5rbgWzE4Ozp/Z1zUxu37A9SrcxcheErqAndQ2tt9PctF81umN85MN\nXXM44HpFh0nutkAMe0PoAnbVQS5uK45tnJ9s6MrMW4sLLVQeZfh6YW8IXcDOKaU8zFAROjegnLdx\nvi0cvTXRKstehK7GQD17R+gCdko7RuZBlrQVV9g4/yITq3bN8IDrixwmuTPxmxpgrfywA7vmIMNQ\n/Ojc08jg/Jgpthj3qcqV1hY+jGoXe0ToAnZGKeWNDL+vl22TPz04P0bomgYtRvaK0AXshNYyfJgl\nR/2cMzg/5ijDotRJmPEB10u1VR8329cPsyd0Abti0VZ8NfbieYPzY1pr61Wbo5qCuR5wvQotRvaG\n0AVMXinlQZJSax09wmeFwfkxzzMsIp2CfWwtLjyN0MWeELqASWt3t53bVlxxcH7MJOa69uCA66Xa\n96y0u1Jh1oQuYOoeJ3m6ZJXCKoPzYyYRutJaizM+4HoVjgViLwhdwGSVUu4luVVr/eCc11cdnD+j\ntSGPJ1Bh2efW4oK7GNkLQhcwSa3t9jjnLEG9zOD8ElOY67qbPW0tLrQq5nEpZQqVR9gYoQuYqsdJ\nDsfWKFxxcH7MVluMLTi+2IMDrleh2sXsCV3A5LQwcifJ+yOvXXVwfsy257q0Fr9N6GL2hC5gUk62\nFc8ZLr/q4PwZi51fW1zOKXQ17Xvxos3xwSwJXcDUPMwQqs7MOV1ncH6Jrcx1tcWsx+cte91Tql3M\nmtAFTEYLIvcz3lZcx+D8mG21GFW5zjpMcrdVO2F2hC5gSg6SvH96sHyNg/NjhK6JaN/bowx/NzA7\nQhcwCaWUh0le1VqfnXp+nYPzZ7R1BTfa5vsuThxwvfavZwa0GJktoQvYurag9EHGj/pZ2+D8Er2r\nXapc5ztMcqdnCIZe/FADU3CQoZJ1uq24icH5Mb2H6YWuc7Q7Vg+j2sUMCV3AVpVS3sjwu/bpqec3\nNTg/plulq1Vwbo/dncmHtBiZJaEL2Jo22/Qwp9qKGx6cP6PNVt3sdNfc3h/7c5EWSG9ucX8abITQ\nBWzTQZInJ3dVbXpwfokX6VPt0lpcjRYjsyN0AVtRSrmfpNRan5x6qcfg/JijbHiuqwVKla7VPI3Q\nxcwIXUB3ba7pUc62FXsNzo95ns1Xuu7EAdcraVXO0u5shVkQuoBteJzkaduRlaT74PyYF0lubXiu\nS2vxcp5lWCUCsyB0AV21A41v11o/OPFc18H5MW1Vwcsktzf4xwhdl+MuRmZF6AK6aVWkxznRVtzi\n4PyYja2OcMD15bVK6HEpZRvHNMHaCV1AT4+SHNZaj048t63B+TGbXJKqynU1ql3MhtAFdNGqFfeS\nvH/iuW0Ozo85yubai0LX1QhdzIbQBWxcayEeJHmvzU5NYXD+jHZtr1orcG0ccH11rR37os0Cwk4T\nuoAeHmZoIT5PpjE4v8Qm5rpUua5HtYtZELqAjWpVo/tpbcWJDc6P2UTouh+h6zoOk9ztdEwTbIzQ\nBWzaQZL3T1S0pjQ4P2atw/RtEewtB1xfXfvZOcpQMYSdJXQBG9MG5V/VWp+deH9Kg/NntF/wx2vc\nhH4vjv25tFLKL5VS/rGUclhK+XJGjgUqpXyhlHJcSvnEdq4SLkfoAjaihZY3knyrvT+5wfkl1tli\nNM91Nf+T5DeS/EF7/3mSO61ymFLKDyT5mSRf3c7lweUJXcCmHGSY23o18cH5MWsJXW0G6U6Erkur\ntf55rfUvkvxve79m+HtcVLt+J8nnMxzfBDtB6ALWrpTyRobfk093YHB+zLrmuu5mOOC6ruFz7auT\nw/PPktwvpXw6w5Ldv9nSNcGVOL0dWKtW1XqY5J321NQH589o1bmUUm5e89gercXr+zCw1lqfl1K+\nN8mXknxqe5cEV6PSBazb4yRPaq0vd2Fwfol1tBjvRui6rtNrIn4lyZu11v9a8jEwSUIXsDallPsZ\nQtaTHRucH3Ot0NWOPXLA9fWdbs1+PMkvl1LeLqW8neT7kvxJKeVX+18aXI72IrAW7a6yR0ne3cHB\n+THPM4TGq9JavIb2M3Q7w++pmy3Ev0ryyXz7d1dJ8laSzyb5221cJ1yGShewLo8z7FJ6md0bnD+j\n1voyyY3FioIrELqu59cz/Dx9PsnPZhii/7Va67u11q+3t69lCGLfrLX+3xavFVZS3FQDXFc7jPhR\nkm9kqHAd7+gc12tKKd+Z5Gmt9VLhqe0o+0gLBQBJVLqAa2orIR4neS9DO25XB+fHXHWuS5ULOEPo\nAq7rUYaAUbLbg/NjhC5gbYQu4MraHXr3kjzJ7g/On1FrPUpyq1XzVuKAa+A8QhdwJS2IHGRoK+78\n4PwSL3K5apcDroFRQhdwVQ8zBJIH2bGN85d02Raj1iIwSugCLq2UcjvDwcMvM6/B+TErhy4HXAPL\nCF3AVRxkCBYPMq/B+TFHGZZ0rsIB18C5hC7gUtp5ijVDG21Wg/NjWoB62W4auIjWInAuoQtYWVv6\n+R1Jbma+g/NjVm0xOuAaOJfQBVzGQYZ/Nw5nPDg/5sLQ5YBr4CJCF7CSUsqDDMtPj2Y+OD9mlUqX\n1iKwlNAFXKiUcjPJRzKsiJj74PwZbW7tVbtr8zxCF7CU0AWcUUp5s5Tydinl/VLKfyT5YpJbSb4x\n98H5Jc6tdrVZt+zRjBtwBUIXMOY3k3x/rfVRkp9O8gtJPrbnoWJZi9EWeuBCQhdwRq31n2utGtbS\nXgAABE5JREFUh+0cwe/J0Fb87y1f1rZdFLq0FoGlhC5gVCnldzMcZP3XSb5Ya/2nLV/SVi3uSly0\nEhcccA2sqlicDIxpKxB+JMMA/ZtJfqrW+pXtXtV2lVIOcuqcyXZX551a63vbuzJgF9y6+EOAfVRr\nPSql/GuGRah/meTnSin/meQ4w5mLr9rbh4/3YEfVosV4ckfZvSTPtnM5wC4RuoBz1VqfJEkp5TjJ\nO7XWt9v6iMXbrQxb2G8ludlabWfC2OLxDO58PMqwkT/Jawdcf3NrVwTsDKELeE0p5buSfDLJX2UY\nDv9Ukk+3/y5mm86taLWZp5Oh7Pbi8ZBRloaySc871FpfllJulFJutAB5N0O7cdLXDUyD0AWcVpP8\nYpLfS1KS/FuSz9Ra31rpf671ZYYQdUarDC3C2CKY3V08bqHsvNbl6OfcgucZrvlZ3LUIXIJBemAy\nWnvydCg7+fg4r4ex7vNkpZQfS/LbGW4yeDfJ52qtf9bjzwZ2m9AF7IyRebKTjzc+T9Zap/+S5I+S\n/FaSn0zyx0l+tNb679f9/MC8CV3AbIzMk518nFxznqyU8tEkX0nygxnai6+S/GmSf6i1fmGtXwww\nO2a6gNnoOE92lORRkrczVNg+uu6vBZgfoQvYC62StSyUnZ4nu53kfoZAtpgne6e9fTbDwthPJPl4\nkr/b9PUDu097EWAFJ+bJPpZhkP6HkryVIYQd1lp/fouXB+wAoQvgGkopf5/ky7XW39/2tQDT5sBr\ngEsopfxwKeVeKeVBKeVzSb47yR9u+bKAHSB0AVzOZ5J8NcnXkvx4kp+otb7Y7iUBu0B7EQCgA5Uu\nAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCA\nDoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6E\nLgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4A\ngA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAO\nhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQu\nAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCA\nDoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6E\nLgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4AgA6ELgCADoQuAIAOhC4A\ngA6ELgCADoQuAIAOhC4AgA6ELgCADv4f88hEYuw7qRAAAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x10a88af98>"
]
}
],
"prompt_number": 31
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"And by name"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"G = nx.Graph()\n",
"plt.figure(figsize=(10,10))\n",
"\n",
"# create graph edges (node pairs) and keep track of edges for each count \n",
"edges = defaultdict(list)\n",
"for names, count in edgesFreqs.most_common():\n",
" if count > 0:\n",
" parts = names.split(\" -- \")\n",
" names = []\n",
" for idNum in parts:\n",
" for key in characterDict:\n",
" if characterDict[key] == idNum:\n",
" names.append(key)\n",
" break\n",
" G.add_edge(names[0], names[1], width=count)\n",
" edges[count].append((names[0], names[1]))\n",
" else:\n",
" break\n",
"\n",
"# draw labels (nx.draw(G) doesn't really work)\n",
"pos = nx.spring_layout(G)\n",
"nx.draw_networkx_labels(G, pos)\n",
"\n",
"# draw edges with different widths\n",
"for count, edgelist in edges.items():\n",
" g = G.subgraph(pos)\n",
" nx.draw_networkx_edges(g, pos, edgelist=edgelist, width=count, alpha=0.1)\n",
"\n",
"plt.axis('off')\n",
"plt.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAl0AAAJPCAYAAABGnGG7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XmUZHlZ5//3k5VLrVmVtXU3zdICCqMioMjITwdw2oVh\nUQdFHQRk5OBvgJ8ogojrILjgMjqAjooHERDocYGjoo2ACyoNorKJCCrYNPRS+5JZuWc+vz++z624\neSv2vHHjRsTndU6eqszYbkRGRnzi+X6/z9fcHREREREZrKlhH4CIiIjIJFDoEhEREamAQpeIiIhI\nBRS6RERERCqg0CUiIiJSAYUuERERkQoodImIiIhUQKFLREREpAIKXSIiIiIVUOgSERERqYBCl4iI\niEgFFLpEREREKqDQJSIiIlIBhS4RERGRCih0iYiIiFRAoUtERESkAgpdIiIiIhVQ6BIRERGpgEKX\niIiISAUUukREREQqoNAlIiIiUgGFLhEREZEKKHSJiIiIVEChS0RERKQCCl0iIiIiFVDoEhEREamA\nQpeIiIhIBRS6RERERCqg0CUiIiJSAYUuERERkQoodImIiIhUQKFLREREpAIKXSIiIiIVUOgSERER\nqYBCl4iIiEgFFLpEREREKqDQJSIiIlIBhS4RERGRCih0iYiIiFRAoUtERESkAgpdIiIiIhVQ6BIR\nERGpgEKXiIiISAUUukREREQqoNAlIiIiUgGFLhEREZEKKHSJiIiIVEChS0RERKQCCl0iIiIiFVDo\nEhEREamAQpeIiIhIBRS6RERERCqg0CUiIiJSAYUuERERkQoodImIiIhUQKFLREREpAIKXSIiIiIV\nUOgSERERqYBCl4iIiEgFFLpEREREKqDQJSIiIlIBhS4RERGRCih0iYiIiFRAoUtERESkAgpdIiIi\nIhVQ6BIRERGpgEKXiIiISAUUukREREQqoNAlIiIiUgGFLhEREZEKKHSJiIiIVEChS0RERKQCCl0i\nIiIiFVDoEhEREamAQpeIiIhIBRS6RERERCqg0CUiIiJSAYUuERERkQoodImIiIhUQKFLREREpAIK\nXSIiIiIVUOgSERERqYBCl4iIiEgFFLpEREREKqDQJSIiIlIBhS4RERGRCih0icg1zOyHzOw3hn0c\nIiLjxNx92McgIjKSzOxjwHPd/a/6vPxLgQe4+9ObnPZDwP3d/dm7O0oRqYvpYR+AiMiocvcv3u1V\ntLnun9nldYtIzWh4UWRMmNkPmtnnzOyymX3CzP6zmf2Wmb08d57Hmtln210mfv5SM3tj7nxfYWa3\nmdkFM/uwmT2m2ns3tmzYByAi1VHoEhkDZvYg4HnAI9x9Hvg64HZSJaVpNaXNZchfxsxuBN4OvMzd\nF4AXAb9vZscHcmdGiJndbmY3m9kjzex9EUrvMrNXm9lM7nxfZGbvMrNzZnZPDB0Wr2vGzN5iZr8b\n/1fwFRkzGl4UGQ9bwBzwRWZ2zt3vADAzaF1NyS7zKDO7DbgSlzkK7AdmzWwBeDbwLuD9ZnYE+Dvg\nw8CTzeyWuK58sPMef1ba6V79JNUs1G4C3wv8PXAf4FbgucArzewQ8G7g54AnALPAF+avxMz2Ar8P\nnAKe5e5uZs2C79Pc/R1m9jWk4Ptgdz874PsoIiVR6BIZA+7+b2b2fcBLScHrT4Hv7+IyLwBeCLyW\nFKxeDNwDrJOCxApwA/BNwONyF58G/oIU3PKhznJf+Z8V/z+Q0y1SZvxskEEv+3cKOAD8Q3x/ELgA\nvB642cx+E/hm0mP6G8BMXPZjZjYV/58H/hT4kLt/X7P7BTwN+BN3fweAu7/bzP4eeDzwBkRkJCh0\niYwJd38L8JaorPw68LPAZVLVKnN94TJvBt6cu8zL3f0ZZrYFbLv7qpn9O/BGd//uSu5IyQpBjDb/\n7yf8ZVWu+5Ee74cD+0ivrR+M89yHNGybn84xBRyO6/mKOP+3t7kb9wOeYmZPyv1sGvjzNpcRkZrR\nnC6RMWBmXxAT5+eANWCVVIX6MPB4M1sws+uB7+viMkW/DTzJzL7OzPaY2d6YkH/jwO9YCbxhO/e1\nlfvajK+N3Nd6fK3lvlZzXyvuvkIKXevALwH/SGr/cBj4kbjtReBfgfu6++Xc10VSWDPgncArgD8z\ns5Mt7sYdpOC7kPs65O4/N9AHT0RKpdAlMh7mgJ8BzgB3A8eBHwLeCHyEVGl5B3ALjaGxVpeB3AR8\nd/8c8I3ADwOnSQHghej1I+8gsAgsm9mDgefkTvtj4AYz+14zmzOzQ2b2SFLInQVw958H3kwKXsea\nXP9IB18RSdQcVUSkTzH0+ixgA3gNcG/gQ6T5bl/t7o+O830R8ErgS0lVxV8CfhH4aeB6d39GnO/l\npMn2NwPPJ1XOstMeSZqM/xBSRfJvSY1Zr7YAEZF6U+gSEemTmX0G+A53/5s+L38SOO/um+UemYjU\nkYYHRET6EIHpBI3eZv1YJU28F5EJoNAlItIjM/ty4JPAq2LOW79Wgb3lHJWI1J2GF0VEhsjMrgPO\nunuzlaMiMkZU6RIRGS5Vu0QmhEKXiMhwaV6XyIRQ6BIRGSJ3XwOmY1sgERlj+iMXERk+DTGKTACF\nLhGR4dMQo8gEUOgSERm+NWAmtzm3iIwhhS4RkSHz1LtnDQ0xiow1hS4RkXrQvC6RMafQJSJSD6vA\nnIYYRcaXQpeISA3EEOM6MDfsYxGRwVDoEhGpDw0xiowxhS4RkfpQ6BIZYwpdIiI14e7bwKaZaYhR\nZAwpdImI1MsKqnaJjCWFLhGRetEQo8iYUugSEakRd98Cts1sdtjHIiLlUugSEakfVbtExpBCl4hI\n/Whel8gYUugSEakZd98EMLOZYR+LiJRHoUtEpJ40xCgyZhS6RETqSUOMImNGoUtEpIbcfQOYMrM9\nwz4WESmHQpeISH2tAvuGfRAiUg6FLhGR+tK8LpExotAlIlJT7r4GTJuZXqtFxoD+kEVE6k1DjCJj\nQqFLRKTeNMQoMiYUukRE6m0NmNEQo8jo0x+xiEiNubuTgtfcsI9FRHZHoUtEpP40r0tkDCh0iYjU\n3yowa2Y27AMRkf4pdImI1FwMMa6jIUaRkabQJSIyGrSKUWTEKXSJiIwGhS6REafQJSIyAtx9G9g0\nMw0xiowohS4RkdGxgqpdIiNLoUtEZHRoiFFkhCl0iYiMCHffArbNbHbYxyIivVPoEhEZLRpiFBlR\nCl0iIqNFQ4wiI0qhS0RkhLj7JoCZzQz7WESkNwpdIiKjR9UukRGk0CUiMno0r0tkBCl0iYiMGHff\nAKbMbHrYxyIi3VPoEhEZTRpiFBkxCl0iIqNJQ4wiI0ahS0RkBLn7OjBtZnuGfSwi0h2FLhGR0aUh\nRpERotAlIjK6FLpERohCl4jI6FoDZsxMr+UiI0B/qCIiI8rdnRS8VO0SGQEKXSIio01DjCIjQqFL\nRGS0rQKzZmbDPhARaU+hS0RkhMUQ4zowN+xjEZH2FLpEREbfKrBv2AchIu0pdImIjL5VVOkSqT2F\nLhGREefu28CGmSl4idSYQpeIyHjQEKNIzSl0iYiMBw0xitScQpeIyBhw9y1gy8xmh30sItKcQpeI\nyPhQo1SRGlPoEhEZH5rXJVJjCl0iImPC3TcBN7OZYR+LiFxLoUtEZLysoCFGkVpS6BIRGS+a1yVS\nUwpdIiJjxN03gCkzmx72sYjITgpdIiLjR9UukRpS6BIRGT+a1yVSQwpdIiJjxt3XgWkz2zPsYxGR\nBoUuEZHxpCFGkZpR6BIRGU8aYhSpGYUuEZEx5O5rwIyZ6XVepCb0xygiMr7WULVLpDYUukRExpfm\ndYnUiEKXiMj4WgVmzcyGfSAiotAlIjK23N2BdVTtEqkFhS4RkfGmIUaRmlDoEhEZb6vA3LAPQkQU\nukRExpq7bwMbZqbgJTJkCl0iIuNvFdg37IMQmXQKXSIi40/zukRqQKFLRGTMufsWsGlms8M+FpFJ\nptAlIjIZNMQoMmQKXSIik0FDjCJDptAlIjIB3H0T2DazmWEfi8ikUugSEZkcqnaJDJFCl4jI5NC8\nLpEhUugSEZkQ7r4BmJlND/tYRCaRQpeIyGRZQUOMIkOh0CUiMlk0xCgyJApdIiITxN3XgSkz2zPs\nYxGZNApdIiKTR6sYRYZAoUtEZPIodIkMgUKXiMiEcfc1YMbM9B4gUiH9wYmITKY1VO0SqZRCl4jI\nZFLrCJGKKXSJiEymNWDWzGzYByIyKRS6REQmkLs7sI6qXSKVUegSEZlcGmIUqZBCl4jI5FoD5jTE\nKFINhS4RkQnl7tvABjA37GMRmQQKXSIik02NUkUqotAlIjLZFLpEKqLQJSIywdx9C9g0s9lhH4vI\nuFPoEhGRVWDfsA9iUpnZfc1ssawFDWZ2k5lta5un+tEvRERENMQ4RO5+h7sfit5pMsYUukREJpy7\nbwLbZjYz7GMRGWcKXSIiAhpiLJWZ3W5mLzKzj8bQ4WvN7Dozu9XMLpnZu8zsSJx3x3CgmT3TzD5l\nZpfN7NNm9tT4+QPN7D1mdtHMzpjZLT0cy825719qZm/Mff9VZnabmV0wszvM7DvN7MvN7J78kKeZ\nPdnMPlzWYzSJFLpERAQ0xFg2B54M3Aw8CHgicCvwEuAk6f33+cULmdkB4JXA49x9HngUkAWdlwPv\ncPcjwI3Aq3o4Fi98n93e/YA/ids8DjwM+JC7/x1wDvj63OWeDry+y9uUJhS6REQEd98AMLPpYR/L\nGHm1u59x97uAvwbe5+4fcfc14G3Aw1tcbht4iJntc/dT7v7x+Pk6cJOZ3eju68D7+px8n7/MU4F3\nufv/dfctdz/v7h+N094APA3AzI4CXwe8uY/bk6DQJSIiGVW7ynUq9/+VwverwMHiBdz9CvBtwP8A\n7jKzt5vZg+LkF5MC0wfM7GPA84ATZrZnF8d4H+DTLU57E/AkM9sPfCvwV+5+qsV5pQsKXSIiktG8\nrsHqqirl7u90968Drgc+AfxG/PyUu3+3u98IvAD4eeCmLq73CnAg9/31NIYY7wAe0OI4Pge8nzRM\n+jTgjc3OJ91T6BIREQBiyGpql5UT2QUzO2lm3xhzuzZIgWkrTnuKmd07Kk8bpOB0IVaftvNh4NvN\nbNrMHgF8c+60NwNfE9c9bWbHzOyhudPfAPwg8MXAW0u5kxNMoUtERPI0xDg4xcnszSa3T5GqWHeS\nJrL/J+A5cdojSJWn08DrgBe6+792cVs/RqpmXQBeSho2TGdyvwN4PPDCuL0PAV+Su+xbgfsCb3P3\n1S7uo7Rh6sUmIiIZM5sDDrn72WEfi+wUixyOk4LZorsvVnS7/wr8v+7+51Xc3jhTpUtERK6KlXXT\n2kKmXuL3cYz0vr1SYeB6MuAKXOXQ0mARESnKhhiXh30gAtEW4iiwB1h39wsV3e5fAg8m9eeSEmh4\nUUREdjCzvcB+dz8/7GMRMLMF0qrSTeCsu28P+ZCkTyofi4hI0Row22fjTSmRmc2TAtc2cF6Ba7Qp\ndImIyA6ehkDW0SrGoYrWEAdJKxHPd9EaQmpOoavmihuV1kFszHr/YR+HiAzUCgpdQxOrSA/Htxej\nh5qMOIWu+iv2chERqcIaMKchxupFa4gFUqf5RXdfGfIhSUkUukRE5Boxd2gDmGt2upm91My0LUzJ\nojXEUSpuDSHVUOgaDQ83s4+Y2UUzu8XM5sxsITZCPW1m583sj8zsxuwCZvaXZvYyM/sbM7tsZn9q\nZsfitJtiiPAZZvYZMztjZj+cu+wjzex9ZnbBzO4ys1eb2UzhmL7WzP4lzvPLFT0OIlKtFWCvmT3W\nzD5bOE0V+JLlWkNMk+bUXRzuEUnZFLrqz4CnAF8PfB5pe4Znxs9fS9qe4b6kF8di+Plvcd6TwCzw\nosLpXwl8AXAz8OO5new3ge8lNeJ7VJz+3MJln0DakuJLgG81s6/v/y6KyDDFcFYz7bYE0rBj+Y6Q\nXqs3SRPnFWzHjEJX/TnwKne/Jxri/RHwMHc/7+5vc/dVd18Cfhp4TOFyr3P3f4v9sn4HeFjhun/C\n3dfc/aPAR7LT3f2D7v4Bd992988ArylcN8Ar3P2yu38W+Ism1y0iNRaLdF5sZh8BlvILZGLT498G\nfgKYAW4F7mVmi1E5v4H0GjNrZq+Pn33MzL5saHdoxKk1xGRQ6BoN9+T+vwIcNLN9Zvbr8cJ5CXgP\ncLgw6fWayxWu90ru/8vAAQAz+4IYurw7rvunSFWvVse03OS6RaT+vp202fHVv28zO0KaxzVNqrpc\nAL4ZuMvdD7n7vLvfTap0fQPwFtIquz/k2mq7dEGtISaHQtfoycrNLyINDT7S3Q+TKlFGbyX/GTM7\n2mR10q8CHwceGNf9I+i5IjJusir6ncCh+NmNwL1IAWAGmI+fHW56DfDX7v6OGAb7beChgz3k8VNo\nDXFJrSHGm/ZeHD1ZQDpIql5dMrOjwP9sc95WzpNeVI8Xfn4QWASWzezBwHOA010ck4iMls/Gark9\n8f318f8Z0uvAKnC/+PlMLNa5RFrVaMCp3HUtkybdT2lorDtNWkNor8sxp+rF6Mn6dv1v0vj/WeA2\n0pyL4qRLb3K5Hae5+0VSeJuh8Xx4EfBU4DJpPtctzS7b5rpFpMbizd6A/cAN8bVGYyI3pDCwQXod\nWIqfHQUeQFq8cwDYZ2YnYkhSeqDWEJNJG14LcHWD28Okzsdrwz4eESlHTB+Yja+Z+HcKeD/wQuBD\nwH2AVwIfBv4P8GXALwBvJE03uAl4M/A1wBlSYPs+Ulh7HimwHQQ+DUyr0tVe/E6OkX4X68A5rVSc\nDBpeFADcfdXMtoCjZrbk7lc6XkhEasfM9tAIWbOk1/niFIBNUnU6q2BdBF4BvAx4MmlF8l/kzn87\n8A7g7aTA9p9pLMQ5TpqqYKji3S21hphQqnTJDvGCfRRYc/fLwz4eEWkvGhfnQ9aewlmcNEy4nn1l\nlagYFryRxpBiNy6R5npdPQRSmwMnzetaUqWrtWgNcZD0mJ3VSsXJotAl18h1RXbggj6FidRDzAMq\nhqxiFWubXMACNpr9DZvZQRoLaYpBrZUrNKpjeefjtg6S5omtkMLXVpfXOxGiNcQRGq0hNJVjwih0\nSUtmdpj0on5On1xFqhcT3otDhUUb5CpZ3VROYg7n0fj2ui4PZ43W29Kczm43gqHCV0G0hjhKCskX\ntVJxMil0SVvxafgA6VPZxrCPR2RcRYW5WMUqrjB3rq1i9fSBKIYjj5Pe/Ke5tvFxMxukalYzHs1S\ni7czRXrtOMCEh68Iz8dJv88lTd2YXJpIL225+5KZbZIm2Gtlo0hJIpTkA9YM1w4VbrFzLtauPvjk\n2hRkt9PNe8A27TdebhqkIgwumtkVUvA6YWarpH5UExO+mrSGUOCaYApd0pFWNorsXhdDhc0mvJcW\nTnJzNfPztzrN5XJS4GpXTWsbBHPha4k07Dgx4Sv3mE+TfqftwqtMAIUu6Yq7b5jZWVLwmnb3S8M+\nJpG6KvTGyqpYxaHCbMJ7fj7WIOd75BufZjq9B1ymQ6gitT3oKO5bFr4OAMfNbI003DauK/jUGkJ2\n0Jwu6YlWNkqdmNntwLPc/c+GfBzd9sbKV7EqCxpmdojG/op5x2gdvFqtVCy64O4rfRyT0ZjzNXbh\nK/eYqzWEXKVKl/QkQta5WNl43My0slGGaShbUHXZGys/4X19WH8nZraP5oELWg8vrtFd4IIuK11F\n8VqylJvzdczM1knDjiMdUKI1xCEaH05H+v5IeRS6pC/ufsnMssmxWtkoY8PM9uTnGuUmvOeDVl+9\nsaoW4bDVvoh7aL5Z/Qa9zT3aVaAohK/9jHj4MrNZ0pZqAJe0+EjytOG19C0m1F8izfPaO+zjkcll\nZo80s/eZ2QUzu8vMXh2BAzO7ycy2Izxl5/9LM3tW/P+ZZvZeM/vFmLf4UjP7QjP7KzM7R9pr8E3A\nvYA5UlDZIA2/XSD1qLrH3c+7+5K7D3puVlearFQsavahe4veAtdWWffVkyvAaVJwPWZmC9nvcRTE\nYonsMV9SLy4pUuiSXXH3VVL/nsNR+RIZhk3ge0lzlB4F3Aw8t835HfCYV7QHeCRwN/AQ4DdJlYpf\nBh4OPBq4Hvge4Bxwt7ufcfdL7r5Sx2pMbkPldqsTmw2JdlqpWFT6fW8Svo6a2dG6hy+1hpBuKHTJ\nrsXQ4llgf8z1EqmUu3/Q3T/g7tvu/hngNcBj2lzESO0LrifNvTlFqmYZaf/ATwB/TApY/wT8PPD/\nuPtaHapYXThCGg5tp1jpukzvIWpggTMLX+5+irTXY23Dl1pDSLc0p0tK4e5bMTSzYGZH0cpGqZCZ\nfQHwi8CXkeYFTQN/3+K8J0jDhMeBfaQhtc+ShgrX47l8HfCrwFfFKrQpWndkr5U43n1dnDVf6Vpi\n5ybW3apkLmcM0y3HBPWFaNi8WKO5pGoNIV1RpUtKE59Mz5PexI7HMnqRQTNSQPo48EB3Pwz8CI3X\nt6yZ7/6okszT2G/wCrAIbMZQYTaB/qdJz+Mvjut7OiPwetlhpWJR9qF7lcZj1KtKh1bdfdndT5OO\necHMjsXE9aHJhdxtUuDSam5pqfYvIjJ6onHqMil41W4oQMbSQVJ4WjazBwPPyU5w9zPAnaTgtB/4\nRuA+pDfurL9Ws+u7Alw2sxuBHxjo0Zegw0rFoqn42iAthunXUOaz5cLXCnBkWOErF3LVGkK6otAl\nA6GVjVIhB14EPJU0L+k1wC3s7N/1bFJw+gzw+aShx+wNco5re339BPClpOfwHwG/3+Q8tRFV5XYr\nFYum6X2lYtH2sKs6ufC1TMXhK24nC7lqDSFdUUd6Gaj49H2UtHxaezbK0EQwyYYVnTQclA2BX3b3\nbpuB1kpM4j5O54nzeXtJoXM3lZl1dz+7i8uXLld52ibN+RpIEIrWEMdJhYslrVSUbqnSJQOllY1S\nI/mK6xppODJzMMLLKFqgt8AFaeh0t0NhtRtKi3l5p0n3b97MjpvZXJm3odYQshsKXTJwMTn5LLAn\nlnyP6pubjLb8m+9qrIjLgsMUaR7XSDGzeXaGyW4sUk5gql3oykT4OkNalVl2+FJrCOmbQpdUQisb\nZZgi6O8IXfFvvtp1YJQ+EMRQWq9BccXdFymnXVBtQ1fG3VebhK++55ia2QJp4cUWag0hfVDokkpp\nZaMMSbZ9D+Q2n3b3FRq9pkam2lWYxN2tdeBirgv/btWlR1ZHhfB1yMxO9Bq+Cq0hzg17EYGMJoUu\nqZxWNsoQFOdz5RWrXbV+XexjpSLsrMyUUeXy/KbgoyIXvi6T5vF1Fb7UGkLKUusXFxlf2rNRKpZ/\nY93ReT2eiyNR7cptN9PLa7ezs2lnGRXmkQ4dsZ3TWXaGr6Zd/NUaQsqk0CVDo5WNUoV408xe67Za\nbB0zKtWuflYqXijc54mYz9WNQvg6YGYn8+ErWkNkVcWlWHwh0re6vrDIhNDKRqlAyypXJqpd6/Gt\n0f1WOpXpc6Xi5bhveQpdBbnwdZH0IfBk7POYVRVX1RpCyqDQJUOnlY0yYB1DV8hXu/bX6XkYAaDX\nYc/lFg1fFbpacPd1dz9HCl83kprp7iFthi6yawpdUhta2Shli+GhLGRst5uPE6flq121mNsVw6O9\nDr+v03pPxTLC5FiGrpz9pAarF0j7O56I4CuyKwpdUita2Sgla7dqsZn8ENLQq10lrFQsXt90j9fV\nytiGrmgNsZ/UGuKe3LDj3tywo0hfFLqkdrSyUUrU7dAikIaXaISzoc7tivmNx+jtdbpTD6lShhbH\ntSloq9YQMex4nlT52mtm1yl8ST8UuqSWtLJRditWIGbD1E53lS7YWe3aF9WhYVigt5DkwMUOPaQ0\nn6uFblpDuPtGhK/zNMLXSO1kIMOl0CW1pZWNsktNu9B3EoE/q4oNpdoVHzR63lOxyUrFIoWuJnpt\nDVEIX7PASYUv6YZCl9SaVjbKLvQ0tFiQX8lYabUrhq16HVZvtVKxaOIboxZFRbSv1hARvi4A51D4\nki4odMlI0MpG6UWbDa67EtWuldyP5ss4rk7MbI4+Viq6+8Uuz6tK17WyYdwN+mwN4e6bTcLXQYUv\nKVLokpGhlY3Sg3wX+s0+9wnMV7v2DjrsRzVtgd5WF26Shri6uf49PV53u9scC2Z2hBTOt0gLEHa1\nQKAQvmZQ+JIChS4ZKYWVjbXooyS1tJuhRSC9gbKz2jWwuV197qm4zc49FTspo8q13cPt1VqhNUS7\nFZ89K4SvaRS+JCh0yciJoZ8zpLk2Wtkozew6dIVF0qpASNWu2V1cVztH6X2l4tWWBl3S0GJo1Rqi\nbBG+LpIWBE0D15nZIYWvyaXQJSMpPpVmKxuP6UVMMjEMmC242I7eW32potoVHxzmOp5xp8vtuuu3\noNDFNa0h+nkce+buWxG+zpCem1n40nvwhNEvXEZWbmXjBlrZKA1lVbky+WrXXJnVrmj+2+tKxSsx\nv7FXZYSujRKuY2gKHf6X+nwc+1YIX1OkYUeFrwmiX7SMvFjirZWNkik1dMUk/HzfplJWMsZKxV6v\nay1W8vZjoitdEWyyDv89tYYoW4SvS+wMX/MKX+NPv2AZC/GJ9SJa2TjRopLRTxf6TpZoVLtmIzD1\nbRcrFftqaRBv5pO+0fWuW0OUrRC+DIWvsadfrIyNmJuhlY2TbccG12XtEdik2tX33K5CM85u9bpS\nsaiMKpf32Xpj6MpuDVG2XPg6HT9S+BpT+oXKWNHKxonXd0PULuTnds3uoqLaz56Ku11hN7FDi/EB\nLGsNsZvgOnDuvh3DnvnwdVjha3zoFyljRysbJ9Nuu9B3Es+r/MTrnqtduYpLL8pYYTeRoStaQ8zT\nCK4jsRCgEL6cRvjSYqERp9AlY0krGydSXxtc92iJVDEBmIk39a7ESsX9Pd5evysViyYudA2jNUTZ\nCuFrGzih8DXaFLpkrGll40TZMZ9rEDfQb7VrCCsViyYqdBVaQ5QVXIcmwtciCl8jT6FLxp5WNk6M\nsvtztZKvdk13qnYNek/FTmLYtYw355EYmov7m28NUVZwHbpc+DpFI3wdUfgaHQpdMhFiaOEcWtk4\nlmIoKXvKyU2QAAAgAElEQVQ92xrk3J1Y+baU+1HLatcuVyqWtcKujI2unbTybxRkWyrVpjVE2WL6\nRBa+tlD4GhkKXTIxYvVXtrLxSKfzy0ipqsqVucLOaleruVpV7KnYSRnD6lt1a7PQTN1bQ5QtF74e\nB/wxaRrFkaiutmVmf2JmTx/4QcoOCl0yUXIrG6e0snGsVBq6uql2RQDodcugSwOY8D0R87lGqTXE\ngGyT5nxtAsfMbKFd+HL3x7v7GztdqZltm9n9SzzOiabQJRNHKxvHS7yxZG8u2xWuUrtCY8htT6xO\nzI4pCwC9WHL35c5n69nYh65Ca4iLo9Iaomzx2rZECl8bNAlfFnq8an04LYlCl0ysWNl4Ba1sHHUD\nX7XYTJNq18F4P9tL7ysVB7kX4FiHriatIaoYXh4aM7uPmb3VzE6b2VkzezXRtNfMft7MzgOfAr6K\nFL7WgfeY2S+Y2W2k5+z9zewvzexZcbkHmtl7zOyimZ0xs7fEz/8qbvYjZnbZzL7VzP7RzJ6YO56Z\nOI6HVvYgjDCFLploUVnIVjZ23XNJaqXq+VxXxcrYq9UuUtjqdb7goCd8j23oiip1tjJ05FtDdBL3\n9+3AvwP3A24EbiHd//8IfIK0cvPngNdG5esK6Tn2FODFwH2BO0lBLZvz9nLgHe5+JK7z1QDu/ug4\n/Uvcfd7dfwd4A/C03GE9HrjT3T8ykDs9ZhS6ZOLlVjbOa2XjaInVgYPY4LoXi9nhAPdmuCsVd4g3\n6TKGhmoXunKtIfYwZq0h2ngkcAPwA+6+4u5r7v7eOO0z7v7aeC69AbjBzE7GaQ68Dngv6YPJYXYu\nsFgHbjKzG9193d1va3MMbwKekHutfDrQcW6YJApdIuxY2bhXKxtHShVd6NuKaukmqcI1S/dzuZwU\nuAbZiqGMKtdWTSelj31riCbuQwpXzX4f92T/yc0NzH+I/Gz8m/295IP+i+PnHzCzj5nZf291AO5+\nFym8fUu8Vj6OFMSkC2X8QYqMBXffNrNzwIKZHWOAFQgpzdCGFgv20FipeIC0C0Inl9x9fXCHBIzp\n0GKhNcQk/Z1+Frivme3pI6zPAidJ1eBz5H6v7n4K+G4AM/tK4N1m9h53/3SL63o98CxStew2d7+7\nx2OZWKp0ieQUVjae0MrG+hr0Btc9HMdBUpUgexObIgWvdga1UrFo7EJXk9YQo9K0tQx/C9wNvMLM\n9pvZ3ghJLcXjNUP6YHDO3S8W+8CZ2VPM7N7x7UVSFSyrpp0CHlC42rcBXwo8nzSUKV1S6BJpIlaS\nLZFWNvbaa0mqke9CvzmMN9/CSsX8JO79tJ5LNciVikVlrMqtTejKPd4T2RoihhWfBDwQuINU+XoK\nOyfFZx9IHDhOYwh2uU3T3UcA7zezReAPgOe7++1x2kuB15vZBTP7ljiOVeCtwE3xr3TJJqcqK9K7\n2Kj4CGkp+sqwj0cazOwwjYrSUoVBJrv9GdKbWj5cHaURdK6ws6UEpDe/s1UNh5nZ9ez+w/W5Cnuf\ntVR4vC+N+0rFfkTYOkj6u1gFFgf1YcTMfgz4fHd/xiCuf1yp0iXSRm5l4yGtbKydoc3nyu2pWKxm\ntat2VTr/KI6xjNf4oVe6Ypg/e7zHvjVEr6I/3CHgOtIw4pkYRhxU4DoKfBfwmkFc/zhT6BLpIEry\nZ9HKxtqIqkc23267ggnp+ds2UgBoNt9vjVTNghQQskpctqdilUOgZczn8mHPmZrQ1hBdqTpsxW0+\nmzS0eau7/82gbmdcaXhRpEvx4n+E9GFlklZM1U680WT7HS67+8UKb3sBaNdId5bUsBNS2DpDer5U\nOjxtaRPu3X5I2HD3M2UcT79iJfEcFQ/N1lmVw4hSLlW6RLoUKxsvoJWNdTCUocUIe512LliPL0jV\nLhvSfMCRX7k4wa0hmjKzqVxla4oKKltSLoUukR5pZeNwRditvAt9bBN1qOMZk2zO0SqwNaSAXkbo\nGtrqwFxriCqayNZaLmydpBG2Lk3yYzKq1BxVpA/uvmxmW6RGqlrZWK0dG1xXUf2IOWS9DNWt01i9\naKSwVtkQaBjZSlehNcSFSWsNkYnFEAfia4UUthS0RpgqXSJ90srGoam0IWph5Vy3tkiTjTP7qqx2\nxZyfkQxdEXCzOXGXoyfURInK1jyqbI0dhS6RXdDKxmpV3YW+w0rFVrLhsFUax5dVu6pS1srFSkPX\npLeGKIQtQ2Fr7Ch0iexSdIk+R3qPPhZDAjIYVW9wfYTeu7rnO6Uv5n6+z8yqmtJRykbXJVxH1woB\nd6JaQyhsTQ69OYiUoLCy8bhWNg7Mjvlcg7yhLlcqFi3m5/dF+BpGtWsUhxazbv4bwIWKb3somoSt\n0wpb402hS6REWtk4cJW0iuhxpWJmxd0Xm/y8WO0qYz/ETkYqdMWWThPTGqJN2Bp05VaGTKFLpGTu\nvkxaqbYQb95Sggix2WvW1qBWtMXt9Do/b50WqxPjOPOrW6uodo1M6IpFKAeYgNYQhbAFClsTR6FL\nZAAKKxurnEA9zgZe5Yph4QV6X6nYqTqzSAoVkBZdDLraNRI9uialNUSLsHVZYWvyKHSJDEhuZeOc\nVjaWYqCha5crFdu+ecZzIV/tmu/9CLsTwbGX0NjKQCtdk9AaQmFLihS6RAZIKxvLEav+surNdlQS\ny7ZA7ysVe6nO5KtdcwOc81dGFW1rkPOqxr01RIStwyhsSYHeAEQGTCsbSzHQVYtRjdjb8Yw7LfZS\nnYm5SlXM7ar1fK5xbg1RCFuOwpYUKHSJVEQrG3dlYEOLZrYf6HVHgVYrFTspVrvm2p25T7UOXYxh\nawgz26OwJd1Q6BKpkFY29i6GZAeywXWE38M9XqzlSsVOotq1nPvRIKpdtQ1d49YaIhe2TqCwJV1Q\n6BKpmFY29mwgXeh3safibsNCvto1O4BqVy1D1zi1hlDYkn4pdIkMgVY29qT0ocXcvKJeXgO36WKl\nYidx+fzE8dJWMkZVsIzX9VJDV641BIxwa4hC2NpGYUt6pNAlMiRa2djZADe47mel4sUSw8IS6U0b\nYCZCSRnKqHJtl1mFGofWEC3C1qLClvRKL/IiQ5Rb2biOVjY2k+9Cv1lGGOhzpWKpYSHerAcxt6tW\nQ4tNWkMslXXdVVDYkrIpdInUQKyE08rGa5U6tNjnSsXlAYWFYrWrjIUVZfToKiV0FVpDrI1Sa4gI\nW0dQ2JKSKXSJ1IRWNjZVWujqd6Wiu/e1UrGTJnO7yqh21anSlQ3hbgDnS7rOgSqErS3glMKWlEmh\nS6RGtLKxIeYCZcOt2+6+vovr6mel4iaDDwv5atd0VOJ2oxahK4bk9jIirSHahK1aH7eMHoUukZrR\nysarSqlyxTDXMYawUrGTeFPPD132OvR5VdzPMuYE7ip0mdkBRqQ1hMKWVE2hS6SGCisbj0/oysay\nhhaP0lsFyEkrFQe64XPOFdIbPuyu2lVGlct3c79HpTWEwpYMyyS+kIuMhNzKxjXSBPsy3lRHQgwH\n7roLfa4Dei8qbWvQpNp1KKpWvSrj+dF3VSrXGsKoaWsIM5uOsHWcVNFT2JJKKXSJ1FxuZeOxCVrZ\nuGOD637eFHPDXL1Ydvcrnc9WumUagWcP0E+1a2jzuereGiIXto6R7uNpd19S2JKqKXSJjIBY2XiB\nyVnZuKuGqLG1Tq+d3tcGtVKxk2Zzu/qodpURunoeDqxzawiFLakbhS6RERGr98Z+ZeNuu9DHMGw2\nzNWtTVKoHZqosOWrXb1W6YZV6apda4gIWwsobEnNKHSJjJDCysaFTucfUX1vcB0LDoayp2JJFnP/\n77XaVXnoqltriELY2kBhS2pGoUtkxORWNjKmKxt3zOfq8bIL9L5S8UKFKxXbimHk7Fim6LLaFdW9\nfibfF3X9ONSpNYTCloyKcXuxFpkIY76ysa9WEbtYqdjXysgB6qfaVcrKxW5DSl1aQyhsyahR6BIZ\nYbGycZExWdkY9yF7Xdrq9s28z5WKV4a0UrEtd19hZ7Wrm4aplQ0t1qE1RCFsraOwJSNCoWsIzOy+\nZrbYZy+egYtjuyn+/1tm9vLhHpG0E2/S47Kysecq1y5WKtZmlV0Tl3P/P9DFEHIloavQGmJQG4G3\nu/1mYeuKwpaMinEakhgZ7n4H5WxuOxDunj82jy+pMXdfN7NzwFEzm44K2CjqKXSN6krFTtx91cw2\nSKsCs2rX5TYXGXjoatIaorL2GlFdOwjMklprXFTQklGkSpd0o5YVOdmpuLKxrpXUViJAZeFhu9Nc\nqzFYqdhJPjh3qnZVUenKWkNUsRE4kMJWVLaOosqWjAGFrpKY2e1m9iIz+2gMz73WzK4zs1vN7JKZ\nvSvbvNjMbjKz7exF1MyeaWafMrPLZvZpM3tq/PyBZvYeM7toZmfM7JY2t/8VZnabmV0wsw+b2WNy\np/2lmb3czN4bx/aHsertTXFsHzCz++XOv21m989dvcfPP2ZmT8ydb8bMzprZQ0t7IGVX3H3b3c/G\nt8dGbGVjr6sWR3qlYicxV2o9vjVaVMfjd1zG77nl/LlCa4hzgw498dpyFIUtGTOj9IJcdw48GbgZ\neBDwROBW4CXASdJj/fzihWIC8CuBx7n7PPAo4MNx8suBd7j7EeBG4FXNbtjMbgTeDrzM3ReAFwG/\nb2bHcmf7NuBpcT0PAN4HvJb0ovbPwP/s4j6+Pq4j83jgTnf/SBeXlQqN6MrGrocW4wNMrysVL9Vw\npWIn+WrX/phTVTTT5Ge92m5V/auyNUQhbK2hsCVjRqGrXK929zPufhfw18D73P0j8UL/NuDhLS63\nDTzEzPa5+yl3/3j8fB24ycxudPd1d7+txeWfAfyJu78DwN3fDfw98IQ43YHXufu/u/tlUhj8F3f/\n83gB/d02xwaN4cU3AU8ws2w11dOBN7a5nAzRKK1sjGpNVxtcx/Ov170Jr0QPrJESrx35alezlYwD\nG1ostIa4OKjWEMWwFa+DClsydhS6ynUq9/+VwverNHnBjCXr3wb8D+AuM3u7mT0oTn4x6YX2AzG0\n99+Ll49Pvg8DvjWGCi+Z2UXgK4F75+b1FI/ldKdja3KsdwHvBb4lKg2PIwUxqanCysZ+NlGuSldd\n6CME9LoIpe4rFTvJT6BvVu0aSOiKyetHaLSGWCnhdq65jVzYWs3CVtm3I1IXozLsMKq6msjs7u8E\n3hlL338K+A3g0e5+CvhuADP7SuDdZvYed/907rJbZvYvpIrT84B98TVHqgZ8Sfx7zMyuJ4XB3YTt\n1wPPIlUlbnP3u3dxXVKBwsrGPTVd2dhxaDGGSbMQ0K3KJn0PSvz+1mgE00NAfuVg6aEr1xpiigG0\nhohAd4j0OrLo7iP9OxLplipdQ2ZmJ83sG2PexAZwddNbM3uKmd07znqRNOzSrALw28CTgMcSy6mB\nzyN9Qv4o6U1shfSCnX2qXDCzB8cE+iPAlJnNNlnxVvz+bcCXkuanvaHf+y3VqvPKxjiWthtcx/Dj\nMXpfqTjwSd8VyQflfYV5eqWGrkG2hmhR2Rq5YV+Rfil0DZYX/l/8HtLv4AXAnaT99P4T8Jw47RHA\n+81sEfgD4PnufnuT2/k34JnAD5OGDe8AXghYvOFskz6t3u3u/w6cIX36/wwpmO2J4/h84Ivj2O5l\nZifjtOyFOFtR9VbgpvhXRkRuZaNTr5WN+S70my0mamchoFtD3w+wTO6+TiOMXl3JGH+XvTwureQr\nXaW3hsiFrQUUtmSC2Xh8CJR4QVvZ7byLeCPeG1/5oUojTehdAZ4L3A94xqgsv5edzOwQ6Xd7fti/\nw2hHkG3hsxSLPfKnH6H3ifMXx+1NPYbkTuR+dJr0d3mi+SW65tk0gdzvYhs4s9vQGgs4DpKqcUvj\n9jsR6ZXmdI2PZdKL5a5CV0xgXo6vq2I4Yw64AfgO0iT/B0UBLAtj2TDm2rDfyKU9d180s01Sxevi\nkFsptJzP1edKxbF8c3f3DTNbIYVlSNWuMvY93IRyW0NE2DpEqsKN5e9DpB8KXWMitg05HBOlSx9S\ncffNWD35S8Ab3P2WGNrIwtg+0pvjUWAmwtgqjSC2SlqVpjBWE+6+YmZbpPl9i8N4Y4zqTTY8th3D\naNlp+XYF3VotVsrGzCKN0LWPnXMup+L7VnM/W9m0nftXXsz/HnqhsCXSnoYXx4iZzZOGCoa6Oi3C\n2AyNMLaPVM3I3lyLYWxDYWx4ooqZDU9X+tyJYc6sBcRyNmk7wthxelupuAGcHeWJ8/G3Y6QA1ezL\nSPOiDsT/95Hud/5xWiItyOnWCulvdYrUGqLnlYoKWyLdUaVrvCyTVngNNXTFm956fF09llwDzCyM\nzRPd+qMytkJqipmFsU2FscGLKuZZUsVrgWo3E75maNEaeyr2EriyPRVrE7hy2/M0C07tTutki/R3\nlE2oX2TnRPheFkgY6e9wgz5aQxTC1uIgenmJjBOFrjESb55bZrY3VhnWSswXW4uvq0NA0RMoC2P7\nSS0s9qaT7Hrgj4AH0ghlIxPGzOy3gM+6+4+1OH0beKC7f9rMfpW0rdJPVnmMcPV3cy4mrR8zs4Fv\nCp37vUN0oS+0K+jWQFcqNglP7UJT/vRB2SIF1H2kx+kAkG/+2sttL5D+FntqDaGwJdIfha7xc4UU\nXGoXulqJN8vsjeTqm0cMe90O3JvGfLHZdJI5O4cp16lnGCu2Cml9RvfndD7XYLn7xRjyOx7Ba5CP\n544Nrt3do9LW65ZFl7qZg5QLT51CU/E8dbREY4hxlvRanv2uuj3mI6TQu0rataAjhS2R3VHoGj+r\nwGEzmxp0pWLQ4g1/kxSqsrk+2eT9fGXseHxPkzC2wYDCmJlNd3m9tWlE2o0KVzbuaIiaa2PRSX7e\n0zLgsfKuUzVqnGzT2JMRdla7unm+HSQ9/hukBrJtXytiov1BFLZEdmXcXogmXsxpWaH3ZfaVMbPb\nzexFZvZRM1s0s9ea2XVmdqulvSPfFcNcmNlNZrada+T5ncAngHuAfwAeE9sibZO2T/oA8MH4/0ng\nvsD9zezzzew+ZnbCzJ5tZp8xs7Nm9qNxPDfH7ZmZvcTM/i1O/79Rfckfy3eZ2WeAd8fPf9fM7jaz\ni2b2HjP7wjb3/QfM7C4z+5yZfVfhtN8ys5fH/x8b5/l+MzsVl3lm7rxzZvYLcT/uMbNfjdV+pcjt\n2XjEBrBnY4TnbPJ2FqJPkELXAdIb/DypGrNAmqt4AriO9Hs9EeeZjdMPkyowB2gs3MgqQOP6OrdG\no4o6S2OottP9zR5jJy08aDksG8+z46THd9ndTytwifRvXF+MJt0yNQ5dpBf7JwM3Aw8CngjcCryE\nmFhP2mZoh6hmvBJ4nLvPA48CPhwnvwy41d2PAPcCftbdPwV8itSh/25SGH0Iqe3Fi0nd/+8X5z9k\nqSfU9wPfADya1JPsAvArhUN5NPBg4Ovj+z8mzTk7QQp8xU3APY7/caSdAr4G+IL4t3i+/FDkdaTg\ncS/Sfpe/Yql5JcAr4jYfGv/eCPx48THbjRiyOwscjJWxfTOzfWZ23NK2V9eTHvfrSY/ZAmnbqsOk\n+3uQRniao3l42mDn/oOTaIqd0wiyv/l2la5seBDSXK6mqwwLYeuKwpZIORS6xpC7b5CGXHqdG1Ol\nV7v7GXe/C/hr4H3u/pEYynob8PAWl9sGHmJm+2IrkY/Hz9eBm8zsRndfd/fbIM0Xc/dVd1+KLXC+\nirSl0u+T5ov9MCno7CWFgOcA/ye+Pwm8FvgWS3tgZoHnZ4nhq6guvYUUAgB+Eniomc1HNSfvW4Hf\ndPePx5L6/9nk/uUvswG8LO7DraR5PA+K63028P3ufjFWnP0M8O0tHrO+RRXkLKn32m72bJxiZ3jK\nqnJZ24NerncLBS5IQ31X2Fntym+pVDRNeg4b6bm0yrUbXWdhax6FLZHSaU7X+MqqXX01OazAqdz/\nVwrfr5KqHTu4+xUz+zbgRcBrzey9wAvd/ZOkytXLgQ+Y2QXgf7n765rc7g3A5/LzxczsHGlLlU+R\nqkq/Qgp32dygbeDLaQSFk6RqQbYS8/nAfyENgWVzY/4D8FlSoDiYq+78s5mdIL1RZu00DkUFawaY\njYrbXtK+d3MxT81Jv9PDpHC4H/iHXAYa2Iq5klY2Fs+fzec6TG8tTpw0d2mk5yuWZJr0eOSnE2R/\n81mT1IwRG9vH+bM+Xlk3+jnSc9pIfbYUtEQGQKFrfC0D15lZtul13XVV6XD3dwLvjDeJnyLN3Xq0\nu58CvhvAzL4SeLeZvSfme+XdTRrSJM67jxSWiNVzdwDfBXyS9Ma+TWN+0P3iYmdJVYYZ4L+SAtcP\nAp+Ln/0FKTRmc2wgvdmdJs0xy37+efFvNscmm9s0T2Nl2kLuOvbQeONcBb46rhNiaNLMrqMxTFnq\n1y5XNuZD0kzch0Pxby+tHi7TqCpOkr8lDU3/TXyfXxywTHqOZn3wsmpX/nFdID1/3g68IH89Udky\n0gT5kVn1LDKKFLrGVASIVdIn3166U9eWmZ0kzeN6N41P61tx2lNIQ5SfIw09tdoK5feA95vZo0gT\n8V/KzsD3GuDngGe7e1aV+o/u/oeW+koB/CuN0LVIGqr5YPws68e1hxSe9tOYm/R24H8Bv0Wqqj0v\nznspjnmTRkPZFRrVrWy1npMCxzrwxjj2HyFVxG4gzRP7q44PZJ+iquZxX06Y2SUak7m3aR/a9pCC\ngZMek3nS47JCCgjdtNbIhsQmUfHxmS6ctkJj0/BsJecvAHeRPpjMkJ5fW3H+WdLvYQOFLZHKKHSN\nt2w4ahRClxf+X/we0hvJC4DXx88+RJqDBfAI4JdimO4U8Hx3v/2aG3H/uJl9D3AL6c3pf5OqRWsx\nP+tNpL+Lt5nZveK0W4A/zB3LZkwyXzGzXyNNyP8gcI40xPnf4nL3kH4Ha6TQ9Hdx/e8ghZRXxfUd\nJgWSbdKWSItmtkzai/Dq3CVLjVQvu/sZM3s+aeL8H5JaZtxJmot2D42Q1svXVA/nXY/jPkr3QWgP\njTlx15EqdsTtzhXO2yy0rcbtzrQ4Pf/V6jqK5xllxeaxy6QQm60GzVpvzJIe323SohAjVWEPAhfc\n/UwlRysigPZeHHtRHboQk+ulIOZPXQC+hFQxOl/2Y2WNzuvTha/ZJj8zUvVhlZ1bItVis/CYSJ99\n7SEFvjVS+OoU6q4nBYD706huXWhx/rxBrVRsVp2jyc/qEOzeTxpefC9pteqbSHMPbwYeRgrt/xY/\nuwN4DPADcdkN4H3A9wJ/SvrQ8k2kpsO3At85wF5sIpKjStf4yybUX+p0xklhZk8C/oz05v4LwD8B\nZ0iBq/QJ2rmO+8XjyObgFIPXXPx7gFQdmk5nt02uDWNrwFZV8/bidrLb2jKze0jzhfbTYc/GCLj5\nyusq7SfRZ4sYLsRtNgtmnap0tDmtitXbuwlt+fNlTYEfRhoC/0lST7pZUsVzkxSqXgI8F3gnqZ3I\nKeBXSY/1clzX44Cnkiqz7wSeCfx66fdcRK6h0DX+loGTZnZ5RCbUV+EbgDeQ3sg+TOqBda7qx6ew\nF+VVEcaKQWyaVM2YpjEnKquMbZpZdj35MLY56PvU7crGqJAdZmfH+U4ra7dJ1cdBVvg6DaV2c55u\nzrdbU8BjgW8kzeP7YFzvrTTmF76JFKZOkh6zbNj2HI3nmJPaoJyJn/8RKciJSAUUusacu2+b2Trp\nDVvLwAF3f7aZPZc0J+lK9LmqjQgt6xRCSQSXVmFshhRoDrEzjK3T2BYpH8ZKrejFysaDtF7ZmK2e\ny29w3Sl0XWawgSs7jirCdrehrVXVDuCbSfMCP0BjePc5pCa7C7n7kT0Xsl0FLtJ4rkAKXNDYYute\nZd5REWlNoWsyLJMmzip0ATFh/jBpo+SRWbUVVasNmrRMsLQ5eP5rhp1hbJ70Jp2FsWzeWHHD8F7a\nNxSPb8nMtijs2Rjd7LNjyQLEBu3DzritVNxtuNsi9af7/+LrJ0gh7Kvi3ztJz+l/IgXrfyLN98pC\n23l334rfz2XSgoyt6AEnIhVR6JoA7r5qZoet+w2ax1ZUYw4wgAnzw5Rr9rpDTOIvhrF9NELZIXaG\nsWzeWBbG/hF4lru/u8vjWIk39gUzWyQFjazRbb5vWbuJ26uMxorbql0BvgP4HeCHSO0g1kiVrH00\n2pVcIVWzTpGqWOukFh/Zlj8buepuGUOfItIlha7JkU2ovzzsAxmGGJo7QgoYZwYxYb6OcpP4280b\nyybz76PRYuAg6bGaBu5rZg+isJqSFPKumTfm7utmdpbUdHaexv5++debVkOL62jRRzuLpO2efpe0\nkvFO0vyuS8CrgW8jPYZbpAn3byHtjPAXpKa/xRYd49JCQ2QkqGXEhIiKx/Ho3D5RImAcJQUE7dnX\nRmHe2OuAp9B4E8/aEbyANFn7n0n7R36SFMb+Fvg10mTum0gVmV8k9Q97eJzvp0kBYS+pWexLSfOS\n9pFCw/tIK0rvBbwV+FFSKPwQaRjtk3Gox+L2vpw0b2mSLZAWHWTNkI3UJubOYssYM5uhsf/ipeg3\nJyIV0YbXEyIqHpsxn2lixJvMCWBVgaszTzbcfcXdv50Usp7g7gdJnfR/Fvg+Uq+td5LaEWRbKe0h\nVVqeAzyetEr0LcArSKvupkj9ofJv9F8c53sJaf/M7yEFva8GngQ8kjT/6w9IoSvzTaSN0ic5cGXb\nRG2SguxB0ly4PTR2Y1giDSEDEL/bs/HzhdjEvNhoVUQGRKFrsmRDjBMh9lU8SvpEX6sViiPqW4C3\nu/vb4437x0lVqJOkbY02gV+O/3+OtM3Sx0hzi+aAT5D2vcwP7f5GXO5PSXOR3kYKUqdIlayHxPl+\njxS08sfye6Xfw9GRVW+zbaP20egFt0kqWpq7LwMz8eHjqtjQ+nSc94SZHbLc7ukiMhgKXZNlFZid\nhE+2sTHzIVL/rXFaBTdMN5AqX8DV1ZSfBW6Ix9iBT5MmcZ8mVV/uJvWD+mdSz61s5Wi2kfcKjV5l\nK469K2AAACAASURBVDTaGUB6vmb7CX4ovn8U8ADS5uPvLPsOjog9pMdvmcaCgwOk8DVNY0FFFqKW\naCxmuCqqmoukx3ya1M9vX/F8IlIeTaSfILEJ9gqp2tWuE/jIyk2YnwLOTsqE+QHKT/q8i0blKXus\n7wPcbWb7SY/5AqkCs0Z6819098/Em/k98fPTNPZhXCWFgxNx+Wwyf7O5Rr9DGmI8Q5oPNjarT3sw\nTXp+51tqHKAx726GxmM3RaoqLgMHW61ejqkHF8xsFpg3swOk6vAkPr4iA6VK1+S5ws6u4GMjWyxA\n2ij6nAJXKU6RKkuQVsw9wcxujkrij5CCz7+QgpKT3qxPu/slGnsbQhpeXCMFg1VSBQxS+L9AClLZ\neQ+QQthsfGVDY28F/gvw5DiWSTNDClyLNALXFDs/RM3QCKNTcLUiuWNuVzPuvh7DxleAo2Z2JBah\niEhJ9Ac1YeKT7raZzXU88wiJT+nHgeV4w5dy/Azwo2Z2gVRleh5pFePngK8Fnujud8UiBWfnfC3Y\nGbpWcqdngWwPaRL+dHyfdVE/Q6qUZX2+TsRpH4+f/V3Zd7Tm5oiGvuxs/3GQxp6KkF7Tt3L/zyyT\nphZ0HN3IzffaIg05XjM0KSL9UcuICRRDQXPuPhYrv2Loap604XK7ppvShRg2zPp1zZGC0Tox96rX\nBrvxRn+MFKY+n1SVOQKcjbPMkaowK7RvijoL/Hxc7tdIoSzbLmmch8L2ksLVRXY2wM3mdmWP4yyp\nSpj9XV+MifTA1cbA072s4o3q8TypgnZZ8yNFdkdzuibTCmnuxtSoD8Hltpg5N+nd9vsVIWuGRsia\nJoWYNdIb924DzSyNocUpGmHpAClkrcX386T5YK32XDxJqq59LakSlg09HqQxgXyNFlsljah9pOHD\nCzQqWJlD7Ayp2e8tUxzJuAJcZ2Z7ut3uKTffa46d8730tybSB4WuCRQT6ldJL+gjud1KBIUF0iTs\nM8Wu6NJetBDIQtYMjcByeQANM+dIfdK2cm0JFknDwdmQo9NomnqEa6tePwA8G3gVqQs7NKpc2fmy\nOWDjEsIOkB6PC1w7bDtLqnTl91OdYefQ447QFX/3V0iPT09D8FFBPhNV8mPx+rE46h/aRKqm4cUJ\nFXOgDrv7mY5nrpkY8jgKrGv+VndiiC8LWbM0tgZaIz2OA3shMLPrgdPuvm1m/4E0qXuLVMGZJQ2b\n7bgIaf7SFK2rXt3IT8TPh7BsC6M6O0Q65myuXNFRGlXCzHFSW44sCC0XhxJjYvxJ4vfRz4FFcD5E\n+tC25O4j+cFNZBhU6ZpQsT+emdnMKC0Nj7C4QPqUvdzp/JMqgulc7mub9Aa9TBoyrKRCEWFvO3d7\nG6TXna04lmYtIpwUNlpVvbqVVcIyWQibJ1WJNnLnqVMIywJnqzmXe0mPUT5wZRXEDdLvepsm9ymC\n7zKp2tXXPqwR0C/H9cxH9euy5lOKdKZK1wSL+Rkzo7I9Try4HyLtJac943IiZOUnv0OjkrU2rGGg\neI5NZxVJM7sfKXRlw2KzRBPbVldBI4Rc4tp5TbuRDa1mQ3V1CGFHSIEpG1LMvjz3/2OkitZa7rRp\n4IC7n+90A2VUuwrXl62s3CSFrzoFWJFaUeiaYLkX31N1nxNlZodJb47nu50EPM7id5cPWcbOFYa1\neIzM7ChpmGs1vr8XKWTlm/MeodGRvpVsBd9yfA1C2SEsH5Ty/y9+ZactkIZ6W34IihA7W1x5HH3T\niA7zHcXfk7t7X9WuNsd2iPT7Waz7a4rIMGh4cYLFUMMaaYinlkN1MX/kKOmN6eykvpB3aONwpcbV\nheKcrXXSseddJlVvsq2EmlmlscJxLi5TdrDMKoOQQmw2H+wQjVC7mjuWVpWobdKQalfP1QjQx0iL\nDVqGoHgOHKR5VXCG3v6Gl0h7Li6VVQV19yux48UhUn8vTQEQKVDokmUan05rJeYDHaXDm9E4qqCN\nw8DFCsmtwpv6BteGrm1SlesQ7ecZbdOY65VNJO/leeu0rji1rETFqr98ZXE2jiELvRv9/j5iWPgY\nqRrYaVP2Q6S/hWYBO7/9T0exknSFxp6NpYjf9aXcfK+sxYSmA4ig0DXx3H0ttvtoui/bsMQ8kSNM\n0IT5its4VCHb+idvk2tDF6TKy3F2btjcSlZtOkSq/Fwghbl2Q3hdV56aiTCR3W5xeHd/hKcshK13\nE8JyTWM7Psfj+veTOsU3O40+Klb5alepFeS4/+fMbC9wxMw2SM/jWgx7iwyLQpdAqhbsp8/VTGWL\nT8cHGfMJ823aOCwx4DYOFZkj3Ze8bRpNUovB6CxpqPtSk9OuVqTy4SIWV8yTKkWVtS7oMoRl7Smu\n6eKfW4V7qcsu74dIw8jNglV+v8Ve7sNW9Ns6wLW/p1K4+2pMYThACnhXSG0mRv25LdIXTaSX7JPy\nCXe/pwbHMrYT5iNk5edlZW0csurIWDWajP5cOxZpxLDpCVpsKWNmx0nhot2k+uJl9pCqokYK6kN/\n3kQIy8L0HClkZiHMSSGqq22rogJ6lLTa8JoX7NiVYbuL4clm151V25ped5niMbk6J6+X37HIuFDo\nEuDqKrOVYb0QxgvyAukN6cI4fBKuaxuHKkQlZ97dzzY57TCw2awy1SlgdLjNbPXcYt0aduZC2Dxp\nGPUiqcLctBJWuOwx0t9m0yHIOH2p3z5ZZpatmqzkMYvf8eH49tIozE8UKYuGFyWzTBoCqDx05SbM\nr3S75L2OOrRxWKxDBaZCzeZzZVrN68LdN2I4qtOk+maXvRLDZQsxl+hiXR7zWCmcNTD9JKnKmVXC\nDsRp+Tlhm3B1buOeDnO++hpezFkkbe2zXMWHnQhZZy1tVH80ft+Xx/lDiEhGoUuAq3MvDveyGW4Z\nchPmR264YYTbOFRhjtar4rZoVP6auUya/7Pc62MYz92zUfU6YWaX67AQw8wOkuZNns39fa3EV7Eq\nejAXwto1jm3W8b9n7r5pZutxfFXOi1uJkHyQ1GJiifR3M/JVbpFWFLokb4X0wltJtSneiA6Q5m/V\nfoghF7KyN8eRa+NQhXicpmndwqBlpQuuVoWWSENxHTust7iOK1FBORIVlaFVvWLO1RwpcDUNR3Fs\nxRCWbVd0IP5WrqmEsfsqV2aJRhuOykTAWsxaTNAIyt0sLhAZOQpdkrdMLGEf9A2Z2RHS8+9MnYcV\nxrCNQxVmSb2rWlUstujw2hOhab+ZzfU7VymCydkILMeH0awz9zzvtbHvNulx/FwMueYrYYdipHKN\n1C9s10EpbmPDzPYPozIYofNCzAU8HJXKy/ogI+NGE+llh1g9ttjvG10X1z9F+kS9Rao+1OoJGCEr\n3wQza+OQVRhqdbx1FJUdbzc/z8yuY+dQW7PzzAGH3f2a3lR9HNM0jX0NLw266hXVvoX4tueFIREU\nZ7yw3U/u9GxD8+tJFbCs4ppNzO/5/kXgOVLG471b1thndZX0elTbD2YivVDokh3ixW6u1Yv9Lq87\nW5m2XJcJ85PWxqEKEdzbVgJjxd1ip2phrKzb6KcdQovry4a0B1b1isB1lNSNv+fN5K2xJ+qZTuEp\na8tBakmRb1EBfYSw+L0s12F+ZTyOh4gpD3VbkSrSDw0vStEKafuOqTIDR6wmO0z3zSAHok0bh9U4\nNoWsXcjmc3Ux9JoNMXY6X35S/a5/N+6+1GSFY5nP82wfxXV3v9Tn1RwkBZ9OgSvbZslJj+fVzcBz\nlbBZ0nCks3NOWKvrXiRVBIceuuJ+XbZrtxQaSBVepAqqdMk1oo/S1gCqC5VPmO/QxqGvYRhpLYLM\nfndvOwE+nhNT3sWemmZ2iNQ2oeeqURfXu5+SVs5aYx/FvlufxHWcIPUpaxsGoyo9283jUqjozpL6\n4TUNYVGpXKrbZPYYbp4nBczLE746WEaUQpdcIz5BL+x2bkdUPY6QVmCdr6KKFLeZH2bJt3Fo24RS\nds+67I4e4WxfN8PY8Ts9yQC2hYrn+hEacwz7eo5ao7P70m6GwXoZTo0PRxv9DJN2CGEAB939TK/X\nWwVrbBO2Qhp21JuYjAwNL8o1YiWTm9lsv29yuQnzm96kK3lZ1MahduZI3dY76biCMePubmaXSVWO\nUp9L8fw4E1WvrF1BT1Wv3FzFXVXMcos4uq3ozRLDib2KDx+bNIYjsxC2N/5diL+tRWq2e0KsbF0h\nzfc6OYxVqSL9UuiSVrJNsHsOXbk3oStlDVEWrj8fstTGoSYiaO/pMui27dVVFI00DwyqpYG7L8Zc\nryNRhetqfp81Nq7uah/FDuZJz+GOlZsIRN0+1h01CWFLpMrdBqmFQ7bAJJuYP9QQFrd/ydIG2vkW\nE5rvJbWm0CWtrJAm4Fov5ftoRDlPiRPm27RxWEJtHOqk3dY/O0T1ih4XbFwibRuzMojfeZOqV9vn\ncG5xyK6HPeO6pnqolGUfNgYi65NGmtB/ISphc6RKWG1CWITFc9nvwsw2qaAliEi/FLqkKU9dwdeA\nfXQ5hBFvVvuAc7uZO9WkjcMW6cV9mZJXm0mpZumtMrpJdysYgavD3qv0sS9jL3JVr4X4EHFN1SvX\nR6qsxSHzpFDZrbI60bezRLqPa7lK2BW4+jfaLIQNpdVKhOPVWKBxIlY8ar6X1I4m0ktL2WqhThNq\ncxPmp0if+nt6wW3SxiE/qXfoQxnSHTM7SQohXQVuS93a13qZBxVDmCfYZbDv8rayPlFZ8FqNnx8g\nrcY9V0ZFJQLcPndvucdik8v0/Nj1I36nF7vop5aFsHw1Or86srK/4XiOZFsvab6X1IoqXdKSu69Z\nMtPs07yZPRZ4I/ClpFVUXb1pxItifoVhvo3DooYGRk8EZ+sxCHU9mT7jjX0ZD9NmI+gy5PpE5ed6\nbdNhH8Ve5IJdr3tMzpIqUYO2SIdNt2HHnLCsEpZNCdhPeuwqC2Fx3RfjGA5HqNV8T6mFqWEfgNRe\nNqG+mWnSc2i5Xa+gCG57zWzezE6Qlv/vI71In3f3U9E64JHA7aUevVSl16FF6HEyfSZaMkxFCBq4\neLM+Q2pTcCPlbktzkFSx6nqoMILaVBXtT6KSticWDPRyuQ13v+Lu5939HtKKzE3Sa8lJMzsRrwd7\n40NY6eIYzpKC4IKZLcSHA5GhUaVrQpnZdKcX7RgyWKGxlN5zp+0jfQLeLvYlatHGYT2+mrZxiNuS\n0dX1JPqcTdIwXT8ukSooaxXN28m6tJ9m5wrHvm87wsYBUqDrxSyDn8+Vt0QKh71W466Kv/mN/7+9\ne4+y86zuO/7dI2l0mxndbWMT29xZLCDQAsElJCzSmgA2tKSmQG1qYjCQFtbi0oSAF5gApWlDCIEs\nCASwsZsACRAIGIghmItxCNAYFwwEc7Fsy7YkS9bMaCRZo9n9Y+939OronDm3931nRvp91ppl6Vze\n9z0z8jl79rOfvTk2E7aaYzNh5cL8yn6mufP1IPEatuWOx2nVe8liUKZrGTOzX5jZa83sJjObMrMP\nmtmpZvZ5M9tnZtdm7QdmdraZzZnZb5vZrcCX2hzvKWZ2u5n9rpndCXyQyES8CbjdzO4ws3dazGeb\nL2Y2s983s115PZcCp+b9o8DrgW8BNwP/O4/X7lx/CVwDnJ6vZdJirpwsD4MEXX0vLxYy+3SYwYO2\nnmSWdnOe855S1suJjM3qBQ+wsHF6GPfTRhNF9POyJmpVBkpVHfOwu0+3ZMLmiCDs1JZMmFVwPveY\nErCL+Dd3Sv7iKNIoBV3LmwPPAX4DeBhwHvB54HXEEt4I8MqW5/wa8HDgaR2OeSrRd+hM4KXAZcBj\ngKcAvwz8mzz+XuLN/zTgl4BHAS8D/pgovt+dz31gPu/BxNLMGzuc64XA04Ed7j7u7hP5ZixLXLFk\n02/wUCzRDfGhOgmM1bVkZEfnKB7xUuf8/ADfR/w/sMHMNvT7GjKzu4aomepXo0FXKrJdtegjCFs9\nTBDm7sXPci+w3sy2VhlMinSjoGv5e7e773L3HcDXgRvc/XvZJPBTwGNbHn+5ux9YoIngHPCmfBM8\nCLwAeDNH33TfDfwnjo73AXiNu9/l7l8APgc8N98YXwK82t3v9WiS+nbgeQuca+jfaGVRDJLlKgyT\n7TpCLFdNDHjujqyHwdWlrBfEslU/Wa9xBl/iGqR+blgzwGhTZQALBGFjRBC2dZggzN3vy18MZ4je\nbxvrqi0TKVMdzfJ3d+nPB1r+XtQxlN3W5Xi7Wnb5nA7cSoxf2QL8P+BUd9+VtRF7W7at3wrcD9hK\n/Jb63dJ7onFsoN96LlmeVhP/1gZR9OoaNHMzTQQ8A4+samVHB1fPeJeJChk07cuAa2PWDi3YVT6L\n0ld5D3Mn2zx3hNgl2ugOX3f33DU6TmSJGlWqCZuGY6ZSjBFLn7Mcuzuyp2DW3Wfs2JFC091+5iLD\nUGR/4un2W1+3N6PW+3cAZ+dvnncRS4I7Svdvyi3ZhbPy/t1EEPgId9+UXxvdvZyVaD2XCluXp9UM\nnnkZaAdjoWjrQLSQGFpmcrYSWaieP3wzc7yT+P9vW5fdfhMMtqwIsbS4WL+oNJrtWkhmqqazzu4u\n4t/AQJmwXC6eJLKWo2Z2SlM7Y+Xko6BLuvkr4LJ8E9tK1GRd1fKYN5vZKjN7MvBM4K/zw/ADwJ9k\nmwjM7AwzO3eBc90NbDGzypeLpB75ATw3ROZl4OXFQi5Nz7UE/33LQGkLsSux74aa+eF9L7GzclO7\nWq/8MDcfvKlp0zsX5+X/0/upsbZrUB2CMOfYIGy8XRBmZteZ2SVZ77WH+PmNm9mWdgGmmZ2Zm30a\nLYcorrPJc0r1FHSdeLzlz61/7+f5AG8FvgPclF/fyduKx95JLDfsIIKxl7r7v+T9vwfcAvyjme0D\nrgUe2ulc7v4jIsj7mZnt0e7FZWGYei4YMtNVUnxQDvSelsuDxeDqoWaGdsl6TTDcCKPFKKIv2w+s\nqWvzQlUyCJvyaNh8N0e/58cFYbS8T7r7IY8pHAeIXwI3lP9dufv23Oyz4PupmV1sZl+v8mWh1YBl\nT2OARGRg2U5hZtBAJT+8t7r73V0f3P1YGwA6Fb4v8LxiSHtVcxTLxy6GYh8gsnqrM5sy6PFOA3b6\nIo7GspixOtLv97kp1qUHYWaoij5ho8BngI8BHyZ+gThcBFT52GIU1DRH51D2ch0XA5e4+5MHfzXH\nHO8rwFXu/qEhj2Mwn7mUhinTJSLDGGonXS5LjlS0VDNJZGF6Xq60mKM4QcxRrDyDlMHoLuK99mwi\n+BpIBqi+mAFX2g+srXO3n1XcgzAf92wzu5HYCXkzcE5mwu4jalX/nhh39A9m9uAMLh+cjz8f+BHw\nVTN7SJ5vJI97sZn91KK34M/M7AVm9nDgfcA5ef178rEbzOwjZrYzX+Mbin/7eZzrzezdZnavmf3Q\nzJ7a8jLONrNv5Lm+aNEzsXh9TzSzb5rZXjO70cx+vXTfdWb2VjO7nvj5PWCoH5AMTEGXiAzEor/R\nkQqCgEqWGPM39yl6LKrPD9X1xBzF2kbq5PfnCLG5ZMKiwHuQIHMxi+jn5euZod7arkp7EJrZE4Ar\nifY2G/KxtxZ3E21wLiKGqQNcmv8tXuNvEDNmz+doi5KRDNrfBfxmbhI6B7gxSyVeSrTwGXf3zfmc\ndxOZswcAv070J3xR6VKfQJRkbCGaUn+yCC7zOl8AXJzfg1Hgtfn6zgA+C/yBu2/K2z9RDsqAC4EX\n52va3vo9kmYo6BKRQQ1bz1UYupi+kAXwXecy5lLkGiLgqrX9gh0d97ObyHqtAAZpyrloRfRtTAPr\n6sx2UW0PwkuAD7r7lwHcfYe7/zjvc+BD7n5LZiY/DjzKo4N90R7jTURblBGOfm6eDWwmdk0+yszW\nesyRvTnvby3YX0EEd7/vMZfyVuAdRLBX2Onu78qi/o8DPyYCzk7X+Zi870LgGo9eibj7l4j622eW\nnnuFu//Q3efq/CVDFqagS0QGNUyriLKqiukL+4iMUttsUmYOVhIBVxNLdRPA/vwgncv+XFNEU87x\nPo6z2EX08/L7doB6s11V9iC8P/DTBe4vT79o97p+moX5ReAMmbkkArqXATvM7LNm9rAO59hK/Axv\nLd22nZjUUbij5TlF38Nu13kWcEEuLe41s73Ak4iJIYVuPRqlAQq6RGRQq6gm01U0SK2EH53LeMwH\np4XNxPveniYKibO+bDXZ1LN0jUWt10qLETe9ZL2WTNCVmsh2lQ3Tg/A2oj5rUO2OfYgIvD7t7ucS\nAc6PiFY57Z6zm/j5nV267Uzg9tLfywEYHO172M12osh+U+lr3N3/V5fXIA1T0CUifcs2CLMVBS6V\nLS+WTBKz9YoB60YuBXmMlmnqA2iCDuN+SlmvabpkvexoP7TFLqKfl8uyB6h56HhFPgi8yMyeamYj\nFj0DyxmpQWrsNhAZ2vOytuswUaReLFffDdy/CKjz+/Vx4G1mNmZmZwGvAq4uHfMUM3ulRd/DC4ga\ntWt6uM6rgfPN7FwzW2ExKPwpWes1zGuUiinoEpFBVFXPBdUvLxYfcNPEMuMIsbRzOJuXNiID05Xu\nvn+hx2Wj1F3EOJtOWa+lluUqTBPBbRMf6AP3IHT3bxMF6+8kdiNeR2SZBjn2SN5WzIN8FbEseA/w\nZODl+bgvAz8A7jKznXnbK4jA7GdEndr/IVpVFL4FPIT49/AW4Lf82HFRba/T3W8Hng28nugRtx14\nDccGWsp0LQHq0yUifctdUdMdipYHOd793P3OKo7VctzTiIBunzc8U89igsN0Pz3M7GjPsJks5C5u\n30BkFhcM4BZD1sjNNv39XQwZXG4lfj6V/iys4r5esjQp0yUifckPnqrbFxyximf65fGKbFPTAdda\nmK/d6lmbrFfxPVmqmS5oNtu12DYTDVKXXPAry4OCLhHp1yilrt0VqXSJMZfothABzHTW3DRpnAHH\n/WSt1x5iGWqLmY0RNW9LMujK9gP3AUPNvlzqMqM35zEcuw4a83MS0PKiiPTFYiC5l5e/KjhmZctn\nFvP0NhJzFA9ltmgLsKuJQvQM8IYa91M61gpiOWsj0bZgSfZXKn2Pd56I42Vyk8NqYnLBCff6pDnK\ndIlIv0aproi+UEmmK5uibgT2FvVmGagcILJPtcoltjGGG2o9LzcETOXxtmbWa8k5kbNduVS8loba\njMiJTUGXiPQsg4qV2QurSkO3jTCzdcQ2/nvaXN8UMZex3y7w/RoHDlackVpFNHzdBaw2s61V179V\nZJp6m6U2LnegFsPQl0y7Dlm+FHSJSD+q6kLfaqgGqZkBGqPDHMV+5zIOeA0riExPZcuuqaihO5ID\nmmeIrNeS6o+VA8MPZ/C77GVgu4nImi7JZV1ZfhR0iUg/Rqkn6DrCgMuLWWO2li5zFHMu4/zOwhqM\nE+N+KsuIZGZxRQY0wPzr2EVk7rYWDWCXiBMi25W93TYDkzVkdeUkpqBLRPpRZVPUeZmJmus3gMgd\nZaP0PkdxwbmMg8ply+PG/VRgFZEFPEYp63UA2LZUsl4ZoBypMbCtXWl6wUy28BCpjIIuEelJ/vZ/\nTNalYn0V05vZJuI9rOcdZXnth6g+GzMBTNVQaL1gf67c7bkLWGtmW5ZI1muKBjYt1OikafYqzVPQ\nJSK9qqueq9BTXVcOrt4CMOAcxWPmMg4rW1SsKJYvK9a1CW1mvXYDB4ms16LWVGW2ay53ki4ruVQ9\n0uS4KDm5KOgSkV7V0SqirOsOxsy2bSEyEXsXemwnuQw5TXVF9RNU1CKijVF6bIqaWa/dwLolkPVa\ndtmuor8aMHR/NZFOFHSJSK9qqecqWXB5MYOILcQYln3DnCiXjlZmlmpgWbvk/Y776fHYRmRdet45\n5+6zmfU6ROxwXJSsV/ZI8+WS7crrHEO9uKRmCrpEpKsMeKzmrfMdM12ljufHDIIe0j6GyHZlUDSR\nx6lDz1muVhlU3kNkvTYvUtZrWexkzE0QG4iAq+PuV5EqKOgSkV7U1SqirG2mqzRHcarKQcOZjZkd\nYuffeuC+GjcWDDXkupT1uo/IejW6ozCzfzZsNrFOGYxuBvbV+HMUmaegS0R6UffSYtE2wrNuC5jv\nCF58KNaxfX8SGC+fsxf5+PXUV8sFQwZdhVLWayyzXk2+70+zRGu7Sq0hputYHhZpR0GXiPSi9qAr\nzS8xZp1N0RG8lg/FXC6dIZYJ+zFGjPupczmqsuxiZr12EUHctqayXhkoj2TwvNRsJuoDK8ueinSj\noEtEFlTUAzVU7zILrMigoKizqXtZc4qYadjTXMYax/2UzzFC1NBV+j3Perg9NJv1WnI7GbOp7py7\n15mpFDmOgi4R6aapLBdEpmsiv+5pos4mlzUn6b2ofoJYkqpzAHLX/lyDcvfDTWa9Mtu1Yqlku8xs\nnMimqheXNE5Bl4h002TQtYYIatoOrq5LUS/WLQDJbNgoUPeS1MA7F3vVkvXaVHPWa0nsZMyf71rU\nGkIWiYIuEemmiZ2LmNkGYvfivYu0db+XuYx1jftpVUkRfTelrNcRIutVS1+t7Na/qtcl3Dpkpm2C\nCLjqzFKKdKSgS0Q6yv5YXncQlHMUVwI76WP+YpVKcxnb1h9l64ORmsb9tGok0C1kbdMeIuisK+u1\naNmu/HdcbMpoLIMq0kpBl4gspNalxZyjuJkoGr+nyEB0yTbVaZJoKNquSWud437mZaG+N52NyaCz\nzqzXDDDa4XtbmwwgNwOTDWzKEFmQgi4RWUhtQVcGVluIXWTleXc9Db6uQwY6U7S0kMhxOnPZULVu\ntRXRd+NhEthLZL02VhUA55LsfhrcyVjqxXWgpj5vIn1R0CUiC6llmSuzD1uJju6tu8i6Dr6uU/Zt\nmp/LmB/c4zSQ5Uq1F9F3kxmhXcAccEqFXeX302y2ayMxHL229h4i/VDQJSJtZdHzkaqXuXL5bCuR\nfWgXyCw4+Loh5bmMdY/7adVIEX03LVmvDVVkvUrZrtpru8xsgqjBU2sIWTIUdIlIJ5UvLWaGBYzs\nFgAAFiRJREFUYyvR52q6w8MWNdMFx8xlHCcChCabaC7a8mI7payXU03Waz+wps4h3DlPczWxOUBk\nyVDQJSKdVLq0WBpcPdllB+Ci1XS12AecRmTkGmlhkUHp3FLrIZVZr31EQ9ENZrZh0KxX3dmu3AAw\nhnpxyRKkoEtEOhmlokxXZkc2Ez24uhU0L4XlRQAjapqafJ9cEkuLnWQGcFf+ddsQWa/9wNqqs10Z\n2Bfjoxaj15vIghR0ichxspHkbBWZguwCvpH4IOwaxGUN2cgito0ojAN3E4XfTTX1bLQ/1yBKWa99\nwMZBsl75M54h6uUqkQHcZmBfg/V3In1R0CUi7VRSz5WtFgaZo7io2a4MOotxP/3MZRzWks50lWUA\nvZPICG4bYLbiNNETbejPoVJriGl3Pzjs8UTqoqBLRNoZOuNiZmNEbc0gcxQXu65rgqg989JcxnUN\nnHfZBF0wn/W6l8h6beon65XZrgNUU9u1GTiU7T5EliwFXSJyjPzQHGoHXW7XX0sEXIPU1izaDsYs\nxLaW2rN9wHidS565hFnJkm7Thsh6DZ3tMrONcQlt24+ILCkKukSk1ShweNAP//wQHCUCrkF7fC3m\n8uJx435yafQg9XZTX1ZZrlalrNckkfXqNjycDMgPMGBtV2ZTVxK9xESWPAVdItJqNQNmuXKO4ghR\nwzVMxmZRMl25hDjboeB/ithxV9d1Lfki+l5kTdUuImje1sMmhGlgfb9ZxNygsQ61hpBlREGXiLTq\nu1VEDq7eQiQ8qvgQbDzTVRr303ZkTGbtpqmvqH5ZZ7rK3H3O3fcSWa/Nudzc6bFHiCxiz9muXL6c\nIAKuRgeDiwxDQZeIzMvAY2V2Ie/1OSNE09PZ/KAdWn4QN728OEYUY3cMfLJQeyTrvipT+r6fEEFX\noZz1MrOFsl49Z7sy07gJ2DvABg2RRaWgS0TK+lpaLM1RPJS9m6p0pKnByBk4rqdDlqvFJJFlqdIJ\nk+VqVcp6TRFZr+Pq4jJ4uo9YLuwof06biZ2ly34pVk4+CrpEpKznuqLSHMX97t5LsNKvJpcYx4GZ\nXnZaZr3X4SzirsoJG3QVSlmvlR2yXlPAWKdsV6kX14EephqILEkKukSkrKemqC1zFOvqjdRIMX0G\nj2voLctVmCQChKqCwiU15LoupazXNC1Zrx6yXZcD76giwDezK8zsLcMeR6RfS2GorIgsAbl0s6Jb\nXVEWMW8ixq3U2f27qQapE0Qn856L/939iJntz+dWUcc2SgQiJwV3P2Bmh4gxQts4Wp81TWSzjgnk\nsxD/T939nqouIb9EGqVMl4gUui4tZgF5UcRc97iV2pcXM4BcOWC2bpqYy9jv+JvWazBgZLkXhfdb\nf5dZrz3E93GLmY1lwH+43P3fzNYTGdg9lV5wNHIVaZSCLhEpLLi0mB+EG4ht+k0shTWxvDhBf8uK\n8zIzto/hW0iMskzruczsF2b2u2Z2EzBlZiNm9kQz+6aZ7TWzG83s10uPf4CZfc3MJs3sWjP7M+D9\nRK3XqJn9DnAjcJuZXWZmvwB+kwi43mRmV5WO1fE8ba7zsWb2f/O8HyWWk0Uap6BLRAodg67MNozR\n/+DqgWXmp7ZMVzbXZJii7Mz2zQ05l3G5F9E/D3g6sBG4H/BZ4A/cfRPwWuAT2cMN4C+BfySWEC8H\nLiTi1zngNOAPgZcDjyc2aZxO1A0eobQcaGZndDjP1taLy0zk3wJXElnavwZ+Cy0vyiJQ0CUiResH\na7fElcXO64iAq+klsCMVFqu3Gqdl3M+Ahp3LuJyDLidqre7IXZ0XAte4+xcA3P1LwHeAZ5rZmcDj\ngDe6+6y7Xw98pnSs/5h//wIwA1yRxy92lJa/v53O84w21/hEYgn5Xe5+xN0/AXx7+Jcu0j8FXSIC\nHeq5zGwDkQG7Z8DB1cOqZYkxM3ezVSyTZiB6kMF7dy338T+3lf58FnBBLvntNbO9wJOILNbpxNJ0\nuRbw9tKfTwduz8DoLne/EehUOL/QeVqdDtzRctutqKZLFoF2L4oItFlaNLNNVDNHcRiVLzFmRmqM\nzh/og5gi5gzu7ycbmDtGbZEC2qqU/21sB65y90tbH2RmZxFtItaWlnR/CSjG+OwAHlZ6/FqiLUk7\nHc/Txp3AGS23nQXc0sNzRSqlTJeIQCnoyjmKmwHcfTEDLqgn0zUGHKxyqTRrkqbov6j+ROvPdTVw\nvpmda2YrzGyNmT3FzM5w91uJJcDLzWyVmZ0DnFd67ifyuedkHdbldM5GdTxPm8d+E5g1s1fmeZ9D\n1IyJNE5Bl8hJJHebPbXlthUw33vKiOxC0cRysVWa6crX2uu4n764+wz9z2VctjsX23H324FnA68H\ndhIZqddw9LPmPwPnEFnGtwAfI4NOd/8B8Argo0TWayqPUWRg53tr9XCe8jUdBp4DXJznfS4R4Ik0\nzhb3l1gRaZKZ/Rx4sbt/uXTbOuLDf5IIuA65+3EF5kWheJOZr2K4sbvvquh4G4EjNY0tKnbKbQR2\n9fJ9yoziTAM9z5YkM/sYcLO7v7nNfWNE49kHZ5ZMZNlTpktkmcls1evM7AdmtsfMPmRmq0v3n5d9\ni/aa2fVm9qi8/SrgTODvzGzKzF6bT3kSsWNsD/Bl4LGlY11nZm81s+uJLuEP6HA9rzGz75nZvWb2\n0fL1DKmy5cUM4FZTY+f3LMw/TCxh9mK5F9H3xcweZ2YPyn5eTweeRbRzKO4/38zW5UaHPwJuUsAl\nJxIFXSLL0wuAc4EHAQ8FLoNoAgl8EHgJ0Qvpz4HPmNkqd7+IWIY5z93H3f2PsgbmY8C7iF1er+bY\nvkoQ2/NfTAQS29tciwMXAE8jgrJHE0s5Q8ts0VwWnA+r73E/A5oE1ndrdZH3Fz2qThanAV8hlg7f\nCbzM3b9Xuv9ZxE7DO4h/289r/ApFaqSgS2T5ceA92RtpL/A24Pl536XAn7v7tz18hKiJeWKHY10E\n3EB8EI4A3wC+y9ECZweucPcf5tiWTsXnf5rb/PcCfwc8ZsjXWDZ0tiszb4OO++lL7kScpnsLiROt\niL4rd/+su5/p7uvd/eHufmXL/S9x903uvtHd/527/2SxrlWkDmoZIbI8lXsjbSeyVBBb4V9oZq8o\n3b+qdH+rM4GnAj/m6Nb/lcC3zOx++dw9WQs1SwRAR4i6qHKbg7tKfz6wwPkGUQy+HiZAmaCaRqi9\n2k+0kBhdoBfYCVVELyLdKegSWZ7ObPlz0fxxO/A2d/8fHZ7XurS2HbgKeBkRmKwmxq4cyML5ovHn\nfcQuwtX535W55DdHZMjWZ+f6I/l3MzOraClvqB2M2e/JmyxWd3c3s0mihUSnTQCrqLG+TESWHi0v\niiw/BvyOmZ2Ru9/eQNRlAXwAeJmZPSH7ba03s2fmTjCAu4lamcLVwPnAvyXqbPYD55rZI4lfypzI\nas24+5S735u9u+529zuB3UTgdTgfu4oIzEaB08zsVDPbamabzGwir2dN9kvqtSP4sMuLVY376Utp\nLuP6Dg856ZYXRU52CrpElh8nBgf/PfBT4CfAWwHc/btEEf17iN2IPwFeWHru24HLcmfjq9v0O/oZ\nUTR/kCjEXzDYKS0x3ufu0+6+j5ibdzCDsl3EbMIDHA2e1hFtFU41s9PMbJuZbTazDWY2ZmZrMygr\n3p8GznRlwHO4inE/A9oHjLVuBMidlHOL3HhWRBqmPl0iy0z22rrE3f+h5vMU43LWExmwynf+5TlW\nEMHYijZfI0SwtoUY53KEUm3ZQuNzMtDZxuIM6i5fxwTxXruvdNtaYM0SaUArIg1RTZeItJUB1pSZ\nzRD1XqeY2WRpbl5V55jNr+OUgrI1xBLmCEfrylZk24U5jhb4l4v911HxuJ9+mdkVxKaH95jZTHZH\nh4r6c5nZ5cCDsh2IiCxxCrpEZEGZTdqb3dYncsluXymAqPPcTszNmyGWMI87ZwZe5a9VRMB1al73\nWo4PyMq7MCvpk2VmFxMZyCeXX0J+TRGBazFkexWx5DosLVWILCMKukSWGXc/rit8Q+e9D9idY4M2\nm9khYqdjE809i3qw44KuDAqPWWbMFhe3uvt0LjOWg7KiM32RLSuO3+5rtpfXlzVaHbn7TG4iWJuZ\nwlXtXkuXc6xos5za62YEEVkCVEgvIn3Jwc47iWW9U0o7I+tU9OrqysyKHZT7AbKp62F3P+ju+919\nn7vvcfdd7n4XsaNzbz5+lnhfXEN0+f9pjkz6kZldZGYbzWzczC41s2+a2TvNbDcxpPm9wDn5+D2l\nS9psZp8lNj18w8wemuc5y8yO6bafY5cuyT9fnGOc/jjP8aY2L9eBUTO70swmzez7Zvave/2mikiz\nFHSJSN+y2/0ksTtxlZmdYmZrajxlPzsYJ4CpXov+87XMuvuhDMoms8D9JuAcdx8nAp73ErsuIQLA\nxxNNYR9NjE96LfBt4Azg/tkFf4QYZXM5sAm4BfifdM5yFcuRhScQwdopQLvea0aMzvkroifYZ4id\nqyKyBCnoEpGBufuRDFDuBcbNbEu3pbYB9dSrqwh0Mhs3FHf/m8yE4e4fI9pvPNrdp4i2GDvc/Q/d\nfQfRnPYgkf2bI5YP1xMF858HbidacHyKGCjeaxH9Dnf/s8zWdWru+nV3/0IGmVcDvzzAyxWRBijo\nEpGhuft97r6LKA7fkj23qnx/6TXTNUEUrQ/NzF5oZv+cPc32Ao8kWlcU5kcxlerK5op+Ze6+hwjE\nbsv/rsrHjPYRFN7W/SHcXfrzDLCm4u+9iFRE/2OKSGVK9V5OzB7s1I293+POkaOFOj0mC/wXygj1\nzMzOAt4P/Fdgs7tvAr7PsYXrrcuXns9dYWbrclrAWo7OWNxJLMcWhfnF8O11pWOc1u6YC9DuRZFl\nREGXiFSqVO91D7A6671WV3DojkuMGYxVOe5nPRHQ7AZGzOxFRKarrWynMUnMwTyNCLRmiAzXgawV\nO6ZfWGYG7wAuykDttzl2RFMvtHtRZBlR0CUitcji9D3EKJyJHPUzTL3XQkuM6+nQx2sQ7n4z8A7g\nBqJY/pHAN1oeZjlT8jRiWfMrRDbsJuBfMuPWWhhPy99fAvx3Irh7BHB9y+N6yXQtdHwRWUI0BkhE\nGpFLjWNE9mey35FCOU5nzt2nW24fIXb37VpoLNCwshXFmvxaARwiXsuhhnqVicgyp6BLRBqTAdI4\nEbhMu/v+Lk8pP3cdsKo8wzBv30Csala1tFgc1/I6V+fXHEeDrMUaoC0iy5g60otIYzIjtM/M9gMb\nMpCadPdDPTx9lihMn5cjgNYSRepDy+XPIpu1kmjtcJDo+1VbFk1ETg4KukSkcVlUfk82VN1gZrPE\nPMeFApt2hfQTRMZsoOW9zGYVmaw1RD1UEWT1EgiKiPRMhfQiUpkcXfP1Xh+fo3l2EvVR28xsolNb\niAzIRor7s8ZqlKOtF3q6ptwpuN7MthBDsdcTWbTd7r4zO9J3DLjM7Bozu6jX1ygiUlCmS0QWnbvv\nN7MDRL3XKWY21aGB6BGiiH2WGHvTa0G+ZSH+GqLNwkEiWDvUb0G/uz+jn8eLiBQUdInIklCq95oh\nWkysJ5Ycy0Xrs8DKrL0ydz/Q7lhZ61UsGW4gArU5YE9rv6yFmNmIdiaKSFW0vCgifTGz15nZLWY2\naWY/MLN/v8BjH25m15rZPWb2IzO7IG9/UN722Pz76Wa2y8x+LXttPQv4GlH39XMze2kechZ4CvAz\n4GIzu9vMduQS4qiZjZvZQ4FrgDuBLwBbgdkczzPb6ZryOq4ws/fmEuJ0nqv1NV1nZpcM/Y0UkZOO\nMl0i0q9bgF9197vM7LnA1Wb2IHcvzwAs+nJdC1wGPA14NHCtmX3f3X9oZr+Xz30c8GHgw+7+tXz6\n3cAzgF8A5wKfMrPvAzcSY3O2ET2/HpiPuxL4KtFk9C3AXqIz/AOBLxJBWtdrynM/H3i6u9/QoZN+\nL01LRUSOo0yXiPTF3f/G3e/KP38c+AnwK20eeh7wc3e/0t3n3P1G4JPABfncvyACuH8iCtrfUDrH\nNe7+8xwp9EUicPpVYDORuToMvI8opP8cMeR6GzF65z8Ab3T3A+7+AyIgK4rzF7ym9LfufkNeh3Yw\nikhllOkSkb6Y2QuBVwFn501jwJY2Dz0L+BUz21u6bSXwkdLf/wL4NPCS8ggfM3s68CbgIcQvh+uI\n8Tp3AduBe9z9ztLjZ/I6tuU5biudY3sf1+TA7R1euojIUBR0iUjPzOws4P3AU4Eb3N3N7J9pP3h5\nO/BVdz+3w7HGgD8hAq83m9kn3X1vLul9ArgQ+LS7HzGzTxGF84fN7OACl7iLqPs6E/hx3nZmr9ck\nIlInLS+KSD/WE9mg3UTPrBcRw6Db+RzwUDO70MxW5dfjzezhef+7gH9y90vzse/L20fzazcwl1mv\nnoKk7OX1SeByM1trZo8A/gtHa7C6XVPbHmEiIlVQ0CUiPXP3m4F3ADcQS32PBL5Rfkh+4e5TRLD0\nPOAOYjfh24HVZvbsvO/l+bxXA//KzJ6fz3sl8HFgD1HY/unWS1ngMv8bsdR4F/Ch/Cquv9M1jbZe\nv4hI1TTwWkSkD2b2VeAD7n71Yl+LiCwvynSJiPQoB3Q/EPj5Yl+LiCw/CrpERHpgZqcQy5HXufv1\ni309IrL8aHlRREREpAHKdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiI\nSAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGX\niIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0\nQEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImI\niIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMU\ndImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiI\nSAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGX\niIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0\nQEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImI\niIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMU\ndImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiI\nSAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg0QEGX\niIiISAMUdImIiIg0QEGXiIiISAMUdImIiIg04P8D0pWkhR9T36YAAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x10a8a2198>"
]
}
],
"prompt_number": 32
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"Sentence Level Parsing"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following block of code can substituted where the text is parsed in order to look at sentence level co-occurance instead of paragraph level. The PunktParameters are set to prevent the accidental parsing of text where abbreviations occur."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#tokenize the text as sentences, set abbreviation parameters\n",
"punkt_param = PunktParameters()\n",
"punkt_param.abbrev_types = set(['dr', 'mr', 'mrs', 'prof', 'st', 'ft'])\n",
"tokenizer = nltk.tokenize.punkt.PunktSentenceTokenizer(punkt_param)\n",
"textSentences = tokenizer.tokenize(textString, realign_boundaries = True)"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"The following section are scripts that can be used for validating your results"
]
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Split text into paragraphs for validation"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"textDir = \"NLMGText\"\n",
"textDirDict = {}\n",
"textDictCount = 0\n",
"\n",
"for filename in os.listdir(textDir):\n",
" textDirDict[textDictCount] = (textDir + \"/\" + filename)\n",
" textDictCount = textDictCount + 1\n",
" \n",
" directory = filename\n",
" if not os.path.exists(directory):\n",
" os.makedirs(directory)\n",
"\n",
" f = open(\"NLMGText/\" + filename, \"r\")\n",
" textString = f.read()\n",
" f.close()\n",
" \n",
" textParagraphs = textString.split(\"\\n\")\n",
" textParagraphs\n",
"\n",
" paraCount = 0\n",
" for para in textParagraphs:\n",
" f = open(filename + \"/\" + str(paraCount) + \".txt\", \"w\")\n",
" f.write(para)\n",
" f.close()\n",
" paraCount = paraCount + 1"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 24
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"The following lines can be used for viewing the entirety of the dictionaries of edge lists for the purposes of validation"
]
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Check hit dictionary"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"hitDict['0']"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 26,
"text": [
"[[0, 6, 'kathy h', '5'],\n",
" [0, 6, 'kathy', '5'],\n",
" [0, 6, 'narrator', '5'],\n",
" [0, 8, 'kathy h', '5'],\n",
" [0, 8, 'kathy', '5'],\n",
" [0, 8, 'narrator', '5'],\n",
" [0, 10, 'tommy', '8'],\n",
" [0, 10, 'ruth', '13'],\n",
" [0, 10, 'narrator', '5'],\n",
" [0, 12, 'narrator', '5'],\n",
" [0, 14, 'ruth', '13'],\n",
" [0, 14, 'narrator', '5'],\n",
" [0, 16, 'narrator', '5'],\n",
" [0, 18, 'tommy', '8'],\n",
" [0, 18, 'ruth', '13'],\n",
" [0, 18, 'narrator', '5'],\n",
" [0, 24, 'narrator', '5'],\n",
" [0, 26, 'narrator', '5'],\n",
" [0, 28, 'ruth', '13'],\n",
" [0, 28, 'narrator', '5'],\n",
" [0, 30, 'jenny b', '24'],\n",
" [0, 32, 'narrator', '5'],\n",
" [0, 34, 'ruth', '13'],\n",
" [0, 36, 'tommy', '8'],\n",
" [0, 36, 'ruth', '13'],\n",
" [0, 36, 'narrator', '5'],\n",
" [0, 38, 'tommy', '8'],\n",
" [0, 38, 'ruth', '13'],\n",
" [0, 38, 'narrator', '5'],\n",
" [0, 40, 'tommy', '8'],\n",
" [0, 40, 'narrator', '5'],\n",
" [0, 42, 'tommy', '8'],\n",
" [0, 42, 'laura', '1'],\n",
" [0, 42, 'ruth', '13'],\n",
" [0, 42, 'narrator', '5'],\n",
" [0, 44, 'tommy', '8'],\n",
" [0, 46, 'narrator', '5'],\n",
" [0, 48, 'tommy', '8'],\n",
" [0, 50, 'tommy', '8'],\n",
" [0, 50, 'laura', '1'],\n",
" [0, 50, 'ruth', '13'],\n",
" [0, 50, 'narrator', '5'],\n",
" [0, 54, 'tommy', '8'],\n",
" [0, 56, 'tommy', '8'],\n",
" [0, 58, 'tommy', '8'],\n",
" [0, 58, 'laura', '1'],\n",
" [0, 58, 'narrator', '5'],\n",
" [0, 60, 'ruth', '13'],\n",
" [0, 62, 'tommy', '8'],\n",
" [0, 62, 'hannah', '14'],\n",
" [0, 64, 'tommy', '8'],\n",
" [0, 64, 'ruth', '13'],\n",
" [0, 64, 'narrator', '5'],\n",
" [0, 66, 'tommy', '8'],\n",
" [0, 66, 'ruth', '13'],\n",
" [0, 66, 'narrator', '5'],\n",
" [0, 68, 'tommy', '8'],\n",
" [0, 68, 'narrator', '5'],\n",
" [0, 70, 'narrator', '5'],\n",
" [0, 72, 'tommy', '8'],\n",
" [0, 72, 'narrator', '5'],\n",
" [0, 74, 'tommy', '8'],\n",
" [0, 74, 'narrator', '5'],\n",
" [0, 76, 'narrator', '5'],\n",
" [0, 78, 'narrator', '5'],\n",
" [0, 82, 'narrator', '5'],\n",
" [0, 84, 'ruth', '13'],\n",
" [0, 84, 'narrator', '5'],\n",
" [0, 95, 'tommy', '8'],\n",
" [0, 95, 'narrator', '5'],\n",
" [0, 97, 'kath', '5'],\n",
" [0, 97, 'narrator', '5'],\n",
" [0, 99, 'tommy', '8'],\n",
" [0, 99, 'narrator', '5'],\n",
" [0, 101, 'narrator', '5'],\n",
" [0, 103, 'kath', '5'],\n",
" [0, 105, 'tommy', '8'],\n",
" [0, 105, 'narrator', '5'],\n",
" [0, 115, 'kath', '5'],\n",
" [0, 117, 'tommy', '8'],\n",
" [0, 117, 'narrator', '5'],\n",
" [0, 119, 'kath', '5'],\n",
" [0, 119, 'narrator', '5'],\n",
" [0, 121, 'tommy', '8'],\n",
" [0, 121, 'narrator', '5'],\n",
" [0, 123, 'tommy', '8'],\n",
" [0, 123, 'reggie d', '4'],\n",
" [0, 123, 'mr christopher', '2'],\n",
" [0, 123, 'narrator', '5'],\n",
" [0, 125, 'tommy', '8'],\n",
" [0, 125, 'ruth', '13'],\n",
" [0, 125, 'narrator', '5'],\n",
" [0, 127, 'kathy', '5'],\n",
" [0, 129, 'narrator', '5'],\n",
" [0, 131, 'tommy', '8'],\n",
" [0, 131, 'narrator', '5'],\n",
" [0, 133, 'ruth', '13'],\n",
" [0, 133, 'narrator', '5'],\n",
" [0, 137, 'narrator', '5'],\n",
" [0, 141, 'jackie', '19'],\n",
" [0, 141, 'susie', '15'],\n",
" [0, 143, 'jackie', '19'],\n",
" [0, 143, 'ruth', '13'],\n",
" [0, 145, 'ruth', '13'],\n",
" [0, 145, 'narrator', '5'],\n",
" [0, 147, 'christy', '17'],\n",
" [0, 147, 'ruth', '13'],\n",
" [0, 147, 'narrator', '5'],\n",
" [0, 149, 'ruth', '13'],\n",
" [0, 149, 'narrator', '5'],\n",
" [0, 151, 'christy', '17'],\n",
" [0, 153, 'tommy', '8'],\n",
" [0, 153, 'ruth', '13'],\n",
" [0, 153, 'narrator', '5'],\n",
" [0, 155, 'tommy', '8'],\n",
" [0, 155, 'miss geraldine', '12'],\n",
" [0, 155, 'narrator', '5'],\n",
" [0, 157, 'miss geraldine', '12'],\n",
" [0, 157, 'narrator', '5'],\n",
" [0, 159, 'tommy', '8'],\n",
" [0, 159, 'mr robert', '3'],\n",
" [0, 159, 'miss emily', '9'],\n",
" [0, 159, 'miss geraldine', '12'],\n",
" [0, 161, 'tommy', '8'],\n",
" [0, 163, 'tommy', '8'],\n",
" [0, 165, 'arthur h', '11'],\n",
" [0, 165, 'arthur', '11'],\n",
" [0, 167, 'tommy', '8'],\n",
" [0, 167, 'narrator', '5'],\n",
" [0, 169, 'tommy', '8'],\n",
" [0, 169, 'narrator', '5'],\n",
" [0, 171, 'tommy', '8'],\n",
" [0, 171, 'peter n', '10'],\n",
" [0, 171, 'alexander j', '23'],\n",
" [0, 171, 'arthur h', '11'],\n",
" [0, 171, 'narrator', '5'],\n",
" [0, 171, 'arthur', '11'],\n",
" [0, 173, 'tommy', '8'],\n",
" [0, 173, 'narrator', '5'],\n",
" [0, 175, 'narrator', '5'],\n",
" [0, 177, 'narrator', '5'],\n",
" [0, 179, 'tommy', '8'],\n",
" [0, 179, 'narrator', '5'],\n",
" [0, 181, 'tommy', '8'],\n",
" [0, 183, 'kath', '5'],\n",
" [0, 187, 'tommy', '8'],\n",
" [0, 189, 'tommy', '8'],\n",
" [0, 191, 'tommy', '8'],\n",
" [0, 193, 'kath', '5'],\n",
" [0, 193, 'narrator', '5'],\n",
" [0, 197, 'kath', '5'],\n",
" [0, 197, 'miss lucy', '7'],\n",
" [0, 205, 'tommy', '8'],\n",
" [0, 205, 'narrator', '5'],\n",
" [0, 207, 'tommy', '8'],\n",
" [0, 209, 'tommy', '8'],\n",
" [0, 209, 'narrator', '5'],\n",
" [0, 211, 'tommy', '8'],\n",
" [0, 211, 'narrator', '5'],\n",
" [0, 213, 'kath', '5'],\n",
" [0, 215, 'tommy', '8'],\n",
" [0, 217, 'kath', '5'],\n",
" [0, 219, 'miss lucy', '7'],\n",
" [0, 219, 'narrator', '5']]"
]
}
],
"prompt_number": 26
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Check interaction dictionary"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"interactionDict['0']"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 27,
"text": [
"{6: ['5'],\n",
" 8: ['5'],\n",
" 10: ['8', '13', '5'],\n",
" 12: ['5'],\n",
" 14: ['13', '5'],\n",
" 16: ['5'],\n",
" 18: ['8', '13', '5'],\n",
" 24: ['5'],\n",
" 26: ['5'],\n",
" 28: ['13', '5'],\n",
" 30: ['24'],\n",
" 32: ['5'],\n",
" 34: ['13'],\n",
" 36: ['8', '13', '5'],\n",
" 38: ['8', '13', '5'],\n",
" 40: ['8', '5'],\n",
" 42: ['8', '1', '13', '5'],\n",
" 44: ['8'],\n",
" 46: ['5'],\n",
" 48: ['8'],\n",
" 50: ['8', '1', '13', '5'],\n",
" 54: ['8'],\n",
" 56: ['8'],\n",
" 58: ['8', '1', '5'],\n",
" 60: ['13'],\n",
" 62: ['8', '14'],\n",
" 64: ['8', '13', '5'],\n",
" 66: ['8', '13', '5'],\n",
" 68: ['8', '5'],\n",
" 70: ['5'],\n",
" 72: ['8', '5'],\n",
" 74: ['8', '5'],\n",
" 76: ['5'],\n",
" 78: ['5'],\n",
" 82: ['5'],\n",
" 84: ['13', '5'],\n",
" 95: ['8', '5'],\n",
" 97: ['5'],\n",
" 99: ['8', '5'],\n",
" 101: ['5'],\n",
" 103: ['5'],\n",
" 105: ['8', '5'],\n",
" 115: ['5'],\n",
" 117: ['8', '5'],\n",
" 119: ['5'],\n",
" 121: ['8', '5'],\n",
" 123: ['8', '4', '2', '5'],\n",
" 125: ['8', '13', '5'],\n",
" 127: ['5'],\n",
" 129: ['5'],\n",
" 131: ['8', '5'],\n",
" 133: ['13', '5'],\n",
" 137: ['5'],\n",
" 141: ['19', '15'],\n",
" 143: ['19', '13'],\n",
" 145: ['13', '5'],\n",
" 147: ['17', '13', '5'],\n",
" 149: ['13', '5'],\n",
" 151: ['17'],\n",
" 153: ['8', '13', '5'],\n",
" 155: ['8', '12', '5'],\n",
" 157: ['12', '5'],\n",
" 159: ['8', '3', '9', '12'],\n",
" 161: ['8'],\n",
" 163: ['8'],\n",
" 165: ['11'],\n",
" 167: ['8', '5'],\n",
" 169: ['8', '5'],\n",
" 171: ['8', '10', '23', '11', '5'],\n",
" 173: ['8', '5'],\n",
" 175: ['5'],\n",
" 177: ['5'],\n",
" 179: ['8', '5'],\n",
" 181: ['8'],\n",
" 183: ['5'],\n",
" 187: ['8'],\n",
" 189: ['8'],\n",
" 191: ['8'],\n",
" 193: ['5'],\n",
" 197: ['5', '7'],\n",
" 205: ['8', '5'],\n",
" 207: ['8'],\n",
" 209: ['8', '5'],\n",
" 211: ['8', '5'],\n",
" 213: ['5'],\n",
" 215: ['8'],\n",
" 217: ['5'],\n",
" 219: ['7', '5']}"
]
}
],
"prompt_number": 27
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Check edge list"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for key in edgesFreqsDict:\n",
" print(\"text#: \"+key+\"\\n\")\n",
" for edge, count in edgesFreqsDict[key].items():\n",
" print(edge+\": \"+str(count))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"text#: 0\n",
"\n",
"13 -- 8: 10\n",
"10 -- 23: 1\n",
"5 -- 8: 31\n",
"14 -- 8: 1\n",
"1 -- 5: 3\n",
"8 -- 9: 1\n",
"13 -- 19: 1\n",
"12 -- 5: 2\n",
"15 -- 19: 1\n",
"11 -- 5: 1\n",
"10 -- 8: 1\n",
"1 -- 13: 2\n",
"23 -- 5: 1\n",
"12 -- 8: 2\n",
"2 -- 5: 1\n",
"4 -- 8: 1\n",
"10 -- 5: 1\n",
"17 -- 5: 1\n",
"11 -- 8: 1\n",
"1 -- 8: 3\n",
"10 -- 11: 1\n",
"4 -- 5: 1\n",
"3 -- 8: 1\n",
"12 -- 3: 1\n",
"13 -- 5: 17\n",
"2 -- 8: 1\n",
"11 -- 23: 1\n",
"13 -- 17: 1\n",
"23 -- 8: 1\n",
"2 -- 4: 1\n",
"5 -- 7: 2\n",
"12 -- 9: 1\n",
"3 -- 9: 1\n"
]
}
],
"prompt_number": 57
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment