##// END OF EJS Templates
python3 syntax fixes on various scripts...
python3 syntax fixes on various scripts revealed by running tools/build_relese

File last commit:

r19938:a47db04a
r20277:6ceb4492
Show More
Using nbconvert as a Library.ipynb
1447 lines | 73.1 KiB | text/plain | TextLexer
/ examples / Notebook / Using nbconvert as a Library.ipynb
Brian E. Granger
Moving things around.
r17497 {
Min RK
upate exmaple notebooks to nbformat v4
r18669 "cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# NbConvert, Python library"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this Notebook, I will introduce you to the programatic API of nbconvert to show you how to use it in various context. \n",
"\n",
"For this I will use one of [@jakevdp](https://github.com/jakevdp) great [blog post](http://jakevdp.github.io/blog/2013/04/15/code-golf-in-python-sudoku/).\n",
"I've explicitely chosen a post with no javascript tricks as Jake seem to be found of right now, for the reason that the becommings of embeding javascript in nbviewer, which is based on nbconvert is not fully decided yet. \n",
"\n",
"\n",
"This will not focus on using the command line tool to convert file. The attentive reader will point-out that no data are read from, or written to disk during the conversion process. Indeed, nbconvert as been though as much as\n",
"possible to avoid IO operation and work as well in a database, or web-based environement."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Quick overview"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Credit, Jonathan Freder (@jdfreder on github)\n",
"\n",
"<center>\n",
Min RK
update nbconvert-as-library notebook...
r19938 " ![nbca](images/nbconvert_arch.png)\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "</center>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The main principle of nbconvert is to instanciate a `Exporter` that controle\n",
"a pipeline through which each notebook you want to export with go through."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's start by importing what we need from the API, and download @jakevdp's notebook."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"'{\\n \"metadata\": {\\n \"name\": \"XKCD_plots\"\\n },\\n \"nbformat\": 3,\\n...'"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import requests\n",
"response = requests.get('http://jakevdp.github.com/downloads/notebooks/XKCD_plots.ipynb')\n",
Min RK
update nbconvert-as-library notebook...
r19938 "response.text[0:60]+'...'"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you do not have request install downlad by hand, and read the file as usual."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We read the response into a slightly more convenient format which represent IPython notebook. \n",
"There are not real advantages for now, except some convenient methods, but with time this structure should be able to\n",
"guarantee that the notebook structure is valid. Note also that the in-memory format and on disk format can be slightly different. In particual, on disk, multiline strings might be spitted into list of string to be more version control friendly."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
Min RK
update nbconvert-as-library notebook...
r19938 "{'cell_type': 'markdown',\n",
" 'metadata': {},\n",
" 'source': '# XKCD plots in Matplotlib'}"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "from IPython import nbformat\n",
"jake_notebook = nbformat.reads(response.text, as_version=4)\n",
"jake_notebook.cells[0]"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So we have here Jake's notebook in a convenient form, which is mainly a Super-Powered dict and list nested.\n",
"You don't need to worry about the exact structure."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The nbconvert API exposes some basic exporter for common format and default options. We will start\n",
"by using one of them. First we import it, instanciate an instance with most of the default parameters and fed it\n",
"the downloaded notebook. "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from IPython.config import Config\n",
"from IPython.nbconvert import HTMLExporter\n",
"\n",
"## I use `basic` here to have less boilerplate and headers in the HTML.\n",
"## we'll see later how to pass config to exporters.\n",
Min RK
update nbconvert-as-library notebook...
r19938 "html_exporter = HTMLExporter(config=Config({'HTMLExporter':{'default_template':'basic'}}))"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 4,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "(body, resources) = html_exporter.from_notebook_node(jake_notebook)"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The exporter returns a tuple containing the body of the converted notebook, here raw HTML, as well as a resources dict.\n",
"The resource dict contains (among many things) the extracted PNG, JPG [...etc] from the notebook when applicable.\n",
"The basic HTML exporter does keep them as embeded base64 into the notebook, but one can do ask the figures to be extracted. Cf advance use. So for now the resource dict **should** be mostly empty, except for 1 key containing some css, and 2 others whose content will be obvious.\n",
"\n",
"Exporter are stateless, you won't be able to extract any usefull information (except their configuration) from them.\n",
"You can directly re-use the instance to convert another notebook. Each exporter expose for convenience a `from_file` and `from_filename` methods if you need."
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 5,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
Min RK
update nbconvert-as-library notebook...
r19938 "['raw_mimetypes', 'inlining', 'metadata', 'output_extension']\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "defaultdict(None, {'name': 'Notebook'})\n",
Min RK
update nbconvert-as-library notebook...
r19938 ".html\n"
Brian E. Granger
Moving things around.
r17497 ]
Min RK
upate exmaple notebooks to nbformat v4
r18669 }
],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "print([key for key in resources ])\n",
"print(resources['metadata'])\n",
"print(resources['output_extension'])\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "# print resources['inlining'] # too lng to be shown"
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 6,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
Min RK
update nbconvert-as-library notebook...
r19938 "<!DOCTYPE html>\n",
"<html>\n",
"<head>\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "<meta charset=\"utf-8\" />\n",
"<title>Notebook</title>\n",
"\n",
"<script src=\"https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js\"></script>\n",
"<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js\"></script>\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "<style type=\"text/css\">\n",
" /*!\n",
"*\n",
"* Twitter Bootstrap\n",
"*\n",
"*/\n",
"/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n",
"html {\n",
" fon...\n"
Brian E. Granger
Moving things around.
r17497 ]
Min RK
upate exmaple notebooks to nbformat v4
r18669 }
],
"source": [
"# Part of the body, here the first Heading\n",
"start = body.index('<h1 id', )\n",
Min RK
update nbconvert-as-library notebook...
r19938 "print(body[:400]+'...')"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can directly write the body into an HTML file if you wish, as you see it does not contains any body tag, or style declaration, but thoses are included in the default HtmlExporter if you do not pass it a config object as I did."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Extracting Figures"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When exporting one might want to extract the base64 encoded figures to separate files, this is by default what does the RstExporter does, let see how to use it. "
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 7,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from IPython.nbconvert import RSTExporter\n",
"\n",
Min RK
update nbconvert-as-library notebook...
r19938 "rst_exporter = RSTExporter()\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "(body,resources) = rst_exporter.from_notebook_node(jake_notebook)"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 8,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "XKCD plots in Matplotlib\n",
"========================\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "This notebook originally appeared as a blog post at `Pythonic\n",
Min RK
update nbconvert-as-library notebook...
r19938 "Perambulations <http://jakevdp.github.com/blog/2012/10/07/xkcd-style-plots-in-matplotlib/>`__\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "by Jake Vanderplas.\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 ".. raw:: html\n",
"\n",
" <!-- PELICAN_BEGIN_SUMMARY -->\n",
"\n",
"*Update: the matplotlib pull request has been merged! See* `*This\n",
"post* <http://jakevdp.github.io/blog/2013/07/10/XKCD-plots-in-matplotlib/>`__\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "*for a description of the XKCD functionality now built-in to\n",
"matplotlib!*\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "One of the problems I've had with typical matplotlib figures is that\n",
"everything in them is so precise, so perfect. For an example of what I\n",
"mean, take a look at this figure:\n",
Min RK
update nbconvert-as-library notebook...
r19938 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 ".. code:: python\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " from IPython.display import Image\n",
" Image('http://jakevdp.github.com/figures/xkcd_version.png')\n",
Brian E. Granger
Moving things around.
r17497 "\n",
"\n",
"\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 ".. image:: output_3_0.png\n",
Brian E. Granger
Moving things around.
r17497 "\n",
"\n",
"\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "Sometimes when showing schematic plots, this is the type of figure I\n",
"want to display. But drawing it by hand is a pain: I'd rather just use\n",
Min RK
update nbconvert-as-library notebook...
r19938 "matpl...\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "[.....]\n",
Min RK
update nbconvert-as-library notebook...
r19938 "mage:: output_3_0.png\n",
"\n",
"\n",
"\n",
"Sometimes when showing schematic plots, this is the type of figure I\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "want to display. But drawing it by hand is a pain: I'd rather just use\n",
"matplotlib. The problem is, matplotlib is a bit too precise. Attempting\n",
"to duplicate this figure in matplotlib leads to something like this:\n",
Min RK
update nbconvert-as-library notebook...
r19938 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 ".. code:: python\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " Image('http://jakevdp.github.com/figures/mpl_version.png')\n",
Brian E. Granger
Moving things around.
r17497 "\n",
"\n",
"\n",
Min RK
update nbconvert-as-library notebook...
r19938 ".. image:...\n"
Brian E. Granger
Moving things around.
r17497 ]
Min RK
upate exmaple notebooks to nbformat v4
r18669 }
],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "print(body[:970]+'...')\n",
"print('[.....]')\n",
"print(body[800:1200]+'...')"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here we see that base64 images are not embeded, but we get what look like file name. Actually those are (Configurable) keys to get back the binary data from the resources dict we havent inspected earlier.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So when writing a Rst Plugin for any blogengine, Sphinx or anything else, you will be responsible for writing all those data to disk, in the right place. \n",
"Of course to help you in this task all those naming are configurable in the right place."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"let's try to see how to get one of these images"
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 9,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
Min RK
update nbconvert-as-library notebook...
r19938 "['output_5_0.png',\n",
" 'output_16_0.png',\n",
" 'output_13_1.png',\n",
" 'output_18_1.png',\n",
" 'output_3_0.png']"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 9,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {},
"output_type": "execute_result"
}
],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "list(resources['outputs'])"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We have extracted 5 binary figures, here `png`s, but they could have been svg, and then wouldn't appear in the binary sub dict.\n",
"keep in mind that a object having multiple _repr_ will store all it's repr in the notebook. \n",
"\n",
"Hence if you provide `_repr_javascript_`,`_repr_latex_` and `_repr_png_`to an object, you will be able to determine at conversion time which representaition is the more appropriate. You could even decide to show all the representaition of an object, it's up to you. But this will require beeing a little more involve and write a few line of Jinja template. This will probably be the subject of another tutorial.\n",
"\n",
"Back to our images,\n",
"\n"
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 10,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/png": [
"iVBORw0KGgoAAAANSUhEUgAAAbAAAAEgCAYAAADVKCZpAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
"AAALEgAACxIB0t1+/AAAIABJREFUeJzsnXd4FGXXxu/ZTYP0RkvoJKH3IvAivQsiINIEgUAsgPIJ\n",
"Cq8IAgroqxRRUJpSpCO9ifQSpEgNvYYSCJDek93z/XEyuwkkIWV3Zjd5fte11yxbZu5ZsnvPc57z\n",
"nAMSCCyApUuXUqlSpUiSJKpfvz4dPnzY8Fy1atUoLCwsy/edPXuWiIjS0tLo008/JVtbW5Ik6aVb\n",
"mTJlKDEx0fA++fX29vak1Wqpe/fu9ODBAyIiWrFiBbm5udHx48fzfT6ffPIJOTo60u3bt/O9j5zY\n",
"vn07VaxY0XB+JUuWpBs3brzyfSdOnCAfHx+Kjo7O8zHv379PDg4O5OTkRFFRUfmRLRCYFBsIBCoz\n",
"e/ZsfPrppyhZsiSmTp2K5ORkrFmzBi1atAAAJCYmIiUlJcv3NmnSBMnJydi4cSNmzZoFLy8vTJky\n",
"Bfb29ple16hRIzg4OAAAUlNT0b9/f2zcuBG1atVCUFAQjhw5giNHjqBv3764efMmoqOjsWnTJjRt\n",
"2hSjR4/G77//jlu3bsHb2ztX57R//34kJibi/v378PT0REJCQo6v9/DwgJ2dXa72/ejRI/Tq1Qup\n",
"qamYNWsWrl69it9++w0dO3bE8ePHUbJkScNrY2Nj4ezsbPi3JEl49OgRlixZgjFjxgAAYmJicqXP\n",
"19cX77zzDpYvX47z58/j9ddfz5VegcBsqO2ggqLNypUrSZIk8vPzo9DQ0Jeef/78Obm6umb5HBGR\n",
"JElERBQeHk6SJNHSpUtfeczAwECSJIm6d+9OKSkpLz0/efJkkiSJ/vrrL7py5QppNBoqX758lq/N\n",
"js8++4wkSaKDBw9Sv379SJIk0mg0ZG9vn+UI8fvvv8/1vtu2bUtubm40d+5cw2ObNm0iOzs7atGi\n",
"heGxzZs3k1arpdOnT2d6f5MmTahcuXKG8+nbt2+u9cmfzaFDh3KtVyAwF8LABKrx6NEjcnNzI3d3\n",
"d3r8+HGWrzlw4ABVq1aN9Hp9ls/LBpaYmEiSJNHYsWMpLCzMcHsxVLZjxw6SJIlatGhBaWlpWe5T\n",
"/pGeMWMG1alTh3x8fOjWrVt5Ojd/f/9MP/SnTp2iq1ev0v3790mSJOrRowft2bOH9uzZQydOnMj1\n",
"fo8dO0aSJNG2bdteek6+GDh//jwREU2ZMiXL1x46dIgkSaL58+cbHsutvh9++IE0Go0hdCsQqIkw\n",
"MIFqTJ8+nSRJom+//Tbb1xw4cCDTqCI2NpbCwsLozp07NGbMGJIkiR48eEDR0dEkSRLZ29uTg4MD\n",
"SZJEtra21Llz50zm16FDB9JoNPTPP/9ke0zZwOTb4MGD83xu5cuXz/aHXpIkWrZsWZ73SUTUvn17\n",
"GjhwYJbP6fV6qly5Mk2ePJmIiJo2bUqurq4UHx+f6XUpKSnk5eVFNjY2dPfu3TzpS0lJoa1bt+ZL\n",
"u0BgasQcmEA1kpOTodFoMHjw4Bxfd+7cOVy+fBlubm5o06YNrl+/bnhOkiT4+Phg5cqVAIC///4b\n",
"tWrVwsmTJ1GzZk2ULl36pWNWrVoVjRs3zrXOVatWoWzZspg2bVoezg4oW7Ys6tatm6f35MSDBw+w\n",
"f/9+XLlyJcvnJUmCk5MTQkJCEB0djQsXLqBXr14oXrx4ptfZ2tqiTZs2WL9+PaKjo/OkwdbWFt26\n",
"dcv3OQgEpkSjtgBB0aVChQrQ6/XYu3dvjq+Li4tDzZo14evri+vXr6Nt27bYvXs3Bg4caHhNWloa\n",
"AOA///kPXF1d0b59+5fMSz7mtWvXcO/evVfqGz9+PHbs2AF7e3t88803GDduXK7OKyUlBbGxsdBo\n",
"TPv1WrduHd544w34+fll+fyWLVtw5coVjBo1CpGRkUhISIBWq83ytRcvXkSJEiVQuXJlk2oUCJRE\n",
"GJhANfr374/y5ctj1KhRePLkSabnTp06halTp0KSJGi1Wnz88cfYvXs3du/ejRUrVqBDhw5o3bo1\n",
"iAgAcOPGDQBAREQEEhMT8fjxY8MtJibGsN/x48eDiDBw4EDodLpMx1y6dCk2bdqEevXqAeDRWufO\n",
"nbF79244Ozvjhx9+wKZNm155XpcvX0ZkZGSBPpus2LFjB9zd3V96PCkpCd9//z369OmDb7755pXZ\n",
"gRcuXMC1a9cwd+5cODo65kkDEeH69esvfXYCgRoIAxOohp2dHdavXw+NRoMGDRpgxowZCAkJwcyZ\n",
"M9G8eXNDWnmzZs0we/ZsdOjQAR06dECpUqUAcMhMJiQkBABQpUoVlC1bFmXKlDHc3n//fcPrqlat\n",
"il9//RXHjx9H48aNsWjRIly9ehWDBw9GYGAgSpcuje7du2PkyJEoX748AKB58+ZYtGgRAGDjxo2v\n",
"PK/jx48D4HCbKfH398fmzZsxbtw4LF68GIsXL8b06dNRqVIlzJw5E7Nnz8bYsWMBwDDy0uv1L+0n\n",
"KCgI9erVwzvvvJNnDXPmzEHVqlXh7++PO3fuFOyEBIICIubABKrSsGFDnDp1CtOnT8eXX36JL774\n",
"Ara2thg5ciQ+++wzHD58ONtQXKNGjVCnTh0AgJ+fHypUqIBWrVoB4B/wLl26wNnZ+aURSWBgIKpW\n",
"rYovv/wSQUFBAAAvLy8sWrQIr732GgDgxx9/zPSePn36IDk5GQEBAa88p/DwcAC8Ru1F7t+//8r3\n",
"Z8fMmTPh7e2NX3/9FU+fPoWtrS2CgoIwf/589OjRI9Nry5Yti5o1a2Lbtm1ITExEsWLFALABnTp1\n",
"CpcuXcryGK/S5+7uDkmSYGdnBycnp3yfi0BgElROIilSJCcnZ5sOLsiaI0eO0Mcff6y2jDwhZzEO\n",
"HTr0peeOHTtGTk5OdOfOHbPrWL58OUmSREFBQbRo0SKaNGkS2djY0PLly7N9j5L6BIKCIhGlTyII\n",
"zMr9+/fRsGFDhIeHY968eRg5cqTakgRmYubMmZg5cyZ27tyJZs2aqarlrbfewpYtWwBwKHb69Omi\n",
"goag0CAMzMzo9XosWLAA48ePR1xcHAAOw5w+fRqVKlVSWZ1AIBBYLyKJw0Q8ffoUqampmR67fPky\n",
"WrRogZEjRyIuLg5ubm4AgMjISHTq1AnPnj1TQ6pAIBAUCoSBmYCIiAh8/PHHOHfuHABeBzR16lTU\n",
"q1cPx48fR+nSpbFx40aULVsWABAQEIAbN26ge/fuSExMVFO6QCAQWC3CwEzA/v37sWbNGsTGxiIt\n",
"LQ1NmjTB5MmTkZKSguHDh+Py5cvo2bOnoaL6okWLUK5cOQQHB6N///5ZpjoLBAKBIGeEgb2ClJSU\n",
"TAthdToddDodiOtIAuBFt9WqVUPNmjVhY2ODbt26wc/PDwcOHMDChQsNoUPZwHx9fbFr1y54eHig\n",
"VatWJq/YIBAIBEUBkcTxClavXo2tW7fivffeQ9u2bWFjY1w6p9frodFo0Lp1azx//hybNm1C5cqV\n",
"kZycDL1eb1h7I+Pr64uHDx/i/v378PX1RWRkZJaVFQQCgUDwasSlfw7o9Xrcvn0ba9euxVtvvYXX\n",
"X38ds2fPxvHjxxEdHW0YOV27dg16vd5gRvb29i+ZF2CsHCGX4RHmJRAIBPlHVOLIAY1Gg+HDh+Pu\n",
"3bv4448/cOLECZw4cQIAULNmTQQGBuKff/4x1Nzz8PDIcX9y5YL4+HizaxcIBILCjggh5pLIyEic\n",
"PXsW27Ztw/79+3H16lUQkaEKepcuXbB9+3bodLpsK4A3bNgQZ86cwcmTJ9GoUSMl5QsEAkGhQ4zA\n",
"skGe31qzZg2aN2+OsmXLok2bNmjTpg0ePXqEQ4cOYdOmTXjy5AkaNmyIYcOGAUCOCRnyCCw2NlaR\n",
"cxAIBILCjDCwbJCNqH///pg/fz6CgoKg1+uh1WpRpkwZ9OvXz7AYuUqVKob5rYwV0l9E7k/16NEj\n",
"85+AQCAQFHKEgeVAWFgYAMDT09PQlwrgnkiSJMHd3T1PiRjyQuaCVCQXCAQCASOyELNAnhY8evQo\n",
"ihcvbugLdfbsWaxZs8YwygoJCclTm3lhYAKBQGA6hIFlgWxg+/fvR5UqVVCiRAkAwMKFC7FmzRrD\n",
"67Zv346lS5cit3kwsoGFhoaaWLFAIBAUPYSB5cDx48dRq1YtQ5jw1KlTKFmypMGw/vnnH1SuXBnR\n",
"0dG52p8YgQkEAoHpEAaWBXICx9WrV2FrawsXFxcAwN27d9G1a1dDCPHff/81tL3PDcLABAKBwHSI\n",
"JI5siIiIgK+vL37//Xc4OTkhOjoaKSkpaNeuHQBOs9fpdChevHiuW6t7eXnBxsYGkZGRSEpKgoOD\n",
"gzlPQSAQCAo1YgSWDW5ubhgzZgy8vLxw4MAB/PXXX0hJSUFgYCD++usv/P7774iIiECjRo0y1UfM\n",
"CY1Gg1KlSgEAHj9+bE75AoFAUOgRI7Bs0Gg0GDlypKEZ5ZUrV7BlyxasXLkS69atA8CjsOTkZADG\n",
"1PpXUapUKTx48ABhYWGoUKGCOU9BIBAICjViBJYFcpLGhQsXMGPGDKSlpaFRo0b4+uuvcffuXZw7\n",
"dw6ff/453njjDTRo0CBP+/b29gYAPH/+3OS6BQKBoCghRmDZsG7dOowaNQpPnz5Fq1at0LRpU9y+\n",
"fRvR0dGoW7cuvvrqK8TExBh6feVm9AXAkPSRmppqNu0CgUBQFBAGlgVnzpxBYGAgunbtioCAACxc\n",
"uBAxMTGYMGEC7t69Cy8vL+zevRuVKlXK875tbW0BGJtbCgQCgSB/iBBiBvR6PQBgx44d8Pb2xs8/\n",
"/4y33noLmzdvxldffYXmzZvj9u3baN26NYKCggAg14uYZWQDEyMwgUAgKBjCwLJg3759aNiwIezt\n",
"7VGnTh1UrFgRvr6++N///gc3Nzf4+flh37592LVrV65DhzKJiYkAIFLoBQKBoIAIA8uAvIC5ePHi\n",
"uHLlisFsEhISUL16dYNZyYkYcgWOvIzCIiMjAYhuzAKBQFBQhIFlwYgRI2BrawsvLy8QEVasWIHB\n",
"gwcb1nvJC5ebNm0KIPcJHIDRwF7VvVkgEAgEOSOSODIgN7GsUqUK/P39ER0dDVdX15e6J1+9ejVT\n",
"lfq8IEZgAoFAYBqEgWVAHkmFhYUhODgYHh4esLW1hZ+fH1q2bIlu3bohICAAly5dQq1atQAAOp3O\n",
"0CcsN4gRmEAgEJgGifKaRlcECA8PR1JSEsqVK4cHDx5g9+7dOHDgAE6cOIFHjx4hOTkZn3zyCWbN\n",
"mmUYteWG1NRU2NnZQavVIjU1Nc8JIAKBQCAwIgwsAxnLQSUlJUGSJNjb27/0utDQUJQsWTLL53Ii\n",
"PDwcJUuWhKenJ549e2YSzQKBQFBUESHEDEiShAMHDuDo0aO4du0aQkNDkZqaiqpVq8Le3h4pKSlw\n",
"c3NDjRo1ULZsWbRt2zZP4cO4uDgAgLOzs7lOQSAQCIoMwsDSOXDgACZMmIDr168jKioK5cuXR8WK\n",
"FSFJEpYtWwZnZ2fY29sjOjoaNWvWxLBhw9ChQ4c8HSMtLQ2AcTGzQCAQCPKPMLB01q1bh5MnT2LU\n",
"qFEYNGgQ/Pz84OLigpEjR+LBgwdYunQp6tati+TkZMTFxeW6B1hG5OobwsAEAoGg4AgDS0euKu/v\n",
"75+pwny7du1w5MgRlCpVCq6urgCAEiVK5OsY8ggst/3DBAKBQJA9YiFzOoGBgXj//fcxfvx4fPbZ\n",
"Zzh79iwAoEePHrh48aKhAaVer89z/UMZMQITCAQC0yGGAhmYOHEibG1tsWLFCnz//fdo3bo17O3t\n",
"4eDggPv37xtS5vV6fb5S4IWBCQQCgekQBpaBMmXKYO7cuRgwYAB+++03rF+/HhEREQCAmTNnQqfT\n",
"YcCAAfkOAYoQokAgEJgOEULMgBwabNy4MRYsWIBr165h+/btGDduHJycnPDhhx/Czs4O3377bb72\n",
"L0ZgAoFAYDrEUCADclhQDhF6enqiS5cu6NKlCwAgJiYGixcvRv369fO1f5FGLxAIBKZDGFgWyKWh\n",
"iAg6nQ4Az4/17NkTH3/8ca5LR72IPAITIUSBQCAoOCKEmE5WmYWSJMHGxgaXLl3Cd999h5s3b0Kr\n",
"1ea7hqEIIQoEAoHpKPJDAb1eD8A46pLDh5IkGWojnj59Gt7e3mjWrFmBjiWSOF6BXg8cPgxs3Aic\n",
"Pg08fMiPV6gANG4M9O0LNGgAiCLIAoEAYgSG4OBgTJgwAYcOHQLARiaPsOTw4YkTJ6DVag2tUPKL\n",
"GIFlAxGwaRNQqxbQujXw00/AiRPA/ft8O3IE+OEHoFEjoGVLNjeBQFDkKfIGdvToUcyZMwcDBw7E\n",
"wIEDsWXLFjxMv/KXR0oXL16Eg4MD3NzcCnSslJQUAMLAMhERAfTsybfLlwFfX+C//wX+/hu4cwe4\n",
"dQvYtQv4+GPA3Z3N7LXXgGnT2PgEAkGRpcjHsoYOHYozZ85gw4YNWLVqFVatWgVbW1s0adIEo0aN\n",
"ws2bN3H58mXEx8cX2MDi4+MBAI6OjqaQbv1cuQJ07w7cvAk4OwPTpwMjRgB2dplfV6kS0KkTMGUK\n",
"3+bMASZNYnNbtAgQFwQCQZGkyBuYt7c3Vq9ejYkTJ+LQoUPYu3cvgoODcfToUVy4cAExMTEAgPLl\n",
"y8Pd3b1AxxIGloFjx4AuXYCYGKBuXWDzZqB8+Zzf4+oKzJoFtGsHvP02sGwZ8OwZ8OefL5ueQCAo\n",
"9BT5ECIAaLVa1K5dG6NGjcLWrVtx6NAh/Pzzz6hXrx4CAgLQvn17/PzzzwCMSR/5QRhYOidPAp07\n",
"s3n17AkcPfpq88pIly7A/v2ApyewYwcQGCjCiQJBEaTIj8Bk9Ho99Ho9bGxsUL16dfj7+6NDhw54\n",
"+vQpqlataggf5ncNGABDF+aCjuSsmqtXgY4dgdhYzipcuRLIQ1NQA02aAHv2cFLHihUcZvzqK5PL\n",
"FQgElosYgaWj0Wgypbfb2NigcuXKeO211wo89yUjJ4f4+PiYZH9WR0QE0K0bEBXFc1/Ll+fPvGQa\n",
"NADWrQM0Gp4b273bdFoFAoHFIwwsB4go361TsuLRo0cAiqiB6fVA//6csFG3LrBqlWmSL7p0AaZO\n",
"5fvvvgukf8YCgaDwIwwsB+QFzaZCHoGVKVPGZPu0GmbP5pCfpyewZQtgynnACROA9u05oeP998V8\n",
"mEBQRJDIlEMMQbbodDrY29tDp9MhOTkZdkUpa+7sWZ6zSk1l8+re3fTHePgQqF6dE0PWrgX69DH9\n",
"MQQCgUUhRmAoWJfl3PLkyRPodDp4e3sXLfNKSuLQYWoq8MEH5jEvAPDxAb77ju+PGgU8f26e4wgE\n",
"AotBGBiM5aMKkiL/KuT5ryIXPvzmG848rFoV+P578x5r+HDg9deB8HDgiy/MeyyBQKA6RdrA4uLi\n",
"MGfOHPzwww+Ij48vUIr8qyiSGYiXLgEzZ/L9RYuA4sXNezyNBvjlF85sXLQICAkx7/EEAoGqFGkD\n",
"c3R0RPHixfH1119j+PDhCA0NBWDMPjRHBmKRGYHp9VwWKi0NCAoC/vMfZY5brRofT68Hxo5V5pgC\n",
"gUAVirSBAcCIESPwv//9D0ePHsXEiRPx+PFjQ/ahKTMQw8PDAQClSpUy2T4tml9/BYKDgVKljKMw\n",
"pfjqK8DFhdeF7d2r7LEFAoFiFFkDk3t9AUBgYCCWLl2KlStXomHDhli4cCFCQkLw+PFjJCQkmOR4\n",
"soGVKFHCJPuzaJ4944ryAPDjj4CJFoLnGm9vYPx4vj9likirFwgKKUXWwCRJMvTnunDhgsFgwsLC\n",
"8MEHH6Bjx44YMmQIJk2aZCjoWxCKlIFNmsTVNtq1A3r3VkfDyJHcfuXYMSC915tAIChcFMlaiBER\n",
"Edi1axfWrl2LkJAQxMTEoGTJkmjbti26dOmCcuXK4dixY9ixYwdOnDgBHx8fjBkzpkDHjI6OBgCT\n",
"laWyWC5c4PChVsttT9TqnuzsDHzyCTB5MvcOa9VKHR0CgcBsFEkDO3HiBKZNmwZJktC2bVvUqFED\n",
"LVq0QP369Q2v6d69O4YMGYLk5GQEBAQU+JjJyckAAHt7+wLvy2Ih4saTej2vxapRQ109o0dz6v7+\n",
"/cD580CdOurqEQgEJqVIGljLli0RHBwMFxcX6PV6Q4dknU4HbXpxWVtbW9SqVctkxywSBvbnn8DB\n",
"g1wuasoUtdXw3NvgwcBPP/GocP58tRUJBAITUiTnwBwdHeHu7g6tVmswLwAG8wJMX8hXnm/LWPG+\n",
"UJGSAowbx/enTeP5J0sgKIi3K1ZwCxeBQFBoKJIGlhtMnUYvN7GUm1oWOhYvBu7c4XqEw4errcZI\n",
"zZq8Bi0ujmskCgSCQoMwMIWQkzciIyNVVmIGEhKAr7/m+1OnApY2ynzvPd6uW6eqDIFAYFqEgSmE\n",
"3IW5UBrY/PlAWBhQrx7Qs6faal6mRw821f37eY2aQCAoFAgDUwjZwKKiolRWYmJiY42VNr7+Wr20\n",
"+Zzw9ATatgV0OmDzZrXVCAQCEyEMTCEK7Qhs8WJuXdK0KdC5s9pqskdeUL1li7o6BAKByRAGphCF\n",
"0sDS0oC5c/n+559b5uhLpmtX3v79N8/ZCQQCq0cYmEIUyiSOTZuAe/eAKlWAN95QW03OlC4NNGzI\n",
"DTb371dbjUAgMAEWli5WeCmUI7BZs3g7ZgyXjrJ0unUDTp8Gtm+3fMMt5EREALt2ccOCe/d4KtXF\n",
"BahY0RiNdnVVW6XA0hEGphCFLokjOBg4cYIXLA8erLaa3PHGG1wbcft2LntlySHPQsrFi9yke9Mm\n",
"XvueFT/+CNjZ8bTlZ5+JCmCC7BEGphCFbgT2ww+8ff99IH2RtsVTrx5Qpgzw8CFw7hz/W6AIkZE8\n",
"TbpoEf9bo+HE0LZtuQepiws3MLhyhacpDx0CVq0CVq/mvqjTpwMeHuqeg8DykMiU9ZIE2fLw4UP4\n",
"+vqiZMmSePz4sdpyCsbdu0Dlyhw2vHuXTcFaCAoCFi7kWo2TJqmtpkhw+jSPpu7dA2xt+Zpn3Dig\n",
"bNns33PvHkeo58/nXCFPT0547dFDOd0Cy0ckcShEoRqB/fQTV5x/5x3rMi+A58EADiMKzM6iRUDz\n",
"5mxIjRpxU4Aff8zZvACgfHlOcD1/njvhPH8OvPUWMHYskF5WVCAQIzClICLY2tpCp9MhKSnJeqvS\n",
"x8YCvr5ATAxfWjdooLaivJGQwJfzSUnAo0ecnSgwCzNmGBtzf/ghj6jy82dPxGY2bhyPxtq04cYH\n",
"IslDIEZgCiFJElxcXAAAsdZcFf3339m8/vMf6zMvAChenDtFA8DOnepqKcRMmsTmJUncyebnn/Nn\n",
"XgDv45NPeF6sVCleBfH66zyVKSjaCANTEGdnZwBWbGA6nXHhcgE7VKuKnEK/bZu6OgopP/7IHXW0\n",
"Wu5iM2KEafbbrBlw/Djg78+Nv1u2FCZW1BEGpiBWb2AbNwK3bgEVKgBvvqm2mvwjV+X46y9usyIw\n",
"GZs28WgJAJYuBQYMMO3+K1ZkE6tfn/8UW7fmSLCgaCIMTEGs2sD0er6sBoDx461j4XJ2+Pry5Xxi\n",
"IrB1q9pqCg3XrgGDBvGc1ddf831z4OkJ7N0L1K0L3LjBc2LWntgryB/CwBTEqg1syxbg0iX+8Zf7\n",
"a1kz/fvzdtUqdXUUEhITgbff5gHtO+8YkzfMhYcHrxerXZuNs2tX0XC7KCIMTEHs7OwAAKnWlgdM\n",
"ZBx9ff55/mfjLYm33+ZR5J49okeYCZg0iats+Ptz6rwSRU48PdnEqlQB/v0X6NNHpNgXNYSBKYg2\n",
"Peym0+lUVpJHduwAzp7llPPAQLXVmIYSJYD27Tkve8MGtdVYNf/+yynyGg2wciWQHmhQBG9vrqno\n",
"5QXs3g188AFfbwmKBsLAFESj4Y9br9errCQPEAFTp/L9zz4DHBzU1WNK5DDi6tXq6rBi0tL4mkav\n",
"B0aP5sXKSlOlCieUFisGLFkCzJunvAaBOggDUxCrHIH99Rdw6hSPWEyVD20p9OjBhnz4MHD/vtpq\n",
"rJIFC3hwXr68McqsBq+9xksUAeDTT/m/VFD4EQamIJYwAiPiYhSRkbys65V88w1vP/2UFwEXJpyd\n",
"ge7d+f6aNepqsUJiYoyD89mzAScndfX06cOlptLSeIpTrBEr/AgDU5DExEQAQLFixRQ7JhEPoP77\n",
"X84cd3Xl4vEeHtyywt+fu6Fs3gwkJ7/w5iNH+ObuzpMLhZF+/XgrshHzzA8/cP5Ls2aWU2R3xgxO\n",
"qw8PB3r1yuJvWlCoEAamIAnpreyLKzCSSUjgousNGgCNG/MXOziYU43t7bl9hV7P62iWL+dCqQ0a\n",
"vJDFNX06b0ePVnZmXknkzonnzgGXL6utxmoIDzd21PnuO8tprWZjw4PpcuWAf/7hEZmg8CIMTEHi\n",
"4+MBAI5m7J+l0/FEtr8/dw45e5bTjUeP5myt8HCuYxsdzVenZ84AM2cCNWvyYMTWNn1H//7LaV2O\n",
"jsCoUWbTqzr29tzrAxDJHHnghx+A+HiuytW8udpqMuPtzYmldnbcOGHtWrUVCcwGCRSjZs2aBIDO\n",
"nz9vlv2fOEFUqxYRBw6J6tYlWrmSKDHx1e/V64lSUjI80KsX72TsWLNotSj27eNzrVSJPwhBjjx9\n",
"SuToyB/ZqVNqq8men35ijU5ORFevqq1GYA7ECExBzBVCTEriVhPNmvFi0goVgD/+4NHVgAG5y3yX\n",
"pAyjrytXuF+FnR3wf/9nUq0WScuWvMbt9m3g5Em11Vg8s2fz6KtLF6BhQ7XVZM+HHwJ9+3J1kN69\n",
"OawuKFwIA1MQc4QQb94EmjYFvv+e/z1uHE/l9O/PC0vzxcyZPIgbOtTQLyspyTR6LRKtln/pAJHM\n",
"8QoiIozrrL78Ul0tr0KSeB44IICroH34oVjkXNgQBqYgsoGZagT255+ceHHuHFC5MidpfPcdL+jM\n",
"N3fv8vBNq+WFy+l88QWwfn2BJVsu8qLmtWs5D1uQJXPnciJQ+/a89srScXbm+bBixYBly7hCvqDw\n",
"IAxMIYjIZCFEvZ5LEvbqxWtxevbkcGHjxiYQ+t13nAnSvz/3rgCHYH75hYu0/vGHCY5hiTRoAPj5\n",
"AU+eAAdPcYCBAAAgAElEQVQOqK3GIomKMraDmzRJXS15oWZN/vsFgI8+4gs+QeFAGJhCpKSkQK/X\n",
"w9bWFraGyaa8k5DAizS/+45ThmfP5itMk7RXDwvjS1RJAiZMMDzs6MgdVIh4zdj27SY4lqUhSaJC\n",
"/SuYN4+zV1u14obc1sSgQVzyKjmZ58Oio9VWJDAJameRFBUiIiIIALm5ueV7H48fEzVuzJlVrq6c\n",
"PGdSxo7lnffsmeXT48fz0w4OnPFY6Lh6lU/Q2ZkoIUFtNRZFbCyRhwd/PPv3q60mfyQkcGau/Ccu\n",
"Ek6tHzECU4iCzn9dvsxzDidPcpbh8eNcccBkRERwYTsg22ZO06cDw4dzQkfPnjxgK1QEBHAoMTYW\n",
"2LlTbTUWxW+/8Z/Ia6/xCMwaKVaM53FdXHj+WA6HCqwXYWAKUZD5r2PHeLHo3bs8z3XiBFC9uokF\n",
"zpvHudEdO/KPeBZIEvDzz8Drr3Mb9969C2G+gxxGFLURDeh0HKoGOMvVUqpu5IcqVdiMAT6X4GB1\n",
"9QgKhjAwhcivge3YAbRrxxPoPXpwfkHJkiYWFxtrvBx9RStdW1u+ivXx4VGgXG2q0CBX5di5kw1d\n",
"gE2bgDt3ONP1zTfVVlNwevYExozhi68+fUQ/U2tGGJhCyBXo5ZYquWHFCv7BSEriCegNG8xUEP7X\n",
"X7k8ffPmQIsWr3x5iRJcPxHgauSnTplBk1qUKwc0acLZMrt3q63GIpBrHn7yCa+uKAx8+y2vn3zw\n",
"ABg4kDN7BdaHMDCFyGsrldmzOXNKp+OEwIULzfTjkZRk/IX64otcx4fatOGrWJ2OC9VbU4uzVyKP\n",
"wkSnZpw5wyFrd3dgyBC11ZgOW1te8ufpCezZY+waJLAuhIEpRG4NjIijeHIFp1mzOExntnmHpUuB\n",
"x4+BevWATp3y9NapUwFfX/6RW7jQTPrUoFcv3m7fDqS3wCmqyAt/Bw3i5RSFibJleV2jJAGTJwN/\n",
"/622IkFeEQamEFK6A1EOtWzS0rjp8YwZPNpatoxHOWYjKck4iZWH0ZeMkxMwZw7f/+9/gadPTaxP\n",
"LSpW5ESWuDi+PC+iJCYaF64PHaquFnPRsSMwcSJfOPbvL5pgWhvCwBTiVSOw1FT+Ai1ezMV3N2/m\n",
"q16zsmgRf2Pr1OGGYPmgZ0+gQwdOMilUCR1vv83bIhxG3LyZF/w2bAjUrq22GvMxeTLQti1fgL3z\n",
"DpCSorYiQW4RBqYQORmYXB1AXqOydy/3WTIrCQlGx5kyJd+VfyWJq4IAwPz5QGioifSpjRxG3Lq1\n",
"yLb1lb373XfV1WFutFouvlKmDC9ZCQwURX+tBWFgCiEbWMX0+oIyiYmcabh1K0+U79unUJmeX37h\n",
"ua8GDYDu3Qu0qzp1uJh7SgowbZqJ9KlNlSpA3bq8xGDvXrXVKE5iojEJM5+Dc6uiRAlg2zbO8l2x\n",
"ohD9HRdyhIEphEajQZ06dbBy5UrDY3FxQNeuPM3i7c1rvBTpr/TsGfD113x/yhSTZIhMncpXsr/9\n",
"Bly/XuDdWQZyNmKhLsOfNX/9xYP0hg052aEoUL8+m9jAgWxkha7STCFEGJhCFCtWDAcOHICHhwcA\n",
"nlvo1IlNq3Rp4OBBHskowoQJvO6rfXvuSmgC/Px4ol+nA776yiS7VB95HmzLliI3MfLnn7zt2VNd\n",
"HUrTpg2PwMaONbTCE1gwEuWUFicwGXq93hBGjIhg8zp1iq9u9+1jA1CEf/7hFZw2Nty+OSDAZLsO\n",
"DeXIm07HtRtNuGv1qF2bP6edO4HOndVWowipqVztJTKSm3NXraq2IguAiMPJAA/PbGzU1SMAIEZg\n",
"iiGb19OnfJV36hRnax8+rKB56XTcEImIF5qZ2GHKlePFrnp9IcpILIKLmg8fZvOqWrUImldcHE9I\n",
"T5nCw8+AAF7tbGPDPYtcXXkVtK0tT5w1aQL068ftqbdtK0RrSawDMQJTkLAwrmt4+TLg788jL19f\n",
"BQX8+ivw/vt80CtXeCGXibl7lw2ZCLh6lUdkVs3ly0CNGoCHBye9FKCXm7UwciQXbf7vf4tIhYq0\n",
"NI6ZrlkD7NrF6yOzwtGR54sTEnKuPeXnx6H5bt248nUR+JtRC2FgChEaymtNbt7k38O//wZKlVJQ\n",
"wPPn7JoREcC6dcb5HTMwbBhXcBg6FFiyxGyHUY4aNdjI9uzhRW+FGL2ew9qPHnGUQJGkIrXQ6Th/\n",
"fto04MYN4+NNm3Jd0Lp1OYRcurRx5AXw1VlqKo+27tzhW0gIh+dPnmSDk3Fz4wWew4ZxtRtrLuVv\n",
"iajYi6zIcPMmUbly3EivXj2ip09VEDFiBAto29bsnfxu3iTSaolsbIhu3zbroZRh0iT+7IYPV1uJ\n",
"2Tlxgk+1bNlC3vDx8mWiRo34ZAGiKlWI5swhevCgYPtNTSU6fpxowgSiGjWM+weI6tQhmjuXKCrK\n",
"NOcgIGFgZubyZaLSpfnv97XXiCIjVRBx8iSRJLGjXL6syCEHDeJzHjFCkcOZl7Nn+WRKly7kv+pE\n",
"n3/OpzpqlNpKzIReT/Tjj0T29kan/v13Np5XEBfHnal1ujwc7/x5oo8/Nrazljt+jx1LFBqa//MQ\n",
"EJEwMLNy+jSRtzf/zbZsSRQTo4IInc54pfnZZ4od9upVIo2GyNaW6N49xQ5rHvR6Ih8f/gzPnFFb\n",
"jdnQ64n8/Pg0DxxQW40ZSEnhUbRsJMOGEUVH5/rthw4ZfW/GjDweOymJaN06/iGQj29jQzRwIF8g\n",
"CfKFMDAzsWsXkaMj/5127EgUH6+SkIULWYSPD18+Kkj//nzoDz9U9LDmQQ7BTp2qthKzcekSn6Kn\n",
"Z64GJNZFQgJRhw58gg4ORGvW5Gs3GzZwMAMgWrIkn1pOnSLq25fj7LKZtW9PtG9foR/hmxphYGbg\n",
"t9+Mf5sDBxIlJxufe1DQGHteePbMGLrI5xe2IISE8Jfdzo4oLEzxw5uWLVv4c2zcWG0lZmPaND7F\n",
"IUPUVmJiEhKI2rXjkytRguiffwq0u59/5l1ptUTbtxdgR3fvEo0ZQ+TkZDSyxo2J/vwzj3HKoosw\n",
"MBOi1xt/BACi8eMzX1Ddvn2bateurZygoCAW0qaNald2PXuyhC++UOXwpiMujuNHkkT05InaasxC\n",
"vXr8f7Vtm9pKTEhCAo9uZPMy0RzwF1/wLosV48SXAhERQfT118b5BoAoIIBo6dLMV7+ClxAGZiIS\n",
"EowhM0kimjcv8/NpaWlUpkwZcnZ2VkbQqVPGxI2QEGWOmQXHjvFn4u7OHmDVdOrEJ/P772orMTl3\n",
"7vCpOTkRJSaqrcZEpKURdetmNC8Tfg/0eqKhQ40h16tXTbDT+Hiin34iKl/eaGS+vkSzZike/rcW\n",
"hIGZgNBQovr1jT8Amza9/JrY2FgCQI6OjuYXpNNxKALgbCeVee01lvLTT2orKSDz5vGJ9O6tthKT\n",
"M3s2n9rbb6utxISMHs0n5eHBE3wmJiWFqEsXPkT58kQPH5pwxytWZE7D9/AgmjxZpTU4loswsALy\n",
"9998cQcQVapEdPFi1q+Lj48nAFSsWDHzi1q0iAWVKaNS6mNmNmwwfj5paWqrKQC3b/OJuLgUutDO\n",
"66/zqa1apbYSEzF3Lp+QnR3R4cNmO0xcnPFasU4dEy/x0uk4ntusmdHIihfntHyrT+01DcLA8klq\n",
"KtHEicaMpLZtOWciOxITEwkA2dvbm1fY8+cc0wCIVq8277FySVoaUcWKLKlAk96WQPXqfCL79qmt\n",
"xGQ8eWJMtslDVrnlsnu38Yu5cqXZD/f0KZG/v3G6OSnJDAc5fNg43JNT8N97T7F1nZaKKOabD0JD\n",
"uSDv119zZZivvuIqQ56e2b9HSi8hQ+au3PXf/3LZqNatuT+6BaDVcglGgPtoWjVdu/J21y51dZiQ\n",
"rVv5V7FtW+4IbtXcvw8MGMAnNHky3zczXl7c/LNUKWD/fmDw4JxLJeaLFi2AHTuAc+e4NJVeD/z+\n",
"O1C9OnfEPXy4aLaRVttBrQm9nuiXX3ghvVyYIbcLPlNSUggA2djYmE/ggQMszNbWLDH/ghAezrI0\n",
"GiuPfvz9N3/GSmaTmpmOHfmUFi5UW0kBSU42Trh27qx4KvrZs8bfhv79zRxlvnWL6IMPjCurAZ7I\n",
"LGIIA8slt29zeED+W+nZk3+Uc0taWhoBII1GYx6B8fFElSuzuK++Ms8xCki/fizvyy/VVlIAkpI4\n",
"dxogevRIbTUF5skTY93KnELgVsH//Z+xPJRKJ3PwoHFZV6dOCmTePn7MX6jSpYnu3zfzwSwPYWCv\n",
"ID6ek3/k3ywvL6K1a/O+rEqv1xMAMtug95NPWGCtWhabYHDwoHHkatWVHjp35hNZtkxtJQXmp5/4\n",
"VLp2VVtJATl0yDg3VOCFWQXj1Cn+nZDrnyqyiN+qv1D5R8yBZQMRsHo1N/SbMgVITAT69uWuGn36\n",
"5L0rgpThDWTqWPWWLcCcOTzZtGQJYGdn2v2biNdf51ZJYWHcTsZq6diRt3v2qKvDBKxaxdv+/dXV\n",
"USDi47mTKsBzwE2aqCqnYUPg2DFu8HriBNCgARAcbOaDFtUO0Wo76Itcu3aNBgwYQI9UCs/o9Vw1\n",
"qGFDY7iwXj2+wCsoGo2GAFCqKa+Wbt0icnVlod9/b7r9mompU41zBFbL5ct8Et7eVl3yR168XLy4\n",
"la+THTXKmMduQdGHsDCiFi2M09ILFohSh6bGYgzswYMHNGLECNJqtQSARo4cqejx09K4WHTt2kbj\n",
"KlGCaPFi06xdyhhC1JnqRy8hgahBAxb75ptW8e2Ql1IVK2YRS9Tyh17P8ywA0b//qq0m38yYwafQ\n",
"t6/aSgrA2bPGijMWWNU9JYWXbeV37twSiI2NpfsWOr+m+rgzIiICM2fOxLx585CUlASNRoPAwEB8\n",
"9tlnihz/6VPuHvzrr9xYFQDKlAE++wwYPhwoXtz4Wr1ej7t37+Lu3bvQaDSwtbWFjY0NbG1tUbx4\n",
"cTg7O8PFxQWOjo7QaDJHZ/XpebWSJL30XL7Q6ThF+MwZoEIF4LffrKLba8WKwH/+Axw9yl3cBw9W\n",
"W1E+kCTuzLxkCbBvH3faBZCWloakpCTo9XoQkWGb8X5+n0tNTc10S0lJMdxPS0uDVquFnZ0dbG1t\n",
"M20dHBxQvHhxFCtWzPA3KoezrT58SAR8/DFvR43iDsoWhq0tR/cbNQI++ID/5o8eBRYu5Ox3a2Dr\n",
"1q0YMGAA6tWrh27duqFbt26oX7++aX7HCohEpM7igbi4OMydOxf/+9//EB0dDQDo2bMnJk2aBH9/\n",
"/0xf4he/zNn9OyUlBQkJCUhMTERCQgISEhKQnJyMzp07wyZDjDgxkZfx/PEHsH07kJLCj1eowMY1\n",
"ZAjg4JBZ77Zt2/Dpp5/iRsbW49kgSRKcnJwMhiab2oEDBwwG7ejoCCcnJzg6Ohpu9vb20Gq1Wd5q\n",
"1aoFHx8f40HGjOFvhqsrB9xr1AAA6HQ6pKSkwMHBIdO8myWxcCEQFMTrjtScC0tNTUVUVBQiIyMz\n",
"3eTHoqOjERMTg+joaERHR6Nz584YOXIkv/n33/kPpVcvYMMGAMD+/fvRtm1b9U7oFfTt2xerV68G\n",
"AFy6BNSqBbi7A48fG6dNhwwZgpiYGIPhZTS/rB6T79vZ2UGSJMMFmnxfvmX1vc3KqOX7kiTBwcHh\n",
"pZubmxu0Wi2LXbeO1zp6ewPXrwNubip9srnj7l3+kzl4kP89YADw/fe8fiw/xMXF4dGjRwgLC8Oj\n",
"R4/w+PFjREdHIz4+HnFxcYiPj0diYiIAZPq/sLGxgb29PRwcHLLdZry/c+dOrFy5EklJSYZjlyhR\n",
"Au3atUOnTp3Qvn17lChRQhVDU8XALl68iNq1ayt2vPXr16N3794A+G9+6FCe9wX4YrpLF7466tSJ\n",
"8yAycuHCBcyfPx+XLl2Ck5MTNBrNS1fDqampSExMRExMDGJjYxEXF2dS/b/88guCgoKMD8ydC3zy\n",
"CV/e7dnDi5YBJCcno0WLFjh16hQ0Go3BRJ2cnF66n91NNlYnJyfY2dlBq9XCxsbmpZtWq830owTg\n",
"pQuOjI/b29ujXLlyAIDISKB0ab5wePCAR7wAcOvWLcTFxeW4vxcvUvK6TUhIQExMDCIjI/P8/9Ss\n",
"WTMcO3aM/3H1KlCtGuDjwycB/kEpXbo0AGT6EZfvv7jN7XOSJMHW1tZwk0dY8n0bGxukpaVlGpml\n",
"pKQgJSUFSUlJhvP/7bff0KVLFwDAF18A06dzlGHhQj6l4OBgNGvWLE+fiZK0bNkSB+Vf/9RUzrC6\n",
"fZvDJyNGAOC/oZ49e4KIoNVqodPpoNPpkJaWluVWp9NlebEs3yRJQrFixV66ZYy4ZLd1dXVFzZo1\n",
"UaJECcM56PXAvHnA+PFAUhIvHJ8yBfjoI/46ZyQqKgohISE4c+YMQkNDM5lVWFgYYmNjFfrkX835\n",
"8+cV/U2XUSWEmJ1Ty19aGxubl67iXvVv+Uvu6Oj40lXiw4cPDceoVo3Nq1Ejzibs149/g7Kjdu3a\n",
"+CWP5SN0Oh3i4uIQGxtrMLXHjx+jR48esLe3x5w5cwxXSBlvycnJhi+V/MUKDAxE9+7djTtfvJjN\n",
"C+DYZ7p5AcD//d//4fbt27C3t0dycjJiYmIQExOTJ+3m5Pr16/Dz84O7O18sbNkCbNrEX14A2Llz\n",
"J0aPHq2YHo1GAzc3N7i7u2e6yY+5uroabi4uLnB3dzf8qMHfn6/4Hz5kA/P1hZOTk0X9qGSHnGEL\n",
"ZA4fenl5YceOHZnM/lX35W1KSkq2kRH5M8uNUcv39Xo9kpOTkZSUZLhNnz7dKHbZMjavgABg2DDD\n",
"wyNHjsSFCxdM+nnFy1e7+aR3795YsGABvLy8oNFw1PONN3i7YwcHU+bNA6ZO5Uxn+SLazc0NzZs3\n",
"R+3atbFp0ybcvXsX58+fR2RkJADAwcEBpUuXRpkyZVCmTBmUKlUK7u7umaI7xYoVA5D5YjAtLc3w\n",
"2eZn++zZMzx8+BA6nQ4Af4/s7e0L9BnlF1VGYEQEnU6H4OBgbNu2Ddu2bcPVq1cNz2u1WkybNg0T\n",
"Jkwww7G52kz6YEAxIiMj4eHhAVdXV0RFReVvJ8uWcQyCCJg1i//ysyE1NRVxcXGGmzwyjI2NRWxs\n",
"rME0M75GNlX5vjy/It/kK1f59uIFBICXHsv4+JgxY/Dhhx8CAFauBN59F2jVCjhwgDWHh4ejffv2\n",
"htdntT87O7tsw1mv2sr3XVxc4ObmBmdn54KFPTp14hHwunXA22/nfz8Kc+IE0LQpX7jdu/dy1MHi\n",
"SUnh9RihoezEffsCABISEvDgwQPDaFSn0xkiCFlt5VtWF8PyTa/XIykpCYmJiZluCQkJhu+SfKGY\n",
"1X15a29vj5kzZxpGwDLbtgHjxgHXrvG/q1UDPv2Uw4svTmMA/Nsp5wrIYVulOHXqFCZMmIB9+/YB\n",
"AEqVKoVJkyZh2LBhsFNr6U5BMkBMyY0bN2jWrFnUunVrsrGxoXXr1qktyaQ8ffqUAJCHh0f+drBq\n",
"FddhAohmzjStOBWIijKWlnr8WG01+WTiRP7/mDBBbSV5Qs46/7//U1tJPlmwgE+gRg2ra2+Qlpb2\n",
"UhZyair3rixXLnMG9IQJllGr98qVK9SrVy9DFrWrqyvNmDGD4iygwZ/FGFhGIiMjKbHQdNVjwsLC\n",
"CACVKFEi729euNBYXXvqVNOLU4muXfmUfvlFbSX5ZM0aPoHu3dVWkmtSU43tf06fVltNPkhM5CaP\n",
"ANH69WqrMSnJydwGrG5do5EB3GtwyhSi4GDzFNzQ6/Wk0+leMtbo6GgaP348DRw4kACQg4MDff75\n",
"5/T8+XPTi8gnFmlghZHQ0FACQD4+Prl/k15vXKxTyMyLiOi33/i02rVTW0k+uXiRT6ByZbWV5Jq/\n",
"/mLJ/v5WsWzwZWbNMi5atuJF5Dmh13P3lMBAY40C+ebqStS6NdGYMTxq27ePu0HnZSG6Xq+ntGxG\n",
"rjqdjmLSF2jOnj2bJEmi0aNH0wcffEAPTdax03QIA1OIW7duEQCqUKFC7t6g03E3ZYBHX/Pnm1eg\n",
"Cjx/zutPtVorbTSbnMwnIElcNNMKeO89/pOaPFltJfkgJsZYZHDHDrXVKEJiItHmzUQffkhUpUpm\n",
"M3vx9vPPL79fp9ORPocrlevXr9OSJUtowIAB5OfnR5Ik0S/pIZFx48aRJEn0VXpxcJNWEDIRqi9k\n",
"LiqkpqYCAGxfzJXNirg4znDYvJlrnK1YYZioLkx4ePBasD17OCMxQzKZdWBnx8kEV67wrUEDtRXl\n",
"SFISL6QFOPvW6pg9G3j2DGjeHOjcWW01iuDgwAue5UXPDx4A589zW7DLl/nfciJsyZIvvz+rJKVn\n",
"z55h8uTJWLRoEdLS0uDq6oqAgAC0bNkSkydPRq9evQBwkgbASxOy25faCANTiFwb2PXrQO/ewMWL\n",
"nKa9bh2QnplXGOnd25jIZ3UGBvAC8itXgJAQizewnTuBmBiWGRCgtpo88uwZr/oFgBkzrKLqjDnw\n",
"9eWb3FdVhghIS9NDr2ejSUlJQXBwMPbt24eIiAgMGDAATZs2BcBFGRYsWICAgADMnj0b3t7eKFmy\n",
"JNzc3ODo6GjIbKxSpQoAGFLkLdHALE+RudHpuG1quqEoRVpaGgBe25ElRLyuq149Nq+AAOCffwq1\n",
"eQFAjx6cxr1vHzeStjrSK6AgJERdHbkgvWCIpTTqzhszZwKxsbx0oUULtdWoAqWveHr48CEOHjyI\n",
"x48fA0B65RLA1lYDjUaD06dPo1KlSmjbti02bNiAvXv34u2338aoUaOQnJwMR0dHAMDnn3+OTp06\n",
"oUGDBvBNX8eYMS1froYSGhqKiIiITBosBrVjmIpz7JhxNvSdd4j++IMoIsLsh719+zZt2bKFkrOq\n",
"ln3jhjElD+DOj1FRZtdkKXTowKe9eLHaSvLB+vVk6ABswSQmGhst3r6ttpo8cv++sfPwmTNqq1EF\n",
"OUPwxo0bZG9vT5Ik0bvvvpvp+X///ZfWr19P1atXpxo1atC2bdsoOjqaIiMjqV27dqTVaunIkSNE\n",
"ROTh4UFBQUH077//0ooVK2jQoEHUsWNHunbtmmGfu3fvJh8fH6pfvz7dvHmTiHgZQE5zakpT9Axs\n",
"925eP5Jx9lOrJWrVijOc0v+jFOHJE6Lx44ns7FiHiwvR8uVWmh6WfxYv5tPv0EFtJfng+nUWn5fs\n",
"UhXYutWYkm11jBjB4t9+W20lqtOnTx9ycXGhLl26kCRJ9NFHHxmSKz799FNq06YN7d27N9N7li9f\n",
"Tj169KD9+/cbHnvjjTdIkiRyc3OjUqVKUevWrWnNmjWUnJxsyFA8fPgwOTs7U8eOHenZCx2uIyMj\n",
"KSQkRHUzK3oGJnPrFtGcOURt2rCBZTQ0Pz/+0qxebfpVtno9X0UGBRE5OBiPOXiwQq1bLY9nz6w4\n",
"GzEtjRtqAaq1sc8NgwezxG++UVtJHrlxg/8wNBrOFy+k3Lhxg4YNG2YY6WTFtWvXyNHR0ZAlOGLE\n",
"CJIkiZYvX05ERMePH6dWrVrRsWPHiIgzDL/88kuSJIlGjBhBqampBsPp27cv1a1blxITEykhIYFi\n",
"s8jDv3TpEjk7O5OzszMFBQXRhg0b6L333qPq1auTJEnk7OxMoaGhpv4o8kTRNbCMRERwpYu+fV9e\n",
"eAEQVa1KNGgQ0dy5REeOcEOfvFx5PHzIubCffkpUsWLmfXfvrnoLdEugUyf+OBYuVFtJPmjShMVn\n",
"uMK1JFJTidzdWaLVeUC/fix86FC1lZiVQYMGGVLYXxzVyP/eu3cveXt70x9//EFERCEhIdSoUSOq\n",
"X78+XU4v2TFy5EiaPn06ERF988035O7uTm+++Sa1bduW6tatSxcvXiSdTkdDhw4lPz+/l3To9Xp6\n",
"mn4VmZSURE2aNCFJkgw3T09PevPNN2n16tX0559/UpTKUx0iCxHgnhL9+vEtNZV7bB04wLejR7ny\n",
"+NWrwPLlxve4ugKVKgElSgCenrwPSeJy06mpQHg48OgRF15Mn2w1UKoUt+EYOZIragvQpw+wezdn\n",
"Iw4frraaPFKnDifcnD+fqbiypXD6NHcA8POzsuzD8+e51qGdHTB5stpq8gSl13vVarU51iuUXyMX\n",
"6PX09IQkSYbH5X1JkoT4+HhERkYiLCwMAFC9enVMmzYN77//Pg4ePIhq1aqhYsWKOHfuHADgww8/\n",
"xLvvvgs3Nzc8efIE3377LaZMmYL169ejSpUqWL58OaKjo3Hv3j3s2LEDBw4cwJkzZ9C4cWOsW7cO\n",
"zs7OWLFiBcaNG4fDhw+jfv36GDt2LBo0aAAvLy+LaNckDOxFbG2B117j24QJXDj07Fk2tdOngQsX\n",
"gBs3gOhofjw3uLgADRtyCfyuXYFmzaywgqp56dGDe4Tt389NRr291VaUB+Q2Eiaugm4q/vqLtx06\n",
"qKsjz0ycyNsPP1S++nYBkftuvQqtVovU1FSULVsWAHLsNyhnMLu4uAAAjhw5gokTJyI8PByHDx/G\n",
"Bx98gGrVqmH79u2G18vvcXZ2RunSpZGUlGQoCAwA5cuXN7SDatWqFcaOHYv33nsPzs7OSEtLg5+f\n",
"H1atWoXiGTv7WhDCwF6FnR3QpAnfZIh4hHX3Lud+P38OyBXmNRq+lSjBTa/KlOEvnwWuobAk3N2B\n",
"du240eiff7KZWQ116vD2/Hl1dWSDVRrYsWPcbdbRkS8krYyoqCisXbsWOp0OgYGBOVZr12q1qJoe\n",
"icnYokRGvm9nZwedTodNmzbB19cXEyZMQEBAgOFYM2fOROXKlSFJEu7du4fy5csjNjYWFy9exC+/\n",
"/IKVK1di48aNkCQJpUqVgouLC/z9/fHGG2+gTJkyaN26NcqVKweNRgMigo2NDYjIYF46nc5Qud9i\n",
"UDWAKRBkQK6N2Lq12krySFQUC7e3N0+11QIQFcU5EDY2RNHRaqvJJXo90euv82f65Zdqq3klGZMj\n",
"5H9/9dVXhkSHyMjIHN+v1+tp3rx5htT4F4vqyvu+dOkS+fj4kCRJVLx4cerWrRtFR0fT2rVrqVix\n",
"Yt33RU8AACAASURBVPTll1/SvXv3qHfv3jRu3DhasmQJjRgxgsqVK0eSJNHYsWMN+wwPD6fz589T\n",
"vJWUQMsOYWAKkZiYSAsWLKBx48apLcViiYw0tlh58kRtNXmkfHn+wbWE/hcZ2LSJZbVoobaSPLB3\n",
"L4t2d7f49ZCRkZE0depUWrZsGRHxOqnjx48bkh6CgoJyrCEom9Py5cupePHi1LNnT4PhvWhkz549\n",
"oxYtWlDNmjUNmYZERPfv36fWrVtT48aN6fbt2/T++++TJElkb29P1apVo2HDhtHGjRuzzDR8UYe1\n",
"IQxMIR48eEAAqHTp0mpLsWi6dOHfrgUL1FaSR7p3Z+Fr1qitJBMffMCypk1TW0ku0euJmjdn0TNm\n",
"qK3mlYSHhxvMavPmzURE1LRpU5IkiVq3bk23bt3K8f2ySS1fvtyQ7p7RaJKSkuj8+fMUHBxMaWlp\n",
"NGTIEGrSpAkRsVnKa7b+/PNP8vLyosuXL9OdO3fo3Llz5jhdi0NMzCiEHEdOSEhQWYll06cPb9ev\n",
"V1dHnrHQRA6rm//at4/nvzw9gY8+UlvNK/H29kZQUBC0Wi3ee+89tG7dGmfPnoWtrS2++OILVKpU\n",
"Kcf3U3ppJg8PD0iShPXr12P8+PGYOXMmWrRogTJlyqBu3br46KOPEBMTg8qVK2d6v5yp2KVLF4wY\n",
"MQKOjo6oUKEC6qTPy+r1euj1essrAWUiRBKHQsj1x+Lj41VWYtm8+SYngh48yHkyJUqorSiXWKCB\n",
"3brFN3d3i68zbGTqVN6OHQs4O6urJZf89NNPKF68OGbPno1Dhw4BAPr27Yu2bdtCr9fnWARXfq5W\n",
"rVqoXr06QkJCMH/+fABA7dq1MWjQILz11lvQaDRwdHREVFQUwsPDkZSUBAcHB8N+7O3t8c0332S7\n",
"/0KL2kPAooJeryetVksAKCUlRW05Fo1cFtKqwohXr7LocuXUVmJgwQIrq8B06hQLdnPj3l9WxJMn\n",
"T2j06NGGcGLVqlUpODiYiCjb5pEvcvv2berYsSPVqlWLPv74Y7p06RIlJCS89JrHpq4OZMUUcnu2\n",
"HCRJEqOwXPL227y1qjBilSrcvCk01LikQmWsLnw4dy5vAwOtZvQl4+rqisTERMO/r127hoEDB+KP\n",
"P/4whPlygohQsWJF7Ny5ExcuXMCcOXNQo0YNFCtW7KXXlMyq8VcRRRiYgjg5OQEA4uLiVFZi2bwY\n",
"RrQKtFqgZk2+bwFhxLQ0nk4CrKQjT1gYsHYtr5e0grmvF9m/fz8WL14MHx8fnD9/Ht26dcPt27fx\n",
"7rvv4vvvv0dMTAyA7NuRSJIEIjKswdLr9Vm+RpAZYWAK4unpCYA7ogqyx82NRw16vbGDsFVgQfNg\n",
"J09y80p/f6B8ebXV5IKVK7kEW/fuQIUKaqvJMxPTq4ZMnDgRtWrVwpYtWzA5vfzVrFmzcqywISMb\n",
"lCRJhX/uykSIJA4F8fLyAgA8ffpUZSWWT+/ewI4dwNatwPvvq60ml8gVOdJr0amJ1YUP167l7aBB\n",
"6urIB4mJiahevTpq1KiBgQMHGh7/4osvUL9+fSQlJaFatWoAxCjK1AgDUxDv9AJ/wsBeTefOvD1w\n",
"AEhIACy0FFtm6tfn7Zkz6uqAlRnYzZv8mTk5Gf/jrYhixYphyZIl0Ov1cHBwMBTftbGxQbdu3dSW\n",
"V6gR41QFEQaWe0qW5PrHSUk8F2YV1K3LHQkuXWLhKhEVxcXxbWyAVq1Uk5F75GydN9/kRBgrxM7O\n",
"zpDWLkZZyiEMTEGEgeWNLl14u3OnujpyjZMTUK0aZ1CoOA+2fz/PHzZrZiXJfHL48J131NUhsDqE\n",
"gSmIMLC8kdHArKaQgLxi+PRp1SQcOMDbdu1Uk5B7rl3jKv6urlYS7xRYEsLAFEQkceSNhg25otCd\n",
"O8D162qrySWvvcbbw4dVkyAfumVL1STkHnn09dZbgL29uloEVocwMAUpkV4XSRhY7tBqgU6d+P6O\n",
"HepqyTVt2/J23z6O4ylMRARw8SK3sWvcWPHD551163grF8EUCPKAMDAFkQ0s3GpW56qPHEZMbzJr\n",
"+fj7A2XLAs+eqdLg8tgxDrc2aWIF+RAhIXzz8LCSeKfA0hAGpiDCwPJO5848Ejt8GIiMVFtNLpAk\n",
"Y+mLXbsUP/yRI7x9/XXFD5135PBhz55cekUgyCPCwBTEw8MDWq0WUVFRSElJUVuOVeDuzj/GOh2w\n",
"e7faanLJm2/ydsMGxQ8tL0GTp+IsFiJg1Sq+L7IPBflEGJiCaDQaQyaiKCeVe+S1oFu3qqsj13To\n",
"ALi4AGfP8iJdhSAyFgGpW1exw+aPQ4e414uvL9C6tdpqBFaKMDCFEWHEvNO9O2937eJyeRaPg4Nx\n",
"FCYnKSjAgwecxOHlBfj4KHbY/LF4MW+HDOEYsUCQD4SBKYwwsLxTuTJQvToQHa1qdnrekMNiK1Yo\n",
"tojt7FneygVBLJaoKGDjRr4/ZIi6WgRWjTAwhXF3dwcARFlIzyhroUcP3q5Zo66OXNOxI1C6NHD1\n",
"KnD8uCKHtJrw4apVXGqrXTugYkW11QisGGFgCiP3BIuNjVVZiXUxYABvN2wAkpPV1ZIrbGyAwYP5\n",
"/pIlihxSHoHVq6fI4fKPHD4cNkxdHQKrRxiYwjinF6cTTS3zRvXqPLKIirKi2ohDh/J23TpAgQuW\n",
"jCFEi+Xff1moh4dxWC0Q5BNhYAojRmD5Rx6F/fGHujpyjZ8frwGIjzeueTITz58D9+5x25mAALMe\n",
"qmDIo9GBA61gpbXA0hEGpjDCwPJPv36cnLB9Oyd0WAVymMzMYUR5/Vfduhac1JeYaLz6EOFDgQkQ\n",
"BqYwNjbcQ1SvQp08a8fHh/tbJScbk9gsnt69uafJiRPAlStmO4xsYHIxfIvkzz/5yqNRI6B2bbXV\n",
"CAoBwsAEVoXcsX3lSnV15JrixY0p9cuWme0wcveWhg3NdoiCI5I3BCZGGJjAqujVi6dODh4E7t9X\n",
"W00ukdc6rVjBNbFMDBEQHMz3LdbAbt7k/7RixYC+fdVWIygkCAMTWBWurlyZI2MpPYunaVNO6Hj0\n",
"CPjrL5Pv/soVICwMKFmSG0JbJEuX8rZPH/5PFAhMgDAwhZHnviSLLpVg2chhRAWLXBQMSQLee4/v\n",
"//67yXf/99+8bdfOQitwpKUZz1uEDwUmRBiYwkSm9wRxc3NTWYn10qkTd2oOCTFWn7B4ZNfdvh1I\n",
"SDDprvfs4a3cxcXi2L2bh4j+/sB//qO2GkEhQhiYwshV6L28vFRWYr3Y2hqnUawmmaNcOW6RnJBg\n",
"dBwT8Pw5sHcvoNEYu1dbHBmTNyxyiCiwVoSBKYxsYHJbFUH+ePdd3q5axREqq6BXL96asE/Y+vVc\n",
"ob99e54DszgeP+ZRp1YLDBqkthpBIUMYmMKIEZhpaNyY8yIePwb27VNbTS6RDWz7dpMVdJRHoHKV\n",
"Eotj+XLOvHzjDaBUKbXVCAoZwsAURhiYaZAk44/2+vXqask1lSsDdeoAMTEmcd07d4Bjx3ip2Vtv\n",
"mUCfqSEyViAJDFRXi6BQIgxMYYSBmY6ePXm7ZYtZlleZB9lpTNBeWl5G8OabQHqFMsvi6FHg+nVu\n",
"K2OxE3QCa0YYmILodDpERERAkiRDXzBB/qlZE6hSBXj2jH8rrYJu3Xi7fXuB1gAQGcOHcoKjxZGx\n",
"63J6CTWBwJQIA1OQyMhIEBHc3d0NNREF+UeSjAOaTZvU1ZJr6tXjoo4PHxr7n+SDs2e5V6aXl4Wm\n",
"z0dHG2O7clsZgcDECANTEBE+ND0ZDcxqFjXLo7AChBHlou7vvMPLCiyONWu4+nyrVjz3JxCYAWFg\n",
"CiIMzPQ0acJTLKGh3CvRKpANbNu2fL1dpwNWr+b7Fh8+FMkbAjMiDExBhIGZHo3G2Nh382Z1teSa\n",
"Nm04dfDff4EHD/L89sOHubBFpUps4BbH+fNcHt/V1ZhpIxCYAWFgCiIMzDxY3TyYgwPQoQPf3749\n",
"z2+Xp5b69LHQwhZy6vyAAVx9XiAwE8LAFOTp06cAhIGZmpYt+WI/JAS4cUNtNbkkn2FEnY77QgLA\n",
"22+bWJMpSEzkKsuACB8KzI4wMAURIzDzYGfHhR4AKxqFde3Kw6d9+4D4+Fy/7ehR4MkTDh/Wq2dG\n",
"ffll40YgKoobk1mkQEFhQhiYgggDMx9yGNFq5sFKluQJrORkrsabS+Qyir17W2j4cNEi3g4frq4O\n",
"QZFAGJiCCAMzH5068dRScDAnOFgF+Qgj7tjBW4vMjbh6lTNMHB2Bfv3UViMoAggDUxBRid58ODoa\n",
"F/Ru2aKullyTsSpHeqPTnLh1i+sfurtzhM7ikFPn+/UDnJ3V1SIoEggDUxAxAjMvVhdGrFkTqFAB\n",
"CA8HTp585cvlzstt2nB3EosiORlYtozvi/ChQCGEgSmIMDDz0q0brwvbv58rGVk8eazKIU+VWWTp\n",
"qC1buChl7dpAo0ZqqxEUEYSBKURKSgpiYmKg1Wrh6uqqtpxCiZcX8Prr3ODRBMXelSGX82A6HRsz\n",
"YKEGtnAhb0eMsNDsEkFhRBiYQkRERAAAPDw8IIkvuNno04e3a9eqqyPXtGzJ80WXLvEEVzacOQNE\n",
"RnL6fKVKCurLDbdu8XKAYsUsuLOmoDAiDEwhnj9/DgDw9PRUWUnhplcvDiPu2QOkXzNYNnZ2xl5Z\n",
"OYzC5Pmvdu0U0JRXfvyRt337Am5u6mr5//bOPS7Kauvjv/0MV+UqIDZeEgVN8M4RMAWviaNg2pt5\n",
"T+3NUsvrqY9ancC3TLDQMLWL4iW1g2bmDdTykimK+cpLmsqBBPWAiiIEKDdh1vvHdh4YAUGF5xkO\n",
"+/v5zGce5tmz99qjzI+199prCRoVQsAUoqIHJqg/mjfnQQ6lpQ3oUHMtlhENBZwHDVLAnschNxdY\n",
"v55fz5mjri2CRocQMIUwCJjwwOqfsWP5c4NZRhw2jLuNx45VGX1SWAjExfHrgQMVtq0moqKAu3e5\n",
"Yd26qW2NoJEhBEwhDEuIwgOrf0aN4gWADx/mEeomj5MT0KcPjz45eLDS7ZMneZR69+48UMVkKC0t\n",
"Xz6cN09dWwSNEiFgCiGWEJWjWTOe7F2v56n5GgSPWEY07H+Z3PLhtm3A1auAhwf3IgUChRECphD5\n",
"+fkAAFuRoUARDMuI0dHq2lFrRozgzzEx3LOpgOH8l0kJWGkpsHgxv160iC+BCgQKI/7XKURJSQkA\n",
"wNLSUmVLGgcvvghYWgLHjwPXr6ttTS3o2JF7Mjk5fM3wAXfu8BD6Jk14xL3JsHUrr13Tvj0waZLa\n",
"1ggaKULAFEIImLLY2QE6HUBUXgDS5KliGTEnhz8PG8ZFzCS4fx/4n//h1yEhfMNRIFABIWAKYRAw\n",
"CwsLlS1pPDTYZcQKaURatuSepElln9+0CUhN5V7j+PFqWyNoxAgBUwiDgJmbm6tsSeMhKIh7LfHx\n",
"wJUraltTC/r04anmk5OBf/0LAE9u8cILJhQjUVICfPQRvw4NNcGswoLGhBAwhZAebHLra1E2Q1A3\n",
"NG1aXql5+3Z1bakVZmZ83RMwWkacMwcwmfSZ69YB164Bnp7A6NFqWyNo5AgBU4gmDzYwCgoKVLak\n",
"cdHgDjUblhErCJi/v0q2PExBQbn39dFHwvsSqI4QMIUwCFhhYaHKljQudDqeKzchgQfNmTxDh3JP\n",
"7MQJIDMTAN8DMwlWrwZu3gS8vcuLrwkEKiIETCGsra0BCA9MaayseEg90EAONdvbcxHT603LbczL\n",
"A8LC+PWSJaJkisAkEAKmEMIDUw/DqtyBA+raUWsmTuTPW7aoa0dFVqzg6f39/XmaE4HABBACphDC\n",
"A1OPwYN5ooi4OO5ImDwjRvCDbGfOAJcuqW0NP00dEcGvhfclMCGEgCmECOJQD0dHwM+PZz8yVDU2\n",
"aayty6NP1qxR1xYACA8H8vOBwEATiigRCISAKYbBAxNLiOpgqBnZYJYR336bP2/cWGWJFcXIzARW\n",
"reLXH3+snh0CQRUIAVMI4YGpS0UBI1LXluq4fZs7OgCALl2AAQN4ra0NG9QzKjycFyR78UXgb39T\n",
"zw6BoAqEgCmEIQdicXGxypY0Try9eS2tq1d5ogtTZNUq7nDJGCocf/opFxGluXED+PJLfh0aqvz4\n",
"AkENCAFTCCFg6iJJ5cFzpriMWFICfP11+WodAJ7ct3t3nk7fICRKEhYGFBXxM1/duys/vkBQA0LA\n",
"FEIImPqY8j7YDz/w7SYLiwpLnJJUvu+0dClfTlSKjAyuqIDwvgQmixAwhRACpj4GD+yXX9RZkXsU\n",
"q1fz57feeihKfdgwHkKZlcVFTClCQ4HiYuDll4GuXZUbVyB4DISAKYQQMPVxdQV69uSrYocPq21N\n",
"Ob//zs+o2dmVn2GWYQxYvpxff/qpMufCzp4FoqJ4SisReSgwYYSAKYQQMNPgv/6LP2/erK4dFTF4\n",
"X5MnAzY2VTTo3RuYNo0Xkpwxo37DKIl48IjhuWPH+htLIHhKGJGpBhX/Z3Hjxg1otVq4urri5s2b\n",
"apvTaPn3v4FnnwXMzXleWkdHde3JyeFFKwsLuXP13HPVNMzO5mKSlQWsXQu8/nr9GLRhA/Daa0Dz\n",
"5jxc02TquAgElREemEIID8w0aN2aF4gsKQG++05ta3jYfGEhT3dVrXgBQLNmwOef8+s5c+SCl3XK\n",
"1avlofsREUK8BCaPEDCFMAiYoTKzQD1ee40/r1mj7qFmvb48U9Rbb9XiDePH80dBAU81VZeH4u/f\n",
"ByZN4iepR40CJkyou74FgnpCLCEqRGlpKczNzaHRaFBaWqq2OY2a+/eBtm358aqffuIemRocPMhD\n",
"+1u3BlJTecxEjeTm8kiU1FReETk6mofbPy1z5gArVwLPPAMkJvIlRIHAxBEemEJoNBowxlBWVoay\n",
"sjK1zWnUmJuXezyGVTk1MBxanjGjluIF8GW9vXt5yOL33wMLFz69G/nll1y8zM35gTQhXoIGgvDA\n",
"FMTKygrFxcUoLCyElZWV2uY0arKyuOdTVAQkJSkfbJeWBrRvzzUjPR1wcXnMDvbv55k6ysqA+fOB\n",
"zz57sjInmzYBU6bw6/oMDhEI6gHhgSmIhYUFABHIYQo4O/MtH4DXalSar77ijtMrrzyBeAGATsc9\n",
"MHNzfk7sv/+bq3FtIeIHo6dO5T9/+mmjEC+9Xo/x48dDkiS8Xov5ZmZm4oUXXkBKSooC1tUNCQkJ\n",
"WLx4MTaomQRaKUigGM7OzgSAbt26pbYpAiK6dImIMSILC6L0dOXGLSggcnIiAoji45+ys337iKys\n",
"eGedOxOdOFHze27dInrpJf4egCgs7CmNUJedO3eSk5MTMcbkR9euXenPP/+s1HbmzJnEGCN7e3ti\n",
"jNGRI0fke9u3b6d33nlH/lmv11Pfvn2JMUaffPIJERF5eHgYjWN4TJgwgdLS0oiIKDk5mZ5//vkq\n",
"2zHGaO7cuURElJGRQf7+/kb3LC0tacuWLU/0ORQVFdG4ceNIkiTS6XSUmJhIREQJCQkkSRKFhYXR\n",
"/fv3ydzcnN57771K7w8JCSHGGH377bdERLR+/Xpq3rx5lXPQaDSUkJDwRHbWJULAFESr1RIA+ve/\n",
"/622KYIHjB7Nv8MffKcowvr1fExvbyK9vg46/L//I3J3LxekgQOJNm4kysgoH6C4mOjMGaJ33yWy\n",
"t+ft7OyI9uypAwPU48yZM2RpaUmtWrWi2bNnU1RUFC1atIjs7e3Jzs6OLl26JLeNj48nxhhFRkbS\n",
"7du3yc3NjTw9PUn/4DOaM2cOMcZowYIFRET0xRdfkIWFBWk0GvL29iYiIsYYSZJEY8eOpaioKIqK\n",
"iqJp06YRY4z8/PyIiEin0xFjjIYOHSq3MTw2bNhA9+7do9LSUvL19SUzMzMaMWIErV27llavXk1d\n",
"unQhxhgtWbLksT6HwsJC8vLyIltbW1q7dq08JyKi5cuXE2OMpk6dSkVFRcQYoyZNmtCJh/7YMQjY\n",
"sWPH6ObNm8QYIzMzMwoNDa00j4MHDz7+P1Y9IARMQdq2bUsA6PLly2qbInhAYiL/Lre2JsrMrP/x\n",
"9Hqibt34mBs21GHHBQVEH3xAZGtbLmQAUdOmRI6ORGZmxq8HBhIlJ9ehAepw8eJFsrS0pMWLFxu9\n",
"np2dTS4uLhQUFCS/tmLFCrK0tKScnBwi4gLFGKPY2FgiKhcwV1dXSkhIIK1WS8uXL6ewsDBijBER\n",
"FzCdTlfJDk9PT3J1dSUiomXLlpG5uTkVFxc/0vaAgAByc3Mzek2v19O0adPIwcGhSg+yKoqKikin\n",
"05GFhQWlpqZWun/x4sVKAsYYo86dOxu1MwjYb7/9RkREnTt3pldffbVWNqiF2ANTEMNZsKLH2asQ\n",
"1CvduvFYiMJCZfbCfv2V5z5s3hwYN64OO7a2Bj76CLh2jeemGjKEH36+d4+n+ygt5ZEq06YBp07x\n",
"lPweHnVoAIeI5wDOyOBJk7dtA37+uf6KSnfq1AmzZs0CPRSL5ujoiE2bNiEmJga5DwaPiYmBjY0N\n",
"HBwcAABBQUFwdHTE3r17AQBt2rQBANy6dQve3t5o0aIFpk+fjhYtWoBVCJAJDg42Gmv//v24dOkS\n",
"/v73vwMAbG1tUVZWhsTERNy8eVN+PHx8Zs2aNZXsZoxh1apVsLW1le2qidWrV+PAgQOYP38+3Nzc\n",
"Kt3ftWuXfF3RhgsXLhjtk5WWlqJly5bo1asXAKBp06ZIS0vD9evX5TlkZWXVyibFUFtBGxPdu3cn\n",
"AHT27Fm1TRFUID6eOyU2NkR37tTvWCNH8rFCQup3HJmcHKKsLKLCwnobIi/P2Lmr6mFmRjRoEN+y\n",
"q2tCQ0MpNDS0ynstWrSg6OhoKigoIK1WS6+88op8Lzs7m4KDg6l///5ERHT06FF5j8rKykr2RFJS\n",
"Uow8sI4dO1J8fDxdv36dIiMjycrKivz9/eV+IyMjiTFGtra2JEmSfL3hIZc7LS2N2rZtW6XdCxcu\n",
"pMDAwFrN//Tp09S6dWtijNGwYcMo+SHP2uBZzZkzh/75z38SY4zi4+Np6NCh1KJFC8rIyCAiok6d\n",
"Ohl5hD169CCNRkM2Njay19axY0e5vSkgPDAFMYTOF5paLY9Gjq8vP8x89y6wbFn9jZOaCuzezWt+\n",
"TZ9ef+MY4eAAODkBCh7bMDPjHmbv3rwaS+/eXMYOHwbu3Kn78fR6fbX3fH190aZNG2RmZuLGjRtI\n",
"SkpCRkYGli1bBhcXF+zbt6+SVzFv3jzExcXJnoj00EHx5ORk9O7dGy1btsTcuXPh4+OD2NhY+f6e\n",
"PXvg7u6OvLw8nDt3DocOHcJff/2FKYbjCg+gR5xg8vHxkT3CmvDx8cG1a9dw+PBh3LlzB15eXthc\n",
"RbbqkSNHyqs/vr6++OKLL1BQUIDAwED88ccfuHPnjuxppqenIzExEaGhocjLy8OhQ4dw/vx5JCUl\n",
"QavV1souJajt8UlBHWBtbQ1ACJgpsmQJX+qKjOSHnFu3rvsxwsL4F/m4cUCLFnXfv1rY2tZ8lvrO\n",
"HeDQIWDAgLof/6effoJOp6v0ekFBAfbv34/NmzfjzgPlPH/+PFq3bg0bGxts374dK1asQFxcHG7d\n",
"umX03p49e8rXx48fN7onSRLeeustDB8+HJIkwd/fX94eAPhSXN++fQEAXl5e8PLyqtbu6tixYwf8\n",
"/PxqmLkxAwYMwMmTJ7Fu3TrMnDkTXl5e6Nmzpzz3h4XY3d0de/fuhU6nQ9cHNd9GjBghzwEAAgIC\n",
"wBjDwIEDH8sWpRAemIIYBEzsgZkevXrxM1lFRfVTgPjKFZ7oXZKARYvqvn9Tx8kJGDOmfpJ8NK+m\n",
"0127dsHX1xe2trbya6+++iqOHDmC3NxcvPTSS3jzzTcBACdPnqy2/4c9pcDAQERGRmLIkCEYPHiw\n",
"kXiVlZUhNTUVOTk5ICJkZ2cb7YPdv39fbutSzQHAkpIS7Nu3r0pRrglJkjBx4kSYm5vjm2++AVBZ\n",
"gCsSEBCAhQsXAuD7b6NHjwYA+dxbVlYWysrKjOZw+/btx7arvhAemIIID8y0+fhjYOdOLjQzZgB/\n",
"+1vd9b10KY+jmDhRlNiqa3r27FlJZAoLCxEREYGlD1WxnjJlCvr37y//3KFDBwDAtWvXqgyAMFDR\n",
"exk1alS17fLz85Geno709HR4eHggNTVVvscYQ2xsLAIDA2W7q2L58uUYPnw43N3dqx3HQEZGBvbv\n",
"34/AwEAcP34cd+/exZo1a5CXl4fg4GBkZ2cjKSkJjDGYm5tX2cf777+P9PR0ODk5YciDsuUXLlwA\n",
"AIwZMwatW7fGlStX5PbPPvssUlJSYFbr/Gf1h/oWNCKEgJk2Hh48p21EBN+jOn0a0Gievt+LF3mB\n",
"Y0kCPvjg6fsTGENERlGC+fn5eOONN+Dg4CB/IScnJ8PKygq9e/c2eq+Pj4/swXXr1g3u7u7y76kB\n",
"Pz8/oz0lQ0adqmjSpAm0Wi08PT3RqlUrBAQE4JlnnkG/fv3g7OxcrWgBPEPPgQMHEBYWhri4uFrN\n",
"/ejRo3jjjTcgSZK8F+jn54djx46hT58+uHLlCkpKSsAYg6+vL/5VRRkeSZLw9ddfG73Wvn172NjY\n",
"YNSoUdA8+CV4/vnn0aZNG3Tr1s0kxAsQAqYoQsBMn9BQHvp99ixPL7hgwdP1RwTMns1TFs6YIbyv\n",
"uqaoqAh79uyBq6sr1q1bh5iYGOzevRu9evXCkSNH5HaXL1+GtbW10XKfgenTp8sBE8nJyZXuP/fc\n",
"c3juQbG2KVOmwNfXt1p7LCwskJ6eXivbt23bhpycHKxbtw6pqan46quvUFxcjNjY2Gr3zR6mb9++\n",
"sLS0RElJCXQ6HWJiYqptK0mSkdA/iuDgYOTl5dWqraqoGgPZyJg1axYBoBUrVqhtiuARxMaWh36f\n",
"Pv10fUVF8b6aNePR7IK6JTEx0SjFkY2NDYWGhlJeXp7aptVI9+7dZbsN6Z/OnTtXp2NkZGSQJEk0\n",
"f/58IiJKTU2lnj171ukYaiI8MAURHljDQKfjS4mRkTwM/ORJoFWrx+/nzz+59wXwsi1OTnVrSCc+\n",
"OgAADbxJREFUpwBwc3PD4sWLERAQgH79+qltzmMxf/585Obm4u233663MbRarVH5Jjc3N5w9e7be\n",
"xlMaIWAKYthEFQUtTZ/wcODMGS5eQ4cCx48Djo61f//t28Dw4TwRxpgxPHhDUPfY2dnhH//4h9pm\n",
"PBGTDOUQBE+MCKNXEMP6M4kSbCaPpSWvG9mpE3DhAtCvH8/SVBtycoBhw4DkZJ6q6uuvn6xUl0Ag\n",
"eDRCwBRECFjDolkz4OBBHnhx/jzQvTsPsX9UQe3TpwE/P+B//xdo146nHLS3V85mgaAxIQRMQQxn\n",
"SYSANRxatwbi4vhyYE4O8NprQIcOPFrx5595iHxCArBxI08K3Ls397y6dgWOHv3PyrghEJgaYg9M\n",
"QQwe2KNytwlMDycnvpz43Xf8HFdqKrB4cdVtLSyAuXOBkBCgSRNl7RQIGhtCwBRELCE2XBgDJkzg\n",
"ARmHDwN79vCyKFlZXLQ6dAD69OHBGtVkCBIIBHWMWEJUECFgDR8zMyAwkJfcOnECSEoCzp0DduwA\n",
"5s0T4mXq6PV6jB8/HpIk4fXXX6+xfWZmJl544QU5N2Bj5ejRowgNDcWPP/6otilGCAFTELEHJhDU\n",
"PT/++COcnZ0hSZL86NatGy5fvlyp7axZsxAdHQ07OzusX78eR48ele99//33ePfdd+WfiQgvv/wy\n",
"Dh8+jB07dgDguRMrjmN4TJw4Uc4XmJKSgj59+lTZTpIkzJs3DwBw/fp1BAQEGN2zsrLC1q1bn+hz\n",
"2LdvH9q3bw9JkvDcc89h586dldro9Xq88847sLCwkMccPXp0td9JOTk5GDJkCAYNGoSUlBR0794d\n",
"ALB7925IkoTo6GikpaVBo9HIyYMrMmXKFEiSJCcUDg8Ph52dXZWfi42NDa5fv/54k1bvDHXjY8mS\n",
"JQSAFi5cqLYpAsF/BGfOnCFLS0tq1aoVzZ49m6KiomjRokVkb29PdnZ2dOnSJbltfHw8McYoMjKS\n",
"bt++TW5ubuTp6Ul6vZ6IiObMmUOMMVqwYAEREX3xxRdkYWFBGo2GvL29iYjkrBljx46lqKgoioqK\n",
"omnTphFjjPz8/IiISKfTEWOMhg4dKrcxPDZs2ED37t2j0tJS8vX1JTMzMxoxYgStXbuWVq9eTV26\n",
"dCHGGC1ZsuSxPoft27eTmZkZOTg40MKFCyk8PJxGjhxZqV1ERAQxxqhr1670zTffkI+PDzHGaObM\n",
"mZXaXr9+nVq1akUuLi60e/duo3uzZ88mxhgtXryYkpKSiDFGLi4ulJSUZNRu8uTJxBijq1ev0unT\n",
"p4kxRk2bNqWIiIhKn01cXNxjzZmISAiYgnzyyScEQP4FEQgET8fFixfJ0tKSFi9ebPR6dnY2ubi4\n",
"UFBQkPzaihUryNLSknJycoiICxRjjGJjY4moXMBcXV0pISGBtFotLV++nMLCwowqMut0ukp2eHp6\n",
"kqurKxERLVu2jMzNzam4uPiRtgcEBBhVQCYi0uv1NG3aNHJwcKA///yzVp/BsWPHSKPRkKurK/3+\n",
"++/VtktNTSUzMzPq0qUL/fHHH0REVFZWRmPHjiXGGEVFRclts7Ozydvbm5ycnCg3N7dSX7GxsZUE\n",
"zFARuiKTJ08mjUZDmZmZVFJSQg4ODvThhx/Wal61QQRxKIjYAxP8R1JczOvFADx7sV7Po14YA/Lz\n",
"gYICwNmZh3MOHgx06VJnQ3fq1AmzZs2q9Dvl6OiITZs2Yfjw4cjNzYW9vT1iYmJgY2MDBwcHAEBQ\n",
"UBBCQkLkoo6GhL63bt2Ct7c3evTogenTp2P79u1GSXCDg4ONxtq/fz8uXbqE8PBwAICtrS3KysqQ\n",
"mJhoVFXZ2dnZKIv7mjVrEBQUZNQXYwyrVq3CgQMHsHfvXsydO/eR8y8uLsakSZPAGMORI0fg6elZ\n",
"bdulS5eiefPmOHv2rJwVSJIkbN26FTk5OVi1ahVee+01AEBISAgSEhLw5Zdfws7OrlJfu3btkq8r\n",
"1jg7cOAADh8+jEGDBgHgWYeef/55OeO/lZUVkpOTcfPmTfk9lpaWcHycNDcVqTMpFNRIeHg4AaB3\n",
"331XbVMEgrojL49nLK7N45tv6nz40NBQCg0NrfJeixYtKDo6mgoKCkir1dIrr7wi38vOzqbg4GDq\n",
"378/EREdPXqUGGM0d+5csrKyot9++42IiFJSUow8sI4dO1J8fDxdv36dIiMjycrKivz9/eV+IyMj\n",
"iTFGtra2JEmSfL1hwwYj29LS0qht27ZV2r1w4UIKDAysce7fffcdMcZoxowZj2yXlpZGFhYWdOjQ\n",
"oSrvG7y4y5cvExHR3r17ycnJiTQaDU2cOJEyMjKM2huWBlesWEFLly4lOzs7OnfuHPXo0YO8vLwo\n",
"Pz+fiIisra1pwIABRMS9y2bNmpG5uTk1adKEGGOk0WioV69edPfu3RrnWhXCA6tniAh//fUXHB0d\n",
"H3kOLDc3F3Z2drUudyAQmAwWFvzgmwFJKvfEbG35gbjMTCA3t069LwN6vd6o4GRFfH190aZNG2Rm\n",
"ZuLGjRtISkpCRkYGtm7divfeew96vb5S6ZJ58+Zh0qRJcu2uh/tOTk42qivm7+9vVMZkz549cHd3\n",
"R3JyMi5cuIDMzEz079+/Uj/0iJUYHx8f3Llzp8a5FxcXAwCmTp36yHZbtmyBr6+v7Bk9jJ2dHfR6\n",
"PS5duoR27dohKCgIWVlZ2LlzJ95//305KGTw4MFG7xs5ciQ2btyIZs2aoUuXLli5ciUGDhyIF198\n",
"EStXrkRRUZH8nRYXF4ecnBx8++23GD16NI4fP4527dqhXbt2Nc6zWp5I9gS1orS0lGbMmEEeHh50\n",
"+/Zt+vTTTwmAXNqAiP9VsnXrVnJ2dqZt27apaK1A0DDx8/OrtAdGRHTv3j2ysLCgvLw8SktLMyq7\n",
"YmtrSz/88AP17duXGGOUmZkpe2BXr1416mfjxo1GHphGo6HZs2fTwYMH6eeff6aioiKj9v369aOp\n",
"U6fWaPdXX31VrQc2fvx4WrlyZY19GGz+6KOPHtmua9eu9OOPP1Z5r7S0lMaNG0cdOnSg0tLSSvdL\n",
"Skrogw8+IK1WS2lpaUREFBQURJIk0ZUrVygkJMRoHtHR0aTRaOTP+uOPPzay9eHP92kQYfT1SGFh\n",
"IU6dOoWUlBQEBwfLa8X04C+vq1evYvjw4ZgwYQKysrJM7oyFQNAQMOyvPMyuXbvg6+sLW1tb+bVX\n",
"X30VR44cQW5uLl566SW8+eabAICTJ09W2z895CkFBgYiMjISQ4YMweDBg42KZJaVlSE1NRU5OTkg\n",
"ImRnZ+PmzZvyo+J+kUs1hwZLSkqwb98+6HS6Gufev39/+Pn5ITQ0FBcvXjS6d+XKFcyaNQvp6ek4\n",
"f/58lftMKSkpGDVqFI4cOYJdu3bJ1ZcrYm5ujrfeegs3btxAdHQ0AMhh8VUxZswYTJ48GQDf03v5\n",
"5ZflsQAgKysLJSUlRp9LdnZ2jXOtCrGEWI/Y2NggJiYGvXv3Rnx8PO7evQuA/ydfuXIl3nvvPdy7\n",
"dw8ODg5Yvnw5pkyZoq7BAkEDpGfPnpVEprCwEBEREVhqCC55wJQpU9C/f3/55w4dOgAArl27Bjc3\n",
"t2rHqLj8N2rUqGrb5efnIz09Henp6fDw8EBqaqp8jzGG2NhYBAYGynZXxfLlyzF8+HC4u7tXO05F\n",
"tmzZgkGDBsHf3x8zZ87EqFGjkJCQgLlz52LixIlwcHCAi4sL5s+fj/Hjx8P+QXbpU6dO4dtvv0WP\n",
"Hj1w6NAhdOrUCQCQlJSEkydPYtiwYThw4AAKCwsRHh4OKysrBAYG4uLFi8jLywNjTA4GeZhVq1Yh\n",
"Ly8PAQEB6PigDPmFCxcA8CVXR0dHozNffn5+j/wjojqEgNUzWq0W+/fvR58+ffDHH38AALZv3y5H\n",
"4YwePRorV65EC5H1VSB4IojIaO84Pz8fb7zxBhwcHDBkyBAAfN/KysrKaO8K4HtNBg+uW7ducHd3\n",
"lwvPGvDz88PmzZvlny0sLKq1pUmTJtBqtfD09ESrVq0QEBCAZ555Bv369YOzs3O1ogXw/awDBw4g\n",
"LCwMcXFxtZ5/u3btcOrUKUREROCzzz7DkiVLwBjD+PHjERERgaZNmyImJgbLli3DggULoNfr0aFD\n",
"B4wePRrJycmVhHvHjh348MMPIUmSvF8/dOhQxMTEwMvLC7/88gsAoGXLltBqtVXaZG1tje+//97o\n",
"NQ8PD7i4uGD48OEAuKAPGjQILi4u8PX1rfV8jaizxUjBI/n1119Jo9EQAAJAWq2Wdu3apbZZAkGD\n",
"prCwkHr06EFDhw6ltWvX0siRI4kxRj4+PkaRbWvWrKFmzZpV2UdISEi1+0MPM3Xq1EqHdZ+UsLAw\n",
"sre3p7Vr19KiRYvI0dGRmjRpQr/88kud9P+knDhxgjQaDUmSVGV0o2Evq127dkTEo0Cr28urb4SA\n",
"KcjUqVMJAHXu3Jn++usvtc0RCBo8iYmJRsEZNjY2FBoaSnl5eWqbViPdu3eX7ZYkiXQ6HZ07d05t\n",
"s2rk5MmTpNFo6PPPPyciotOnT9cq5L8+YETiVK1S0ENLHQKB4OnIy8tDZGQkAgIC0K9fP7XNeSw2\n",
"b96M3NxcvP3222qb0mARAiYQCASCBokIoxcIBAJBg0QImEAgEAgaJELABAKBQNAgEQImEAgEggaJ\n",
"EDCBQCAQNEiEgAkEAoGgQSIETCAQCAQNEiFgAoFAIGiQCAETCAQCQYPk/wEPvRJNIO9OCwAAAABJ\n",
"RU5ErkJggg==\n"
],
"text/plain": [
Min RK
update nbconvert-as-library notebook...
r19938 "<IPython.core.display.Image object>"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 10,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import Image\n",
"Image(data=resources['outputs']['output_3_0.png'],format='png')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Yep, this is indeed the image we were expecting, and I was able to see it without ever writing or reading it from disk. I don't think I'll have to show to you what to do with those data, as if you are here you are most probably familiar with IO."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Extracting figures with HTML Exporter ?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use case:\n",
"\n",
"> I write an [awesome blog](http://jakevdp.github.io/) in HTML, and I want all but having base64 embeded images. \n",
"Having one html file with all inside is nice to send to coworker, but I definitively want resources to be cached !\n",
"So I need an HTML exporter, and I want it to extract the figures !"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Some theory"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The process of converting a notebook to a another format with the nbconvert Exporters happend in a few steps:\n",
"\n",
" - Get the notebook data and other required files. (you are responsible for that)\n",
" - Feed them to the exporter that will\n",
Min RK
update nbconvert-as-library notebook...
r19938 " - sequentially feed the data to a number of `Preprocessors`. Preprocessor only act on the **structure**\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " of the notebook, and have access to it all. \n",
" - feed the notebook through the jinja templating engine\n",
" - the use templates are configurable.\n",
" - templates make use of configurable macros called filters.\n",
" - The exporter return the converted notebook as well as other relevant resources as a tuple.\n",
" - Write what you need to disk, or elsewhere. (You are responsible for it)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "Here we'll be interested in the `Preprocessors`. Each `Preprocessor` is applied successively and in order on the notebook before going through the conversion process.\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "We provide some preprocessor that do some modification on the notebook structure by default.\n",
"One of them, the `ExtractOutputPreprocessor` is responsible for crawling notebook,\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "finding all the figures, and put them into the resources directory, as well as choosing the key\n",
"(`filename_xx_y.extension`) that can replace the figure in the template.\n",
"\n",
"\n",
Min RK
update nbconvert-as-library notebook...
r19938 "The `ExtractOutputPreprocessor` is special in the fact that it **should** be availlable on all `Exporter`s, but is just inactive by default on some exporter."
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 11,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
Min RK
update nbconvert-as-library notebook...
r19938 "[<function IPython.nbconvert.preprocessors.coalescestreams.cell_preprocessor.<locals>.wrappedfunc>,\n",
" <IPython.nbconvert.preprocessors.svg2pdf.SVG2PDFPreprocessor at 0x107d1a630>,\n",
" <IPython.nbconvert.preprocessors.extractoutput.ExtractOutputPreprocessor at 0x107d1a748>,\n",
" <IPython.nbconvert.preprocessors.csshtmlheader.CSSHTMLHeaderPreprocessor at 0x107d1aba8>,\n",
" <IPython.nbconvert.preprocessors.revealhelp.RevealHelpPreprocessor at 0x107d1a710>,\n",
" <IPython.nbconvert.preprocessors.latex.LatexPreprocessor at 0x107daa860>,\n",
" <IPython.nbconvert.preprocessors.clearoutput.ClearOutputPreprocessor at 0x107db7080>,\n",
" <IPython.nbconvert.preprocessors.execute.ExecutePreprocessor at 0x107db7160>,\n",
" <IPython.nbconvert.preprocessors.highlightmagics.HighlightMagicsPreprocessor at 0x107db7048>]"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 11,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {},
"output_type": "execute_result"
}
],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "# 3rd one should be <ExtractOutputPreprocessor>\n",
"html_exporter._preprocessors"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To enable it we will use IPython configuration/Traitlets system. If you are have already set some IPython configuration options, \n",
"this will look pretty familiar to you. Configuration option are always of the form:\n",
"\n",
Min RK
update nbconvert-as-library notebook...
r19938 " ClassName.attribute_name = value\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " \n",
Min RK
update nbconvert-as-library notebook...
r19938 "A few ways exist to create such config, like reading a config file in your profile, but you can also do it programatically usign a dictionary. Let's create such a config object, and see the difference if we pass it to our `HTMLExporter`"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 12,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"resources without the \"figures\" key :\n",
Min RK
update nbconvert-as-library notebook...
r19938 "['raw_mimetypes', 'inlining', 'metadata', 'output_extension']\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "Here we have one more field\n",
"['outputs', 'raw_mimetypes', 'inlining', 'metadata', 'output_extension']\n"
Brian E. Granger
Moving things around.
r17497 ]
},
{
Min RK
upate exmaple notebooks to nbformat v4
r18669 "data": {
"text/plain": [
Min RK
update nbconvert-as-library notebook...
r19938 "['output_5_0.png',\n",
" 'output_16_0.png',\n",
" 'output_13_1.png',\n",
" 'output_18_1.png',\n",
" 'output_3_0.png']"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 12,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.config import Config\n",
"\n",
"c = Config({\n",
Min RK
update nbconvert-as-library notebook...
r19938 " 'ExtractOutputPreprocessor':{'enabled':True}\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " })\n",
"\n",
Min RK
update nbconvert-as-library notebook...
r19938 "exportHTML = HTMLExporter()\n",
"exportHTML_and_figs = HTMLExporter(config=c)\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "(_, resources) = exportHTML.from_notebook_node(jake_notebook)\n",
"(_, resources_with_fig) = exportHTML_and_figs.from_notebook_node(jake_notebook)\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "print('resources without the \"figures\" key :')\n",
"print(list(resources))\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "print('')\n",
"print('Here we have one more field')\n",
"print(list(resources_with_fig))\n",
"list(resources_with_fig['outputs'])"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So now you can loop through the dict and write all those figures to disk in the right place... "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "#### Custom Preprocessor"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "Of course you can imagine many transformation that you would like to apply to a notebook. This is one of the reason we provide a way to register your own preprocessors that will be applied to the notebook after the default ones.\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "To do so you'll have to pass an ordered list of `Preprocessor`s to the Exporter constructor. \n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 "But what is an preprocessor ? Preprocessor can be either *decorated function* for dead-simple `Preprocessor`s that apply\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "independently to each cell, for more advance transformation that support configurability You have to inherit from\n",
Min RK
update nbconvert-as-library notebook...
r19938 "`Preprocessor` and define a `call` method as we'll see below.\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
"All transforers have a magic attribute that allows it to be activated/disactivate from the config dict."
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 13,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Four relevant docstring\n",
"=============================\n",
Min RK
update nbconvert-as-library notebook...
r19938 " A configurable preprocessor\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " Inherit from this class if you wish to have configurability for your\n",
Min RK
update nbconvert-as-library notebook...
r19938 " preprocessor.\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 " Any configurable traitlets this class exposed will be configurable in\n",
" profiles using c.SubClassName.attribute = value\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 " you can overwrite :meth:`preprocess_cell` to apply a transformation\n",
" independently on each cell or :meth:`preprocess` if you prefer your own\n",
" logic. See corresponding docstring for informations.\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
" Disabled by default and can be enabled via the config by\n",
Min RK
update nbconvert-as-library notebook...
r19938 " 'c.YourPreprocessorName.enabled = True'\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " \n",
"=============================\n",
"\n",
Min RK
update nbconvert-as-library notebook...
r19938 " Preprocessing to apply on each notebook.\n",
Brian E. Granger
Moving things around.
r17497 " \n",
Min RK
update nbconvert-as-library notebook...
r19938 " Must return modified nb, resources.\n",
" \n",
" If you wish to apply your preprocessing to each cell, you might want\n",
" to override preprocess_cell method instead.\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " \n",
" Parameters\n",
" ----------\n",
" nb : NotebookNode\n",
" Notebook being converted\n",
" resources : dictionary\n",
" Additional resources used in the conversion process. Allows\n",
Min RK
update nbconvert-as-library notebook...
r19938 " preprocessors to pass variables into the Jinja engine.\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " \n",
"=============================\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
update nbconvert-as-library notebook...
r19938 " Override if you want to apply some preprocessing to each cell.\n",
" Must return modified cell and resource dictionary.\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " \n",
" Parameters\n",
" ----------\n",
" cell : NotebookNode cell\n",
" Notebook cell being processed\n",
" resources : dictionary\n",
" Additional resources used in the conversion process. Allows\n",
Min RK
update nbconvert-as-library notebook...
r19938 " preprocessors to pass variables into the Jinja engine.\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " index : int\n",
" Index of the cell being processed\n",
" \n",
"=============================\n"
Brian E. Granger
Moving things around.
r17497 ]
Min RK
upate exmaple notebooks to nbformat v4
r18669 }
],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "from IPython.nbconvert.preprocessors import Preprocessor\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "import IPython.config\n",
Min RK
update nbconvert-as-library notebook...
r19938 "print(\"Four relevant docstring\")\n",
"print('=============================')\n",
"print(Preprocessor.__doc__)\n",
"print('=============================')\n",
"print(Preprocessor.preprocess.__doc__)\n",
"print('=============================')\n",
"print(Preprocessor.preprocess_cell.__doc__)\n",
"print('=============================')"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"***\n",
Min RK
update nbconvert-as-library notebook...
r19938 "We don't provide convenient method to be aplied on each worksheet as the **data structure** for worksheet will be removed. (not the worksheet functionality, which is still on it's way)\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "***"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Example"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "I'll now demonstrate a specific example [requested](https://github.com/ipython/nbconvert/pull/137#issuecomment-18658235) while nbconvert 2 was being developed. The ability to exclude cell from the conversion process based on their index. \n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
"I'll let you imagin how to inject cell, if what you just want is to happend static content at the beginning/end of a notebook, plese refer to templating section, it will be much easier and cleaner."
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 14,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from IPython.utils.traitlets import Integer"
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 15,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "class PelicanSubCell(Preprocessor):\n",
" \"\"\"A Pelican specific preprocessor to remove somme of the cells of a notebook\"\"\"\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " \n",
" # I could also read the cells from nbc.metadata.pelican is someone wrote a JS extension\n",
" # But I'll stay with configurable value. \n",
" start = Integer(0, config=True, help=\"first cell of notebook to be converted\")\n",
" end = Integer(-1, config=True, help=\"last cell of notebook to be converted\")\n",
" \n",
Min RK
update nbconvert-as-library notebook...
r19938 " def preprocess(self, nb, resources):\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
" #nbc = deepcopy(nb)\n",
" nbc = nb\n",
Min RK
update nbconvert-as-library notebook...
r19938 " # don't print in real preprocessor !!!\n",
" print(\"I'll keep only cells from \", self.start, \"to \", self.end, \"\\n\\n\")\n",
" nbc.cells = nb.cells[self.start:self.end] \n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " return nbc, resources"
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 16,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# I create this on the fly, but this could be loaded from a DB, and config object support merging...\n",
Min RK
update nbconvert-as-library notebook...
r19938 "c = Config()\n",
"c.PelicanSubCell.enabled = True\n",
"c.PelicanSubCell.start = 4\n",
"c.PelicanSubCell.end = 6"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "I'm creating a pelican exporter that take `PelicanSubCell` extra preprocessors and a `config` object as parameter. This might seem redundant, but with configuration system you'll see that one can register an inactive preprocessor on all exporters and activate it at will form its config files and command line. "
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 17,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "pelican = RSTExporter(preprocessors=[PelicanSubCell], config=c)"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 18,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I'll keep only cells from 4 to 6 \n",
Brian E. Granger
Moving things around.
r17497 "\n",
"\n",
"\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "Sometimes when showing schematic plots, this is the type of figure I\n",
"want to display. But drawing it by hand is a pain: I'd rather just use\n",
"matplotlib. The problem is, matplotlib is a bit too precise. Attempting\n",
"to duplicate this figure in matplotlib leads to something like this:\n",
Min RK
update nbconvert-as-library notebook...
r19938 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 ".. code:: python\n",
Brian E. Granger
Moving things around.
r17497 "\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 " Image('http://jakevdp.github.com/figures/mpl_version.png')\n",
"\n",
"\n",
"\n",
".. image:: output_5_0.png\n",
"\n",
"\n",
"\n"
Brian E. Granger
Moving things around.
r17497 ]
Min RK
upate exmaple notebooks to nbformat v4
r18669 }
],
"source": [
Min RK
update nbconvert-as-library notebook...
r19938 "print(pelican.from_notebook_node(jake_notebook)[0])"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Programatically make templates"
]
},
{
"cell_type": "code",
Min RK
update nbconvert-as-library notebook...
r19938 "execution_count": 19,
Min RK
upate exmaple notebooks to nbformat v4
r18669 "metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
Min RK
update nbconvert-as-library notebook...
r19938 "</div>\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "</div>\n",
"FOOOOOOOOTEEEEER\n",
"\n"
Brian E. Granger
Moving things around.
r17497 ]
}
],
Min RK
upate exmaple notebooks to nbformat v4
r18669 "source": [
"from jinja2 import DictLoader\n",
"\n",
Min RK
update nbconvert-as-library notebook...
r19938 "dl = DictLoader({'full.tpl': \n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\"\"\"\n",
Min RK
update nbconvert-as-library notebook...
r19938 "{%- extends 'basic.tpl' -%} \n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "\n",
"{% block footer %}\n",
"FOOOOOOOOTEEEEER\n",
"{% endblock footer %}\n",
"\"\"\"})\n",
"\n",
"\n",
Min RK
update nbconvert-as-library notebook...
r19938 "exportHTML = HTMLExporter(extra_loaders=[dl])\n",
"(body,resources) = exportHTML.from_notebook_node(jake_notebook)\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "for l in body.split('\\n')[-4:]:\n",
Min RK
update nbconvert-as-library notebook...
r19938 " print(l)"
Min RK
upate exmaple notebooks to nbformat v4
r18669 ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Real World Use"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"@jakevdp use Pelican and IPython Notebook to blog. Pelican [Will use](https://github.com/getpelican/pelican-plugins/pull/21) nbconvert programatically to generate blog post. Have a look a [Pythonic Preambulations](http://jakevdp.github.io/) for Jake blog post."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"@damianavila Wrote a Nicholas Plugin to [Write blog post as Notebook](http://www.damian.oquanta.info/posts/one-line-deployment-of-your-site-to-gh-pages.html) and is developping a js-extension to publish notebooks in one click from the web app."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<center>\n",
Min RK
update nbconvert-as-library notebook...
r19938 "<blockquote class=\"twitter-tweet\"><p>As <a href=\"https://twitter.com/Mbussonn\">@Mbussonn</a> requested... easieeeeer! Deploy your Nikola site with just a click in the IPython notebook! <a href=\"http://t.co/860sJunZvj\">http://t.co/860sJunZvj</a> cc <a href=\"https://twitter.com/ralsina\">@ralsina</a></p>&mdash; Damián Avila (@damian_avila) <a href=\"https://twitter.com/damian_avila/statuses/370306057828335616\">August 21, 2013</a></blockquote>\n",
Min RK
upate exmaple notebooks to nbformat v4
r18669 "</center>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And finaly, what you just did, is replicate what [nbviewer](http://nbviewer.ipython.org) does. WHich to fetch a notebook from url, convert it and send in back to you as a static html."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### A few gotchas"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Jinja blocks use `{% %}`by default which does not play nicely with $\\LaTeX$, hence thoses are replaced by `((* *))` in latex templates."
]
Brian E. Granger
Moving things around.
r17497 }
Min RK
upate exmaple notebooks to nbformat v4
r18669 ],
Min RK
update nbconvert-as-library notebook...
r19938 "metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.4.2"
}
},
Min RK
upate exmaple notebooks to nbformat v4
r18669 "nbformat": 4,
"nbformat_minor": 0
Brian E. Granger
Moving things around.
r17497 }