{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Understand_Tables.ipynb:\n", "

\n", "Extract Structured Information from Tables in PDF Documents\n", " using IBM Watson Discovery and Text Extensions for Pandas\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction\n", "\n", "Many organizations have valuable information hidden in tables inside human-readable documents like PDF files and web pages. Table identification and extraction technology can turn this human-readable information into a format that data science tools can import and use. Text Extensions for Pandas and Watson Discovery make this process much easier.\n", "\n", "In this notebook, we'll follow the journey of Allison, an analyst at an investment bank. Allison's employer has assigned her to cover several different companies, one of which is IBM. As part of her analysis, Allison wants to track IBM's revenue over time, broken down by geographical region. That detailed revenue information is all there in IBM's filings with the U.S. Securities and Exchange Commission (SEC). For example, here's IBM's 2019 annual report:\n", "\n", "![IBM Annual Report for 2019 (146 pages)](images/IBM_Annual_Report_2019.png)\n", "\n", "Did you see the table of revenue by geography? It's here, on page 39:\n", "\n", "![Page 39 of IBM Annual Report for 2019](images/IBM_Annual_Report_2019_page_39.png)\n", "\n", "Here's what that table looks like close up:\n", "\n", "![Table: Geographic Revenue (from IBM 2019 annual report)](images/screenshot_table_2019.png)\n", "\n", "But this particular table only gives two years' revenue figures. Allison needs to have enough data to draw a meaningful chart of revenue over time. 10 years of annual revenue figures would be a good starting point. \n", "\n", "Allison has a collection of IBM annual reports going back to 2009. In total, these documents contain about 1500 pages of financial information. Hidden inside those 1500 pages are the detailed revenue figures that Allison wants. She needs to find those figures, extract them from the documents, and import them into her data science tools.\n", "\n", "Fortunately, Allison has [Watson Discovery](https://www.ibm.com/cloud/watson-discovery), IBM's suite of tools for managing and extracting value from collections of human-readable documents.\n", "\n", "The cells that follow will show how Allison uses Text Extensions for Pandas and Watson Discovery to import the detailed revenue information from her PDF documents into a Pandas DataFrame...\n", "\n", "![Screenshot of a DataFrame from later in this notebook.](images/revenue_table.png)\n", "\n", "...that she then uses to generate a chart of revenue over time:\n", "\n", "![Chart of revenue over time, from later in this notebook.](images/revenue_over_time.png)\n", "\n", "But first, let's set your environment up so that you can run Allison's code yourself.\n", "\n", "(If you're just reading through the precomputed outputs of this notebook, you can skip ahead to the section labeled [\"Extract Tables with Watson Discovery\"](#watson_discovery))." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Environment Setup\n", "\n", "This notebook requires a Python 3.7 or later environment with the following packages:\n", "* The dependencies listed in the [\"requirements.txt\" file for Text Extensions for Pandas](https://github.com/CODAIT/text-extensions-for-pandas/blob/master/requirements.txt)\n", "* `matplotlib`\n", "* `text_extensions_for_pandas`\n", "\n", "You can satisfy the dependency on `text_extensions_for_pandas` in either of two ways:\n", "\n", "* Run `pip install text_extensions_for_pandas` before running this notebook. This command adds the library to your Python environment.\n", "* Run this notebook out of your local copy of the Text Extensions for Pandas project's [source tree](https://github.com/CODAIT/text-extensions-for-pandas). In this case, the notebook will use the version of Text Extensions for Pandas in your local source tree **if the package is not installed in your Python environment**.\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Core Python libraries\n", "import json\n", "import os\n", "import sys\n", "from typing import *\n", "import pandas as pd\n", "from matplotlib import pyplot as plt\n", "\n", "# And of course we need the text_extensions_for_pandas library itself.\n", "try:\n", " import text_extensions_for_pandas as tp\n", "except ModuleNotFoundError as e:\n", " # If we're running from within the project source tree and the parent Python\n", " # environment doesn't have the text_extensions_for_pandas package, use the\n", " # version in the local source tree.\n", " if not os.getcwd().endswith(\"notebooks\"):\n", " raise e\n", " if \"..\" not in sys.path:\n", " sys.path.insert(0, \"..\")\n", " import text_extensions_for_pandas as tp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", "\n", "# Extract Tables with Watson Discovery\n", "\n", "Allison connects to the [Watson Discovery](https://cloud.ibm.com/docs/discovery-data?topic=discovery-data-install) component of her firm's [IBM Cloud Pak for Data](\n", "https://www.ibm.com/products/cloud-pak-for-data) installation on their [OpenShift](https://www.openshift.com/) cluster.\n", "\n", "She creates a new Watson Discovery project and uploads her stack of IBM annual reports to her project. Then she uses the Watson Discovery's [Table Understanding enrichment](https://cloud.ibm.com/docs/discovery-data?topic=discovery-data-understanding_tables) to identify tables in the PDF documents and to extract detailed information about the cells and headers that make up each table.\n", "\n", "To keep this notebook short, we've captured the output of Table Understanding on Allison's documents and checked it into Github [here](https://github.com/CODAIT/text-extensions-for-pandas/tree/master/resources/tables/Financial_table_demo/IBM_10-K). We will use these JSON files as input for the rest of this scenario. If you'd like to learn more about importing and managing document collections in Watson Discovery, take a look at the [Getting Started Guide for Watson Discovery](https://cloud.ibm.com/docs/discovery-data?topic=discovery-data-getting-started).\n", "\n", "Allison reads the JSON output from Watson Discovery's table enrichment into a Python variable, then prints out what the 2019 \"Geographic Revenue\" table looks like in this raw output." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"location\": {\n", " \"begin\": 664612,\n", " \"end\": 673296\n", " },\n", " \"text\": \"($ in millions)\\n For the year ended December 31: 2019 2018\\nYr.-to-Yr. Percent Change\\nYr.-to-Yr. Percent Change Adjusted for Currency\\nYr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\\nTotal revenue $77,147 $79,591 (3.1 )% (1.0)% 0.2%\\nAmericas $36,274 $36,994 (1.9)% (1.1)% 0.8%\\nEurope/Middle East/Africa 24,443 25,491 (4.1) 0.4 1.3\\nAsia Pacific 16,430 17,106 (4.0) (3.0) (2.5)\\n\",\n", " \"section_title\": {\n", " \"location\": {\n", " \"begin\": 663834,\n", " \"end\": 663852\n", " },\n", " \"text\": \"Geographic Revenue\"\n", " },\n", " \"title\": {},\n", " \"table_headers\": [\n", " {\n", " \"cell_id\": \"tableHeader-664612-664628\",\n", " \"location\": {\n", " \"begin\": 664612,\n", " \"end\": 664628\n", " },\n", " \"text\": \"($ in millions)\",\n", " \"row_index_begin\": 0,\n", " \"row_index_end\": 0,\n", " \"column_index_begin\": 0,\n", " \"column_index_end\": 0\n", " }\n", " ],\n", " \"row_headers\": [\n", " {\n", " \"cell_id\": \"rowHeader-667212-667226\",\n", " \"location\": {\n", " \"begin\": 667212,\n", " \"end\": 667226\n", " },\n", " \"text\": \"Total revenue\",\n", " \"text_normalized\": \"Total revenue\",\n", " \"row_index_begin\": 2,\n", " \"row_index_end\": 2,\n", " \"column_index_begin\": 0,\n", " \"column_index_end\": 0\n", " },\n", " {\n", " \"cell_id\": \"rowHeader-668801-668810\",\n", " \"location\": {\n", " \"begin\": 668801,\n", " \"end\": 668810\n", " },\n", " \"text\": \"Americas\",\n", " \"text_normalized\": \"Americas\",\n", " \"row_index_begin\": 3,\n", " \"row_index_end\": 3,\n", " \"column_index_begin\": 0,\n", " \"column_index_end\": 0\n", " },\n", " {\n", " \"cell_id\": \"rowHeader-670386-670412\",\n", " \"location\": {\n", " \"begin\": 670386,\n", " \"end\": 670412\n", " },\n", " \"text\": \"Europe/Middle East/Africa\",\n", " \"text_normalized\": \"Europe/Middle East/Africa\",\n", " \"row_index_begin\": 4,\n", " \"row_index_end\": 4,\n", " \"column_index_begin\": 0,\n", " \"column_index_end\": 0\n", " },\n", " {\n", " \"cell_id\": \"rowHeader-671979-671992\",\n", " \"location\": {\n", " \"begin\": 671979,\n", " \"end\": 671992\n", " },\n", " \"text\": \"Asia Pacific\",\n", " \"text_normalized\": \"Asia Pacific\",\n", " \"row_index_begin\": 5,\n", " \"row_index_end\": 5,\n", " \"column_index_begin\": 0,\n", " \"column_index_end\": 0\n", " }\n", " ],\n", " \"column_headers\": [\n", " {\n", " \"cell_id\": \"colHeader-664705-664706\",\n", " \"location\": {\n", " \"begin\": 664705,\n", " \"end\": 664706\n", " },\n", " \"text\": \"\",\n", " \"text_normalized\": \"\",\n", " \"row_index_begin\": 0,\n", " \"row_index_end\": 0,\n", " \"column_index_begin\": 1,\n", " \"column_index_end\": 1\n", " },\n", " {\n", " \"cell_id\": \"colHeader-664770-664771\",\n", " \"location\": {\n", " \"begin\": 664770,\n", " \"end\": 664771\n", " },\n", " \"text\": \"\",\n", " \"text_normalized\": \"\",\n", " \"row_index_begin\": 0,\n", " \"row_index_end\": 0,\n", " \"column_index_begin\": 2,\n", " \"column_index_end\": 2\n", " },\n", " {\n", " \"cell_id\": \"colHeader-664835-664836\",\n", " \"location\": {\n", " \"begin\": 664835,\n", " \"end\": 664836\n", " },\n", " \"text\": \"\",\n", " \"text_normalized\": \"\",\n", " \"row_index_begin\": 0,\n", " \"row_index_end\": 0,\n", " \"column_index_begin\": 3,\n", " \"column_index_end\": 3\n", " },\n", " {\n", " \"cell_id\": \"colHeader-664900-664901\",\n", " \"location\": {\n", " \"begin\": 664900,\n", " \"end\": 664901\n", " },\n", " \"text\": \"\",\n", " \"text_normalized\": \"\",\n", " \"row_index_begin\": 0,\n", " \"row_index_end\": 0,\n", " \"column_index_begin\": 4,\n", " \"column_index_end\": 4\n", " },\n", " {\n", " \"cell_id\": \"colHeader-664965-664966\",\n", " \"location\": {\n", " \"begin\": 664965,\n", " \"end\": 664966\n", " },\n", " \"text\": \"\",\n", " \"text_normalized\": \"\",\n", " \"row_index_begin\": 0,\n", " \"row_index_end\": 0,\n", " \"column_index_begin\": 5,\n", " \"column_index_end\": 5\n", " },\n", " {\n", " \"cell_id\": \"colHeader-665217-665249\",\n", " \"location\": {\n", " \"begin\": 665217,\n", " \"end\": 665249\n", " },\n", " \"text\": \"For the year ended December 31:\",\n", " \"text_normalized\": \"For the year ended December 31:\",\n", " \"row_index_begin\": 1,\n", " \"row_index_end\": 1,\n", " \"column_index_begin\": 0,\n", " \"column_index_end\": 0\n", " },\n", " {\n", " \"cell_id\": \"colHeader-665513-665518\",\n", " \"location\": {\n", " \"begin\": 665513,\n", " \"end\": 665518\n", " },\n", " \"text\": \"2019\",\n", " \"text_normalized\": \"2019\",\n", " \"row_index_begin\": 1,\n", " \"row_index_end\": 1,\n", " \"column_index_begin\": 1,\n", " \"column_index_end\": 1\n", " },\n", " {\n", " \"cell_id\": \"colHeader-665788-665793\",\n", " \"location\": {\n", " \"begin\": 665788,\n", " \"end\": 665793\n", " },\n", " \"text\": \"2018\",\n", " \"text_normalized\": \"2018\",\n", " \"row_index_begin\": 1,\n", " \"row_index_end\": 1,\n", " \"column_index_begin\": 2,\n", " \"column_index_end\": 2\n", " },\n", " {\n", " \"cell_id\": \"colHeader-666061-666087\",\n", " \"location\": {\n", " \"begin\": 666061,\n", " \"end\": 666087\n", " },\n", " \"text\": \"Yr.-to-Yr. Percent Change\",\n", " \"text_normalized\": \"Yr.-to-Yr. Percent Change\",\n", " \"row_index_begin\": 1,\n", " \"row_index_end\": 1,\n", " \"column_index_begin\": 3,\n", " \"column_index_end\": 3\n", " },\n", " {\n", " \"cell_id\": \"colHeader-666356-666404\",\n", " \"location\": {\n", " \"begin\": 666356,\n", " \"end\": 666404\n", " },\n", " \"text\": \"Yr.-to-Yr. Percent Change Adjusted for Currency\",\n", " \"text_normalized\": \"Yr.-to-Yr. Percent Change Adjusted for Currency\",\n", " \"row_index_begin\": 1,\n", " \"row_index_end\": 1,\n", " \"column_index_begin\": 4,\n", " \"column_index_end\": 4\n", " },\n", " {\n", " \"cell_id\": \"colHeader-666675-666948\",\n", " \"location\": {\n", " \"begin\": 666675,\n", " \"end\": 666948\n", " },\n", " \"text\": \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\",\n", " \"text_normalized\": \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\",\n", " \"row_index_begin\": 1,\n", " \"row_index_end\": 1,\n", " \"column_index_begin\": 5,\n", " \"column_index_end\": 5\n", " }\n", " ],\n", " \"body_cells\": [\n", " {\n", " \"cell_id\": \"bodyCell-667480-667488\",\n", " \"location\": {\n", " \"begin\": 667480,\n", " \"end\": 667488\n", " },\n", " \"text\": \"$77,147\",\n", " \"row_index_begin\": 2,\n", " \"row_index_end\": 2,\n", " \"column_index_begin\": 1,\n", " \"column_index_end\": 1,\n", " \"row_header_ids\": [\n", " \"rowHeader-667212-667226\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Total revenue\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Total revenue\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664705-664706\",\n", " \"colHeader-665513-665518\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"2019\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"2019\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Currency\",\n", " \"text\": \"$77,147\",\n", " \"location\": {\n", " \"begin\": 667480,\n", " \"end\": 667487\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-667744-667752\",\n", " \"location\": {\n", " \"begin\": 667744,\n", " \"end\": 667752\n", " },\n", " \"text\": \"$79,591\",\n", " \"row_index_begin\": 2,\n", " \"row_index_end\": 2,\n", " \"column_index_begin\": 2,\n", " \"column_index_end\": 2,\n", " \"row_header_ids\": [\n", " \"rowHeader-667212-667226\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Total revenue\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Total revenue\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664770-664771\",\n", " \"colHeader-665788-665793\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"2018\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"2018\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Currency\",\n", " \"text\": \"$79,591\",\n", " \"location\": {\n", " \"begin\": 667744,\n", " \"end\": 667751\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-668006-668014\",\n", " \"location\": {\n", " \"begin\": 668006,\n", " \"end\": 668014\n", " },\n", " \"text\": \"(3.1 )%\",\n", " \"row_index_begin\": 2,\n", " \"row_index_end\": 2,\n", " \"column_index_begin\": 3,\n", " \"column_index_end\": 3,\n", " \"row_header_ids\": [\n", " \"rowHeader-667212-667226\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Total revenue\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Total revenue\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664835-664836\",\n", " \"colHeader-666061-666087\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"3.1\",\n", " \"location\": {\n", " \"begin\": 668007,\n", " \"end\": 668010\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-668266-668273\",\n", " \"location\": {\n", " \"begin\": 668266,\n", " \"end\": 668273\n", " },\n", " \"text\": \"(1.0)%\",\n", " \"row_index_begin\": 2,\n", " \"row_index_end\": 2,\n", " \"column_index_begin\": 4,\n", " \"column_index_end\": 4,\n", " \"row_header_ids\": [\n", " \"rowHeader-667212-667226\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Total revenue\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Total revenue\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664900-664901\",\n", " \"colHeader-666356-666404\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change Adjusted for Currency\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change Adjusted for Currency\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"1.0\",\n", " \"location\": {\n", " \"begin\": 668267,\n", " \"end\": 668270\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-668530-668535\",\n", " \"location\": {\n", " \"begin\": 668530,\n", " \"end\": 668535\n", " },\n", " \"text\": \"0.2%\",\n", " \"row_index_begin\": 2,\n", " \"row_index_end\": 2,\n", " \"column_index_begin\": 5,\n", " \"column_index_end\": 5,\n", " \"row_header_ids\": [\n", " \"rowHeader-667212-667226\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Total revenue\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Total revenue\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664965-664966\",\n", " \"colHeader-666675-666948\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Percentage\",\n", " \"text\": \"0.2%\",\n", " \"location\": {\n", " \"begin\": 668530,\n", " \"end\": 668534\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-669065-669073\",\n", " \"location\": {\n", " \"begin\": 669065,\n", " \"end\": 669073\n", " },\n", " \"text\": \"$36,274\",\n", " \"row_index_begin\": 3,\n", " \"row_index_end\": 3,\n", " \"column_index_begin\": 1,\n", " \"column_index_end\": 1,\n", " \"row_header_ids\": [\n", " \"rowHeader-668801-668810\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Americas\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Americas\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664705-664706\",\n", " \"colHeader-665513-665518\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"2019\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"2019\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Currency\",\n", " \"text\": \"$36,274\",\n", " \"location\": {\n", " \"begin\": 669065,\n", " \"end\": 669072\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-669330-669338\",\n", " \"location\": {\n", " \"begin\": 669330,\n", " \"end\": 669338\n", " },\n", " \"text\": \"$36,994\",\n", " \"row_index_begin\": 3,\n", " \"row_index_end\": 3,\n", " \"column_index_begin\": 2,\n", " \"column_index_end\": 2,\n", " \"row_header_ids\": [\n", " \"rowHeader-668801-668810\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Americas\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Americas\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664770-664771\",\n", " \"colHeader-665788-665793\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"2018\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"2018\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Currency\",\n", " \"text\": \"$36,994\",\n", " \"location\": {\n", " \"begin\": 669330,\n", " \"end\": 669337\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-669591-669598\",\n", " \"location\": {\n", " \"begin\": 669591,\n", " \"end\": 669598\n", " },\n", " \"text\": \"(1.9)%\",\n", " \"row_index_begin\": 3,\n", " \"row_index_end\": 3,\n", " \"column_index_begin\": 3,\n", " \"column_index_end\": 3,\n", " \"row_header_ids\": [\n", " \"rowHeader-668801-668810\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Americas\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Americas\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664835-664836\",\n", " \"colHeader-666061-666087\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"1.9\",\n", " \"location\": {\n", " \"begin\": 669592,\n", " \"end\": 669595\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-669853-669860\",\n", " \"location\": {\n", " \"begin\": 669853,\n", " \"end\": 669860\n", " },\n", " \"text\": \"(1.1)%\",\n", " \"row_index_begin\": 3,\n", " \"row_index_end\": 3,\n", " \"column_index_begin\": 4,\n", " \"column_index_end\": 4,\n", " \"row_header_ids\": [\n", " \"rowHeader-668801-668810\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Americas\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Americas\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664900-664901\",\n", " \"colHeader-666356-666404\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change Adjusted for Currency\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change Adjusted for Currency\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"1.1\",\n", " \"location\": {\n", " \"begin\": 669854,\n", " \"end\": 669857\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-670116-670121\",\n", " \"location\": {\n", " \"begin\": 670116,\n", " \"end\": 670121\n", " },\n", " \"text\": \"0.8%\",\n", " \"row_index_begin\": 3,\n", " \"row_index_end\": 3,\n", " \"column_index_begin\": 5,\n", " \"column_index_end\": 5,\n", " \"row_header_ids\": [\n", " \"rowHeader-668801-668810\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Americas\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Americas\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664965-664966\",\n", " \"colHeader-666675-666948\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Percentage\",\n", " \"text\": \"0.8%\",\n", " \"location\": {\n", " \"begin\": 670116,\n", " \"end\": 670120\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-670663-670670\",\n", " \"location\": {\n", " \"begin\": 670663,\n", " \"end\": 670670\n", " },\n", " \"text\": \"24,443\",\n", " \"row_index_begin\": 4,\n", " \"row_index_end\": 4,\n", " \"column_index_begin\": 1,\n", " \"column_index_end\": 1,\n", " \"row_header_ids\": [\n", " \"rowHeader-670386-670412\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664705-664706\",\n", " \"colHeader-665513-665518\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"2019\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"2019\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"24,443\",\n", " \"location\": {\n", " \"begin\": 670663,\n", " \"end\": 670669\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-670924-670931\",\n", " \"location\": {\n", " \"begin\": 670924,\n", " \"end\": 670931\n", " },\n", " \"text\": \"25,491\",\n", " \"row_index_begin\": 4,\n", " \"row_index_end\": 4,\n", " \"column_index_begin\": 2,\n", " \"column_index_end\": 2,\n", " \"row_header_ids\": [\n", " \"rowHeader-670386-670412\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664770-664771\",\n", " \"colHeader-665788-665793\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"2018\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"2018\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"25,491\",\n", " \"location\": {\n", " \"begin\": 670924,\n", " \"end\": 670930\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-671187-671193\",\n", " \"location\": {\n", " \"begin\": 671187,\n", " \"end\": 671193\n", " },\n", " \"text\": \"(4.1)\",\n", " \"row_index_begin\": 4,\n", " \"row_index_end\": 4,\n", " \"column_index_begin\": 3,\n", " \"column_index_end\": 3,\n", " \"row_header_ids\": [\n", " \"rowHeader-670386-670412\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664835-664836\",\n", " \"colHeader-666061-666087\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"4.1\",\n", " \"location\": {\n", " \"begin\": 671188,\n", " \"end\": 671191\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-671449-671453\",\n", " \"location\": {\n", " \"begin\": 671449,\n", " \"end\": 671453\n", " },\n", " \"text\": \"0.4\",\n", " \"row_index_begin\": 4,\n", " \"row_index_end\": 4,\n", " \"column_index_begin\": 4,\n", " \"column_index_end\": 4,\n", " \"row_header_ids\": [\n", " \"rowHeader-670386-670412\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664900-664901\",\n", " \"colHeader-666356-666404\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change Adjusted for Currency\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change Adjusted for Currency\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"0.4\",\n", " \"location\": {\n", " \"begin\": 671449,\n", " \"end\": 671452\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-671711-671715\",\n", " \"location\": {\n", " \"begin\": 671711,\n", " \"end\": 671715\n", " },\n", " \"text\": \"1.3\",\n", " \"row_index_begin\": 4,\n", " \"row_index_end\": 4,\n", " \"column_index_begin\": 5,\n", " \"column_index_end\": 5,\n", " \"row_header_ids\": [\n", " \"rowHeader-670386-670412\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Europe/Middle East/Africa\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664965-664966\",\n", " \"colHeader-666675-666948\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"1.3\",\n", " \"location\": {\n", " \"begin\": 671711,\n", " \"end\": 671714\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-672244-672251\",\n", " \"location\": {\n", " \"begin\": 672244,\n", " \"end\": 672251\n", " },\n", " \"text\": \"16,430\",\n", " \"row_index_begin\": 5,\n", " \"row_index_end\": 5,\n", " \"column_index_begin\": 1,\n", " \"column_index_end\": 1,\n", " \"row_header_ids\": [\n", " \"rowHeader-671979-671992\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664705-664706\",\n", " \"colHeader-665513-665518\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"2019\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"2019\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"16,430\",\n", " \"location\": {\n", " \"begin\": 672244,\n", " \"end\": 672250\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-672505-672512\",\n", " \"location\": {\n", " \"begin\": 672505,\n", " \"end\": 672512\n", " },\n", " \"text\": \"17,106\",\n", " \"row_index_begin\": 5,\n", " \"row_index_end\": 5,\n", " \"column_index_begin\": 2,\n", " \"column_index_end\": 2,\n", " \"row_header_ids\": [\n", " \"rowHeader-671979-671992\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664770-664771\",\n", " \"colHeader-665788-665793\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"2018\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"2018\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"17,106\",\n", " \"location\": {\n", " \"begin\": 672505,\n", " \"end\": 672511\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-672767-672773\",\n", " \"location\": {\n", " \"begin\": 672767,\n", " \"end\": 672773\n", " },\n", " \"text\": \"(4.0)\",\n", " \"row_index_begin\": 5,\n", " \"row_index_end\": 5,\n", " \"column_index_begin\": 3,\n", " \"column_index_end\": 3,\n", " \"row_header_ids\": [\n", " \"rowHeader-671979-671992\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664835-664836\",\n", " \"colHeader-666061-666087\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"4.0\",\n", " \"location\": {\n", " \"begin\": 672768,\n", " \"end\": 672771\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-673028-673034\",\n", " \"location\": {\n", " \"begin\": 673028,\n", " \"end\": 673034\n", " },\n", " \"text\": \"(3.0)\",\n", " \"row_index_begin\": 5,\n", " \"row_index_end\": 5,\n", " \"column_index_begin\": 4,\n", " \"column_index_end\": 4,\n", " \"row_header_ids\": [\n", " \"rowHeader-671979-671992\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664900-664901\",\n", " \"colHeader-666356-666404\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change Adjusted for Currency\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change Adjusted for Currency\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"3.0\",\n", " \"location\": {\n", " \"begin\": 673029,\n", " \"end\": 673032\n", " }\n", " }\n", " ]\n", " },\n", " {\n", " \"cell_id\": \"bodyCell-673290-673296\",\n", " \"location\": {\n", " \"begin\": 673290,\n", " \"end\": 673296\n", " },\n", " \"text\": \"(2.5)\",\n", " \"row_index_begin\": 5,\n", " \"row_index_end\": 5,\n", " \"column_index_begin\": 5,\n", " \"column_index_end\": 5,\n", " \"row_header_ids\": [\n", " \"rowHeader-671979-671992\"\n", " ],\n", " \"row_header_texts\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"row_header_texts_normalized\": [\n", " \"Asia Pacific\"\n", " ],\n", " \"column_header_ids\": [\n", " \"colHeader-664965-664966\",\n", " \"colHeader-666675-666948\"\n", " ],\n", " \"column_header_texts\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\"\n", " ],\n", " \"column_header_texts_normalized\": [\n", " \"\",\n", " \"Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency\"\n", " ],\n", " \"attributes\": [\n", " {\n", " \"type\": \"Number\",\n", " \"text\": \"2.5\",\n", " \"location\": {\n", " \"begin\": 673291,\n", " \"end\": 673294\n", " }\n", " }\n", " ]\n", " }\n", " ],\n", " \"contexts\": [\n", " {\n", " \"location\": {\n", " \"begin\": 664050,\n", " \"end\": 664171\n", " },\n", " \"text\": \"In addition to the revenue presentation by reportable segment, we also measure revenue performance on a geographic basis.\"\n", " },\n", " {\n", " \"location\": {\n", " \"begin\": 673587,\n", " \"end\": 674274\n", " },\n", " \"text\": \"Total revenue of $77,147 million in 2019 decreased 3.1 percent year to year as reported (1 percent adjusted for currency), but increased 0.2 percent excluding divested businesses and adjusted for currency.\"\n", " },\n", " {\n", " \"location\": {\n", " \"begin\": 674465,\n", " \"end\": 674948\n", " },\n", " \"text\": \"Americas revenue decreased 1.9 percent as reported (1 percent adjusted for currency), but grew 1 percent excluding divested businesses and adjusted for currency.\"\n", " }\n", " ],\n", " \"key_value_pairs\": []\n", "}\n" ] } ], "source": [ "# Location of the output from Watson Discovery's Table Understanding enrichment\n", "# (relative to this notebook file)\n", "FILES_DIR = \"../resources/tables/financial_table_demo/IBM_10-K\"\n", "\n", "with open(f\"{FILES_DIR}/2019.json\", \"r\") as f:\n", " ibm_2019_json = json.load(f)\n", "\n", "# Find the table in the \"Geographic Revenue\" section.\n", "table_index = [i for i in range(len(ibm_2019_json[\"tables\"])) \n", " if ibm_2019_json[\"tables\"][i][\"section_title\"][\"text\"] == \"Geographic Revenue\"][0]\n", "print(json.dumps(ibm_2019_json[\"tables\"][table_index], indent=2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That raw output contains everything Allison needs to extract the revenue figures from this document, but it's in a format that's cumbersome to deal with. So Allison uses Text Extensions for Pandas to convert this JSON into a collection of Pandas DataFrames. These DataFrames encode information about the row headers, column headers, and cells that make up the table." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dict_keys(['row_headers', 'col_headers', 'body_cells', 'given_loc'])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table_data = tp.io.watson.tables.parse_response(ibm_2019_json,\n", " select_table=\"Geographic Revenue\")\n", "table_data.keys()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
textcolumn_index_begincolumn_index_endrow_index_beginrow_index_endcell_idcolumn_header_idscolumn_header_textsrow_header_idsrow_header_textsattributes.textattributes.type
0$77,1471122bodyCell-667480-667488[colHeader-664705-664706, colHeader-665513-665...[2019][rowHeader-667212-667226][Total revenue][$77,147][Currency]
1$79,5912222bodyCell-667744-667752[colHeader-664770-664771, colHeader-665788-665...[2018][rowHeader-667212-667226][Total revenue][$79,591][Currency]
2(3.1 )%3322bodyCell-668006-668014[colHeader-664835-664836, colHeader-666061-666...[Yr.-to-Yr. Percent Change][rowHeader-667212-667226][Total revenue][3.1][Number]
3(1.0)%4422bodyCell-668266-668273[colHeader-664900-664901, colHeader-666356-666...[Yr.-to-Yr. Percent Change Adjusted for Currency][rowHeader-667212-667226][Total revenue][1.0][Number]
40.2%5522bodyCell-668530-668535[colHeader-664965-664966, colHeader-666675-666...[Yr.-to-Yr. Percent Change\\n Excluding Diveste...[rowHeader-667212-667226][Total revenue][0.2%][Percentage]
\n", "
" ], "text/plain": [ " text column_index_begin column_index_end row_index_begin \\\n", "0 $77,147 1 1 2 \n", "1 $79,591 2 2 2 \n", "2 (3.1 )% 3 3 2 \n", "3 (1.0)% 4 4 2 \n", "4 0.2% 5 5 2 \n", "\n", " row_index_end cell_id \\\n", "0 2 bodyCell-667480-667488 \n", "1 2 bodyCell-667744-667752 \n", "2 2 bodyCell-668006-668014 \n", "3 2 bodyCell-668266-668273 \n", "4 2 bodyCell-668530-668535 \n", "\n", " column_header_ids \\\n", "0 [colHeader-664705-664706, colHeader-665513-665... \n", "1 [colHeader-664770-664771, colHeader-665788-665... \n", "2 [colHeader-664835-664836, colHeader-666061-666... \n", "3 [colHeader-664900-664901, colHeader-666356-666... \n", "4 [colHeader-664965-664966, colHeader-666675-666... \n", "\n", " column_header_texts \\\n", "0 [2019] \n", "1 [2018] \n", "2 [Yr.-to-Yr. Percent Change] \n", "3 [Yr.-to-Yr. Percent Change Adjusted for Currency] \n", "4 [Yr.-to-Yr. Percent Change\\n Excluding Diveste... \n", "\n", " row_header_ids row_header_texts attributes.text attributes.type \n", "0 [rowHeader-667212-667226] [Total revenue] [$77,147] [Currency] \n", "1 [rowHeader-667212-667226] [Total revenue] [$79,591] [Currency] \n", "2 [rowHeader-667212-667226] [Total revenue] [3.1] [Number] \n", "3 [rowHeader-667212-667226] [Total revenue] [1.0] [Number] \n", "4 [rowHeader-667212-667226] [Total revenue] [0.2%] [Percentage] " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table_data[\"body_cells\"].head(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Text Extensions for Pandas can convert these DataFrames into a single Pandas DataFrame that matches the layout of the original table in the document. Allison calls the `make_table()` function to perform that conversion and inspects the output." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
20192018Yr.-to-Yr. Percent ChangeYr.-to-Yr. Percent Change Adjusted for CurrencyYr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency
Total revenue$77,147$79,591-3.1-1.00.2
Americas$36,274$36,994-1.9-1.10.8
Europe/Middle East/Africa24,44325,491-4.10.41.3
Asia Pacific16,43017,106-4.0-3.0-2.5
\n", "
" ], "text/plain": [ " \\\n", " 2019 2018 Yr.-to-Yr. Percent Change \n", "Total revenue $77,147 $79,591 -3.1 \n", "Americas $36,274 $36,994 -1.9 \n", "Europe/Middle East/Africa 24,443 25,491 -4.1 \n", "Asia Pacific 16,430 17,106 -4.0 \n", "\n", " \\\n", " Yr.-to-Yr. Percent Change Adjusted for Currency \n", "Total revenue -1.0 \n", "Americas -1.1 \n", "Europe/Middle East/Africa 0.4 \n", "Asia Pacific -3.0 \n", "\n", " \n", " Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency \n", "Total revenue 0.2 \n", "Americas 0.8 \n", "Europe/Middle East/Africa 1.3 \n", "Asia Pacific -2.5 " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "revenue_2019_df = tp.io.watson.tables.make_table(table_data)\n", "revenue_2019_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "  \n", "\n", "The reconstructed dataframe looks good! Here's what the original table in the PDF document looked like:\n", "![Table: Geographic Revenue (from IBM 2019 annual report)](images/screenshot_table_2019.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If Allison just wanted to create a DataFrame of 2018/2019 revenue figures, her task would be done. But Allison wants to reconstruct ten years of revenue by geographic region. To do that, she will need to combine information from multiple documents. For tables like this one that have multiple levels of header information, this kind of integration is easier to perform over the \"exploded\" version of the table, where each cell in the table is represented a single row containing all the corresponding header values.\n", "\n", "Allison passes the same table data from the 2019 report through the Text Extensions for Pandas function `make_exploded_df()` to produce the exploded represention of the table:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
textrow_header_texts_0column_header_textsattributes.type
0$77,147Total revenue2019[Currency]
1$79,591Total revenue2018[Currency]
2(3.1 )%Total revenueYr.-to-Yr. Percent Change[Number]
3(1.0)%Total revenueYr.-to-Yr. Percent Change Adjusted for Currency[Number]
40.2%Total revenueYr.-to-Yr. Percent Change\\n Excluding Divested...[Percentage]
5$36,274Americas2019[Currency]
6$36,994Americas2018[Currency]
7(1.9)%AmericasYr.-to-Yr. Percent Change[Number]
8(1.1)%AmericasYr.-to-Yr. Percent Change Adjusted for Currency[Number]
90.8%AmericasYr.-to-Yr. Percent Change\\n Excluding Divested...[Percentage]
1024,443Europe/Middle East/Africa2019[Number]
1125,491Europe/Middle East/Africa2018[Number]
12(4.1)Europe/Middle East/AfricaYr.-to-Yr. Percent Change[Number]
130.4Europe/Middle East/AfricaYr.-to-Yr. Percent Change Adjusted for Currency[Number]
141.3Europe/Middle East/AfricaYr.-to-Yr. Percent Change\\n Excluding Divested...[Number]
1516,430Asia Pacific2019[Number]
1617,106Asia Pacific2018[Number]
17(4.0)Asia PacificYr.-to-Yr. Percent Change[Number]
18(3.0)Asia PacificYr.-to-Yr. Percent Change Adjusted for Currency[Number]
19(2.5)Asia PacificYr.-to-Yr. Percent Change\\n Excluding Divested...[Number]
\n", "
" ], "text/plain": [ " text row_header_texts_0 \\\n", "0 $77,147 Total revenue \n", "1 $79,591 Total revenue \n", "2 (3.1 )% Total revenue \n", "3 (1.0)% Total revenue \n", "4 0.2% Total revenue \n", "5 $36,274 Americas \n", "6 $36,994 Americas \n", "7 (1.9)% Americas \n", "8 (1.1)% Americas \n", "9 0.8% Americas \n", "10 24,443 Europe/Middle East/Africa \n", "11 25,491 Europe/Middle East/Africa \n", "12 (4.1) Europe/Middle East/Africa \n", "13 0.4 Europe/Middle East/Africa \n", "14 1.3 Europe/Middle East/Africa \n", "15 16,430 Asia Pacific \n", "16 17,106 Asia Pacific \n", "17 (4.0) Asia Pacific \n", "18 (3.0) Asia Pacific \n", "19 (2.5) Asia Pacific \n", "\n", " column_header_texts attributes.type \n", "0 2019 [Currency] \n", "1 2018 [Currency] \n", "2 Yr.-to-Yr. Percent Change [Number] \n", "3 Yr.-to-Yr. Percent Change Adjusted for Currency [Number] \n", "4 Yr.-to-Yr. Percent Change\\n Excluding Divested... [Percentage] \n", "5 2019 [Currency] \n", "6 2018 [Currency] \n", "7 Yr.-to-Yr. Percent Change [Number] \n", "8 Yr.-to-Yr. Percent Change Adjusted for Currency [Number] \n", "9 Yr.-to-Yr. Percent Change\\n Excluding Divested... [Percentage] \n", "10 2019 [Number] \n", "11 2018 [Number] \n", "12 Yr.-to-Yr. Percent Change [Number] \n", "13 Yr.-to-Yr. Percent Change Adjusted for Currency [Number] \n", "14 Yr.-to-Yr. Percent Change\\n Excluding Divested... [Number] \n", "15 2019 [Number] \n", "16 2018 [Number] \n", "17 Yr.-to-Yr. Percent Change [Number] \n", "18 Yr.-to-Yr. Percent Change Adjusted for Currency [Number] \n", "19 Yr.-to-Yr. Percent Change\\n Excluding Divested... [Number] " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exploded_df, row_header_names, col_header_names = (\n", " tp.io.watson.tables.make_exploded_df(table_data, col_explode_by=\"concat\"))\n", "exploded_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This exploded version of the table is the exact same data, just represented in a different way. If she wants, Allison can convert it back to the format from the original document by calling `pandas.DataFrame.pivot()`:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
column_header_texts20182019Yr.-to-Yr. Percent ChangeYr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for CurrencyYr.-to-Yr. Percent Change Adjusted for Currency
row_header_texts_0
Americas$36,994$36,274(1.9)%0.8%(1.1)%
Asia Pacific17,10616,430(4.0)(2.5)(3.0)
Europe/Middle East/Africa25,49124,443(4.1)1.30.4
Total revenue$79,591$77,147(3.1 )%0.2%(1.0)%
\n", "
" ], "text/plain": [ "column_header_texts 2018 2019 Yr.-to-Yr. Percent Change \\\n", "row_header_texts_0 \n", "Americas $36,994 $36,274 (1.9)% \n", "Asia Pacific 17,106 16,430 (4.0) \n", "Europe/Middle East/Africa 25,491 24,443 (4.1) \n", "Total revenue $79,591 $77,147 (3.1 )% \n", "\n", "column_header_texts Yr.-to-Yr. Percent Change\\n Excluding Divested Businesses And Adjusted for Currency \\\n", "row_header_texts_0 \n", "Americas 0.8% \n", "Asia Pacific (2.5) \n", "Europe/Middle East/Africa 1.3 \n", "Total revenue 0.2% \n", "\n", "column_header_texts Yr.-to-Yr. Percent Change Adjusted for Currency \n", "row_header_texts_0 \n", "Americas (1.1)% \n", "Asia Pacific (3.0) \n", "Europe/Middle East/Africa 0.4 \n", "Total revenue (1.0)% " ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exploded_df.pivot(index=\"row_header_texts_0\", columns=\"column_header_texts\", values=\"text\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But because she is about to merge this DataFrame with similar data from other documents, Allison keeps the data in exploded format for now. \n", "\n", "Allison's next task is to write some Pandas transformations that will clean and reformat the DataFrame for each source table prior to merging them all together. She uses the 2019 report's data as a test case for creating this code. The first step is to convert the cell values in the Watson Discovery output from text to numeric values. Text Extensions for Pandas includes a more robust version of [`pandas.to_numeric()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_numeric.html) that can handle common idioms for representing currencies and percentages. Allison uses this function, called `convert_cols_to_numeric()`, to convert all the cell values to numbers. She adds a new column \"value\" to her DataFrame to hold these numbers." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
textrow_header_texts_0column_header_textsattributes.typevalue
0$77,147Total revenue2019[Currency]77147.0
1$79,591Total revenue2018[Currency]79591.0
2(3.1 )%Total revenueYr.-to-Yr. Percent Change[Number]-3.1
3(1.0)%Total revenueYr.-to-Yr. Percent Change Adjusted for Currency[Number]-1.0
40.2%Total revenueYr.-to-Yr. Percent Change\\n Excluding Divested...[Percentage]0.2
5$36,274Americas2019[Currency]36274.0
6$36,994Americas2018[Currency]36994.0
7(1.9)%AmericasYr.-to-Yr. Percent Change[Number]-1.9
8(1.1)%AmericasYr.-to-Yr. Percent Change Adjusted for Currency[Number]-1.1
90.8%AmericasYr.-to-Yr. Percent Change\\n Excluding Divested...[Percentage]0.8
1024,443Europe/Middle East/Africa2019[Number]24443.0
1125,491Europe/Middle East/Africa2018[Number]25491.0
12(4.1)Europe/Middle East/AfricaYr.-to-Yr. Percent Change[Number]-4.1
130.4Europe/Middle East/AfricaYr.-to-Yr. Percent Change Adjusted for Currency[Number]0.4
141.3Europe/Middle East/AfricaYr.-to-Yr. Percent Change\\n Excluding Divested...[Number]1.3
1516,430Asia Pacific2019[Number]16430.0
1617,106Asia Pacific2018[Number]17106.0
17(4.0)Asia PacificYr.-to-Yr. Percent Change[Number]-4.0
18(3.0)Asia PacificYr.-to-Yr. Percent Change Adjusted for Currency[Number]-3.0
19(2.5)Asia PacificYr.-to-Yr. Percent Change\\n Excluding Divested...[Number]-2.5
\n", "
" ], "text/plain": [ " text row_header_texts_0 \\\n", "0 $77,147 Total revenue \n", "1 $79,591 Total revenue \n", "2 (3.1 )% Total revenue \n", "3 (1.0)% Total revenue \n", "4 0.2% Total revenue \n", "5 $36,274 Americas \n", "6 $36,994 Americas \n", "7 (1.9)% Americas \n", "8 (1.1)% Americas \n", "9 0.8% Americas \n", "10 24,443 Europe/Middle East/Africa \n", "11 25,491 Europe/Middle East/Africa \n", "12 (4.1) Europe/Middle East/Africa \n", "13 0.4 Europe/Middle East/Africa \n", "14 1.3 Europe/Middle East/Africa \n", "15 16,430 Asia Pacific \n", "16 17,106 Asia Pacific \n", "17 (4.0) Asia Pacific \n", "18 (3.0) Asia Pacific \n", "19 (2.5) Asia Pacific \n", "\n", " column_header_texts attributes.type value \n", "0 2019 [Currency] 77147.0 \n", "1 2018 [Currency] 79591.0 \n", "2 Yr.-to-Yr. Percent Change [Number] -3.1 \n", "3 Yr.-to-Yr. Percent Change Adjusted for Currency [Number] -1.0 \n", "4 Yr.-to-Yr. Percent Change\\n Excluding Divested... [Percentage] 0.2 \n", "5 2019 [Currency] 36274.0 \n", "6 2018 [Currency] 36994.0 \n", "7 Yr.-to-Yr. Percent Change [Number] -1.9 \n", "8 Yr.-to-Yr. Percent Change Adjusted for Currency [Number] -1.1 \n", "9 Yr.-to-Yr. Percent Change\\n Excluding Divested... [Percentage] 0.8 \n", "10 2019 [Number] 24443.0 \n", "11 2018 [Number] 25491.0 \n", "12 Yr.-to-Yr. Percent Change [Number] -4.1 \n", "13 Yr.-to-Yr. Percent Change Adjusted for Currency [Number] 0.4 \n", "14 Yr.-to-Yr. Percent Change\\n Excluding Divested... [Number] 1.3 \n", "15 2019 [Number] 16430.0 \n", "16 2018 [Number] 17106.0 \n", "17 Yr.-to-Yr. Percent Change [Number] -4.0 \n", "18 Yr.-to-Yr. Percent Change Adjusted for Currency [Number] -3.0 \n", "19 Yr.-to-Yr. Percent Change\\n Excluding Divested... [Number] -2.5 " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "exploded_df[\"value\"] = \\\n", " tp.io.watson.tables.convert_cols_to_numeric(exploded_df[[\"text\"]])\n", "exploded_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now all the cell values have been converted to floating-point numbers, but only some of these numbers represent revenue. Looking at the 2019 data, Allison can see that the revenue numbers have 4-digit years in their column headers. So she filters the DataFrame down to just those rows with 4-digit numbers in the \"column_header_texts\" column." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
textrow_header_texts_0column_header_textsattributes.typevalue
0$77,147Total revenue2019[Currency]77147.0
1$79,591Total revenue2018[Currency]79591.0
5$36,274Americas2019[Currency]36274.0
6$36,994Americas2018[Currency]36994.0
1024,443Europe/Middle East/Africa2019[Number]24443.0
1125,491Europe/Middle East/Africa2018[Number]25491.0
1516,430Asia Pacific2019[Number]16430.0
1617,106Asia Pacific2018[Number]17106.0
\n", "
" ], "text/plain": [ " text row_header_texts_0 column_header_texts attributes.type \\\n", "0 $77,147 Total revenue 2019 [Currency] \n", "1 $79,591 Total revenue 2018 [Currency] \n", "5 $36,274 Americas 2019 [Currency] \n", "6 $36,994 Americas 2018 [Currency] \n", "10 24,443 Europe/Middle East/Africa 2019 [Number] \n", "11 25,491 Europe/Middle East/Africa 2018 [Number] \n", "15 16,430 Asia Pacific 2019 [Number] \n", "16 17,106 Asia Pacific 2018 [Number] \n", "\n", " value \n", "0 77147.0 \n", "1 79591.0 \n", "5 36274.0 \n", "6 36994.0 \n", "10 24443.0 \n", "11 25491.0 \n", "15 16430.0 \n", "16 17106.0 " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rows_to_retain = exploded_df[exploded_df[\"column_header_texts\"].str.fullmatch(\"\\d{4}\")].copy()\n", "rows_to_retain" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's looking good! Now Allison drops the unnecessary columns and gives some more friendly names to the columns that remain." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearRegionRevenue
02019Total revenue77147.0
12018Total revenue79591.0
52019Americas36274.0
62018Americas36994.0
102019Europe/Middle East/Africa24443.0
112018Europe/Middle East/Africa25491.0
152019Asia Pacific16430.0
162018Asia Pacific17106.0
\n", "
" ], "text/plain": [ " Year Region Revenue\n", "0 2019 Total revenue 77147.0\n", "1 2018 Total revenue 79591.0\n", "5 2019 Americas 36274.0\n", "6 2018 Americas 36994.0\n", "10 2019 Europe/Middle East/Africa 24443.0\n", "11 2018 Europe/Middle East/Africa 25491.0\n", "15 2019 Asia Pacific 16430.0\n", "16 2018 Asia Pacific 17106.0" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rows_to_retain.rename(\n", " columns={\n", " \"row_header_texts_0\": \"Region\",\n", " \"column_header_texts\": \"Year\",\n", " \"value\": \"Revenue\"\n", " })[[\"Year\", \"Region\", \"Revenue\"]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The code from the last few cells worked to clean up the 2019 data, so Allison copies and pastes that code into a Python function:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "def dataframe_for_file(filename: str):\n", " with open(f\"{FILES_DIR}/{filename}\", \"r\") as f:\n", " json_output = json.load(f)\n", " table_data = tp.io.watson.tables.parse_response(json_output,\n", " select_table=\"Geographic Revenue\")\n", " exploded_df, _, _ = tp.io.watson.tables.make_exploded_df(\n", " table_data, col_explode_by=\"concat\")\n", " rows_to_retain = exploded_df[exploded_df[\"column_header_texts\"].str.fullmatch(\"\\d{4}\")\n", " & (exploded_df[\"text\"].str.len() > 0)].copy()\n", " rows_to_retain[\"value\"] = tp.io.watson.tables.convert_cols_to_numeric(\n", " rows_to_retain[[\"text\"]])\n", " rows_to_retain[\"file\"] = filename\n", " return (\n", " rows_to_retain.rename(columns={\n", " \"row_header_texts_0\": \"Region\", \"column_header_texts\": \"Year\", \"value\": \"Revenue\"})\n", " [[\"Year\", \"Region\", \"Revenue\"]]\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then she calls that function on the Watson Discovery output from the 2019 annual report to verify that it produces the same answer. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearRegionRevenue
02019Total revenue77147.0
12018Total revenue79591.0
52019Americas36274.0
62018Americas36994.0
102019Europe/Middle East/Africa24443.0
112018Europe/Middle East/Africa25491.0
152019Asia Pacific16430.0
162018Asia Pacific17106.0
\n", "
" ], "text/plain": [ " Year Region Revenue\n", "0 2019 Total revenue 77147.0\n", "1 2018 Total revenue 79591.0\n", "5 2019 Americas 36274.0\n", "6 2018 Americas 36994.0\n", "10 2019 Europe/Middle East/Africa 24443.0\n", "11 2018 Europe/Middle East/Africa 25491.0\n", "15 2019 Asia Pacific 16430.0\n", "16 2018 Asia Pacific 17106.0" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dataframe_for_file(\"2019.json\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looks good! Time to run the same function over an entire stack of reports. Allison puts the names of all her Watson Discovery output files into a single Python list." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['2009.json',\n", " '2010.json',\n", " '2012.json',\n", " '2013.json',\n", " '2015.json',\n", " '2016.json',\n", " '2017.json',\n", " '2018.json',\n", " '2019.json']" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all_files = sorted([f for f in os.listdir(FILES_DIR) if f.endswith(\".json\")])\n", "all_files" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the annual reports for 2011 and 2014 aren't in the collection of files that Allison has. But that's ok; each report contains the previous year's figures, so Allison can reconstruct the missing data from adjacent years.\n", "\n", "Allison calls her `dataframe_for_file()` function on each of the files, then concatenates all of the resulting Pandas DataFrames into a single large DataFrame." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearRegionRevenue
02009Total revenue:95758.0
12008Total revenue:103630.0
42009Geographies:93477.0
52008Geographies:100939.0
82009Americas40184.0
............
62018Americas36994.0
102019Europe/Middle East/Africa24443.0
112018Europe/Middle East/Africa25491.0
152019Asia Pacific16430.0
162018Asia Pacific17106.0
\n", "

82 rows × 3 columns

\n", "
" ], "text/plain": [ " Year Region Revenue\n", "0 2009 Total revenue: 95758.0\n", "1 2008 Total revenue: 103630.0\n", "4 2009 Geographies: 93477.0\n", "5 2008 Geographies: 100939.0\n", "8 2009 Americas 40184.0\n", ".. ... ... ...\n", "6 2018 Americas 36994.0\n", "10 2019 Europe/Middle East/Africa 24443.0\n", "11 2018 Europe/Middle East/Africa 25491.0\n", "15 2019 Asia Pacific 16430.0\n", "16 2018 Asia Pacific 17106.0\n", "\n", "[82 rows x 3 columns]" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "revenue_df = pd.concat([dataframe_for_file(f) for f in all_files])\n", "revenue_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Allison can see that the first four lines of this DataFrame contain total worldwide revenue; and that this total occurred\n", "under different names in different documents. Allison is interested in the fine-grained revenue figures, not\n", "the totals, so she needs to filter out all these rows with worldwide revenue.\n", "\n", "What are all the names of geographic regions that IBM annual reports have used over the last ten years?" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Region
0Total revenue:
4Geographies:
8Americas
12Europe/Middle East/Africa
16Asia Pacific
0Total revenue
4Geographies
16Asia Pacifi c
\n", "
" ], "text/plain": [ " Region\n", "0 Total revenue:\n", "4 Geographies:\n", "8 Americas\n", "12 Europe/Middle East/Africa\n", "16 Asia Pacific\n", "0 Total revenue\n", "4 Geographies\n", "16 Asia Pacifi c" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "revenue_df[[\"Region\"]].drop_duplicates()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It looks like all the worldwide revenue figures are under some variation of \"Geographies\" or \"Total revenue\". \n", "Allison uses Pandas' string matching facilities to filter out the rows whose \"Region\" column contains the \n", "words \"geographies\" or \"total\"." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearRegionRevenue
82009Americas40184.0
92008Americas42807.0
122009Europe/Middle East/Africa32583.0
132008Europe/Middle East/Africa37020.0
162009Asia Pacific20710.0
172008Asia Pacific21111.0
82010Americas42044.0
92009Americas40184.0
122010Europe/Middle East/Africa31866.0
132009Europe/Middle East/Africa32583.0
162010Asia Pacific23150.0
172009Asia Pacific20710.0
82012Americas44556.0
92011Americas44944.0
122012Europe/Middle East/Africa31775.0
132011Europe/Middle East/Africa33952.0
162012Asia Pacific25937.0
172011Asia Pacific25273.0
82013Americas43249.0
92012Americas44556.0
122013Europe/Middle East/Africa31628.0
132012Europe/Middle East/Africa31775.0
162013Asia Pacific22923.0
172012Asia Pacific25937.0
82015Americas38486.0
92014Americas41410.0
122015Europe/Middle East/Africa26073.0
132014Europe/Middle East/Africa30700.0
162015Asia Pacifi c16871.0
172014Asia Pacifi c20216.0
82016Americas37513.0
92015Americas38486.0
122016Europe/Middle East/Africa24769.0
132015Europe/Middle East/Africa26073.0
162016Asia Pacifi c17313.0
172015Asia Pacifi c16871.0
82017Americas37479.0
92016Americas37513.0
122017Europe/Middle East/Africa24345.0
132016Europe/Middle East/Africa24769.0
162017Asia Pacific16970.0
172016Asia Pacific17313.0
42018Americas36994.0
82018Europe/Middle East/Africa25491.0
122018Asia Pacific17106.0
52019Americas36274.0
62018Americas36994.0
102019Europe/Middle East/Africa24443.0
112018Europe/Middle East/Africa25491.0
152019Asia Pacific16430.0
162018Asia Pacific17106.0
\n", "
" ], "text/plain": [ " Year Region Revenue\n", "8 2009 Americas 40184.0\n", "9 2008 Americas 42807.0\n", "12 2009 Europe/Middle East/Africa 32583.0\n", "13 2008 Europe/Middle East/Africa 37020.0\n", "16 2009 Asia Pacific 20710.0\n", "17 2008 Asia Pacific 21111.0\n", "8 2010 Americas 42044.0\n", "9 2009 Americas 40184.0\n", "12 2010 Europe/Middle East/Africa 31866.0\n", "13 2009 Europe/Middle East/Africa 32583.0\n", "16 2010 Asia Pacific 23150.0\n", "17 2009 Asia Pacific 20710.0\n", "8 2012 Americas 44556.0\n", "9 2011 Americas 44944.0\n", "12 2012 Europe/Middle East/Africa 31775.0\n", "13 2011 Europe/Middle East/Africa 33952.0\n", "16 2012 Asia Pacific 25937.0\n", "17 2011 Asia Pacific 25273.0\n", "8 2013 Americas 43249.0\n", "9 2012 Americas 44556.0\n", "12 2013 Europe/Middle East/Africa 31628.0\n", "13 2012 Europe/Middle East/Africa 31775.0\n", "16 2013 Asia Pacific 22923.0\n", "17 2012 Asia Pacific 25937.0\n", "8 2015 Americas 38486.0\n", "9 2014 Americas 41410.0\n", "12 2015 Europe/Middle East/Africa 26073.0\n", "13 2014 Europe/Middle East/Africa 30700.0\n", "16 2015 Asia Pacifi c 16871.0\n", "17 2014 Asia Pacifi c 20216.0\n", "8 2016 Americas 37513.0\n", "9 2015 Americas 38486.0\n", "12 2016 Europe/Middle East/Africa 24769.0\n", "13 2015 Europe/Middle East/Africa 26073.0\n", "16 2016 Asia Pacifi c 17313.0\n", "17 2015 Asia Pacifi c 16871.0\n", "8 2017 Americas 37479.0\n", "9 2016 Americas 37513.0\n", "12 2017 Europe/Middle East/Africa 24345.0\n", "13 2016 Europe/Middle East/Africa 24769.0\n", "16 2017 Asia Pacific 16970.0\n", "17 2016 Asia Pacific 17313.0\n", "4 2018 Americas 36994.0\n", "8 2018 Europe/Middle East/Africa 25491.0\n", "12 2018 Asia Pacific 17106.0\n", "5 2019 Americas 36274.0\n", "6 2018 Americas 36994.0\n", "10 2019 Europe/Middle East/Africa 24443.0\n", "11 2018 Europe/Middle East/Africa 25491.0\n", "15 2019 Asia Pacific 16430.0\n", "16 2018 Asia Pacific 17106.0" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "geo_revenue_df = (\n", " revenue_df[~( # \"~\" operator inverts a Pandas selection condition\n", " (revenue_df[\"Region\"].str.contains(\"geographies\", case=False))\n", " | (revenue_df[\"Region\"].str.contains(\"total\", case=False))\n", " )]).copy()\n", "geo_revenue_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now every row contains a regional revenue figure. What are the regions represented? " ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Region
8Americas
12Europe/Middle East/Africa
16Asia Pacific
16Asia Pacifi c
\n", "
" ], "text/plain": [ " Region\n", "8 Americas\n", "12 Europe/Middle East/Africa\n", "16 Asia Pacific\n", "16 Asia Pacifi c" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "geo_revenue_df[[\"Region\"]].drop_duplicates()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's strange — one of the regions is \"Asia Pacifi c\", with a space before the last \"c\". It looks like the PDF conversion on the 2016 annual report added an extra space. Allison uses the function `pandas.Series.replace()` to correct that issue." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearRegionRevenue
82009Americas40184.0
92008Americas42807.0
122009Europe/Middle East/Africa32583.0
132008Europe/Middle East/Africa37020.0
162009Asia Pacific20710.0
172008Asia Pacific21111.0
82010Americas42044.0
92009Americas40184.0
122010Europe/Middle East/Africa31866.0
132009Europe/Middle East/Africa32583.0
162010Asia Pacific23150.0
172009Asia Pacific20710.0
82012Americas44556.0
92011Americas44944.0
122012Europe/Middle East/Africa31775.0
132011Europe/Middle East/Africa33952.0
162012Asia Pacific25937.0
172011Asia Pacific25273.0
82013Americas43249.0
92012Americas44556.0
122013Europe/Middle East/Africa31628.0
132012Europe/Middle East/Africa31775.0
162013Asia Pacific22923.0
172012Asia Pacific25937.0
82015Americas38486.0
92014Americas41410.0
122015Europe/Middle East/Africa26073.0
132014Europe/Middle East/Africa30700.0
162015Asia Pacific16871.0
172014Asia Pacific20216.0
82016Americas37513.0
92015Americas38486.0
122016Europe/Middle East/Africa24769.0
132015Europe/Middle East/Africa26073.0
162016Asia Pacific17313.0
172015Asia Pacific16871.0
82017Americas37479.0
92016Americas37513.0
122017Europe/Middle East/Africa24345.0
132016Europe/Middle East/Africa24769.0
162017Asia Pacific16970.0
172016Asia Pacific17313.0
42018Americas36994.0
82018Europe/Middle East/Africa25491.0
122018Asia Pacific17106.0
52019Americas36274.0
62018Americas36994.0
102019Europe/Middle East/Africa24443.0
112018Europe/Middle East/Africa25491.0
152019Asia Pacific16430.0
162018Asia Pacific17106.0
\n", "
" ], "text/plain": [ " Year Region Revenue\n", "8 2009 Americas 40184.0\n", "9 2008 Americas 42807.0\n", "12 2009 Europe/Middle East/Africa 32583.0\n", "13 2008 Europe/Middle East/Africa 37020.0\n", "16 2009 Asia Pacific 20710.0\n", "17 2008 Asia Pacific 21111.0\n", "8 2010 Americas 42044.0\n", "9 2009 Americas 40184.0\n", "12 2010 Europe/Middle East/Africa 31866.0\n", "13 2009 Europe/Middle East/Africa 32583.0\n", "16 2010 Asia Pacific 23150.0\n", "17 2009 Asia Pacific 20710.0\n", "8 2012 Americas 44556.0\n", "9 2011 Americas 44944.0\n", "12 2012 Europe/Middle East/Africa 31775.0\n", "13 2011 Europe/Middle East/Africa 33952.0\n", "16 2012 Asia Pacific 25937.0\n", "17 2011 Asia Pacific 25273.0\n", "8 2013 Americas 43249.0\n", "9 2012 Americas 44556.0\n", "12 2013 Europe/Middle East/Africa 31628.0\n", "13 2012 Europe/Middle East/Africa 31775.0\n", "16 2013 Asia Pacific 22923.0\n", "17 2012 Asia Pacific 25937.0\n", "8 2015 Americas 38486.0\n", "9 2014 Americas 41410.0\n", "12 2015 Europe/Middle East/Africa 26073.0\n", "13 2014 Europe/Middle East/Africa 30700.0\n", "16 2015 Asia Pacific 16871.0\n", "17 2014 Asia Pacific 20216.0\n", "8 2016 Americas 37513.0\n", "9 2015 Americas 38486.0\n", "12 2016 Europe/Middle East/Africa 24769.0\n", "13 2015 Europe/Middle East/Africa 26073.0\n", "16 2016 Asia Pacific 17313.0\n", "17 2015 Asia Pacific 16871.0\n", "8 2017 Americas 37479.0\n", "9 2016 Americas 37513.0\n", "12 2017 Europe/Middle East/Africa 24345.0\n", "13 2016 Europe/Middle East/Africa 24769.0\n", "16 2017 Asia Pacific 16970.0\n", "17 2016 Asia Pacific 17313.0\n", "4 2018 Americas 36994.0\n", "8 2018 Europe/Middle East/Africa 25491.0\n", "12 2018 Asia Pacific 17106.0\n", "5 2019 Americas 36274.0\n", "6 2018 Americas 36994.0\n", "10 2019 Europe/Middle East/Africa 24443.0\n", "11 2018 Europe/Middle East/Africa 25491.0\n", "15 2019 Asia Pacific 16430.0\n", "16 2018 Asia Pacific 17106.0" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "geo_revenue_df[\"Region\"] = geo_revenue_df[\"Region\"].replace(\"Asia Pacifi c\", \"Asia Pacific\")\n", "geo_revenue_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Allison inspects the time series of revenue for the \"Americas\" region:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearRegionRevenue
92008Americas42807.0
82009Americas40184.0
92009Americas40184.0
82010Americas42044.0
92011Americas44944.0
82012Americas44556.0
92012Americas44556.0
82013Americas43249.0
92014Americas41410.0
92015Americas38486.0
82015Americas38486.0
92016Americas37513.0
82016Americas37513.0
82017Americas37479.0
42018Americas36994.0
62018Americas36994.0
52019Americas36274.0
\n", "
" ], "text/plain": [ " Year Region Revenue\n", "9 2008 Americas 42807.0\n", "8 2009 Americas 40184.0\n", "9 2009 Americas 40184.0\n", "8 2010 Americas 42044.0\n", "9 2011 Americas 44944.0\n", "8 2012 Americas 44556.0\n", "9 2012 Americas 44556.0\n", "8 2013 Americas 43249.0\n", "9 2014 Americas 41410.0\n", "9 2015 Americas 38486.0\n", "8 2015 Americas 38486.0\n", "9 2016 Americas 37513.0\n", "8 2016 Americas 37513.0\n", "8 2017 Americas 37479.0\n", "4 2018 Americas 36994.0\n", "6 2018 Americas 36994.0\n", "5 2019 Americas 36274.0" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "geo_revenue_df[geo_revenue_df[\"Region\"] == \"Americas\"].sort_values(\"Year\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Every year from 2008 to 2019 is present, but many of the years appear twice. That's to be expected, \n", "since each of the annual reports contains two years of geographical revenue figures.\n", "Allison drops the duplicate values using `pandas.DataFrame.drop_duplicates()`." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
YearRegionRevenue
82009Americas40184.0
92008Americas42807.0
122009Europe/Middle East/Africa32583.0
132008Europe/Middle East/Africa37020.0
162009Asia Pacific20710.0
172008Asia Pacific21111.0
82010Americas42044.0
122010Europe/Middle East/Africa31866.0
162010Asia Pacific23150.0
82012Americas44556.0
92011Americas44944.0
122012Europe/Middle East/Africa31775.0
132011Europe/Middle East/Africa33952.0
162012Asia Pacific25937.0
172011Asia Pacific25273.0
82013Americas43249.0
122013Europe/Middle East/Africa31628.0
162013Asia Pacific22923.0
82015Americas38486.0
92014Americas41410.0
122015Europe/Middle East/Africa26073.0
132014Europe/Middle East/Africa30700.0
162015Asia Pacific16871.0
172014Asia Pacific20216.0
82016Americas37513.0
122016Europe/Middle East/Africa24769.0
162016Asia Pacific17313.0
82017Americas37479.0
122017Europe/Middle East/Africa24345.0
162017Asia Pacific16970.0
42018Americas36994.0
82018Europe/Middle East/Africa25491.0
122018Asia Pacific17106.0
52019Americas36274.0
102019Europe/Middle East/Africa24443.0
152019Asia Pacific16430.0
\n", "
" ], "text/plain": [ " Year Region Revenue\n", "8 2009 Americas 40184.0\n", "9 2008 Americas 42807.0\n", "12 2009 Europe/Middle East/Africa 32583.0\n", "13 2008 Europe/Middle East/Africa 37020.0\n", "16 2009 Asia Pacific 20710.0\n", "17 2008 Asia Pacific 21111.0\n", "8 2010 Americas 42044.0\n", "12 2010 Europe/Middle East/Africa 31866.0\n", "16 2010 Asia Pacific 23150.0\n", "8 2012 Americas 44556.0\n", "9 2011 Americas 44944.0\n", "12 2012 Europe/Middle East/Africa 31775.0\n", "13 2011 Europe/Middle East/Africa 33952.0\n", "16 2012 Asia Pacific 25937.0\n", "17 2011 Asia Pacific 25273.0\n", "8 2013 Americas 43249.0\n", "12 2013 Europe/Middle East/Africa 31628.0\n", "16 2013 Asia Pacific 22923.0\n", "8 2015 Americas 38486.0\n", "9 2014 Americas 41410.0\n", "12 2015 Europe/Middle East/Africa 26073.0\n", "13 2014 Europe/Middle East/Africa 30700.0\n", "16 2015 Asia Pacific 16871.0\n", "17 2014 Asia Pacific 20216.0\n", "8 2016 Americas 37513.0\n", "12 2016 Europe/Middle East/Africa 24769.0\n", "16 2016 Asia Pacific 17313.0\n", "8 2017 Americas 37479.0\n", "12 2017 Europe/Middle East/Africa 24345.0\n", "16 2017 Asia Pacific 16970.0\n", "4 2018 Americas 36994.0\n", "8 2018 Europe/Middle East/Africa 25491.0\n", "12 2018 Asia Pacific 17106.0\n", "5 2019 Americas 36274.0\n", "10 2019 Europe/Middle East/Africa 24443.0\n", "15 2019 Asia Pacific 16430.0" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "geo_revenue_df.drop_duplicates([\"Region\", \"Year\"], inplace=True)\n", "geo_revenue_df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now Allison has a clean and complete set of revenue figures by geographical region for the years 2008-2019.\n", "She uses Pandas' `pandas.DataFrame.pivot()` method to convert this data into a compact table." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Year200820092010201120122013201420152016201720182019
Region
Americas42807.040184.042044.044944.044556.043249.041410.038486.037513.037479.036994.036274.0
Asia Pacific21111.020710.023150.025273.025937.022923.020216.016871.017313.016970.017106.016430.0
Europe/Middle East/Africa37020.032583.031866.033952.031775.031628.030700.026073.024769.024345.025491.024443.0
\n", "
" ], "text/plain": [ "Year 2008 2009 2010 2011 2012 \\\n", "Region \n", "Americas 42807.0 40184.0 42044.0 44944.0 44556.0 \n", "Asia Pacific 21111.0 20710.0 23150.0 25273.0 25937.0 \n", "Europe/Middle East/Africa 37020.0 32583.0 31866.0 33952.0 31775.0 \n", "\n", "Year 2013 2014 2015 2016 2017 \\\n", "Region \n", "Americas 43249.0 41410.0 38486.0 37513.0 37479.0 \n", "Asia Pacific 22923.0 20216.0 16871.0 17313.0 16970.0 \n", "Europe/Middle East/Africa 31628.0 30700.0 26073.0 24769.0 24345.0 \n", "\n", "Year 2018 2019 \n", "Region \n", "Americas 36994.0 36274.0 \n", "Asia Pacific 17106.0 16430.0 \n", "Europe/Middle East/Africa 25491.0 24443.0 " ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "revenue_table = geo_revenue_df.pivot(index=\"Region\", columns=\"Year\", values=\"Revenue\")\n", "revenue_table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then she uses that table to produce a plot of revenue by region over that 11-year period." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "image/png": "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PPLII/jhhx+gUJhOY7FhwwY88sgj0Ol0iIyMRGhoKE6cOIG4uDj4+vri4MGD0lCNyi5duoThw4cjMzMTHTp0wIABAxAfH4/jx49DoVBg/fr1Uk+JytRqNcaMGYMjR47A3d0dt99+O4qLi7F7925oNBrMmTMH//nPf8y+ztmzZ2PZsmWwtbXF6NGj4eTkhN27dyMvLw9Dhw7F//73Pzg4ONTp2hUUFMDV1RX5+fmcA4KIiIiIiIgaXW3vQ5tlABEfH49ly5YhKioK8fHxyM7OhhACvr6+GDhwIB5//PEahyacPHkS77//Pg4cOID8/Hz4+flh3LhxeOutt+Dr62uxXnp6Ot599138+uuvSEtLg6urK4YPH4433nijxrkYysvL8fHHH2PNmjW4evUqlEolevfujRdeeAGTJ0+u8bWuX78e//3vf3H69GloNBp07NgR06ZNwyuvvAKlUnnzi1UFAwgiIiIiIiJqSi06gKD6YwBBRERERERETam296HNcg4IIiIiIiIiImpdGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OgYQRERERERERNToGEAQERERERERUaNjAEFEREREREREjY4BBBERERERERE1OoW1G0BERNYXn1WMn48n4mhcNuwVNlDZK6CyU0Blr4Cz3Y3HKjsFnO0VUNnZVjy3kR472tpALpdZ+6UQERERUTPFAIKIqI3S6PTYdfE61hxLxMErWbd8PJkMUCkVJuHFjcCiIrSwM4YbtjfCDancsK+TnQK2NuygR0RERNTaMIAgImpjUvJKsO54ItaeSEJGYRkAQ3hwW5gPHujjD1sbOYpKtSgs06KoVIvici0KS7UoKtOiqFSDorJKzyse6/QCQgCFZYZ6t8reVg6VnW1FIGEjBRjOFsMNY28NQ7DhZGcDZztb2NvKIZOxVwYRERFRc8AAgoioDdDpBfbHZmLNsQT89XcG9MKw3UtlhykDgvDwgCAEeTjW69hCCJRp9ZVCCi0KyzQoqnheXHYjzLhRXum5FGhoUKrRAwBKNXqUasqQVVR2S6/bRi4z6V1hsWdGleEkVfd3Uipgw+ElRERERLeEAQQRUSuWUViKDVHJ+OlYIlLySqTtQzp6YmpkCO7o7gul4taGO8hkMtjb2sDe1gbezna3dCyNTm8ILCqFE0UWw4sqvTEqfy/XQghD8JJfokF+ieaW2gUATsrKc2NUDCexU8DDyQ5hvip083NBN38XuNjb3vK5iIiIiFojBhBERK2MEAJH4rKx5lgi/jyfDm1FdwdXB1tM7heIRyKD0dFbZeVWmmdrI4eboxJujspbOo5eL6DW6EzDjIrQompgYbZ3RqUeHBqd4foVl+tQXK7DddTcKyPAzQHd/FzQ3c/ZEEr4uSDYw5ETdBIREVGbxwCCiKiVyFOX45eTht4OcVnF0vZ+Ie6YGhmMe3r6wd7WxootbDrySkMvfF1u7VhlWt2NsMJMeHE9vxQxaQWISStAan4pUvJKkJJXgl0x16VjOCltENbuRiDRzc8FXds5w8mO/w0TERFR28G/fIiIWjAhBE4l5mHNsQT8ejYN5VrDHApOShuMjwjAowND0N3/Fu/A2zg7hQ3sVDbwVN18eEmeuhwxaYVSIPF3eiEuXS9EcbkOpxLzcCoxT9pXJgNCPBwrwggXdKvoMRHo7sCJM4mIiKhVkgkhhLUbQQ2noKAArq6uyM/Ph4sLbzqIWqvCUg22nE7FmqMJ+Du9UNre3c8F0waF4P4+/lDx0/VmQavTIz6rGBfTCkzCCeMKJFU52yvQrVIg0c3PBWHtnNtM7xUiIiJqeWp7H8oAopVhAEHUul1IzceaY4nYGp2C4nIdAMBOIcf9vf0xdVAIege68tPzFiK7qMwkkLiYVoCrmUXSnBOVyWVAey8nKZDoXvHd18WO/95ERERkdQwg2igGEEStT0m5Dr+eTcWaY4k4nZQnbe/o7YSpkSGYGBEIV0euvNAalGv1uJJRhL/TCyqCCUNAkV1cbnZ/d0fbiuEbN3pMdPZVwU7B3hJERETUdBhAtFEMIIhajysZhVhzLBEbTyajoFQLALC1keGuHn6YGhmMyPYe/PS7DRBCILOwrNoQjrisYuj01f8LV8hl6OitMhnC0c3P5ZaXSCUiIiKyhAFEG8UAgqhlK9fq8eeFdKw5loCjcTnS9iAPBzw6MAST+wfCqxaTIVLrV6rR4fL1Imn4hjGYMIZVVXmp7NDNz1kavtHVzxkdvVWwtZE3ccuJiIiotWEA0UYxgCBqmZJy1PjpeCI2RCUhq8jQ3V4uA0Z388XUyGCM6OwNuZy9HahmQgikVVoW1NhjIj67GOb+t1fayNHJRyUN4TCGE+5OyqZvPBEREbVYDCDaKAYQRC2HVqfHX39nYM2xROy/nCndIPq62GHKgGBMGRgEP1cH6zaSWgV1uRaX0gurLRFaVGa+t0Q7F/tqQzjaeznBhiEYERERmcEAoo1iAEHU/KXnl2LdiSSsPZGItPxSafuILt6YGhmM0V19oGC3eGpker1Acm4JYtILTHpMJOaoze5vbytHmK8hlOjaruK7nwtcHTgBKhERUVvHAKKNYgBB1Dzp9QIHr2RhzbEE7IrJkCYP9HBSYnL/QDw6MBghnk5WbiURUFiqqegtUYCLFT0mLqUXokSjM7t/gJtDxdKgN3pMBHs4csgQERFRG8IAoo1iAEHUvGQXlWHDyWT8dCzR5JPlge09MDUyGHf1aMclE6nZ0+kFErKLTYZwxKQVILVSD57KnJQ2CGtnOoSjaztnONkpmrjlRERE1BQYQLRRDCCIrE8IgePxOVhzLBF/nE9HuU4PAHC2V2BiRCCmRgajs6+zlVtJdOvy1ZpqQzguXS9EuVZvdv8QT0d0a+eCnoGuGNzRE70CXDnciIiIqBVgANFGMYAgsp78Eg02n0rGmmOJuJxRJG3vHeSGqZHBuK+XPxyU7O1ArZtWp0d8VnHF0qA3ekxkFJZV21dlp8DA9h4Y0tETgzt6ols7Fw7dICIiaoEYQLRRDCCImpYQAmeT87HmWAK2nUlFqcbwya+DrQ0e7OuPRweGoGegq5VbSWR92UVl+Du9EBdTC3AyIRdH4rKRX6Ix2cfd0RaDOnhiSEdPDOnkhQ5eTpDJGEgQERE1dwwg2igGEERNo7hMi21nUrHmWALOpxRI28N8nTFtUDAe6BsAF3uuDkBkiV4vcDGtAEeuZuPw1Swcj89BcbnpRJe+LnYY0tELgzsaQolAd0crtZaIiIhqwgCijWopAYROL7iePLVIf6cX4Kdjidh8KgWFZVoAgFIhx7iefpg6KBgRwe78xJaoHjQ6Pc4m5+PI1SwcvpqNqITcanNJBHs4SsM1Bnf0hI+zvZVaS0RERJUxgGijWkIAka/W4I6l+3BHd19MiAhERLAbb9ioWSvV6PD7+TSsOZqIqIRcaXuopyOmRoZgYr9AeDgprdhCotanVKPDqcTcih4S2TidlCctX2vU2UdVEUh4YVAHD7g58ueQiIjIGhhAtFEtIYDYEJWEf/5yVnoe6umICRGBGN83AEEe7F5LzUd8VjF+OpaADSeTkac2jFVXyGUYG+6LqZEhGNzBkxPmETWRojItTlzLkYZsXEgtQOW/YGQyINzfRRqyMSDUAyou+0lERNQkGEC0US0hgNDrBY7GZWPjqRT8fj4N6kpjfge298CkiEDc3bMdnDl+nqxAo9PjfxevY82xBBy6ki1tD3BzwCMDg/BQ/yD4uLDbN5G15anLcTQuRxqyUXnlGcAQFvYOcpOGbEQEu8PelqvQEBERNQYGEG1USwggKisu0+LPC+nYdCoFh65mSZ9m2SnkuDO8HSZEBGBYJy+uE0+NLiWvBGuPJ2LtiSRkViwXKJMBt4X5YGpkMEaF+XDeEqJmLKOgFEfisnH4SjYOx2UhKafEpFypkKN/iLs0ZKNXoCts+X8LERFRg2AA0Ua1tACisrT8EmyJTsXGU8m4UumTLG9nOzzYxx8T+wWia7uW9ZqoedPpBfbFZmDN0UTsuZQB4/ByL5UdpgwIwpSBQZx1n6iFSspRS8M1Dl/NRkZFsGjkpLTBwPYe0pCN7n4uHFJFRERUTwwg2qiWHEAYCSFwLiUfm06lYOvpFOSqb6wT393PBRMiAvBAnwB4O9tZsZXUkmUUlmL9iST8fDwJKXk3PiUd2skTUyNDMKabL5QKfjJK1FoIIXA1s1garnEkLlua18XIzdEWg9p7Ykgnw5KfHb1VnCCZiIiolhhAtFGtIYCorFyrx77YTGw6lYzdMRko1xmWZLORyzCyizcmRARgTDdfjuulmxJC4MjVbKw5log/L6RDW9HdwdXBFpP7BeKRyGB09FZZuZVE1BT0eoGY9AJphY1jcdkorjQfEWDofTeko2fFlxcnSSYiIqoBA4g2qrUFEJXlqcux/WwaNp1KRnRinrTd2V6Bcb38MCEiEP1D3PmJFZnILS7HxlPJ+OlYIuKyiqXt/ULcMTUyGPf09GOARdTGaXR6nEvJl4ZsRF3LRZlWb7JPoLuDFEYM7ugJX05GS0REJGEA0Ua15gCisrjMImw6lYLN0SkmXeiDPRwxISIAE/oGItiTn1a1VbnF5TgSl43/XbyO386lobziRkJlp8D4vgF4NDIY3fxa788HEd2aUo0O0Yl50pCN00l5Uq8po04+KqmHRGR7T7g7Ka3UWiIiIutjANFGtZUAwkivFzgWn4NNp5Kx41yaSRfaAaHumBARiHt6+sHVgUt6tmbFZVocv5aDI1ezcehKFi6mFaDyb7bufi6YNigE9/fxh8pOYb2GElGLVFymxYmK3zGHr2bjfGq+ye8Ymczwe8bYQ2JAew/+riEiojaFAUQb1dYCiMpKynXYeTEdv5xMxqErWdKKBkqFHHd098WkiEAM78wlPVuDcq0ep5PycOhKFg5fzUJ0YvVPJ7v4qjCkoxce7BuA3oGuHJpDRA0mX63B0fhsachG7PUik3IbuQy9A10xpKMXhnT0RESIO4d6ERFRq8YAoo1qywFEZen5pdh6OgUbTyWb/GHopbLDA338MSEiAOH+rlZsIdWFTi8Qk1aAQ1eycOhqNk7E56BEYzphXICbA4Z28sTQTobx2T7OHJ9NRE0jo7AUR+NypCEbCdlqk3KlQo5+we6GHhKdPNEr0A22DMOJiKgVYQDRRjGAMCWEwIXUAmlJz+zicqmsaztnTIwIxAN9/OHDycSaFSEE4rKKcfhKFg5dMSyZl19iumSep5MSgzsaAoehHb0Q5OHAXg5E1Cwk56oNy31W9JC4XlBmUu6otMHA9h7SkI1ufi6wkfP3FxERtVwMINooBhCWaXR67I/NxKZTKfjfxevSkp5yGTC8s2FJz7Hd28FByW6y1pCWX4JDV7Jx+IrhE8T0glKTcpWdApHtPTCkkxeGdvJEFx9nyPkHOxE1c1KgejUbR65m4cjVbOSqTQNVVwdbDOrgIQ3Z6OSjYqBKREQtCgOINooBRO3kqzX47VwaNp5KxsmEXGm7yk6Be3q2w8SIQAwI9eANbiMyrlRx+GoWDl/JNlkiEwCUNnL0C3HH0E6eGNzRC70DXTl/BxG1eHq9wN/phThcEUYci89BUZnWZB8vlZ20wsYQ9vAiIqIWgAFEG8UAou6uZRVjU3QKNp1KRnLujSU9A90dMKFvAMZHBKK9l5MVW9g6GGeRP2xhpQq5DOgZ6IahFX9w9w/lpG1E1PppdXqcS8mXhmycuJaDsoqlg40C3BwwupsPpkaGIKyds5VaSkREZBkDiDaKAUT96fUCUQm52HgyGb+dSzP5RCoi2A0TIgJxXy9/uDpySc/aqLpSxemkPGh05leqGNLRE5EdPLlcKhG1eWVaHaIT86QhG1VX+RkQ6o5pg0JwV492sFMwpCUiouaBAUQbxQCiYZRqdNh58To2nUrG/tjMG0t62sgxprsPJvQNxMgwb85iXoleL3CRK1UQETWo4jItjsfnYMPJJPx54Tp0Ff8heTopMbl/EKZGBiPIw9HKrSQioraOAUQbxQCi4WUUlGLbmVT8cjIZf6cXSts9nZS4v48/JkYEItzfpc2Nz626UsXR+GzkqblSBRFRY7leUIq1x5Pw8/FEaaJemQwY2cUb0yJDcFtXH66mQUREVsEAoo1iANG4LqYWYNOpZGw5nYqsohvLqnXxVWFCRCAe7BOAdq6t91N9aaWKiokjuVIFEVHT0+r02P13BlYfTcCBy1nS9gA3BzwyMAgPDQhiDzMiImpSDCDaKAYQTUOr0+PAlSxsPJmMnRevo7xiwjCZDBjWyQsTIwIxNtwXjkqFlVt6a3KLy3E0LhuHuFIFEVGzdC2rGD8dT8SGqCRpeU+FXIY7w9th6qBgDO7gyZ5nRETU6BhAtFEMIJpefokGv59Lw6ZTKTh+LUfa7qS0wd09/TAhIgCD2nu2iJ4AtV2pYkhHTwzlShVERM1GqUaHHefSsPpoAk4l5knbO3o7YWpkCCb2C+REv0RE1GgYQLRRDCCsKzFbjc3RKdgUnYyEbLW0PcDNAQ/29ceEiEB09FZZsYWmuFIFEVHrczG1AKuPJWBLdArU5YbJgO1t5XigdwCmDQpBz0BXK7eQiIhaGwYQbRQDiOZBCIGTCbnYeCoFv55NRWHpjSU9+wS5YWJEAMb18oe7k7JJ28WVKoiI2o7CUg22RKdg9dFEXLp+YxLl3oGumBoZgvt6+8NByV5sRER061plAPGvf/0LH330EQBg8eLFePPNN83ut2vXLnz88cc4fvw4iouLERISgokTJ2L+/PlQqSx/+nzlyhW8++672LVrFzIzM+Ht7Y0xY8ZgwYIF6NChg8V6hYWFWLJkCTZu3IjExEQ4OTkhMjISr776Km6//XaL9fR6PZYvX47vv/8eFy9eBAB0794ds2bNwlNPPVWvMZsMIJqfUo0Ou2MysOlUMvbGZkpLqNnayHB7Vx9MjAjEqDAfKBUNP3dC5ZUqDl/NxpE4rlRBRNTWGEPxH48m4Pdz6SjXGeYtcrFXYGK/QEyNDEEnn+bTO4+IiFqeVhdAHD58GMOHD4cQAkIIiwHE0qVLMWfOHMhkMgwfPhy+vr44cOAA0tPTERYWhoMHD8LLy6tavUOHDmHs2LFQq9UIDw9Hjx49cP78eVy4cAFOTk7YtWsXBg0aVK1eRkYGhg8fjtjYWPj5+WHYsGG4fv06Dhw4AAD49NNP8eKLL1arp9Pp8NBDD2HTpk1wdHTE6NGjARjCk5KSEkyePBlr166FXF63m1IGEM1bZmEZtp1JxaZTybiQWiBtd3e0xf29DUM0egW63lIAkJZfgsNXbkwcyZUqiIjIKLuoDOujkvHT8QQk5ZRI2wd38MS0QSEYG+4LW04mTEREddSqAgi1Wo0+ffpArVZjwIAB2LJli9kAIjo6Gv369YNcLsf27dtx9913S/Xvv/9+7N69GxMnTsQvv/xS7fidO3dGamoq5s+fj/fff18qe/3117FkyRIEBQXh0qVLcHBwMKn74IMPYuvWrRg9ejS2bdsGR0dHAMCOHTtw//33QwiB6Oho9OrVy6TeJ598gldeeQUBAQE4cOAA2rdvDwCIj4/HsGHDkJqais8++wwvvPBCna4VA4iW4+/0Amw6lYLN0SnILLyxpGcnHxUmRATgwT4B8HdzqOEIBlypgoiI6kqvF9h3ORNrjibgr78zUNE5D97OdpgyIAiPDAyu1f9BREREQCsLIGbPno1ly5bht99+w/r167Fq1SqzAcRDDz2EDRs24Mknn8Ty5ctNyhISEtChQwfo9XrExMSga9euUtkXX3yB559/Hl26dEFMTIxJrwO9Xo9u3bohNjYWX331Ff7xj39IZRcvXkR4eDhsbGxw9epVhISEmJzzySefxHfffYcpU6bg559/NjlmQEAA0tPTsXr1akydOtWk3urVq/HYY4/B398fSUlJdeoFwQCi5dHq9Dh0NRubTiXjzwvpKNXcWNJzSEdPTOgbiLt6tIOTnWFJT3W5FsfjuVIFERE1jJS8Evx8LBFrTyQhq8gQiMtlwO1dfTFtUDBGdPZmTzkiIqpRbe9DFU3YpnrZu3cvPvvsM0yfPh333HMP1q9fb3a/8vJy/PbbbwCARx99tFp5SEgIhg4digMHDmDz5s2YP3++VLZ582YAwJQpU6rd7Mvlcjz88MNYvHgxNm3aZBJAGOsNHTq0WvhgbMd3332H7du3Q6PRwNbWsHrAkSNHkJ6eDjs7O0ycOLFavYkTJ2LWrFlITU3FsWPHMHjw4BqvEbVsChs5Rnbxxsgu3igs1eD38+nYeDIZx+JzcOhKNg5dycabW87j9m4+yCwoQ3RSLleqICKiBhPg5oDX7gzDS6M7Y+fFdKw5mogjcdnYFXMdu2KuI9jDEY9GBuOh/kHwaOLJk4mIqHVp1gFEUVERnnjiCfj6+uKTTz6pcd/Y2Fio1YZlD/v37292n/79++PAgQOIjo422W58XlO9yvvVtV5xcTEuX76M7t27m9QLDw+HvX31FQYcHBwQHh6O6OhoREdHM4BoQ5ztbfFQ/yA81D8ISTlqbIlOwaboFMRnFeO3s2nSflypgoiIGppSIce4Xv4Y18sfVzKKsOZYAn45mYzEHDU++P1vfLwzFvf0bIdpg0LQL8SdExYTEVGdNesA4rXXXkN8fDw2b94Md3f3GveNj48HALi5ucHZ2dnsPkFBQSb7AoYVLLKzswEAwcHBNdbLzMxEcXExnJycTI5jqZ6LiwtcXFxQUFCA+Ph4KYC4WT3jOaOjo03aSm1LkIcjXhzdGS/c3gnRSXnY83cG/N0cuFIFERE1uk4+Krx9Xzj+dWdXbD+TitXHEnA2OR9bTqdiy+lUdG3njKmDQjC+bwBUds36z0kiImpGmu3/GDt37sTXX3+NKVOm4MEHH7zp/oWFhvWtjeGAOcYlOAsKbqw+YKxXU93KS3cWFBRI+9X2nAUFBWbPWde2mlNWVoayshsTGN5sf2p5ZDIZIoLdERFccwhHRETU0ByUNnhoQBAeGhCEM0l5WH00AdvPpuLv9EK8teU8PtgRgwf7BmDaoBB08+PcU0REVLNmORV+fn4+Zs2aBW9vb3z22WfWbk6ztmTJEri6ukpfxt4aRERERA2pd5AbPprcG8fmj8Fb47qjg7cTist1WHMsEXd/egATvzyMzdHJKNXorN1UIiJqppplAPHyyy8jOTkZn3/+Oby8vGpVxzjsori42OI+RUVFAGAyK2fl4RqW6hrrWapb33PWtZ458+fPR35+vvSVlJRU4/5EREREt8LV0RazhrXH7jkj8dOTkbinZzso5DKcTMjFK+vOYPCS3ViyIwYJ2Zb/ziEiorapWQ7B2Lx5MxQKBb744gt88cUXJmV///03AOC7777Drl270K5dO6xduxahoaEAgLy8PBQWFpqdB8J4c27cFzCEAR4eHsjJyUFiYiJ69+5tsZ6Xl5fJsInQ0FCcOnUKiYmJZl9H5aEXlc9pfGypnqW2mmNnZwc7O7sa9yEiIiJqaDKZDEM6eWFIJy9kFJRi3Ykk/Hw8Ean5pfh6fxy+3h+HEV28MS0yGLd39YHCpll+7kVERE2oWQYQAKDVarFv3z6L5deuXcO1a9ek5S/DwsLg6OgItVqNqKgo3HbbbdXqREVFAQAiIiJMtkdERGDXrl2IiorCfffdV6d6mzZtksot1XNyckKXLl1M6gHAhQsXUFpaWm0ljJKSEly4cMHsOYmIiIiaGx8Xe7w4ujOeHdURey5lYvXRBOy/nIn9sYYvP1d7PDIwGFMGBMHHhSs3ERG1Vc0yis7Ly4MQwuzXjBkzAACLFy+GEALXrl0DACiVStx7770AgJ9++qnaMRMSEnD48GEAwPjx403KjM/Xrl0LvV5vUqbX67Fu3ToAwIQJE0zKjJNjHjp0yGxvBmM77rvvPtja2krbBw8ejHbt2qGsrAwbN26sVm/jxo0oLy+Hv78/IiMjzVwhIiIiouZHYSPHHd19seqJgdj32m34x8gO8HBSIi2/FB//LxZDPvgLz605icNXsiCEsHZziYioiTXLAKK+5s2bB5lMhhUrVuCPP/6QtqvVasyaNQs6nQ4TJ05E165dTerNnDkT/v7+iI2NxVtvvWVS9tZbbyE2NhaBgYGYPn26SVl4eDgeeOAB6HQ6zJo1CyUlJVLZ77//jpUrV0Iul2P+/Pkm9eRyOebOnQsAmDt3rslSm/Hx8Zg3bx4Aw/wOcnmr+iciIiKiNiLY0xHz7+6Gw/NuxycP90G/EHdo9QI7zqXj0W+PYfTH+/DdwXjkqzXWbioRETURmWhh8fPMmTOxatUqLF68GG+++Wa18qVLl2LOnDmQyWQYOXIkfHx8cODAAaSlpSEsLAwHDx40O7HloUOHMHbsWKjVavTo0QM9evTA+fPncf78eTg5OWHXrl0YNGhQtXoZGRkYNmwYLl++DD8/PwwfPhwZGRnYt28fhBD49NNP8dJLL1Wrp9PpMHnyZGzevBmOjo4YM2YMAGDXrl1Qq9WYNGkS1q1bV+cAoqCgAK6ursjPz7/pBJZERERETSkmrQCrjyZgS3QKissNq2XY28pxXy9/TBsUgt5BbtZtIBER1Utt70NbXQABGG7i//Of/+D48eMoLi5GcHAwJk2ahPnz55udnNLoypUrWLx4MXbt2oXMzEx4e3tjzJgxWLBgATp27GixXkFBAZYsWYKNGzciMTERTk5OGDhwIF577TWMHj3aYj29Xo/ly5fj22+/RUxMDACge/fumDVrFp5++mnIZLJaXhXTtjCAICIiouasqEyLzdEpWHM0AX+nF0rbewa4YtqgYNzX2x+OymY7VRkREVXRagMIqhkDCCIiImophBA4mZCLNccS8dvZNJTrDHNxOdsrMDEiENMGBaOTj+UPj4iIqHlgANFGMYAgIiKiliinuBwbopKw5lgiEnPU0vZBHTwwbVAIxnZvB6WCc2MRETVHDCDaKAYQRERE1JLp9QIHrmRh9dEE7I65Dn3FX6peKjtMGRCEKQODEOjuaN1GEhGRCQYQbRQDCCIiImotUvNKsPZ4In4+kYTMwjIAgFwG3Bbmg2mDQjCiizds5HWfM4uIiBoWA4g2igEEERERtTYanR47L1zH6qMJOBKXLW0PdHfAo5HBeKh/ELxUdlZsIRFR28YAoo1iAEFERESt2ZWMIqw5loCNJ5NRUKoFACht5LirRztMGxSCAaHu9VpJjIiI6o8BRBvFAIKIiIjagpJyHbafTcWaowk4k5wvbQ/zdcbUQcG4vasP/FwdOESDiKgJMIBooxhAEBERUVtzLjkfq48mYOuZFJRq9NJ2pY0cge4OCPZ0RIiHI4I9nRDi4YgQT0cEeTjC3tbGiq0mImo9GEC0UQwgiIiIqK3KL9Fg06lkbIhKxuWMQmh0Nf+Z287FXgonQjwNAUWwh+G5m6Mth3IQEdUSA4g2igEEEREREaDTC6TmlSAxR42EbDUScoqRVPE4MVuNwjJtjfWd7RUI8XREiIdTpR4UjgjxdIKfiz3kHNpBRCRhANFGMYAgIiIiqpkQArlqDRKyi28EFNlqJOYUIyFbjYyKJT8tUdrIEejhUNFzoqLXhKfhK9CdQzuIqO2p7X2oognbRERERERkdTKZDB5OSng4KdE32L1aeUm5riKYqBRQ5KiRlKNGcq4a5To94jKLEZdZDCCzWn1zQzuMj90clU3wComImif2gGhl2AOCiIiIqPGYG9qRKPWgUKPoJkM7XOwVhl4TlQMKDyeEeDqiHYd2EFELxSEYbRQDCCIiIiLrEEIgp7gcCTlqKZQwBhSJORzaQUStV6MOwcjLy8Off/6J3bt349SpU7h+/Tpyc3Ph7u4OX19f9OvXD7fffjvuvPNOuLm51fc1EBERERG1GDKZDJ4qO3iq7BBhZmiHulyLpJySakM7ErOLkZxbUuPQDpmsYmiHFEpUCig8nODqaNtEr5KIqP7q1APi3Llz+PTTT/Hzzz+jtLQUNVWVyWSwt7fHo48+ihdffBG9evVqkAZTzdgDgoiIiKjl0er0SMsvrTaswxhQFJfraqzPoR1EZE0NOgQjIyMD8+fPx6pVq6DX6+Hl5YVRo0ZhyJAhCA8Ph6enJ1xcXJCfn4/s7GycP38ehw8fxv79+5GVlQW5XI6ZM2fi/fffh4+PT4O+UDLFAIKIiIiodalpaEdCjhqZNxvaoZAjyN2h2rCOYA8nBHk4wE7BoR1EdGsaNIBwdXVFYWEhxo0bh1mzZuHee++FQnHz0RtarRbbt2/H999/j99++w2urq7Izc2t2yuhOmEAQURERNS2qMu10pCOxIpwwjgpZkpuCbT6mnotG4Z2BHk4wlFpAxkMPZkNHSZkkMkAGQC5rOKxDJDBsFEuk1Xsf2MfVJTLZIC80mNZxfHklY4hqzgGUHWboQ0VVaqcx3g8023ScSsd7+b1ALnceB6Z6eusoZ5xH7lMBpW9Am4OtnB1sIWboxIu9goobOQN/m9M1Nw1aABxxx134IMPPkC/fv3q3aATJ07g9ddfx//+9796H4NujgEEERERERnd6tAOqjuVnQKuUihx47uLcZuD0qTM1cEWro62cLZTSAEKUUvDVTDaKAYQRERERFQbQghkF5cjIVuN5Fw1yrR6QAACAnoBiIrHhu+G/YWo+A5Dub7iVqLyvvpKjwFAr7+xv3Q8UX2bsR4qna9aOyzUg1Revf3G4+mFmddioZ50PDP1ULFNpxcoLNUiT61BQYkGhTdZgvVm5DJUCiQqQgoHW5Mww6XSNreKfVwdbGFvK2d4QVbVqKtgEBERERFRyyaTyeClsoOXyg79Qqqv2kF1o9XpUVCqRX6JBnnqcuSXaG58qTXIq3hsDCzySm7sU6rRQy+AXLUGuWoNkK2u07mVCnm1wMLVsXKPC4UUWLhU6X1hyyEj1IQYQBAREREREd0ihY0cHk5KeDgpATjVqW6pRlcRStwIKW6EF4agIq9KoGHcptMLlGv1yCwsu+mEpOY4KW0M81c42BqCikpDRFyqDiWpKDMOGeHqKlRXDRpAFBYWYt++fSgtLcXAgQMRHBzckIenVkIIgU9OfYL7OtyHTu6drN0cIiIiIiKrsre1gb2tDXxc7OtUTwiB4nKdaY+LSuFE9W3lUsBRWGoYMlJcrkNxeQlS8krqdG65DHC2rzKXRZXeFW4OSpMeF+6OSniqlOx10YbVKYCIiYnBkSNHEBERgT59+piU7dmzB5MnT5ZWuZDL5Zg7dy7efffdBmsstQ5/JvyJ789/jx8u/ICZPWbi6V5Pw0HhYO1mERERERG1KDKZDCo7BVR2CgTWcRSNYQ6LG70tTAOLcpOeGHklhmEjxm0lGh30AtL+dWsz4OlkBx9nO/i62MHXxR4+LvaGx872Fc/t4Omk5IoirVCdJqF89tln8c0332Dv3r0YPny4tL2wsBCdOnVCZmYmevfujeDgYOzatQulpaVYt24dJk2a1CiNp+pawiSU6cXpWHJsCf5K+gsAEKAKwJuD3sSwgGFWbhkREREREd1MmVaH/IpQovJwEZOhI9K2cpPympaFrUwuA7xUhoDC18UOPi72FaFFxfOKsMLTScmhIM1Ao6yCERERgaysLCQmJpps/+qrr/Dcc89h0qRJWLduHWQyGQ4fPowRI0bgtttu49KbTaglBBBGfyX+hfePvY/r6usAgLtC78K/BvwL3o7eVm4ZERERERE1NL1eIFddjusFZbheWIqMglLD44rvmYUV34vKoKtlUKGQy+DtbOhRYa4nhW9FcOHuyKCiMTVKAOHr64tBgwZh69atJtvHjx+Pbdu24eTJkyZDM+68805ERUUhOzu77q+A6qUlBRAAUKwpxn9P/xdrYtZAL/RQ2aowO2I2JneZDBu5jbWbR0RERERETUynF8guLkNGRTiRUXgjpMgoKMX1iqAiu6gMtcwpYGsjg49zRSjhbK5XhWGbq4MtlzSthwYNIBYtWiR979GjByZMmGBS/vnnnyMnJwdvvvkm5PIb43T++OMPHD9+HAsWLJC2VX5MDa+lBRBGMdkxWHRkEc5nnwcA9PTqiQWDF6CrR1crt4yIiIiIiJojrU6P7OJyKZy4XnCjV0VG4Y3vWUXltT6mUiGvNMTjxlAP43wVvi528Ha2h4u9gkFFJbW9D63VJJTx8fEAKmZZLS6WngOG+R+ysrIQEhKChIQEk3plZWUm9fkPRJZ08+yG1fesxrpL67AsehnOZZ3DlF+nYFq3aXiuz3NwtHW0dhOJiIiIiKgZUdjIpd4LNSnX6pFVVH2ox/WCUlwvrOhVUVCKXLUG5Vo9knJKkJRT86og9rYV53Y2HepReeiHr4s9VHYNuvBki1enIRienp4IDQ3FyZMnpW2bNm3CpEmTMHfuXCxZssRk/3nz5mHVqlVIS0truBZTjVpqD4jKMtQZ+PD4h9iZsBMA4Ofkh9cjX8eooFHWbRgREREREbVaZVodMgvLbgz1qAgorheUVmw3BBd1WfnDSWkDXxd7eFeaQFNa+aNSYOGobNlBRaPMATF27Fjs3r0bX331FZ566ink5uZizJgxOH36NA4cOIAhQ4aY7H/PPfcgIyMDUVFR9X8lVCetIYAw2p+8H+8fex8pRSkAgNHBozFv4Dy0c2pn5ZYREREREVFbVarRGeanKCytGPZhnFTTGFIYHheWaWt9TGc7hUnPCZ9Kw0AGhHrctJeHtTVKAPHHH3/gnnvugUwmg5ubG4qLi1FeXo7hw4dj3759Jvvm5eXB398fM2bMwJdffln/V0J10poCCAAo0ZbgqzNf4YcLP0ArtHBUOOLFvi/ika6PcJJKIiIiIiJqttTl2huhRKWhHsa5KTIKypBeUAp1ua7G43w1LQJ39fBrolbXT4POAWF01113YeXKlZg3bx7S09Mhk8kwduxYrFq1qtq+n376KUpLSzF+/Pi6t56ogoPCAa/0ewX3drgXi44swpnMM/jwxIfYdnUb3h78NsK9wq3dRCIiIiIiomoclQqEeikQ6uVU435FZVqp50TloR7GnhRBHq1nPrw69YCo7Pr163B0dISzs7PZ8vT0dJSVlSE4OJiTTzah1tYDojK90GPj5Y1YenIpCssLIZfJ8UjXR/BCnxegUqqs3TwiIiIiIqI2qVGGYFDz15oDCKOskix8dOIj7IjfAQDwcfDB/Mj5GB08mmEXERERERFRE2MA0Ua1hQDC6HDqYbx39D0kFiYCAEYGjsTrka/DX+Vv5ZYRERERERG1HU0eQGzcuBFbtmxBVlYWAgMDMWXKFIwePbohDk110JYCCAAo1ZZi+bnl+P7899DqtXBQOODZ3s9iWvdpsJXbWrt5RERERERErV6DBhC7du3C66+/jgkTJmDevHnVyp944glpIkrj4WQyGV5//XUsXry4vq+B6qGtBRBGcXlxWHR0EU5ePwkA6OLeBQsGL0Bv795WbhkREREREVHrVtv7UHltDvbnn3/i5MmTGDZsWLWy9evXY+XKlRBCoG/fvnjttdfw0EMPQSaT4f3338exY8fq/yqIaqmDWwesuHMFFg1ZBDc7N8TmxuKxHY9h8ZHFKCgvsHbziIiIiIiI2rxaBRBHjhyBp6en2QBi2bJlAICxY8fi+PHj+Pe//421a9fiv//9L4QQ+O677xq2xUQWyGQyjO88Htse3IYHOj4AAYH1setx/+b78Xv87+B0J0RERERERNZTqyEYoaGh6Nq1K/744w+T7QUFBfDw8IAQAgcOHMCQIUOkMp1Oh6CgILi7u+PChQsN33Iyq60OwTDnRPoJLDqyCNcKrgEAhvgPwZuRbyLIJci6DSMiIiIiImpFGnQIRmZmJry9vattP3HiBPR6PVxdXTF48GCTMhsbG/Tu3RtJSUl1bDpRwxjQbgA23r8Rz/d5Hkq5EodTD2P8tvFYfnY5NDqNtZtHRERERETUptQqgBBCIDc3t9r2U6dOAQAiIiIgk8mqlXt6eqKsrOwWm0hUf0obJZ7p/Qw2PbAJkX6RKNOVYVn0MkzePlmasJKIiIiIiIgaX60CiICAAJw9e7baGPp9+/ZBJpNhwIABZuvl5eWZ7TlB1NRCXEKw/I7lWDJ8CTzsPXA1/ypm/jETbx9+G3mledZuHhERERERUatXqwBi+PDhSElJweeffy5tu3DhAnbu3AkAuOuuu8zWO3PmDPz8/BqgmUS3TiaTYVyHcdj24DZM7DwRALDp8ibcv+V+bLu6jZNUEhERERERNaJaTUIZHR2NAQMGQAiBwYMHw8fHB7t370ZRURG6du1qdpLJc+fOoXfv3nj66afx1VdfNUrjqTpOQll70RnRWHRkEa7kXQEARLaLxBuD3kB71/ZWbhkREREREVHL0aCTUPbt2xdLly6FTCbD4cOHsWXLFhQWFkKlUmHFihVm6yxfvhwAMHr06Ho0n6jx9fXpi/Xj1mN2xGzY29jjWPoxTNw2EV+c/gJlOs5dQkRERERE1JBq1QPC6Ny5c9iwYQOuX7+O4OBgzJgxA4GBgWb3feONN6BWq7FgwQK4u7s3WIOpZuwBUT9JhUl479h7OJRyCAAQ6hKKtwa9hYF+A63cMiIiIiIiouattvehdQogqPljAFF/Qgj8mfAnPjz+IbJKsgAA93W4D68NeA0e9h5Wbh0REREREVHz1KBDMIjaAplMhrtC78K2B7fh4bCHIYMM2+O2477N92HT5U3QC721m0hERERERNRisQdEK8MeEA3nbOZZLDqyCJdyLwEAInwisGDwAnR062jllhERERERETUfDdoDwsbGplZfrq6u6NmzJ15++WXExcU12IshsoZe3r2wdtxavNb/NTgoHHAq4xQmbZ+EZaeWoVRbau3mERERERERtSi16gEhl9dtpIZMJoO9vT1Wr16N8ePH17txVHfsAdE40orS8P7x97E3aS8AIFAViDcHvYmhAUOt2i4iIiIiIiJra9BJKPft23fTEwohUFRUhMuXL+OXX37BkSNH4OjoiHPnzqF9+/Z1az3VGwOIxrU7cTfeP/Y+MtQZAIC7Q+/Gvwb+C14OXlZuGRERERERkXVYfRWMt99+G4sXL8bLL7+Mjz/+uDFOQWYwgGh8xZpifB79OX76+yfohR7Ots6YHTEbk8MmQy7jvK5ERERERNS2WD2A0Ol0CAkJgYeHB86ePdsYpyAzGEA0nYvZF7HoyCJcyL4AwDBnxIJBCxDmEWbllhHVT1pRGq4VXENPr55QKVXWbg4RERERtRBWDyAAYMKECdi9ezfy8/Mb6xRUBQOIpqXT67D20lp8Fv0ZijXFsJHZ4LHuj+HZ3s/C0dbR2s0jqpFWr8WZzDPYn7wfB1IO4HLuZQCAQq7AwHYDMSpoFEYFjoKfys/KLSUiIiKi5qxZBBDTpk3Dhg0bUFZW1linoCoYQFjH9eLr+PDEh/hfwv8AAH5Ofngj8g2MDBpp5ZYRmcotzcXBlIM4kHwAh1IPoaC8QCqTy+TwcvCS5jgx6urR1RBGBI1Cd4/ukMlkTd1sIiIiImrGmkUAMXz4cFy5cgVpaWmNdQqqggGEde1P3o/3jr6H1OJUAMCY4DGYN3AefJ18rdwyaquEELiUewn7k/djf/J+nM08C4Ebv/ZdlC4YGjAUIwJHYJj/MLjZuyE+Px57k/Zib9JeRGdEm+zv4+iD24Juw6igURjYbiCUNsqmf1FERERE1KxYPYC4fPkywsPDcccdd+C3335rjFOQGQwgrE+tUeOrs1/hhws/QCd0cLJ1wot9X8SUsCmwkdtYu3nUBqg1ahxJO4IDyQdwIPkAMkpMezR0ce+C4QHDMSJwBHp594JCrrB4rJzSHOxP3o+9SXtxOPUwSrQlUpmjwhFDA4ZiVNAoDA8YDnd798Z6SURERETUjFk1gNizZw+eeeYZXLlyBatWrcK0adMa+hRkAQOI5uNSziUsOroIZzMNk7B29+yOBYMXINwz3Moto9YosSBR6uUQdT0KGr1GKnNQOCCyXSSGBxpCh3ZO7ep1jjJdGY6lHZN6R2SWZEplcpkcfX36Sr0jQlxCbvEVEREREVFL0aABxO23337TEwohUFxcjKtXryIvLw9CCNx2223YtWsXxws3IQYQzYte6PFL7C/45OQnKNQUQi6T49Guj+KFvi/AydbJ2s2jFkyj0+BkxknDBJLJB3Ct4JpJeYAqACMCR2BE4AgMaDcAdjZ2DXp+vdAjJjsGfyX9hb1JexGbG2tS3t61PUYFjcJtQbehl1cv9v4hIiIiasUaNICQy+V1OrlCocCMGTPw6aefwtGRKwE0JQYQzVNWSRb+feLf+D3+dwCGcfTzB87H6ODRDOio1jLVmTiQcgD7k/fjSOoRqLVqqUwhUyDCN0IaWtHetX2TvrdSilKknhFR6VHQCq1U5mHvgRGBIzAqaBQG+w3mCjFERERErUyDBhALFy686QllMhmcnJwQHByMESNGwNeXk+5ZAwOI5u1wymEsProYyUXJAIBRgaMwP3I+/FX+Vm4ZNUd6ocf5rPPS0IqYnBiTcg97DylwGOw/GM5KZyu11FRheSEOphzEnqQ9OJh8EIWaQqlMKVdikP8gaYlPb0dvK7aUiIiIiBqC1SehJOtgANH8lWpL8c3Zb7Diwgpo9Vo4KBzwfJ/nMbXb1BonA6S2oaC8AIdTD+NA8gEcTDmInNIck/Jwz3BpaEV3z+6Qy+rWQ62pafQanLp+CnuT9mJP0h6kFKWYlPf06ikt8dnZrTN7BBERERG1QAwg2igGEC3H1byrWHRkEU5lnAIAhLmHYcHgBejl3cvKLaOmJITA1byr2J9i6OVwOuM0dEInlatsVRjsP9iwTGbAMHg5eFmxtbdGCIHLeZeloRrnss6ZlAeoAqRJLCN8I2Art7VKO4mIiIiobhhAtFEMIFoWvdBj65Wt+M/J/yC/LB8yyPBQ2EN4KeIluCj579dalWpLcTz9uDSBZGpxqkl5e9f2GBFg6OXQ16cvbG1a5414pjoT+5L3YW/SXhxNO4oyXZlU5mzrjGGBw3Bb0G0YGjCUPw9EREREzRgDiDaKAUTLlFOag/9E/Qfbrm4DAHg5eGHugLm4M/ROdklvJdKK0gxzOaTsx/G04yjVlUplSrkSA9oNkJbJDHIOsmJLrUOtUeNI2hHsTdqL/cn7TYaeKGQK9GvXT+odEaAKsF5DiYiIiKgaBhBtFAOIlu142nEsPrpYWlJxqP9QvDHojTZ5Q9rSafVanM44jf0phl4OV/KumJT7OvpKczkMbDeQK0NUotPrcC7rHPYk7cHepL2Iy48zKe/i3kVa4rMlzINBRERE1NoxgGijGEC0fOW6cnx37jssP7ccGr0GdjZ2eKb3M5jRfUar7YrfWuSU5uBQyiHsT96PQ6mHUFh+Y/UHuUyO3t69MSJwBIYHDEcX9y7s3VJLCQUJ0iSW0RnR0Au9VObj4IORQSMxKmgUIv0iYWdjZ72GEhEREbVRDCDaKAYQrce1/Gt49+i7OJZ+DADQya0T7gy9Ez6OPvB28Ia3oze8Hbzhbu/OT4CtRAiBmJwYHEg+gP0p+3Eu8xwEbvxKdbVzxVD/oRgROAJD/YfCzd7Neo1tJfJK83Ag5QD2JO3BoZRDUGvVUpmDwgFD/IdgVNAojAgcAQ97Dyu2lIiIiKjtYADRRjGAaF2EEPg17ld8dOIj5Jblmt1HIVPAy9HLEEpUBBNVQwofRx+42bnxE/cGUKwpxtHUo9LQisySTJPyMPcwaWhFT6+esJHbWKmlrV+5rhzH049LvSMy1BlSmQwy9PHpI80b0d61vfUaSkRERNTKNWgA0aFDB0yePBkffvghAOCHH35Ap06dMGTIkIZrMTUIBhCtU35ZPjbEbkBSYRIy1BnIKslChjrDZKK+m1HIFTcCCgcfeDl4GYIKR2+T7a52rgwqqkgoSDBMIJm8H1HXo6DVa6UyB4UDIv0ipaEV7ZzaWbGlbZexN4pxic+YnBiT8lCXUGneiN7evRkMERERETWgBg0g5HI5Zs6cie+//97sc2o+GEC0LRqdBtml2chUZyKjJMPw3RhQVDzPVGda7D1hjq3c1mJPCmNI4e3oDRelS6sNKsp15Yi6HoUDyQdwIOUAEgoSTMoDVYFSL4f+7fpz3oFmKK0oDXuTDWHE8fTjJqGRm50bRgSOwG1Bt2GI/xBOAEpERER0i2p7H6qozcGUSiXUavXNdySiJmVrY4t2Tu1u+qm7RqeRQoksdZbFsCKvLA8avQapxalILU6t8ZhKuVIKKaTeFA5Vnjt6w9nWuUUEFRnqDMNcDsn7cTTtqMncAgqZAv18+0nLZIa6hLaI19SW+an88EjXR/BI10dQVF6EQ6mHpCU+88rysO3qNmy7ug22cltE+kXitqDbMDJwJHydfK3ddCIiIqJWq1Y9ILp06YKioiIcPHgQHTp0YA+IZow9IOhWlOvKpeEdmSWZJsM9MtWZyCwxfOWX5df6mPY29maHexjDCuNzla2qSW/qdXodzmefx/5kw1wOVbvse9p7SoHDYL/BUClVTdY2ajwavQanM05jT9Ie7Encg+SiZJPycM9waagGVyohIiIiqp0GHYLx+uuv44MPPpD+EBNC1PqPMplMBq1We/MdqUEwgKCmUKYrQ6Y6s8awIqMkw2QZyptxUDjA28HbJKzwcfCBl6OXNOzDx9EHTrZO9W53flk+DqcexoHkAziYcrDa0JQenj2koRXdPLtxdZFWTgiBuPw47Enag71Je3E286zJKiZ+Tn5SGNHftz+XwSUiIiKyoEEDiPLycrz55pvYsGEDEhMTARj+cKstvV5/852oQTCAoOakVFtq6DVREUhUHv5h3J6pzkShpm5BhblVPqo+d7R1hBACV/KuSBNInsk8A53QScdS2aowxH+IYZnMgKHwcvBqjMtALURWSRb2J+/HnqQ9OJp6FKW6UqlMZavCsIBhGBU0CsMChsHVztWKLSUiIiJqXhp1GU4OwWi+GEBQS1SiLalxbgrj8yJNUa2P6WTrBDsbu2orhXRw7SD1cujj0we2cn6qTdWVaEtwLO2YtKpGdmm2VGYjs0E/336GeSOCRiLIOchq7SQiIiJqDho1gAgNDcVDDz2Ef//737fUSGp4DCCoNVNr1DXOTWEMKypPIKmUKzHAbwBGBBhCh0DnQCu+AmqJ9EKPc1nnpDDiSt4Vk3J/J384KBygkCugkCtgK7c1+9j43LjNXJlCroBCpoCtzY3HCrnhua3M/HEtHafyuRRyBYcUERERUaNp1ACCmi8GEERAsaYYmepMFJQXoLN7ZzgoHKzdJGpFkgqSsDd5L/Yk7cGp66dMhvU0Z3KZ3DSsMAYdlUIOhUxhNiCxGJaYeVw5SKl83Mr7Oiud4a/yh5eDF4MRIiKiVqDJAojy8nKcPHkSKSkpAICAgAD069cPSqXyVg5L9cQAgoio6eSX5eNq3lVo9Bpo9VrpS6PXSNtMyoQWGp0GWmG6r7l61eqa2dfccY3bWwI7Gzv4q/wRoApAoCoQgc6BhscV352VztZuIhEREdVCbe9DFfU9gVarxcKFC/HZZ5+hsNB0AjlnZ2e89NJLWLBgARSKep+CiIioWXO1c0WEb4S1m1GNEMJiyFGn0MMYbFQ8rjFcqWVgotFrkF+Wj3R1Osp0ZYjPj0d8frzZ1+GidLkRSlQKKAJUAfBX+UNpww87iIiIWpJ69YDQ6/UYN24c/vzzTwgh4O7ujvbt2wMA4uPjkZubC5lMhrvuugvbt2+HXM7ulU2FPSCIiKgl0Og1SC9KR3JRMlKKUpBcaPhu/Ko6gWxVMsjg4+gj9ZgIVAUiwDlACiu8Hb05vIOIiKiJNOoQjG+++QbPPPMMQkND8X//93+YMGGCSfnmzZvx6quvIiEhAV999RWeeuqpur8CqhcGEERE1BoUa4oNYURhihRSVH5coi2psb5SrjQM73A2BBKVh3YEqAK4lCoREVEDatQAYtiwYYiOjsaFCxcQGhpqdp/4+HiEh4cjIiICBw8erOspqJ4YQBARUWsnhEBOaY4hjCi80WsiuTAZyUXJSC9Ov+nkoM5KZ7PBRKBzIPxV/rCzsWuiV0NERNTyNWoA4ebmhqFDh+K3336rcb9x48bh4MGDyMvLq+spqJ4YQBARUVun1WuRXpxeLZgwPr7Z8A4A8HHwuRFMVOlF4e3gDRu5TRO8EiIiopahUSehLCsrg6vrzbsuOjs7o6ysrD6nICIiIqoXhVxhmBfCOdBsuVqjRmpRqkkoUXmYh1qrRkZJBjJKMnAq45TZ4xt7TFTuQWGcKNNF6QKZTNbYL5OIiKjFqVcPiC5dukCj0eDKlSuwsTH/CYBOp0OnTp2gUChw+fLlW24o1Q57QBAREdWfEAK5ZbnS0I7komSTCTLTitKgFTUvc6qyVZkd2hGoMgzvsFfYN9GrISIiahqN2gPizjvvxBdffIHZs2dj6dKlsLW1NSkvLy/HK6+8gsTERDz//PP1OQURERFRk5PJZPCw94CHvQd6evesVq7Va5GhzjA7tCOlKAVZJVko0hThUu4lXMq9ZPYc3g7eZod2BKgC4Ovoy+EdRETUatWrB0RKSgp69eqFvLw8+Pv7Y8qUKdIynHFxcVi3bh1SU1Ph4eGB06dPIyAgoMEbTuaxBwQREZH1lGhLkFqUahpQVOpNUawprrG+Qq6An5NftaEdfXz6oJ1TuyZ6FURERHXTqJNQAsCJEycwefJkJCYmVhvnKIRAcHAwfvnlF/Tv378+h6d6YgBBRETUPAkhkF+Wb3ZoR3JhMlKLU6HVmx/eoZQr8Vyf5zAjfAYU8np1YCUiImo0jR5AAIahFhs2bMDevXuRkpICAAgICMCoUaMwefJkKJXK+h4aa9aswZ9//okzZ84gLS0Nubm5cHR0RFhYGMaPH48XX3wRKpXKbN1du3bh448/xvHjx1FcXIyQkBBMnDgR8+fPt1gHAK5cuYJ3330Xu3btQmZmJry9vTFmzBgsWLAAHTp0sFivsLAQS5YswcaNG5GYmAgnJydERkbi1Vdfxe23326xnl6vx/Lly/H999/j4sWLAIDu3btj1qxZeOqpp+o1gRUDCCIiopZJp9chsyQTSYVJJsHElbwr+DvnbwBAN49uWDR0Ebp6dLVya4mIiG5okgCiMQ0bNgyHDx9Gt27dEBQUBA8PD1y/fh1HjhxBSUkJOnXqhH379sHf39+k3tKlSzFnzhzIZDIMHz4cvr6+OHDgANLT0xEWFoaDBw/Cy8ur2vkOHTqEsWPHQq1WIzw8HD169MD58+dx4cIFODk5YdeuXRg0aFC1ehkZGRg+fDhiY2Ph5+eHYcOG4fr16zhw4AAA4NNPP8WLL75YrZ5Op8NDDz2ETZs2wdHREaNHjwZgCE9KSkowefJkrF27FnK5vE7XjQEEERFR6yKEwPa47fjw+IcoKC+AjcwGT/R4Av/o/Q/Y2dhZu3lERES1vw8VzdTRo0dFdnZ2te1ZWVli2LBhAoCYMmWKSdmpU6eETCYTNjY2YseOHdL24uJiMXr0aAFATJw4sdoxi4uLhb+/vwAg5s+fb1I2f/58AUAEBQUJtVpdre4DDzwgAIjRo0eL4uJiaftvv/0mbGxshFwuF2fOnKlWb+nSpQKACAgIEHFxcdL2uLg4qS2fffZZDVfIvPz8fAFA5Ofn17kuERERNV+Z6kzxyp5XRI+VPUSPlT3EfZvvE6eun7J2s4iIiGp9H9pse0DU5MCBAxgxYgQ8PDyQnZ0tbX/ooYewYcMGPPnkk1i+fLlJnYSEBHTo0AF6vR4xMTHo2vVG18UvvvgCzz//PLp06YKYmBiTXgd6vR7dunVDbGwsvvrqK/zjH/+Qyi5evIjw8HDY2Njg6tWrCAkJMTnnk08+ie+++w5TpkzBzz//bHLMgIAApKenY/Xq1Zg6dapJvdWrV+Oxxx6Dv78/kpKS6tQLgj0giIiIWrfdCbvx7rF3kVWSBRlkeKTrI5gdMRuOto7WbhoREbVRtb0PrVv//mZCoTBMvmRnd6PbYXl5OX777TcAwKOPPlqtTkhICIYOHQoA2Lx5s0mZ8fmUKVOq3ezL5XI8/PDDAIBNmzaZrTd06NBq4UPldmzfvh0ajUbafuTIEaSnp8POzg4TJ06sVm/ixIlQKpVITU3FsWPHqpUTERFR2zU6ZDS2PLAF4zuNh4DAT3//hPFbx+NQyiFrN42IiKhGLS6AKCwsxDvvvAMAuP/++6XtsbGxUKvVAGBx5Q3j9ujoaJPtxueNVa+4uBiXL1+uVi88PBz29vbV6jk4OCA8PNzsOYmIiIhc7VyxaOgifHPHNwhQBSC1OBXP7HoGbxx8A/ll+dZuHhERkVnNPoDYuXMnZs6cienTp+POO+9EQEAAdu7cibvuugsffvihtF98fDwAwM3NDc7OzmaPFRQUZLIvYAg0jMM4goODa6yXmZmJ4uIb63cbj2OpnouLi9T9pPI5b1bPUlvNKSsrQ0FBgckXERERtQ2D/Qdj0/2bMK3bNMggw7ar2/DAlgfwv4T/WbtpRERE1TT7AOLixYtYtWoVfvzxR+zcuROFhYV49NFHsXLlSri6ukr7FRYWAgCcnJwsHsu4BGflm3RjvZrqVl6601zd+p6zrvXMWbJkCVxdXaUvY3BBREREbYOjrSPmDpyLH+7+AR1dOyK7NBtz9s7BK3teQaY609rNIyIikjT7AOLll1+GEALl5eW4cuUK/vOf/+D3339H9+7dsX//fms3z+rmz5+P/Px86SspKcnaTSIiIiIr6OPTB+vvW49/9PoHFDIFdiXuwgNbH8Dmy5vRAuccJyKiVqjZBxBGtra26NixI+bMmYPff/8dubm5mDZtGkpKSgBAGnZReYhEVUVFRQBgMitn5eEaluoa61mqW99z1rWeOXZ2dtJQj8pDPoiIiKjtUdoo8ULfF7B23FqEe4ajsLwQCw4vwNP/exrJhcnWbh4REbVx9QogdDodCgoKoNVqTbaXlJRg4cKFGD9+PF555RWkpqY2SCOrioyMRPfu3ZGUlISoqCgAQGhoKAAgLy/PZFhFZcbeAcZ9AUMY4OHhAQBITEyssZ6Xl5fJsAnjcSzVqzwnQ+Vz3qyepbYSERER1UaYRxhW37Mar/Z7FXY2djiadhQTtk3A6ourodPrrN08IiJqo+oVQCxatAju7u44cuSItE0IgVGjRmHRokXYunUrli1bhsGDByM3N7fBGluZMQjIyMgAAISFhcHR0bD+tTGUqMq4PSIiwmS78Xlj1XNyckKXLl2q1btw4QJKS0ur1SspKcGFCxfMnpOIiIioNhRyBWb2mIlN929Cf9/+KNGW4MMTH2LGHzNwNe+qtZtHRERtUL0CiN27d6Ndu3YYPny4tG379u04ceIEOnfujE8++QRjx45FcnIyli9f3mCNNcrKysKZM2cAQLqxVyqVuPfeewEAP/30U7U6CQkJOHz4MABg/PjxJmXG52vXroVerzcp0+v1WLduHQBgwoQJJmUPPvggAODQoUNmezMY23HffffB1tZW2j548GC0a9cOZWVl2LhxY7V6GzduRHl5Ofz9/REZGWnuEhARERHVSrBLML678zssGLwATrZOOJN5BpO3T8bXZ76GRqexdvOIiKgNqVcAER8fj65du5ps27p1K2QyGdasWYOXXnoJ27dvh7e3N3755Zc6H//ixYtYs2aN2d4BsbGxmDx5MsrKyjBo0CD07NlTKps3bx5kMhlWrFiBP/74Q9quVqsxa9Ys6HQ6TJw4sVrbZ86cCX9/f8TGxuKtt94yKXvrrbcQGxuLwMBATJ8+3aQsPDwcDzzwAHQ6HWbNmiXNRwEAv//+O1auXAm5XI758+eb1JPL5Zg7dy4AYO7cudWW6Jw3bx4AwwSTcnmLmaaDiIiImim5TI7JXSZjywNbMCJwBDR6DT4//Tmm/DYFF7IuWLt5RETURshEPaZFtre3x8SJE7FmzRppW9euXaFWq016Ajz44IM4evQo0tPT63T8vXv34rbbboOTkxP69u2LwMBAlJeXIzExEadOnYJer0e3bt3wxx9/IDg42KTu0qVLMWfOHMhkMowcORI+Pj44cOAA0tLSEBYWhoMHD8LLy6vaOQ8dOoSxY8dCrVajR48e6NGjB86fP4/z58/DyckJu3btwqBBg6rVy8jIwLBhw3D58mX4+flh+PDhyMjIwL59+yCEwKeffoqXXnqpWj2dTofJkydj8+bNcHR0xJgxYwAAu3btglqtxqRJk7Bu3bo6BxAFBQVwdXVFfn4+J6QkIiKiaoQQ+D3+d3xw/APkluVCLpNjRvcZeLbPs3BQOFi7eURE1ALV9j60XgGESqXCmDFjsGXLFgBAbm4uvLy88NBDD+Hnn3+W9nvsscfwyy+/mPQMqI3MzEwsX74cBw4cwN9//43MzExoNBp4eHigZ8+emDBhAh5//HHY2dmZrb9r1y785z//wfHjx1FcXIzg4GBMmjQJ8+fPN1n1oqorV65g8eLF2LVrFzIzM+Ht7Y0xY8ZgwYIF6Nixo8V6BQUFWLJkCTZu3IjExEQ4OTlh4MCBeO211zB69GiL9fR6PZYvX45vv/0WMTExAIDu3btj1qxZePrppyGTyWp5xUzbwgCCiIiIbianNAcfHv8QO+J3AACCnYPxzpB3MKDdACu3jIiIWppGDSB69eqFjIwMpKamQi6X48cff8SMGTPw2Wef4fnnn5f2u/POOxETE1Pjag/UsBhAEBERUV3sS9qHRUcXIUNtmNh7cpfJeKXfK3BWWv7QhoiIqLLa3ofWa4KB+++/HxkZGXjggQfw6aefYu7cubCxscF9990n7SOEQHR0NNq3b1+fUxARERFRExgZNBJbHtiCyV0mAwA2xG7Ag1sfxP7k/VZuGRERtTb1CiD+9a9/ITw8HL/99hteeeUVpKen45///KfJfAwHDx5EVlYWhg0b1mCNJSIiIqKG56x0xoLBC/D9nd8j2DkYGeoMPL/7eczdPxc5pTnWbh4REbUS9RqCAQAlJSX45ZdfcP36dQwYMAAjR440Kd+yZQv27duHxx9/HL169WqQxtLNcQgGERER3YoSbQm+PP0lVl1cBb3Qw93OHfMGzsPd7e+u1/xURETU+jXqHBDUfDGAICIiooZwIesC3jr8Fi7nXgYAjAwciTcHvYl2Tu2s3DIiImpuGnUOCCIiIiJq3cK9wrHu3nV4oc8LsJXbYl/yPjy49UGsv7QeeqG3dvOIiKgFuqUeEGVlZYiKikJKSgpKS0st7jd9+vT6noLqiD0giIiIqKFdzbuKBYcX4GzmWQDAgHYD8M7gdxDsEnyTmkRE1BY0+hCMZcuW4Z133kF+fv5N99XpdPU5BdUDAwgiIiJqDDq9Dj///TOWRS9DibYEdjZ2eKHPC5jWfRoUcoW1m0dERFbUqAHEjz/+iBkzZgAAunbtim7dutV4khUrVtT1FFRPDCCIiIioMSUXJmPhkYU4mnYUABDuGY6FQxYizCPMyi0jIiJradQAol+/fjh9+jRWrFjB4RXNDAMIIiIiamxCCGy5sgUfRX2EwvJCKGQKzOo5C0/3ehpKG6W1m0dERE2sUQMIR0dH9O3bF4cOHbqlRlLDYwBBRERETSVTnYn3jr2H3Ym7AQAdXDtg4ZCF6OPTx7oNIyKiJtWoq2DY29sjNDS0vm0jIiIiolbA29Ebn9z2CT4e9TE87T0Rlx+H6b9Px4fHP4Rao7Z284iIqJmpVwDRv39/XL58uaHbQkREREQt0B0hd2Drg1txf8f7ISCwOmY1JmybgCOpR6zdNCIiakbqFUDMnz8fJ0+exO+//97Q7SEiIiKiFsjVzhXvDXsPX435Cn5OfkgpSsHT/3saCw4tQH7ZzVdNIyKi1q9ec0AkJibiu+++w4cffoiXXnoJ48aNQ3BwMORy83lGcDDXiG4qnAOCiIiIrK1YU4xlp5bh579/hoCAl4MX3ox8E6NDRlu7aURE1AgadRJKuVwOmUwGIQRkMlmN+8pkMmi12rqeguqJAQQRERE1F9EZ0VhwaAGuFVwDYBiq8Xrk6/By8LJuw4iIqEE1agARGhp60+Chsvj4+LqeguqJAQQRERE1J2W6Mnx95mt8f/576IQOLkoX/GvAv3B/x/vr9PckERE1X40aQFDzxQCCiIiImqO/c/7GgkMLEJMTAwAY6j8UCwYvgL/K38otIyKiW9Woy3ASEREREdVFV4+u+Onen/ByxMtQypU4lHoID259ED/F/AS90Fu7eURE1AQYQBARERFRk1DIFZjVcxZ+uf8XRPhEoERbgiXHl2DmHzMRlx9n7eYREVEju6UhGNnZ2Vi+fDn27NmDlJQUAEBAQABuv/12PPnkk/D09GywhlLtcAgGERERtQR6ocf6S+ux9ORSqLVq2Mpt8WzvZzGzx0zYym2t3TwiIqqDRp8DYufOnXjkkUeQl5eHqoeQyWRwd3fHTz/9hLFjx9bn8FRPDCCIiIioJUkrSsOio4twMOUgAMNQjYVDFqK7Z3crt4yIiGqrUQOIy5cvo2/fvlCr1ejVqxcef/xxdOzYEQAQFxeHlStX4vTp03B0dER0dDQ6d+5c/1dCdcIAgoiIiFoaIQR+jfsVH574EPll+bCR2WBm+Ew80/sZ2Cvsrd08IiK6iUYNIGbNmoUVK1bgnXfewYIFC8zus3jxYrz99tt44okn8O2339b1FFRPDCCIiIiopcouycYHxz/AH9f+AACEuoTinSHvoJ9vPyu3jIiIatKoAURoaCgcHBwQExNT437dunVDSUkJrl27VtdTUD0xgCAiIqKW7q/Ev/Du0XeRWZIJAHg47GG8HPEyVEqVlVtGRETmNOoynOnp6YiIiLjpfhEREUhPT6/PKYiIiIiojbo9+HZseXALJnaeCABYd2kdxm8bjwPJB6zcMiIiuhX1CiCcnJyQkZFx0/0yMjLg5ORUn1MQERERURvmonTBO0Pewbdjv0WgKhDpxel4bvdzmH9gPnJLc63dPCIiqod6BRB9+vTB/v37ce7cOYv7nD17Fvv27UOfPn3q2zYiIiIiauMi/SKx8f6NmN59OuQyOX6N+xUPbn0Qf1z7o9pKbERE1LzVK4B46qmnoNFoMGbMGHzxxRcoKiqSyoqKivD555/jjjvugE6nw9NPP91gjSUiIiKitsfR1hH/HPBP/Hj3j+jk1gk5pTn4575/Yvae2chQ37xXLhERNQ/1moQSAGbMmIEff/wRMpkMAODp6QkAyM7OBmBYTmn69OlYuXJlw7SUaoWTUBIREVFrptFp8O25b/HNuW+g1WvhbOuMV/u/igmdJ0h/lxIRUdNq1EkoAWDVqlX44osv0L59ewghkJWVhaysLAgh0KFDB3z55ZcMH4iIiIioQdna2OLZPs9i/bj16OnVE4WaQrxz5B08tfMpJBUkWbt5RERUg3r3gKgsJSUFKSkpAICAgAAEBATccsOoftgDgoiIiNoKnV6H1TGr8Xn05yjVlcLexh4v9H0B07pNg43cxtrNIyJqM2p7H9ogAQQ1HwwgiIiIqK1JKkjCO0fewfH04wCAnl498UzvZ9DNoxu8HLw4NIOIqJExgGijGEAQERFRWySEwKbLm/B/Uf+HIs2NCdLd7dzRxaMLwtzDEOYRhjD3MHRw7QBbG1srtpaIqHVp0ADihx9+AACMHz8ezs7O0vPamj59ep32p/pjAEFE1EC05UBxBlB0HSjKrPhufH4dKK7YJrMBej8MRMwEVN7WbjVRm3e9+Dq+PPMlTmWcQkJBAvRCX20fhUyB9m7tDaGEe5gUUHg6eFqhxURELV+DBhByuRwymQwxMTHo0qWL9Ly2dDpdrfelW8MAgoioBnodoM65ESJIgULF9+KMG49Lcut2bBslED4BGPg0ENivcdpPRHVSoi1BXF4cLuVewqWcS7iUewmxObEo1BSa3d/T3lPqJWEMJUJdQ2ErZ28JIqKa1PY+VFGbg02fPh0ymQyurq4mz4mIiKxOCKA037R3QlGGaZggbcsEzHwaapFcAah8AZWP4buTd8XzSttyrwEnlgMpJ4Gzaw1f/hGGICJ8PGBr32gvnYhq5qBwQLhXOMK9wqVtQgikFachNjf2RiiRG4vEgkRkl2bjcOphHE49LO1vK7dFR7eO6OJuOozDzd7NCq+IiKhl4xwQrQx7QBBRq1Guttw7weR7BqArq8OBZYCTF+DkcyNEkL77GoZRGB/buwHyWq5YnXzSEESc3wjoyg3bHL2AfjOA/k8AroF1vQJE1ITUGjWu5F2RekvE5sYiNjcWxZpis/v7OPhUm1si2CUYCnmtPt8jImpVOAllG8UAgoiaNW35jbkTjN/NBQpFGUC5+S7SFtm5mgkUzIQMjl6ATSPeIBRlAqdWAVHfAwWGJaohkwNd7zX0iggdDrAXIVGLoBd6pBSlGMKInFgpnEguSja7v52NHTq6dZRCiS7uXdDFvQtc7VybuOVEzY9Wr0VBeQHc7Nwgl9Uy3KcWgwFEG8UAgoianF4PqLMrTdhooZdC0XWgJKdux1bYVxnyYK7Hgo+hN0NzG+qg0wKXdgDHvwGuHbix3bsbMPApoNfDgJ3Keu0jonorKi/C5bzLN0KJ3Eu4nHsZJdoSs/u3c2pnmFfCvYvUWyLIOQg2cpsmbjlR4yvTleFa/jXE58fjav5VxOXFIS4/DgkFCdDoNbC3sUewSzBCXEKqfbnbuXOofwvVoAFEYmLiLTUmODj4lupT7TGAIKIGIQRQVlB9DgWTFSEqz6tQh8mG5YqK4Q/elsME42M759bRW+D6RcPwjDNrAY3asM3OBegz1RBGeHa0bvuI6JbphR5JhUnS8A3jhJepxalm93dQOKCTWyeTUKKLexeolAwmqWUoKi9CXL4hXDCGDHH5cUgpSjG7+kxtOCudEeIcghDXilDC+Ng5hD8bzVyjrIJRHzKZDFqttl51qe4YQBBRnek0QOJRIPYPIOkYUFgRLtRpXgUAjp7Vhz84memx4OBe+3kVWpuSPOD0T4YwIifuxvZOYwzDMzrd0XavDVErVVBeIPWUuJx7GZdyLuFK3hWU6krN7h+gCjAJJcLcwxDgHMAu62QVQghkl2YbejPkXZVChvi8eGSUZFis56x0RgfXDujo1hEdXDugvWt7dHDtAB9HH6QVpyGhIEH6ulZwDYkFiUgrTquxLZ72nia9JUJdQhHsEowg5yDYK5pZL8g2qEEDiNDQ0FvqChMfH1/vulQ3DCCIqFbUOcCVXcCl34Eru4GyfPP72bmYCRSq9FhQ+RomdbThMnW1ptcDV/8yDM+4vBNAxX/F7qHAgKeAvlMNQQ0RtUo6vQ4JhQlSMGFckeO6+rrZ/R0Vjujs3rna3BKOto5N3HJqrfRCj7TiNFzNu4r4/HiTXg0F5QUW63k7eKODWwd0cK305dYBnvaedb5/LNWWIrEwEYkFiVIoYQwockotD+GUQYZ2Tu2qDecIdQmFv8qfE8M2Ec4B0UYxgCAis4QAMv829HKI/dPQ06Fy90hHT6DzWKDjaMA95EbYoOQft40uJw448R0Q/aNhOVEAUDgAvR4y9Ipo18O67SOiJpNXmndj+EZFKHE17yrK9eXV9pVBhiDnIEMYUWk1Dn8nf46hJ4s0eg2SCpJM5maIz4/HtYJrFucwkUGGAFWAaW8GN8N3F2XT3G8UlheaBBOVvxdpiizWU8gUCHQORIhLCIJdgqVeE6EuofBx9GHPogbEAKKNYgBBRBJtGXDtoCFwiP0DyEswLfftAXS5E+hyFxDQD+BkaNZVXgyc2wAc+wbIuHBje/AQIPJpoOs49jIhaoO0ei2u5V+TJrs0rsiRWZJpdn+VrUrqIWEcxtHJvRMcFA5N3HKyJrVGjfiCeMTlxd3o0ZAfh6SCJGiF+eHxCrkCoS6hUi8GY4+GEJeQZjvEQQiBnNIcJBYm4lr+NSQUJBgeF1xDUkGSxaFOAGBvY48glyCEuoQaAgrnYIS6hiLYORge9h4M8uqIAUQbxQCCqI0ryjB06b/0O3B1D1B5/XobO6D9iIrQ4U7AjRMEN0tCAIlHDMMzLm67McGnsx/Q/wkgYgbg7GvdNhKR1eWU5tyY8LLi+9X8q9Dqq99cymVyBDsHm84t4REGX0df3mS1cHmleTcmgqw0P4OlyU8Bw5AeY8hgnJuhg2sHBDoHtqrhCnqhR4Y6w6S3REJBAhILEpFcmGwxiAEAZ1tnk14TxmEdwS7BcFY6N+GraDkYQLRRDCCI2hghgPRzFUMr/gBSTpqWq3wrAoe7gQ4jAaWTddpJ9VOQCkStAE6uMKw2AgByWyB8vGF4RmD/1rFKCBE1CI1Og7j8OJNQ4lLuJYvj512ULiahhJeDF5yVzlDZqqBSquCidIGDwoEhhZUJIXBdfV0aLlF5xYma5kbwsPcwCRiMoQODJ8NQlLSiNCmUqPyVXpwOAcu3yB72Hjd6TVQKKNr6ZJgNGkB06NCh3g2RyWS4evVqvetT3TCAIGoDNCVA3L4b8zkUVvmUw68PEHa3IXho15urKrQG2jJDb4jjXwPJJ25s9+tjCCJ6TARs2+4fPURUs6ySLFzKMQzhMAYT8fnx0NViCWUbmQ2cbJ3grHQ2CSecbSueVzxWKStCC1sX6bFxHzsbu/9v776jo6rWPo5/J72RUEKHhNA7UkUB6VWKSBUVAbmK3auCgAW9Fq5YsL8q0hS9KAJKB0E6SBFE6b230JKQnsx+/xhnyJBJJRV+n7VmkexyznOGw5DzZJdb/oE3M5KtyZy8etIpwWCfPhGdckTjdcr6l3Vam8GebCjmo8WMsyMuKY4TUSdSJSaORR7jYtzFNPultRhmaGAo5QLK4el2c0+jzPFtOLPLYrGQnJyF/eHlhigBIXKTijgFB5baEg6HV0PKhaI8/aByW1vCoVonCCybf3FK7ju1DbZ8DX//dG2rVN/i0Pgh2xQNTa0RkUxISE7g0JVDjqTEwSsHiYiPIDIhkquJV7macDVTCYrM8HDzcCQpingVuZaw8AxwSmw4Ehou2ni5e+VILAVBfHI8RyOOOq3NcDjiMEcjjpJoTXTZx93iTsUiFVOtzxAWFKbdUPLQ1YSrHIs6xrGIf5ISKb6OSoxKs5+HxYPyRcpfS0oUCSU0KPSmWgwzRxMQx44dy6hJukJDQ2+ov2SeEhAiNwmrFU5v/2eUw2LbNIuUAitAjS62BSQrtQRPLS52y4m+CNumw9YpEHHCVmZxgxrdoNm/IKy1pmeISLYZY4hNiiUqIYqriVcdf15NuOqUpIhKiCIqMcrxdcryq4lX0x3KnhXe7t6pEhb2ZIWr8kCvQKfRGgFeAXm+vsHVhKup1mY4FHGIU1dPYU25E1UKPu4+VAqq5Jg6Yd95IqRICJ5aiLjAMsZwOf6yy1ETxyOPp7sYpre7NyGBIbakxHUjJwrTYphaA+IWpQSESCEWH2VbOHL/Uttoh+iUK5xboEJT2yiHGl2hVG09XIpNcpItUbX5Kziy+lp5cA1bIqLBQPDWglkikvesxkpMYgxXE/9JWiRcvZbMSLhKVGKUy69TJjzSm3qQVb4evk7TRVKOtEg5pSStkRkBngGpflNtjOFi3EWntRkORRziyJUjnI89n2YsRbyKpFqboXJQZcoFlLspfhsu19gXw3SVnMhoMcwAzwBCA0N5utHT3FnuzjyMOuuUgLhFKQEhUshcPnptm8yj6yA5xV7vXkWganvbKIdqHcE/ON/ClELi/F7YMgn+/N+1HVC8isBtg2zJiOBq+RufiEgWJVuTbaMqUo6+uC5JEZUQlWr0hX1UxtXEq8SmnLZ4g+yjKgI8A/B29+ZE1AkiEyLTbF/St6RjqoR9NEPlopUp4VOi0PxmW3JPkjWJ01dPOxIS9h07jkUe40z0GccIoq86fsUd5e7I52jTpwTELUoJCJECLjnJtoigfQHJ8D3O9cXCri0gGXIneNw8c14lD8VFwI6ZtlERFw9eK6/SzrZoZbVO4Oaef/GJiOShRGuiLRnxz0iLVFNHrptC4mpURoI1Ic3jW7BQPqA8lYtWpkpQFcdikGFBYQR66edxyZ745HhORNoWw2xSpglB3kH5HVK6cjQBMWzYMCwWC2+//TalS5dm2LBhmQ7EYrEwefLkTLeXG6MEhEgBFHsFDq34Z2rFMoi9fK3O4g4hd1ybWlGiqqZWSM6xWuHIKtg8CfYtBvtc7KIh0HQ4NHwQ/IrnZ4QiIoVCQnKC00iLqIQo4pLiKBdQjtDA0Ft6+0URyIVdMCwWC3v27KF69epZ2hVDu2DkLSUgRAqICwdti0fuXwrHNkDKlcR9itqmVFTvYpti4attsiQPXD4KWybDtm8g7oqtzMMH6vWzjYooWz8/oxMREZFCLLPPoZlaCnbq1KkAlC1b1ul7ERH5R3KiLdFgX8/h0iHn+uAa13atqNAM3PN2JW4RilWCTm9AmzGwczZs/tK2u8r2b22vis1t60TU6qmpPyIiIpIrtAbETUYjIETyUPRFOPirLeFwcAXEp1iEys3Ttj1m9S5QvRMUr5x/cYq4Ygyc2GRbJ2L3L2D9ZxXugDLQZCg0HgJFyuRriCIiIlI4aBHKW5QSECK5yBg4v+faApInN0PKfbz9gm1rOVTvbFvsT1sfSmERdRa2ToU/psLVc7YyNw+o3QuaPQoVm2ltEhEREUmTEhC3KCUgRHJYYhwcWwf7/kk6RBx3ri9d79rUinKNIAtr5IgUOEkJsGeebdHKE79fKy9T37ZORL2+4Ombf/GJiIhIgZSjCYjvv//+hoIZNGjQDfWXzFMCQiQHRJ217VaxfykcWgmJ0dfqPHwgrPW1kQ5BFfIvTpHcdGaHbXrG3z9BUpytzLcYNBoMTR6GYqH5G5+IiIgUGLmyC0Z2aReMvKMEhEg2GGN72LIvIHl6m3N9kbL/JBy62JIPXn75E6dIfoi5ZFukcsvXcMU+Ashi2za22b+gcltNzxAREbnF5UoCon79+hQtWjTLwaxcuTLLfSR7lIAQyaSEGDiy+tp6DlFnnOvLNbIlHGp0sQ0/1wOW3OqsybaRQZu/gkO/XSsvUc02PaPBQPDR/zsiIiK3ohxNQHh4eGC1WvHx8eGee+5h2LBhdOjQIUcDlpyhBIRIOiJOXhvlcGTNtWHlAJ7+UKWtLelQrRMUKZ1/cYoUdOH7bSMi/vweEqJsZV4B0OA+26iIkjXyNz4RERHJUzmagDh79izTpk1j2rRp7N+/H4vFQmhoKEOGDGHo0KFUrFgxR4OX7FMCQiQFqxVO/XFtlMO5v53rg0L+WUCyM4S2BE+f/IlTpLCKj4IdM22LVl7Yd608rDXc/qgtoefmnn/xiYiISJ7ItV0w1q5dy5QpU/jpp5+Ijo7Gzc2Ndu3aMWzYMHr37o23t/cNBy/ZpwSE3PKsyXBsA+yaA3vmQ3T4tTqLG1Rodm09h1K1NLVCJCcYY5vStHkS7Ft0bXvaoBBoOgwaDgb/Evkbo4iIiOSaXN+G8+rVq8ycOZPJkyezadMmLBYLQUFBDBo0iGHDhtGoUaNsBy/ZpwSE3JKMgZNbYOcc2DUXrp69VucdCFXbQ/WuULWDHoJEctuV47BlMmz7BmIv2crcvaFeP9v0jHK35Wt4IiIikvNyPQGR0p49e5g6dSrffvst58+fJzg4mHPnzt3oYSUblICQW4Z954qds2HXzxBx/FqdTxDU6gF17oWwu8DdM9/CFLllJcbakoKbv7T9W7Wr0MyWiKjVAzx98y8+ERERyTGZfQ71yImThYaGUqtWLUJDQzl37hw5kNMQEXHt/B5b0mHnHLh06Fq5VwDUvNuWdKjSDjy88i9GEbElFxreD7cNgpNbbYmIXT/Dyc22l3cQ1L0XGj4I5RtpOpSIiMgt4IZGQKxfv54pU6Ywa9YsoqOjAWjXrh2PPPII/fr1y7EgJfM0AkJuShcP2RIOO2dD+J5r5R6+tvUc6t5r27lCv00VKdiizsG26bDtW+dRSyVrwm33Q/0B2oFGRESkEMq1KRhnz55l+vTpTJ06lQMHDmCMcdoRIyQk5IaDl+xTAkJuGleO29Zz2Dnbefi2mydU6wh1+9gWkvQOyL8YRSR7rFY4uhb+/A52z4OkWFu5xd2WTGx4P1TrrJFMIiIihUSOJiCSk5OZN28eU6ZMYenSpSQlJeHj40Pv3r0ZNmwY7du3z9HgJfuUgJBCLeqsbYj2ztm2Idp2Fneo3MaWdKh5N/gWzacARSTHxUXYRjj9+Z1tMVk7v2DbiIiG90PpOvkXn4iIiGQoRxMQpUuX5sKFCxhjaNSoEQ8//DD33XcfRYsWzcmYJQcoASGFTvRF2POL7QHk6DrA/pFkgUotbdMravUE/+D8jFJE8kL4PlsiYsdMuJpiMeuyt0HDB2xJSL/i+RaeiIiIuJajCQg3NzcsFgtNmjShQYMGWQrEYrHw5ZdfZqmPZJ8SEFIoxF6BvQtsSYfDq8AkX6ur0Mz2kFG7FwSWza8IRSQ/JSfBoRWw/VvYtwSsibZydy+o2d02KqJyW3Bzz984RUREBMiFBISjg8WSpV0uLBYLycnJGTeUHKEEhBRY8Vdh32LYNQcOLofkhGt1ZW+zjXSo0xuKah0ZEUkh+iL8/SNsnwHndl4rDywPDQbaFq8sUSX/4hMREZGc3YZz3LhxORaYiNxCEmPhwDLbSIf9S68tNAdQqrZty8y69+rhQUTS5l8Cmj8Gt4+wLUj753fw148QeQrWvm97hdxpGxVR+x4tTCsiIlKA3dA2nFLwaASE5LukBDj0m20hyX2LIOHqtbriVWzTK+reC6Vq5V+MIlK4JcXbPl+2f2ebqmGstnJPf6hzj21UROidYLHka5giIiK3ilzbhlMKNiUgJF8kJ8HRNbakw575tlXt7YIq/jO94l4o20APBCKSsyJPw47/2ZIRlw5dKy9eGW4bBA3ug6AK+RefiIjILUAJiFuUEhCSZ6xWOL7RlnTY/QvEXLhWF1DGtp5D3XuhQlMlHUQk9xkDJzbZ1orYNTfF6CsLVGlr20Wjxt3g6ZOvYYqIiNyMcjQBMXfuXHr37n3DQc2ZM4d77733ho8jaVMCQnKVMXDqD1vSYddciDpzrc6vhG3nirp9IOQOrU4vIvknIdqWGN3+HRxbd63cJwjq9bNN0SjXUMlRERGRHJLju2DcfvvtvPbaa3Tu3DlLgRhjWLRoEf/5z3/YunWrdsTIZUpASI4zBs7+ZVtIctccuHL8Wp13ENTqYRvpENYa3DO1rq2ISN65dBj+/B7+/B9EnrxWXqq2LRFRfwAElMy/+ERERG4COZqA+Oijj3j99deJiIigfPnyDB48mPbt29OsWTP8/f1TtY+OjmbTpk38+uuvzJgxg9OnTxMUFMRrr73G008/fWNXJulSAkJyzPm9toTDztlw8eC1ck9/qNnNNtKhSjvw8M6/GEVEMsuaDEdW20ZF7JkPyfG2cjcPqN7Floyo1hHcPfM3ThERkUIox9eAuHDhAq+99hrTp08nOjoai8WCm5sbFSpUoESJEgQGBhIZGcnFixc5efIkVqsVYwz+/v4MGTKEcePGERwcnGMXKK4pASE35OKhf5IOc+H8rmvlHj5QrZMt6VCtE3j55V+MIiI3KvaKLbm6fQac3nat3L8U1O9vWy9CO/WIiIhkWq4tQhkREcGUKVP4+eef2bRpEwkJCanaeHl50bx5c+655x6GDh1KUFBQ1q9AskUJCMmyKyds6znsmgOnt18rd/OEqh1s0ytqdAXvIvkXo4hIbjm/x5aI+OsHiA6/Vl6+sW1URN0+4Fs038ITEREpDPJkF4y4uDh27drFuXPniIiIoGjRopQqVYo6derg46NVpvODEhCSKVHnYPfPtnUdTvx+rdziDpVb27bMrNUdfIvlW4giInkqOREOLLNN0TiwFKxJtnIPH6jZ3TYqIqw1uLnlb5wiIiIFkLbhvEUpASFpir4Ie+bZhh0fWw/G+k+FBUJb2EY61O4F/poqJSK3uKvhthERf34H53dfKw+qCA3ug9sGQfGw/ItPRESkgFEC4halBIQ4iYuAvQttSYfDq679Rg+gQlPb0OLa90Bg2fyKUESk4DLGNjVt+wzY+ZPtM9UutCU0vN+WuPVKvSC3iIjIrUQJiFtUoUhAnN4OM/rY1hTwDrS9fAJTfF/E9vIJvFafqqyIVipPS0I07Ftsm15x8FdITrFOS5n6tqRDnd5QLDT/YhQRKWwS42DvAtuoiEMrgX9+fPIKsH2mNnwAKt4OFku+hikiIpIflIC4RRWKBMShlfDtPTd+HA/fFEmJlMmLtBIaQanLvIuAm/uNx5LfEuNsyYads2HfEkiKvVZXsuY/SYd7Ibhq/sUoInKzuHICdsy0JSMuH7lWXqKqbXpGg/sgsFz+xSciIpLHlIC4RRWKBERCNFw+BvGREB9l+zMuxdfxUbZXXMS1r+3lcZHOD9c5wSvAxSiLIs6jLzJKcnj55/1vvZIS4PBK20iHvQshIepaXfHKtoRD3T5QunbexiUicqswBo5tsCUids2FxBhbucUNqrS3TdGo0Q08vPM3ThERkVymBMQtqlAkIG5UcmLqpIQjURHhoiyNREdy6i1ks83iBl6uEhUpy4IyTnJ4+KSfyEhOgqNrbVtm7p4HcVeu1QVWgLq9bUmHsrdpGLCISF6Kj4JdP9uSEcc3Xiv3LQb1+tmmaJRtkG/hiYiI5CYlIG5Rt0QCIqckxV830iLl6IvIf76/vizKuTwuEkxyzsXk5pH2KAuLGxxa4bxPfUBp29zjOvfaFpXU9nAiIvnv4iFbIuLP/0HU6WvlpevZRkXU6w/+JfIvPhERkRymBMQtSgmIPGYMJMY6JyZcjb5IazpJyjIy+U/Rt7ht1fW6fSD0zptjDQsRkZuRNdm27tGfM2xT5ewj79w8oUYXuO0BqNoB3D3yN04REZEbVKgTEImJiaxZs4YlS5awatUqDhw4QHR0NCVKlKBZs2Y8+uij3H333Wn2X758OR988AGbN28mOjqa0NBQ+vTpw5gxYwgICEiz38GDB3nzzTdZvnw54eHhlCxZkg4dOvDqq69SuXLlNPtFRUUxfvx4Zs+ezfHjx/H39+f222/n+eefp127dmn2s1qtTJo0iSlTprB7t22f8dq1a/Pwww/zr3/9C0s2htArAVFIWa2QGO16Ook9WZEYA+UbQVhr7QAiIlLYxFyyLRS8/Vs4s+NaeUBpaDDQlowoWT3/4hMREbkBeZaA2L17Nxs2bCA8PJw6derQs2dPwPZwnZSUhJeXV5aPuXz5cjp27AhAmTJlaNy4Mf7+/uzevZudO3cC8Mgjj/DFF1+kekifOHEizz33HBaLhVatWlG6dGnWrl3L2bNnqVGjBuvWrSM4ODjVOdevX0+nTp2IiYmhTp061K1bl507d7Jr1y78/f1Zvnw5zZs3T9Xv/PnztGrViv3791O2bFlatmzJuXPnWLt2LQAfffQRTz31VKp+ycnJ9O/fnzlz5uDn50f79u0d1x4bG0u/fv2YOXMmblkcUq8EhIiISAF3dqdtisZfP0DMxWvlFZrCbfdD3XttOzeJiIgUEpl+DjXZdPz4cdO+fXvj5ubmeA0dOtRR/8UXXxg3NzezfPnyLB97xYoVpk+fPmbNmjWp6mbOnGnc3d0NYKZPn+5Ut23bNmOxWIy7u7tZtGiRozw6Otq0b9/eAKZPnz6pjhkdHW3KlStnADNmzBinujFjxhjAVKxY0cTExKTq26tXLwOY9u3bm+joaEf5woULjbu7u3FzczM7duxI1W/ixIkGMOXLlzeHDx92lB8+fNgRyyeffJLOu+RaRESEAUxERESW+4qIiEgeSow3Zvc8Y74bYMxrxYwZF2h7vVHamNn/MubQKmOSk/M7ShERkQxl9jk0WwmIixcvmrCwMGOxWEy9evXME088YSwWi1MC4tKlS8bDw8M8/fTT2TlFuh5++GHHQ39K/fr1M4AZPnx4qj5Hjx41bm5uBjB79uxxqvvss88MYKpXr26Sr/uPPjk52VSvXt0A5osvvnCq27VrlwGMu7u7OXr0aJpxDhw4MNUxy5QpYwAzY8aMVP2+/fZbA5hy5cqliicjSkCIiIgUQpFnjVn3oTGfNL2WiBgXaMzEusb89rYxl4/nd4QiIiJpyuxzaLaWzH/nnXc4evQoL7zwAjt27ODTTz9N1aZYsWLUq1ePdevWZecU6WrYsCEAJ06ccJQlJCSwcOFCAAYNGpSqT2hoKC1atABg7ty5TnX27wcOHJhqyoObmxsDBgwAYM6cOS77tWjRgtDQ0FTntMcxf/58EhMTHeUbN27k7NmzeHt706dPn1T9+vTpg5eXF6dPn2bTpk2p6kVEROQmU6Q0tHgGntgEw1dA4yG2HZCuHIfV/4WPGsCcR+Dc7vyOVEREJNuylYD45ZdfqFSpEv/973/TXSixcuXKnD59Os367Dpw4AAAZcuWdZTt37+fmJgYAJo0aeKyn718+/btTuX273OrX3R0tCPmlP3q1KmDj49Pqn6+vr7UqVPH5TlFRETkJmaxQIUm0OMjeH4f3DsJKrWybfn81w/wf3fA9wPguH5BISIihU+2EhDHjh2jUaNGGS6Q6OXlxaVLl7IVWFrOnj3LtGnTAJxGDxw5cgSAokWLUqRIEZd9K1as6NQWbDtYXLxoWwAqJCQk3X7h4eFER0enOmda/QIDAx0LcKQ8Z0b90orVlfj4eCIjI51eIiIichPw8oP6/WHIAvjXStsWzFhg/xKY0gmmdIX9y2xbQouIiBQC2UpA+Pj4EBUVlWG748ePExSUc6s4JyUl8cADDxAREUG9evV49NFHHXX2ePz9/dPsb9+CM+VDesrrSKtvyq07XfXN7jmz2s+V8ePHExQU5HjZExciIiJyEynfCPp/A09uhUaDwc0Tjm+A7/vB/7WAv2ZBclJ+RykiIpKubCUgatasybZt25xGA1zvwoUL7Nixg/r162c7uOuNGDGCFStWUKJECX766adsbfF5sxkzZgwRERGOV8p1MUREROQmE1wVen4Cz/4Fdz4FXgFwfhfMGQ6fNITNkyAxNr+jFBERcSlbCYi+ffty8eJFnnvuOaxWq8s2I0eOJCYmxrGA44165plnmDx5MsWKFePXX3+levXqTvX2aRfpJUWuXr0K4LQvacrpGmn1tfdLq292z5nVfq54e3s7pnqknPIhIiIiN7HActDpTfj3Tmj7MviVsC1YuegF+LAerH0fYq/kd5QiIiJOspWAeOKJJ6hbty5ff/01zZo14+233wbg0KFDfPDBB9xxxx1888033HbbbQwZMuSGg3z++ef5+OOPKVq0KMuWLXPsgpFSpUqVALhy5Uqa00PsowPsbcGWDChevDhgmzKSXr/g4GCnaRP246TVL+WaDCnPmVG/tGIVERERceJbDFqPhGd3Qtd3ISgEosNhxX9gYl349VWIOpvfUYqIiAA3sAbE0qVLueOOO9i2bRuvvPIKAOvWrWPkyJFs2rSJJk2asGDBAjw9PW8owFGjRvHBBx8QFBTEsmXL0txxokaNGvj5+QGwdetWl23s5Y0aNXIqt3+fW/38/f2dRmzY++3atYu4uLhU/WJjY9m1a5fLc4qIiIik4uUHtz8CT2+D3l9ByVqQEAXrP7KNiJj/DFw8lN9RiojILS5bCQiwbYG5bt06Fi9ezBNPPEG3bt3o3Lkzw4cPZ86cOfz+++9O22Rmx+jRo3n33XcJCgri119/pWnTpmm29fLy4u677wbg+++/T1V/7NgxNmzYAEDv3r2d6uzfz5w5M9WUEqvVyg8//ADAvffe61R3zz33ALB+/XqXoxnscfTo0cMpEXPHHXdQpkwZ4uPjmT17dqp+s2fPJiEhgXLlynH77benec0iIiIiTtw9ocEAeGwD3PcDVLwdkhPgj2nwaROYNQRO/5nPQYqIyC3LFFAvvfSSAUzRokXN5s2bM9Xnjz/+MBaLxbi7u5vFixc7yqOjo0379u0NYPr06ZOqX3R0tClXrpwBzNixY53qxo4dawBToUIFExMTk6pvr169DGA6dOjgVL9o0SLj7u5u3NzczI4dO1L1mzhxogFM+fLlzeHDhx3lhw8fNuXLlzeA+eSTTzJ13SlFREQYwERERGS5r4iIiNyEjm4wZkY/Y8YFXnt9c48xh1cbY7Xmd3QiInITyOxzqMWYgrd59Lx58+jVqxcATZo0oU6dOi7bBQcH89577zmVTZw4keeeew6LxULr1q0pVaoUa9eu5cyZM9SoUYN169YRHByc6ljr16+nU6dOxMTEULduXerWrcvOnTvZuXMn/v7+LF++nObNm6fqd/78eVq2bMmBAwcoW7YsrVq14vz586xevRpjDB999BFPP/10qn7Jycn069ePuXPn4ufnR4cOHQBYvnw5MTEx9O3blx9++AE3t6wNUomMjCQoKIiIiAgtSCkiIiLXnN0J6z+EnbPB/DPis3xjaPkc1OgGWfyZQ0RExC6zz6EFMgExbdo0hg4dmmG70NBQjh49mqp8+fLlvP/++2zevJno6GhCQkLo27cvY8aMcdr14noHDx7kjTfeYPny5YSHh1OyZEk6dOjAq6++SpUqVdLsFxkZyfjx45k9ezbHjx/H39+fZs2a8cILL9C+ffs0+1mtViZNmsTXX3/Nnj17AKhduzYPP/wwjzzyCBaLJcP3wFUsSkCIiIhImi4dgY2fwvYZkPTPWlTB1aHFs1CvH3hom3MREcmaXE1AuLu7Z7qtxWIhKSkpq6eQbFICQkRERDLl6nnY9AVs/hriI2xlgeXhjieh0WDwDsjf+EREpNDI1QREVqcFXL+wo+QeJSBEREQkS+Ii4Y+psPEzuHrOVuZbDJo9Crc/Cn7F8zc+EREp8DL7HJqtyX5Wq9XlKzk5mcOHD/Pxxx9TrFgxxo0bp+SDiIiISEHmEwgtnoFn/oLuH0KxMIi9DKv/CxPrwOLREHEyv6MUEZGbQK6tAbFq1So6dOjADz/8QJ8+fXLjFOKCRkCIiIjIDbEmw+5fYN1EOPuXrczNA+oPsCUqStbI3/hERKTAKRCLUDZt2hQvLy/Wr1+fW6eQ6ygBISIiIjnCGDj0my0RcXTttfKa3aHlv6FCk/yLTURECpRcnYKRWZUrV+bvv//OzVOIiIiISG6wWKBqexiyAIavsCUeAPYugK/bw7TucHC5LVEhIiKSCbmagDhw4AAFcJdPEREREcmKCk1g4HfwxGa47QHblIyja2FGH/iyFeycbZu6ISIiko5cSUAkJSXx1ltv8eeff9KwYcPcOIWIiIiI5LWSNeCez+CZHdD8cfD0g7N/w0/D4JPGsHUqJMbld5QiIlJAZWsNiHbt2qVZFxUVxeHDh7ly5QoWi4UFCxbQpUuXGwpSMk9rQIiIiEieibkEm7+CTV/Yds4ACChtS040GWbbYUNERG56uboIpZtbxgMnqlWrxn//+1969+6d1cPLDVACQkRERPJcQjRs+wY2fAKRp2xl3kHQ9GFo/hgElMrf+EREJFflagJi9erVadZ5eXlRvnx5QkJCsnpYyQFKQIiIiEi+SUqAnT/Bug/hwj5bmbs3NHwA7nwKiofla3giIpI7CsQ2nJL3lIAQERGRfGe1wv7FsPYDOLXVVmZxgzr3QstnoUy9fA1PRERylhIQtyglIERERKTAMAaOroN1E+HQimvl1TpBy39DyB227T5FRKRQUwLiFqUEhIiIiBRIZ3bYpmbs/hmM1VZW8XZbIqJaZ8jEGmMiIlIwZfY5NNuf9MePH+exxx6jWrVq+Pn54e7u7vLl4eGR3VOIiIiIyM2ibAPoNxWe3AqNh4K7F5zYBP8bCP93J+yYCcmJ+R2liIjkomyNgNi7dy8tWrTgypUrZKa71WrNVnCSdRoBISIiIoVC1Fn4/f9gy2RIiLKVBVW0LVbZ8EHw8svf+EREJNNydQTESy+9xOXLl+nUqRO///47ERERWK3WNF8iIiIiIk6KlIGOr8O/d0L7V8G/JEScgMWj4MO6sPpdiL2c31GKiEgOytYIiODgYAICAti/fz9eXl65EZdkk0ZAiIiISKGUGAt/fgfrP4Yrx2xlXgHQeAjc8QQElsvX8EREJG25OgIiJiaGZs2aKfkgIiIiIjnD0xeaDoentkGfyVC6LiRchY2fwof14Zcn4cKB/I5SRERuQLZWiKxcuTLR0dE5HYuIiIiI3OrcPaBeX6jbBw4uh7UfwPENsP1b2D4DavWw7ZxRvlF+R1rwJCdCXETGr/hIF2VR4O4JXv62kSdeAf987Q/eRa597ZXia++U7VJ87R0Anv7a2UREUsnWFIx33nmHN998k8OHD1OyZMnciEuySVMwRERE5KZz/HfbFp77F18rC2sNrZ6z/Wmx5FtoOSop/p+EgD1BcCXzCYS4CEiMye8rcObp5zo5kd0kh6ffzfN3LXKTyexzaLYSEElJSXTr1o1Lly4xbdo06tate0PBSs5RAkJERERuWud2w/qP4O9ZYJJtZeUa2kZE1OwObu75F5sxkBSXInkQkXYSIa0EQlJczsTiFQA+Qa5f3oFplycnQEK0bepLwtVrX8fbv4627Vji+DraNnLC8f0//UxuLUJvuS5pcf0IjH/+TCvJ4arOw/vmTGoYYxsRY038588k28tRluRcZy+3JqVdl5wI1uQUX6d1nKS068C24GxAKQgoDUVK2/60v7yL3Jx/H7eAXE1AtGvXjsTERNavX4+bmxshISGEhITg5mKYlcViYcWKFVk9hWSTEhAiIiJy07tyHDZ8Ctu+gaRYW1mJqtDiGag/wPZQmVXG2EYQpEogXJdESCt5EBdhe4DPCd5B4JNGoiC9JIK9zj1bs6xzhj0RE39dEsP+dXzKsvTqrjonNnKLxf26xISrERtp1Hn5gdWa4oHb1QN7UhoJgOsf/JPTrktOSuOh/vrvUyQH7Am6wsbDN43kRCkIKHOtLqCUbcqQFBi5moBwlWhI8wQWC8nJhfQfQCGkBISIiIjcMqIvwKYvYfOXtgQAQJGytl0zyjdxnUhIL4FgTbrxmCxu6ScIMkokeBfJ35EcBZHVaksOuUpOOI3ASPF1qgTIdaM57ImrW4nFDdw8wc3DlqRy87Q9xLt5Xve9xz9tPFP86Xnd9x7p1Hna7mFXdcZq+3d79dw/r/MQddb2Z0JU1q7Hr0QayYmUyYtS4FNUoyryQK4mIFavXp2l9q1bt87qKSSblIAQERGRW058FPwx3bZjRtSZGzuWxT2NhEGg7UEmo0SCV4AWXywMrMlpJyfSTXKkrIux/V27fHC//qHe/r1HOnVZTQ64qHO0cXGOgn5fJkTbEhEpkxNXz11LUKQsy8oID3fvFImK65ITAWVSfF0qe6OnBMjlBIQUXEpAiIiIyC0rKR7++hG2TLI9TGYnkeDlr9+WihRkVivEXkojOXHWOYlhHxmVWb7FnJMVKV8pp4T4FtPnxHWUgLhFKQEhIiIiIiICJMb+k5CwJyVSJCiirhtpYU3M/HHdPK9LVJSCIimngaT42tMn966vAMnsc+gNrVBjjGHx4sVs2LCB8PBwbr/9doYNGwZAeHg4ly9fpkqVKri7ax6biIiIiIiI5CFPXygWanulxxiIvexibQoXIytiL9uSFZEnba+MeAe5mPZxfeKiNPgWL/jTZHJAthMQO3bsYMCAARw4cABjDBaLhcTEREcC4tdff+XBBx/k559/pkePHjkWsIiIiIiIiEiOsVjAr7jtVapW+m2T4q8bVXGO1OtW/PN9cjzER9heF/ZnEIP7dVM/7GtWlIGqHaB4WM5dbz7KVgLi5MmTdOjQgYsXL9KtWzfatGnDqFGjnNrcc889eHp68ssvvygBISIiIiIiIoWfhzcUrWh7pccY2xoUGS6qeRZiLtoW1ow643oh3YHf39oJiLfffpuLFy/y4Ycf8vTTTwOkSkD4+fnRoEEDtmzZcuNRioiIiIiIiBQWFgv4FrW9StZIv21yIkSHu1ib4p9pIMUr50XEeSJbCYglS5ZQs2ZNR/IhLZUqVWLlypXZCkxERERERETkpufuCYHlbK+bXLZWuTh9+jT16tXLsJ3FYiEyMjI7pxARERERERGRm0i2EhD+/v6Eh4dn2O7IkSMUL148O6cQERERERERkZtIthIQ9erV448//uDChQtptjl27Bg7duygcePG2Q5ORERERERERG4O2UpAPPDAA0RFRTF8+HBiYmJS1SckJPD444+TmJjIAw88cMNBioiIiIiIiEjhlq1FKIcOHcp3333HvHnzqFmzJl26dAFgx44dPP3008ybN4/jx4/ToUMHBgwYkKMBi4iIiIiIiEjhYzHGmOx0vHr1Ko8++igzZ87E1SH69OnD1KlTCQgIuOEgJfMiIyMJCgoiIiKCwMDA/A5HREREREREbnKZfQ7NdgLCbu/evSxatIjDhw9jtVqpWLEiXbt25bbbbruRw0o2KQEhIiIiIiIieSmzz6HZmoKRUs2aNalZs+aNHkZEREREREREbmLZWoRy/vz5WK3WnI5FRERERERERG5S2UpA9OrVi4oVK/Liiy+yZ8+enI5JRERERERERG4y2UpANGrUiDNnzvDuu+9St25d7rzzTiZNmkRkZGROxyciIiIiIiIiN4FsJSC2bt3KX3/9xbPPPktwcDC///47I0aMoGzZsgwePJjffvstp+MUERERERERkULshnfBSEpKYsGCBUydOpXFixeTlJSExWIhJCSEoUOH8tBDDxEaGppT8UoGtAuGiIiIiIiI5KU824YzpfDwcL799lumTp3Krl27sFgsuLm5kZiYmFOnkAwoASEiIiIiIiJ5KbPPodmagpGWkiVL8txzz7F582aeeeYZjDHaLUNERERERERE8MjJg/3+++9MnTqVH3/80bEgZfHixXPyFCIiIiIiIiJSCN1wAuLMmTN88803TJs2jf3792OMwc3NjU6dOjF06FDuueeeHAhTRERERERERAqzbCUgEhIS+Pnnn5k2bRq//vorVqsVYwxVqlRhyJAhDBkyhPLly+d0rCIiIiIiIiJSSGUrAVG2bFmuXLmCMQY/Pz/69u3LsGHDuOuuu3I6PhERERERERG5CWQrAXH58mXuuOMOhg0bxoABAwgICMjpuERERERERETkJpKtBMSePXuoUaNGTsciIiIiIiIiIjepbG3DqeSDiIiIiIiIiGRFthIQdocOHWLUqFG0bNmSGjVqMGrUKEfdpk2b+Oqrr4iIiLjhIEVERERERESkcMv2NpzTp09nxIgRxMfHA2CxWLhw4YKjPiYmhsceewwvLy+GDBlyw4GKiIiIiIiISOGVrREQv//+O8OHD8fLy4sJEyawadMmjDFObVq3bk1QUBDz58/PkUBFREREREREpPDK1giICRMmYIxh4cKFtGzZ0mUbNzc3brvtNnbv3n1DAYqIiIiIiIhI4ZetERDr16+nWbNmaSYf7MqUKcOZM2eyFZiIiIiIiIiI3DyylYC4cuUKISEhGbaLjY0lISEhO6cQERERERERkZtIthIQJUqU4NixYxm2O3jwIGXKlMnOKURERERERETkJpKtBETz5s3ZunUru3btSrPN+vXr2bVrV4bTNERERERERETk5petBMQTTzxBcnIyffr04c8//0xVv2fPHoYNG4bFYuHxxx+/0RhFREREREREpJDLVgKiffv2PPfcc+zfv5/GjRtTvXp1LBYLS5cupX79+tSrV48DBw4wcuRImjdvntMxi4iIiIiIiEghk61tOAHee+89atSowWuvvcbBgwcBOHPmDGfOnCE4OJhx48bxxBNP5FigkvsSExNJTk7O7zBERCQFd3d3PD098zsMERERkRtmMcaYGzmAMYbt27dz+PBhrFYrFStWpGnTpnh4ZDu3ITcgMjKSoKAgIiIiCAwMzHSfCxcuEB8fn8vRiYhIdnh7exMcHJzpz3URERGRvJTZ59AbzhJYLBYaNWpEo0aNUtVduXKFd999l7feeutGTyO5JDIyklOnThEQEEBwcDCenp5YLJb8DktERLAl+RMTE4mIiODUqVMASkKIiIhIoXXDIyBciYyM5P333+ejjz4iKipKw/rzUFZHQBw+fBhPT08qVKigxIOISAFljOHkyZMkJiZSuXLl/A5HRERExEmujID4448/mD9/PufOnaN06dL07NnTaeRDXFwcH3zwAe+99x4REREYY6hdu3b2r0JyVWJiIvHx8QQHByv5ICJSgFksFoKCgjh16hSJiYlaE0JEREQKpUwnIF544QUmTpzoVPbGG2/wyiuv8Nprr7FlyxYGDBjAsWPHMMYQEhLCa6+9xuDBg3M8aMkZ9pEp+kFWRKTgs39WJycn63NbRERECqVMJSAWLlzIBx98ANjmnlarVo3IyEgOHz7MG2+8QY0aNXjssceIjIykePHivPzyyzz++ON4eXnlavCSMzT6QUSk4NNntYiIiBR2mUpATJo0CYCnnnqKCRMm4O3tDcCePXvo06cPDz30EElJSbRt25YffviB4ODg3ItYRERERERERAodt8w0+uOPP6hUqRITJ050JB8AatWqxYcffkhSUhKBgYH8/PPPSj6IiIiIiIiISCqZSkCEh4fTsGFD3NxSN2/evDkArVq1okiRIjkbnYiIiIiIiIjcFDKVgEhISCAoKMhlnX2LjZIlS+ZcVCJS6FSqVAmLxeL08vb2pkKFCvTq1YsFCxbkd4i0adMGi8XCqlWr8jsUEREREZFbTpa24RQRyUiLFi2oWrUqABEREWzfvp158+Yxb948/v3vfzsWtBURERERkVtLphMQBw8e5JtvvslWvbbiFLl1DB8+nCFDhji+T0pK4t///jeffvopEydO5L777qNp06b5Ets333xDTEwMISEh+XJ+EREREZFbWaYTEOvXr2f9+vUu6ywWS5r1FotFCQiRW5iHhwfvvvsu33zzDZGRkcyfPz/fEhBKPIiIiIiI5J9MrQEREhKS7VfFihVz+xpEpIDz8fGhWrVqAJw7dy5V/YoVK7j33nspW7YsXl5elCpVit69e7Nx48Y0j7lz50769OlDcHAwfn5+1KtXjw8//BCr1epYj+Lo0aNOfdJbAyIpKYkvvviCO++8k6CgIEfMTz/9NKdOnXIZg32tC4DZs2fTsmVLAgMD8ff3p0WLFixatCiT75CIiIiIyM0vUyMgrv8hXkQkqyIjIwEoXbq0U/kLL7zA+++/j5ubG02aNKFVq1YcP36cX375hfnz5zNp0iSGDh3q1Gf16tV07dqV2NhYqlSpQseOHbl48SIvvvgiv//+e5Zji4+Pp3v37ixfvhwfHx/atm1LYGAgGzZs4JNPPuF///sfS5cupVGjRi77jxs3jjfeeIM777yTbt26sXfvXjZs2ED37t2ZPXs2vXv3znJMIiIiIiI3Gy1CKSK5bs+ePRw+fBiAnj17OsonTZrE+++/T9WqVZk9ezb169d31K1Zs4bu3bszYsQIWrZs6RhBERsby/33309sbCzPP/88EyZMcGwRvHv3btq1a+dylEV6xo0bx/Lly6lSpQrLly+nUqVKACQmJvLYY48xefJk+vbty969e/Hy8krV/+OPP2bjxo3cfvvtjrLXXnuN119/ndGjRysBISIiIiJCJqdgiIhkR0REBMuWLePee+8lOTmZl19+mSZNmgBgtVp57bXXAJg5c6ZT8gHgrrvu4pVXXiEhIYEvv/zSUf7TTz9x6tQpQkNDGT9+vCP5AFC7dm1eeeWVLMUYFxfHZ599BsDEiRMdyQcAT09PPv74Y0qXLs2RI0f46aefXB7jP//5j1PyAWDMmDEEBQWxf/9+Tpw4kaWYRERERERuRkpAiEiOGjp0qGNthKJFi9K5c2cOHDjAjBkzeOONNxzttm/fzunTp6lSpQqNGzd2eaw2bdoAsGHDBkfZ6tWrAejXrx+enp6p+tx///1Zinfr1q1cvXqV4sWL06NHj1T1fn5+DBw4EICVK1e6PIarft7e3lSuXBkgzTUkRERERERuJZqCISI5qkWLFlStWhWA8PBw1q5dS1RUFI899hjVqlWjWbNmAI4pGYcOHXIs5JiW8PBwx9cnT54EcBqpkFLRokUJCgoiIiIiU/HakwNhYWFptqlSpYpT2+ultbtGYGAgYBtlISIiIiJyq1MCQkRy1PDhwxkyZIjj+4iICHr37s3KlSvp378/u3fvxs/PD6vVCkCZMmXo3LlzuscMDg5OVZZe0iKjhEZOSzkNREREREREXFMCQkRyVVBQED/88AM1a9bk2LFjfPDBB7z88suOLXpLlCjBtGnTMn288uXLA2nvzhMREcGVK1eyfLwjR46k2cY+WsPeVkREREREsk6/thORXFeyZElefvllAN577z2uXLlC06ZNCQ4OZvfu3ezatSvTx7rrrrsAmDVrFklJSanqv//++yzF1qRJEwICArh06RLz5s1LVR8bG8vMmTMBaNu2bZaOLSIiIiIi1ygBISJ54vHHHyckJISIiAjef/99PD09GTduHMYYevfuzbp161L1SU5O5rfffuP33393lPXr14+yZcty9OhRXnrpJcdUDoC9e/fyn//8J0tx+fj48MQTTwDw/PPPc+zYMUddYmIizzzzDGfPniUsLIy+fftm9bJFREREROQfSkCISJ7w9vZ2bLv50UcfcenSJZ588klGjhzJgQMHaNWqFXXr1uWee+7hvvvuo23btgQHB9O+fXv+/PNPx3H8/PyYMWMGPj4+TJgwgRo1anDffffRuXNnGjRoQKtWrRyLQnp5eWUqttdff5327dtz8OBBatWqxd13383AgQOpWrUqkyZNokSJEsyaNSvTxxMRERERkdSUgBCRPDN48GBq165NVFQU7777LgATJkxg/fr13H///Vy9epUlS5awcOFCTp8+TZs2bfj6668ZMGCA03HatWvHpk2b6N27N5cuXeLnn3/m5MmTvPXWW8yYMYOzZ8/i5uZG8eLFMxWXt7c3S5Ys4fPPP6dBgwasXbuWuXPn4unpyVNPPcWOHTvS3CpUREREREQyx2KMMfkdhOScyMhIxxaE9i0A0xIXF8eRI0cICwvDx8cnjyIUyV1r1qyhdevW1KtXj7/++iu/wxHJMfrMFhERkYIqs8+hGgEhIoVOeHi4y10rdu7cyb/+9S8Ahg4dmtdhiYiIiIhIOgpsAmLfvn188sknDBkyhHr16uHh4YHFYuHNN9/MsO/y5cvp1q0bwcHB+Pr6UrNmTV566SWuXr2abr+DBw8yZMgQKlSogLe3NxUqVGDIkCGOLfjSEhUVxdixY6lRowa+vr4EBwdz991389tvv6Xbz2q18uWXX3L77bdTpEgRihQpwu23385XX32FBqaIpG3Xrl1UrlyZOnXq0KNHD/r370/Tpk1p0KAB+/fvp2PHjjz11FP5HaaIiIiIiKRQYBMQ//d//8fTTz/N9OnT2blzJ8nJyZnqN3HiRDp27MiSJUscDycRERG8/fbbNGnShAsXLrjst379eho0aMD06dMpWrQovXv3pmjRokyfPp369es7rcKf0vnz52nSpAnjx48nKiqKHj16UKdOHRYvXkyHDh345JNPXPZLTk6mX79+jBgxgp07d9K2bVvatm3L33//zaOPPsqAAQOcVvcXkWuqV6/OE088gZubG+vXr2fu3LkcOnSIO++8k88//5xFixbh4eGR32GKiIiIiEgKBfYn9Lp16/LCCy/QsGFDGjVqxNtvv823336bbp/t27fz/PPP4+7uzvz58+natSsAMTEx9OzZkxUrVjBixAh++uknp34xMTH079+fmJgYxowZw9tvv+2oGzt2LOPHj6d///7s27cPX19fp76PPPII+/fvp3379sybNw8/Pz8AFi1aRM+ePXn22Wdp3bo19evXd+r3ySefMGfOHMqXL8/atWsJCwsD4MiRI7Rs2ZJZs2Zx11138eSTT2bvDRS5iZUrV45PP/00v8MQEREREZEsKLAjIIYPH867777LoEGDqFmzJm5uGYc6fvx4jDEMHTrUkXwA27Z9kydPxs3NjdmzZ7N3716nftOmTeP06dNUr1491RSPN998k+rVq3PixAm++eYbp7rdu3fzyy+/4O7uzuTJkx3JB4Bu3boxZMgQrFYr48ePd+pntVp55513AHjnnXccyQeAsLAwR9348eM1CkJERERERERuCgU2AZFVCQkJLFy4EIBBgwalqg8NDaVFixYAzJ0716nO/v3AgQNTJTrc3NwcWwDOmTPHZb8WLVoQGhqa6pz2OObPn09iYqKjfOPGjZw9exZvb2/69OmTql+fPn3w8vLi9OnTbNq0KZ2r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dSurV69m+fLlrF+/nk2bNrF+/Xrefvttxo8fz4svvpjr8YuIiIiISO7Q06VIOs6cOcOiRYsAuHjxIuvXr0+z7enTp1myZAl33313rsVTsWJF9u7dy8MPP0zfvn1z7Twp2Udo7N27N1Pt16xZw7lz52jUqJFj7YyUDhw4kGZfi8VCmzZtaNOmDWBL+kybNo0nnniCsWPH0rdvX6pUqZL1ixARERERkXynNSBE0jFt2jSSk5O5/fbbMcak+Ro1ahRwbbREbunatSsAP/74Y66eJ6UuXboA8L///Y/o6OgM21+6dAlIe+rJjBkzMn1uHx8fRowYQf369bFarfz111+Z7isiIiIiIgWLEhAi6bD/Bv+hhx5Kt93gwYMBWLBggcu1F3LKI488QmhoKLNmzeLFF18kKioqVZuzZ88yadKkHDtnz549adiwIadPn6Zfv35cvHjRqT4uLo7Fixc7vrev1bBixQp2797t1Parr77ihx9+cHme9957z+WaEXv37nWMmnA1rURERERERAoHTcEQScPq1as5ePAg3t7eDBw4MN22derUoVGjRmzbto1vvvmG559/Pldi8vf3Z+HChXTv3p0JEybw1VdfUb9+fSpUqEBMTAz79+9nz549lCpVin/96185ck43Nzfmzp1L586dWbx4MSEhIbRs2ZISJUpw6tQpduzYQdGiRTl69CgADRs2pFevXvzyyy80bNiQNm3aULx4cf7880/27dvH2LFjXS7W+eabbzJy5Ehq1qxJrVq18PX15fTp044dMQYPHkyjRo1y5JpERERERCTvaQSESBrs0yl69OhBsWLFMmxvHwWR29Mw6tSpw19//cWECROoVasWf/31F7NmzWLTpk34+/vzwgsvMHfu3Bw9Z2hoKFu3buWdd96hTp06bNy4kTlz5nDs2DFat27NO++849R+1qxZvPvuu9SoUYN169axbNkyQkJCWLp0KcOHD3d5js8++4yhQ4fi4eHB6tWrmT17NkeOHKFjx47MnTuXadOm5eg1iYiIiIhI3rKY65eil0ItMjKSoKAgIiIiCAwMTLdtXFwcR44cISwsDB8fnzyKUEREskOf2SIiIlJQZfY5VCMgRERERERERCTXKQEhIiIiIiIiIrlOCQgRERERERERyXVKQIiIiIiIiIhIrlMCQkRERERERERynRIQIiIiIiIiIpLrlIAQ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bNiQjRs3OqY55LZZs2bx7rvvUqNGDdatW8eyZcsICQlh6dKlDB8+PM1+DRs25O+//+bll1+mYsWKrFq1innz5nH27Fl69uzJmDFjcj32sWPHsmHDBu677z6ioqKYM2cO69atw9PTk1GjRtGuXbtcj0FERERE5FZnMVq2/qYSGRlJUFAQERERBAYGpts2Li6OI0eOEBYWho+PTx5FKCIi2aHPbBERESmoMvscqhEQIiIiIiIiIpLrlIAQERERERERkVynBISIiIiIiIiI5DolIEREREREREQk1ykBISIiIiIiIiK5TgkIEREREREREcl1SkCIiIiIiIiISK5TAkJEREREREREcp0SECIiIiIiIiKS65SAEBEREREREZFcpwSEiIiIiIiIiOQ6JSBEREREREREJNcpASEiIiIiIiIiuU4JCBERERERERHJdUpAiGSgUqVKWCyWDF/Tpk3L71ALrJUrV2KxWHj88ccBOHr0qNN7N3fu3HT733333Y62HTp0SFVvr8uqNm3aYLFYWLVqVZb6DRkyxOXf+WuvvYbFYuG1117LcixZZT9XRq82bdrkeiw36siRI1gsFrp16+ayPiEhgZIlS2KxWChTpgxJSUnpHu/UqVM8+OCDlCtXDg8PDywWC0OGDMl0PNOmTctyHxERERHJmEd+ByBSWLRo0YKqVaumWZ9e3a1u9uzZAPTp08dl/ZQpU+jdu7fLulOnTrF06dJci62wK126NF26dEmzvmbNmnkYjc2qVato27YtrVu3zlRyJ6P745dffuHChQsAnDt3joULF9KrVy+XbY0x3HvvvWzevJnatWvTtm1bPD09admyZfYuRkRERERyjBIQIpk0fPhw/UY0G4wxzJ07lxIlStC6dWunOnd3d+rVq8eSJUs4e/YsZcqUSdV/+vTpJCcn07RpU7Zs2eLyHHv27MmV2AuDmjVrFvrRN7Nnz8bd3T3NpMLkyZMBKF++PKdOnWLy5Mlptj127BibN28mJCSEHTt24OGR9f/mevfuTfPmzQkKCspyXxERERFJm6ZgiEiu2rhxI6dPn6Znz54uHwaHDRtGUlIS06dPd9l/6tSp+Pj4MGjQoDTPUbNmzXz5Tb/cuFOnTrFp0ybuuusugoODU9WfOHGCX3/9FXd3d3788UcsFguLFi3izJkzLo93/PhxAMLCwrKVfAAICgqiZs2a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FRXlsj4xMZEzZ85k69jly5dn7969HD582GV9RESEY6tIV79JP3LkSJrHtm9VWKFCBcC2a4Gvry+xsbG89957LncxSMvs2bPx8vKie/fume4zbNgwVq5cyfz58ylWrJjLNRoyy37t129zmpL9N9pZ7Zde3fVu5D3MaXv37uWvv/6iVKlSzJ07Fw8P5/8C7FMC0tK0aVPHaIekpCR+/vlnBg8ezOeff07fvn0d229mRnrrg2zZsoW///4bsI34sY/6cWXTpk3s2rUrWzuTZFVISAj79u1j79696U7Hsps1axbGGJ566ilGjRqVqj6j91tERETkZuOW3wGI3IxKliyJl5cXly5d4vz586nqly5dSlJSUraO3aZNGwCmT5/ust6+lWO1atVcJiCWLVvmMqZFixZx8eJFihQpQuPGjQFwd3d3bJ/5448/ZjrGw4cPs2PHDjp06EBgYGCm+/Xp04fQ0FBKlCjB0KFDb2idgdatWwO2efv2hExK8+bN48qVK6nK77rrLiwWC9u2bWPv3r2p6nfs2JHp6ReQ/fcwN9jfh3LlyqVKPoBt2kNmeXh40LdvXzp37gzAn3/+6aizJ+DSusejo6NZtmwZtWvXdjmd4euvvwZsa2bY16Zw9erfvz9AmlvO5jT7WhuTJk3KVHv7++1qGlFcXJwjCSMiIiJyq1ACQiQXeHp6OnYGePnll52G4e/YsYMnn3wy28f+17/+RWBgINu2bePtt992Gr69fft23nzzTQCnXQxSio2N5bHHHiM2NtZRdvr0aZ5//nkARowY4fTgP27cOLy8vBg5ciTTp093OXVk586djgUFIevTL+x8fX05evQoFy5c4P33389S3+u1atWKRo0acfXqVZ544gni4+MddSdOnOCFF15w2S8kJITevXtjtVp57LHHnObnX758mccffzzLQ+az8x7mhurVq+Pu7s7ff//tWKTTbv78+UycONFlv88//9zlQolnz55l69atgPNDtn0EzYEDBxwLLqa0aNEiYmNjXd4fMTExzJw5E8h4yop9x5AZM2a4PE9Oe+655yhSpAjz5s3j5ZdfTnXO8+fPs27dOsf39h1Hpk+f7jQaKi4ujscffzzd0UgiIiIiNyNNwRDJpK+//jrVQ1tKnTp1YtCgQY7v33zzTdasWcOkSZNYvXo19evX59SpU2zdupVBgwaxatUql1MAMlK6dGm+++47+vXrx0svvcS3335Lw4YNOX/+PKtXryYpKYmhQ4emOS9+8ODBLFiwgMqVK9OqVSvi4uL47bffiI6O5o477uD11193at+oUSNmzJjBkCFDGDJkCC+//DK1a9emZMmSXLp0ib///puTJ08yYMAAx3D62bNn4+HhQa9evbJ8fTnp22+/pU2bNsycOZM1a9bQsmVLYmJi+O2336hfvz7BwcFs3LgxVb/PPvuMHTt2sGrVKsfaFMYYVq5cSYkSJejZsyfz5s3LdBzZeQ8za+/evekujurn58fnn38O2KaDPPnkk3z00Ue0b9+eVq1aUa5cOfbt28e2bdt4+eWXHQmslL766iueeOIJwsLCqFu3LoGBgYSHh7N27VpiY2Np166d05axISEhNGnShK1bt1KvXj2aNGmCj48PwcHB/Pe//003QTVr1iwiIyMpU6YMnTp1SvfaO3fuTOnSpTl37hzz5s3LcsIrq0JCQvjpp5/o27cvb731Fl9//TV33HEHnp6eHDt2jO3btzNo0CDHmhVDhw7lo48+Yvv27YSFhdGqVSvc3d0d79szzzzDRx99lKsxi4iIiBQoRm4qERERBjAREREZto2NjTW7d+82sbGxeRBZ4RUaGmqADF/PPPNMqr4bN240nTp1MoGBgcbX19c0aNDAfP7558ZqtTqOe+TIEZfnu778ert37zYPPfSQqVChgvH09DRFixY1bdu2NTNnznTZfty4cQYw48aNM4cPHzb33XefKV26tPHy8jJVq1Y1r776qomOjk7zfEeOHDH//ve/Td26dY2/v7/x8fExoaGhpk2bNua///2vOXjwoDHGmBMnThiLxWLatWuX7rEA4+7unu41pjR16lQDmPbt26eqs/8duHLs2DEzZMgQx7VWrlzZvPjiiyY6Otq0bt3aAGblypWp+l24cME89dRTpkKFCsbLy8tUqFDBjBgxwoSHh5uHHnrIAGbq1KlOfVK+x2ldd2bew8ywnyujV1BQkFM/q9VqJk+ebBo3bmwCAgJMUFCQadmypeO+cfVeLliwwDz22GOmYcOGpmTJko73o02bNmb69OkmISHB5fs+aNAgU7ZsWePh4WEAExoaauLi4kxAQICpUqWKy+tq1aqVAcwLL7yQqffh2WefNYDp2rWrMcaYlStXGsC0bt3aZfv0/s7t7PfaQw895LL+2LFj5plnnjE1atQwPj4+JiAgwFSvXt0MGzbMbNy40alteHi4efzxx02VKlWMt7e3KVeunHnggQfMgQMHMjzP9fSZLSIiIgVVZp9DLcZo+e2bSWRkJEFBQURERGQ49z4uLo4jR44QFhZ2Q3PtpXB47bXXeP311xk3bhyvvfZarp3nk08+4emnn+azzz7j8ccfz7XzSOE0f/58evbsyciRI5kwYUJ+h1Oo6DNbRERECqrMPodqCoaI5KgyZcowbtw4+vbtm9+hSAHk4+PDuHHjnKYriYiIiMitQQkIEclR/fr1o1+/fvkdhhRQHTt2dOwKIiIiIiK3Fu2CISIiIiIiIiK5TiMgRG4Rr732Wq6u/SAiIiIiIpIejYAQERERERERkVynBISIiIiIiIiI5DolIEREREREREQk1ykBIRhj8jsEERHJgD6rRUREpLBTAuIW5uZm++tPTk7O50hERCQj9s9q+2e3iIiISGGjn2JuYZ6enri7uxMbG5vfoYiISAZiY2Nxd3fH09Mzv0MRERERyRYlIG5hFosFPz8/IiIiNApCRKQAS05OJiIiAj8/PywWS36HIyIiIpItHvkdgOSvUqVKcfToUY4dO0bx4sXx9vbWD7ciIgWEMYb4+HguXbqE1WqlVKlS+R2SiIiISLYpAXGL8/LyokKFCly4cIEzZ87kdzgiIuKCv78/ZcqUwcvLK79DEREREck2JSAEPz8/QkJCSEpKIikpKb/DERGRFDw8PPDw0H/XIiIiUvjpJxpx0A+5IiIiIiIiklu0CGUBMGvWLNq0aUOxYsXw9/enQYMGTJgwgcTExPwOTURERERERCRHKAGRz5599ln69+/P+vXradasGV26dOH48eO8+OKLtGvXTltkioiIiIiIyE1BCYh89PPPP/PRRx8REBDApk2bWLp0KbNnz+bAgQPUq1ePdevW8corr+R3mCIiIiIiIiI3TAmIfPT2228DMHr0aBo1auQoDw4O5vPPPwfg008/JSIiIl/iExEREREREckpSkDkk1OnTrFlyxYABg0alKq+ZcuWVKxYkfj4eBYtWpTX4YmIiIiIiIjkKCUg8sn27dsBKF68OGFhYS7bNGnSxKmtiIiIiIiISGGlBEQ+OXLkCAAhISFptqlYsaJTWxEREREREZHCyiO/A7hVRUVFAeDv759mm4CAAAAiIyPTbBMfH098fLzje/t6Een1EREREREREckp9udPY0y67ZSAKOTGjx/P66+/nqrcPnpCREREREREJC9ERUURFBSUZr0SEPmkSJEiAERHR6fZ5urVqwAEBgam2WbMmDE899xzju+tViuXLl2iRIkSWCyWHIo250VGRlKxYkVOnDiR7vWJ3AjdZ5LbdI9JXtB9JnlB95nkNt1jNzdjDFFRUZQrVy7ddkpA5JNKlSoBcOLEiTTb2OvsbV3x9vbG29vbqaxo0aI3Gl6eCQwM1AeQ5DrdZ5LbdI9JXtB9JnlB95nkNt1jN6/0Rj7YaRHKfNKwYUMALl68mOYik1u3bgWgUaNGeRaXiIiIiIiISG5QAiKfVKhQgaZNmwLw/fffp6pft24dJ06cwNvbm27duuV1eCIiIiIiIiI5SgmIfDR27FgA/vvf/7Jt2zZH+cWLF3n88ccBePLJJzM1lKWw8fb2Zty4cammj4jkJN1nktt0j0le0H0meUH3meQ23WMCYDEZ7ZMhueqZZ57h448/xtPTk/bt2+Pv78+KFSu4cuUKLVq04Ndff8XX1ze/wxQRERERERG5IUpAFAA//vgjn332GX/++SeJiYlUqVKFBx54gH//+994eXnld3giIiIiIiIiN0wJCBERERERERHJdVoDQkRERERERERynRIQ4iQxMZEVK1YwcuRImjZtStGiRfH09KRMmTL07NmThQsXptt/+fLldOvWjeDgYHx9falZsyYvvfQSV69eTbffwYMHGTJkCBUqVMDb25sKFSowZMgQDh8+nG6/RYsW0aNHD8qUKYOnpydFihShcePGvPnmm0RFRWX5+iVv5PV9Fh0dzffff8/zzz9PmzZtCAwMxGKxULVq1UzFe+7cOZ588knCwsLw9vamdOnS9OvXz2nxWCl4Cst9dvz4cb788kvuvfdeQkND8fb2JiAggAYNGjB27FjCw8Oz/R5I7ios95grp06dolixYlgsFjw8PLLcX/JOYbzPduzYwbBhwwgLC8PHx4dixYpRr149HnvsMS5evJil65e8UZjuM2MM3333HR06dCA4OBhPT0+KFi1KixYt+Pjjj0lISMjWeyB5xIik8OuvvxrAAKZMmTLm7rvvNv379zd169Z1lD/yyCPGarWm6vvBBx8YwFgsFnPXXXeZfv36mTJlyhjA1KhRw4SHh7s857p164yfn58BTJ06dcyAAQNM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TgkIEREREREREcl1SkCIiIiIiIiISK5TAkJEREREREREcp0SECIiIiIiIiKS65SAEBEREREREZFcpwSEiIiIiIiIiOQ6JSBEREREREREJNcpASEiIiIiIiIiuU4JCBERESk0HnjgASwWC926dUu33eXLlylfvjwWi4Wvv/46j6ITERGR9CgBISIiIoXGp59+Svny5Vm8eDFffvllmu2eeOIJTp8+zd13383w4cPzMEIRERFJi8UYY/I7CBEREZHMWrp0KV26dCEgIIAdO3ZQuXJlp/qffvqJfv36UaJECXbu3EmZMmXyKVIRERFJSSMgREREpFDp3LkzI0aM4OrVqzz00ENYrVZH3blz53jssccA+Pzzz5V8EBERKUCUgBAREZFC57333qNKlSqsW7eO9957z1H+yCOPcOHCBe677z769+8PwOnTp3nuueeoVasWfn5+FClShKZNm/Lpp5+SlJSU6tjh4eF8/PHHdOvWjbCwMHx9fQkMDKRJkya88847xMXFuYzJYrFgsVgAmDp1KnfccQdBQUFYLBaOHj2a82+CiIhIIaMpGCIiIlIorV+/nrvuugtPT0+2bNnCH3/8wdChQylXrhw7d+6kWLFirFmzhnvuuYfLly9TqVIl6tevT3x8PJs3b+by5ct06tSJBQsW4Onp6TjujBkzePDBBylfvjxVq1albNmyhIeHs2nTJq5evcodd9zBypUr8fb2dorHnnx48skn+fzzz7nzzjupWLEihw8f5ocffiA0NDRP3x8REZGCRgkIERERKbRefPFFJkyYQJ06dTh58iQREREsWrSIrl27cvbsWerWrculS5f47LPPePTRR3Fzsw3+vHjxIv379+e3337j9ddf59VXX3Ucc8+ePURERNC8eXOnc12+fJmBAweybNkyJkyYwMiRI53q7QmIwMBAli5dmqq/iIjIrU4JCBERESm04uPjadq0KX///Tdgm4Jh3x1j9OjRvPPOOzz55JN88sknqfqeOnWKsLAwihYtyrlz5xwJhPTs37+fGjVq0LRpUzZv3uxUZ+//n//8h1deeeVGL01EROSmowSEiIiIFGoLFiygR48eAERFRREQEABAvXr12LlzJ2vXrqVly5Yu+9apU4fdu3ezb98+qlev7ihPTk5m1apVbNiwgTNnzhAbG4sxBmMM33zzDYGBgURERDgdy56A2L17N7Vq1cqNSxURESnUPPI7ABEREZEbYU84XP/14cOHAWjVqlWGxwgPD3ckIA4cOEDv3r3ZtWtXmu0jIyPTrKtUqVKG5xMREbkVKQEhIiIiNyX79px9+/bF398/3bYlSpRwfN23b1927dpF9+7dGTVqFLVr1yYwMBBPT08SEhJSLT55PV9f3xsPXkRE5CakBISIiIjclCpWrMiBAwd48cUXadKkSab67N27l7/++otSpUoxd+5cPDycf1Q6cOBAboQqIiJyS3DL7wBEREREckPXrl0B+PHHHzPd59KlSwCUK1cuVfIBbFt0ioiISPYoASEiIiI3pZEjR1K0aFE++OAD3n//fRISElK1OXLkiFNSoXr16ri7u/P333+zatUqp7bz589n4sSJuR22iIjITUu7YIiIiEihtmrVKtq2bQvA9T/WrFmzhj59+nDhwgVKlSpF3bp1KVu2LBEREezZs4dDhw5x++238/vvvzv6PPvss3z00Ue4ubnRqlUrypUrx759+9i2bRsvv/wyb775pstz2XfB0I9WIiIirikBISIiIoVaegkIgPPnz/Ppp5+ycOFCDhw4QHx8PKVKlSIkJISOHTvSp08f6tWr52hvjGHq1Kl8/vnn7Nu3D3d3d+rVq8eTTz7JgAED0kw0KAEhIiKSPiUgRERERERERCTXaQ0IEREREREREcl1SkCIiIiIiIiISK5TAkJEREREREREcp0SECIiIiIiIiKS65SAEBEREREREZFcpwSEiIiIiIiIiOQ6JSBEREREREREJNcpASEiIiIiIiIiuU4JCBERERERERHJdUpAiIiIiIiIiEiuUwJCRERERERERHKdEhAiIiIiIiIikuv+HzizMVZ8ivraAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.rcParams.update({'font.size': 16})\n", "_ = revenue_table.transpose().plot(title=\"Revenue by Geographic Region\",\n", " ylabel=\"Revenue (Millions of US$)\",\n", " figsize=(12, 7), ylim=(0, 50000))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now Allison has a clear picture of the detailed revenue data that was hidden inside those 1500 pages of PDF\n", "files. As she works on her analyst report, Allison can use the same process to extract DataFrames for\n", "other financial metrics too!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.17" } }, "nbformat": 4, "nbformat_minor": 4 }