pax_global_header00006660000000000000000000000064131536160560014520gustar00rootroot0000000000000052 comment=d0f2b32ca5d4e2a34ae9509911df78dc03e442ef nbconvert-5.3.1/000077500000000000000000000000001315361605600135265ustar00rootroot00000000000000nbconvert-5.3.1/.gitignore000066400000000000000000000006351315361605600155220ustar00rootroot00000000000000MANIFEST build dist _build docs/man/*.gz docs/source/api/generated docs/source/config/options docs/source/interactive/magics-generated.txt docs/gh-pages nbconvert/resources/style.min.css *.py[co] __pycache__ *.egg-info *~ *.bak .ipynb_checkpoints .tox .DS_Store \#*# .#* .coverage* htmlcov .cache docs/source/*.tpl docs/source/config_options.rst # Eclipse pollutes the filesystem .project .pydevproject .settings nbconvert-5.3.1/.mailmap000066400000000000000000000250671315361605600151610ustar00rootroot00000000000000A. J. Holyoake ajholyoake Aaron Culich Aaron Culich Aron Ahmadia ahmadia Benjamin Ragan-Kelley Benjamin Ragan-Kelley Min RK Benjamin Ragan-Kelley MinRK Barry Wark Barry Wark Ben Edwards Ben Edwards Bradley M. Froehle Bradley M. Froehle Bradley M. Froehle Bradley Froehle Brandon Parsons Brandon Parsons Brian E. Granger Brian Granger Brian E. Granger Brian Granger <> Brian E. Granger bgranger <> Brian E. Granger bgranger Christoph Gohlke cgohlke Cyrille Rossant rossant Damián Avila damianavila Damián Avila damianavila Damon Allen damontallen Darren Dale darren.dale <> Darren Dale Darren Dale <> Dav Clark Dav Clark <> Dav Clark Dav Clark David Hirschfeld dhirschfeld David P. Sanders David P. Sanders David Warde-Farley David Warde-Farley <> Doug Blank Doug Blank Eugene Van den Bulke Eugene Van den Bulke Evan Patterson Evan Patterson Evan Patterson Evan Patterson Evan Patterson epatters Evan Patterson epatters Ernie French Ernie French Ernie French ernie french Ernie French ernop Fernando Perez Fernando Perez Fernando Perez Fernando Perez fperez <> Fernando Perez fptest <> Fernando Perez fptest1 <> Fernando Perez Fernando Perez Fernando Perez Fernando Perez <> Fernando Perez Fernando Perez Frank Murphy Frank Murphy Gabriel Becker gmbecker Gael Varoquaux gael.varoquaux <> Gael Varoquaux gvaroquaux Gael Varoquaux Gael Varoquaux <> Ingolf Becker watercrossing Jake Vanderplas Jake Vanderplas Jakob Gager jakobgager Jakob Gager jakobgager Jakob Gager jakobgager Jason Grout Jason Grout Jason Gors jason gors Jason Gors jgors Jens Hedegaard Nielsen Jens Hedegaard Nielsen Jens Hedegaard Nielsen Jens H Nielsen Jens Hedegaard Nielsen Jens H. Nielsen Jez Ng Jez Ng Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic jon Jonathan Frederic U-Jon-PC\Jon Jonathan March Jonathan March Jonathan March jdmarch Jörgen Stenarson Jörgen Stenarson Jörgen Stenarson Jorgen Stenarson Jörgen Stenarson Jorgen Stenarson <> Jörgen Stenarson jstenar Jörgen Stenarson jstenar <> Jörgen Stenarson Jörgen Stenarson Juergen Hasch juhasch Juergen Hasch juhasch Julia Evans Julia Evans Kester Tong KesterTong Kyle Kelley Kyle Kelley Kyle Kelley rgbkrk Laurent Dufréchou Laurent Dufréchou Laurent Dufréchou laurent dufrechou <> Laurent Dufréchou laurent.dufrechou <> Laurent Dufréchou Laurent Dufrechou <> Laurent Dufréchou laurent.dufrechou@gmail.com <> Laurent Dufréchou ldufrechou Lorena Pantano Lorena Luis Pedro Coelho Luis Pedro Coelho Marc Molla marcmolla Martín Gaitán Martín Gaitán Matthias Bussonnier Matthias BUSSONNIER Matthias Bussonnier Bussonnier Matthias Matthias Bussonnier Matthias BUSSONNIER Matthias Bussonnier Matthias Bussonnier Michael Droettboom Michael Droettboom Nicholas Bollweg Nicholas Bollweg (Nick) Nicolas Rougier Nikolay Koldunov Nikolay Koldunov Omar Andrés Zapata Mesa Omar Andres Zapata Mesa Omar Andrés Zapata Mesa Omar Andres Zapata Mesa Pankaj Pandey Pankaj Pandey Pascal Schetelat pascal-schetelat Paul Ivanov Paul Ivanov Pauli Virtanen Pauli Virtanen <> Pauli Virtanen Pauli Virtanen Pierre Gerold Pierre Gerold Pietro Berkes Pietro Berkes Piti Ongmongkolkul piti118 Prabhu Ramachandran Prabhu Ramachandran <> Puneeth Chaganti Puneeth Chaganti Robert Kern rkern <> Robert Kern Robert Kern Robert Kern Robert Kern Robert Kern Robert Kern <> Robert Marchman Robert Marchman Satrajit Ghosh Satrajit Ghosh Satrajit Ghosh Satrajit Ghosh Scott Sanderson Scott Sanderson smithj1 smithj1 smithj1 smithj1 Steven Johnson stevenJohnson Steven Silvester blink1073 S. Weber s8weber Stefan van der Walt Stefan van der Walt Silvia Vinyes Silvia Silvia Vinyes silviav12 Sylvain Corlay Sylvain Corlay sylvain.corlay Ted Drain TD22057 Théophile Studer Théophile Studer Thomas Kluyver Thomas Thomas Spura Thomas Spura Timo Paulssen timo vds vds2212 vds vds Ville M. Vainio Ville M. Vainio ville Ville M. Vainio ville Ville M. Vainio vivainio <> Ville M. Vainio Ville M. Vainio Ville M. Vainio Ville M. Vainio Walter Doerwald walter.doerwald <> Walter Doerwald Walter Doerwald <> W. Trevor King W. Trevor King Yoval P. y-p nbconvert-5.3.1/.travis.yml000066400000000000000000000024671315361605600156500ustar00rootroot00000000000000# Use a newer travis environment: # https://docs.travis-ci.com/user/trusty-ci-environment/ # needs these two lines: sudo: required dist: trusty language: python python: - "nightly" - 3.6 - 3.5 - 3.4 - 3.3 - 2.7 env: global: - PATH=$TRAVIS_BUILD_DIR/bin:$PATH addons: apt: packages: - texlive-latex-extra # we need this for all the latex package we use, recommended is not enough - texlive-generic-recommended # .. and more ... - latex-xcolor # ... and more latex packages - texlive-fonts-recommended # fonts... - cm-super # more fonts - texlive-xetex # latex to pdf converter - inkscape # for svgs in pdf output before_install: - git clone --quiet --depth 1 https://github.com/minrk/travis-wheels travis-wheels install: - wget https://github.com/jgm/pandoc/releases/download/1.19.1/pandoc-1.19.1-1-amd64.deb && sudo dpkg -i pandoc-1.19.1-1-amd64.deb - pip install --upgrade setuptools pip - pip install -f travis-wheels/wheelhouse . codecov coverage - pip install nbconvert[execute,serve,test] - python -m ipykernel.kernelspec --user script: # cd so we test the install, not the repo - cd `mktemp -d` - py.test --cov nbconvert -v --pyargs nbconvert after_success: - codecov matrix: allow_failures: - python: "nightly" nbconvert-5.3.1/CONTRIBUTING.md000066400000000000000000000013321315361605600157560ustar00rootroot00000000000000# Contributing We follow the [Jupyter Contribution Workflow](https://jupyter.readthedocs.io/en/latest/contributor/content-contributor.html) and the [IPython Contributing Guide](https://github.com/ipython/ipython/blob/master/CONTRIBUTING.md). # Testing In order to test all the features of nbconvert you need to have `pandoc` and `TexLive` installed. In your environment `pip install nbconvert[all]` will be needed to be able to run all of the tests and to test all of the features. If you only want to run some of the tests run `pip install nbconvert[test]`. # Releasing If you are going to release a version of `nbconvert` you should also be capable of testing it. Please follow the instructions in [Testing](#testing). nbconvert-5.3.1/LICENSE000066400000000000000000000055101315361605600145340ustar00rootroot00000000000000# Licensing terms This project is licensed under the terms of the Modified BSD License (also known as New or Revised or 3-Clause BSD), as follows: - Copyright (c) 2001-2015, IPython Development Team - Copyright (c) 2015-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Jupyter Development Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## About the Jupyter Development Team The Jupyter Development Team is the set of all contributors to the Jupyter project. This includes all of the Jupyter subprojects. The core team that coordinates development on GitHub can be found here: https://github.com/jupyter/. ## Our Copyright Policy Jupyter uses a shared copyright model. Each contributor maintains copyright over their contributions to Jupyter. But, it is important to note that these contributions are typically only changes to the repositories. Thus, the Jupyter source code, in its entirety is not the copyright of any single person or institution. Instead, it is the collective copyright of the entire Jupyter Development Team. If individual contributors want to maintain a record of what changes/contributions they have specific copyright on, they should indicate their copyright in the commit message of the change, when they commit the change to one of the Jupyter repositories. With this in mind, the following banner should be used in any source code file to indicate the copyright and license terms: # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. nbconvert-5.3.1/MANIFEST.in000066400000000000000000000006011315361605600152610ustar00rootroot00000000000000include LICENSE include CONTRIBUTING.md include README.md # Documentation graft docs exclude docs/\#* # Examples graft examples graft scripts # docs subdirs we want to skip prune docs/build prune docs/gh-pages prune docs/dist # Patterns to exclude from any directory global-exclude *~ global-exclude *.pyc global-exclude *.pyo global-exclude .git global-exclude .ipynb_checkpoints nbconvert-5.3.1/README.md000066400000000000000000000051621315361605600150110ustar00rootroot00000000000000# nbconvert ### Jupyter Notebook Conversion [![Google Group](https://img.shields.io/badge/-Google%20Group-lightgrey.svg)](https://groups.google.com/forum/#!forum/jupyter) [![Build Status](https://travis-ci.org/jupyter/nbconvert.svg?branch=master)](https://travis-ci.org/jupyter/nbconvert) [![Documentation Status](https://readthedocs.org/projects/nbconvert/badge/?version=latest)](https://nbconvert.readthedocs.io/en/latest/?badge=latest) [![Documentation Status](https://readthedocs.org/projects/nbconvert/badge/?version=stable)](http://nbconvert.readthedocs.io/en/stable/?badge=stable) [![codecov.io](https://codecov.io/github/jupyter/nbconvert/coverage.svg?branch=master)](https://codecov.io/github/jupyter/nbconvert?branch=master) The **nbconvert** tool, `jupyter nbconvert`, converts notebooks to various other formats via [Jinja][] templates. The nbconvert tool allows you to convert an `.ipynb` notebook file into various static formats including: * HTML * LaTeX * PDF * Reveal JS * Markdown (md) * ReStructured Text (rst) * executable script ## Usage From the command line, use nbconvert to convert a Jupyter notebook (*input*) to a a different format (*output*). The basic command structure is: $ jupyter nbconvert --to where `` is the desired output format and `` is the filename of the Jupyter notebook. ### Example: Convert a notebook to HTML Convert Juptyer notebook file, `mynotebook.ipynb`, to HTML using: $ jupyter nbconvert --to html mynotebook.ipynb This command creates an HTML output file named `mynotebook.html`. ## Dev Install Check if pandoc is installed (``pandoc --version``); if needed, install: ``` sudo apt-get install pandoc ``` Or ``` brew install pandoc ``` Install nbconvert for development using: ``` git clone https://github.com/jupyter/nbconvert.git cd nbconvert pip install -e . ``` Running the tests after a dev install above: ``` pip install nbconvert[test] py.test --pyargs nbconvert ``` ## Resources - [Documentation for Jupyter nbconvert](https://nbconvert.readthedocs.io/en/latest/) [[PDF](https://media.readthedocs.org/pdf/nbconvert/latest/nbconvert.pdf)] - [nbconvert examples on GitHub](https://github.com/jupyter/nbconvert-examples) - [Issues](https://github.com/jupyter/nbconvert/issues) - [Technical support - Jupyter Google Group](https://groups.google.com/forum/#!forum/jupyter) - [Project Jupyter website](https://jupyter.org) - [Documentation for Project Jupyter](https://jupyter.readthedocs.io/en/latest/index.html) [[PDF](https://media.readthedocs.org/pdf/jupyter/latest/jupyter.pdf)] [Jinja]: http://jinja.pocoo.org/ nbconvert-5.3.1/codecov.yml000066400000000000000000000002261315361605600156730ustar00rootroot00000000000000coverage: status: project: default: target: auto threshold: 10 patch: default: target: 0% comments: off nbconvert-5.3.1/docs/000077500000000000000000000000001315361605600144565ustar00rootroot00000000000000nbconvert-5.3.1/docs/Makefile000066400000000000000000000166001315361605600161210ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " applehelp to make an Apple Help Book" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* html: source/config_options.rst $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." source/config_options.rst: python3 autogen_config.py @echo "Created docs for config options" dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/nbconvert.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/nbconvert.qhc" applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @echo @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." @echo "N.B. You won't be able to view it unless you put it in" \ "~/Library/Documentation/Help or install it in your application" \ "bundle." devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/nbconvert" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/nbconvert" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." coverage: $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage @echo "Testing of coverage in the sources finished, look at the " \ "results in $(BUILDDIR)/coverage/python.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." nbconvert-5.3.1/docs/README.md000066400000000000000000000026061315361605600157410ustar00rootroot00000000000000# Documenting nbconvert [Documentation for `nbconvert`](https://nbconvert.readthedocs.io/en/latest/) is hosted on ReadTheDocs. ## Build Documentation locally 1. Change directory to documentation root: $ cd docs 2. Create conda env (and install relevant dependencies): $ conda env create -f environment.yml 3. Activate the newly built conda environment `nbconvert_docs` $ source activate nbconvert_docs 4. Create an editable install for nbconvert using $ pip install -e ../. or if you want, `cd ..` and `pip install . -e`. But then you will need to `cd docs` before continuing to the next step. 5. Build documentation using Makefile for Linux and OS X: $ make html or on Windows: $ make.bat html 6. Display the documentation locally by navigating to ``build/html/index.html`` in your browser: Or alternatively you may run a local server to display the docs. In Python 3: $ python -m http.server 8000 In your browser, go to `http://localhost:8000`. ## Developing Documentation ### Helpful files and directories * `conf.py` - Sphinx build configuration file * `source` directory - source for documentation * `source/api` directory - source files for generated API documentation * `autogen_config.py` - Generates configuration of ipynb source files to rst * `index.rst` - Main landing page of the Sphinx documentation nbconvert-5.3.1/docs/autogen_config.py000066400000000000000000000015601315361605600200210ustar00rootroot00000000000000#!/usr/bin/env python """ autogen_config.py Create config_options.rst, a Sphinx documentation source file. Documents the options that may be set in nbconvert's configuration file, jupyter_nbconvert_config.py. """ import os.path from nbconvert.nbconvertapp import NbConvertApp header = """\ .. This is an automatically generated file. .. do not modify by hand. Configuration options ===================== Configuration options may be set in a file, ``~/.jupyter/jupyter_nbconvert_config.py``, or at the command line when starting nbconvert, i.e. ``jupyter nbconvert --Application.log_level=10``. """ try: indir = os.path.dirname(__file__) except NameError: indir = os.path.dirname(os.getcwd()) destination = os.path.join(indir, 'source/config_options.rst') with open(destination, 'w') as f: f.write(header) f.write(NbConvertApp().document_config_options()) nbconvert-5.3.1/docs/environment.yml000066400000000000000000000003231315361605600175430ustar00rootroot00000000000000name: nbconvert_docs channels: - conda-forge dependencies: - python==3.5 - pandoc - nbformat - jupyter_client - ipython - sphinx>=1.5.1 - sphinx_rtd_theme - tornado - entrypoints - pip: - nbsphinx>=0.2.12 nbconvert-5.3.1/docs/make.bat000066400000000000000000000161331315361605600160670ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source set I18NSPHINXOPTS=%SPHINXOPTS% source if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled echo. coverage to run coverage check of the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) REM Check if sphinx-build is available and fallback to Python version if any %SPHINXBUILD% 2> nul if errorlevel 9009 goto sphinx_python goto sphinx_ok :sphinx_python set SPHINXBUILD=python -m sphinx.__init__ %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) :sphinx_ok if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\nbconvert.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\nbconvert.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "coverage" ( %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage if errorlevel 1 exit /b 1 echo. echo.Testing of coverage in the sources finished, look at the ^ results in %BUILDDIR%/coverage/python.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end nbconvert-5.3.1/docs/source/000077500000000000000000000000001315361605600157565ustar00rootroot00000000000000nbconvert-5.3.1/docs/source/_static/000077500000000000000000000000001315361605600174045ustar00rootroot00000000000000nbconvert-5.3.1/docs/source/_static/empty.txt000066400000000000000000000000001315361605600212710ustar00rootroot00000000000000nbconvert-5.3.1/docs/source/api/000077500000000000000000000000001315361605600165275ustar00rootroot00000000000000nbconvert-5.3.1/docs/source/api/exporters.rst000066400000000000000000000024101315361605600213110ustar00rootroot00000000000000Exporters ========= .. module:: nbconvert.exporters .. seealso:: :doc:`/config_options` Configurable options for the nbconvert application .. autofunction:: export .. autofunction:: get_exporter .. autofunction:: get_export_names Exporter base classes --------------------- .. autoclass:: Exporter .. automethod:: __init__ .. automethod:: from_notebook_node .. automethod:: from_filename .. automethod:: from_file .. automethod:: register_preprocessor .. autoclass:: TemplateExporter .. automethod:: __init__ .. automethod:: from_notebook_node .. automethod:: from_filename .. automethod:: from_file .. automethod:: register_preprocessor .. automethod:: register_filter Specialized exporter classes ---------------------------- The :class:`~nbconvert.exporters.NotebookExporter` inherits directly from :class:`~nbconvert.exporters.Exporter`, while the other exporters listed here inherit either directly or indirectly from :class:`~nbconvert.exporters.TemplateExporter`. .. autoclass:: NotebookExporter .. autoclass:: HTMLExporter .. autoclass:: SlidesExporter .. autoclass:: LatexExporter .. autoclass:: MarkdownExporter .. autoclass:: PDFExporter .. autoclass:: PythonExporter .. autoclass:: RSTExporter nbconvert-5.3.1/docs/source/api/filters.rst000066400000000000000000000025101315361605600207270ustar00rootroot00000000000000Filters ======= Filters are for use with the :class:`~nbconvert.exporters.TemplateExporter` exporter. They provide a way for you transform notebook contents to a particular format depending on the template you are using. For example, when converting to HTML, you would want to use the :func:`~nbconvert.filters.ansi2html` function to convert ANSI colors (from e.g. a terminal traceback) to HTML colors. .. seealso:: :doc:`/api/exporters` API documentation for the various exporter classes .. module:: nbconvert.filters .. autofunction:: add_anchor .. autofunction:: add_prompts .. autofunction:: ansi2html .. autofunction:: ansi2latex .. autofunction:: ascii_only .. autofunction:: citation2latex .. autofunction:: comment_lines .. autofunction:: escape_latex .. autoclass:: DataTypeFilter .. autofunction:: get_lines .. autofunction:: convert_pandoc .. autoclass:: Highlight2HTML .. autoclass:: Highlight2Latex .. autofunction:: html2text .. autofunction:: indent .. autofunction:: ipython2python .. autofunction:: markdown2html .. autofunction:: markdown2latex .. autofunction:: markdown2rst .. autofunction:: path2url .. autofunction:: posix_path .. autofunction:: prevent_list_blocks .. autofunction:: strip_ansi .. autofunction:: strip_dollars .. autofunction:: strip_files_prefix .. autofunction:: wrap_text nbconvert-5.3.1/docs/source/api/index.rst000066400000000000000000000003421315361605600203670ustar00rootroot00000000000000Python API for working with nbconvert ===================================== .. module:: nbconvert Contents: .. toctree:: :maxdepth: 2 nbconvertapp exporters preprocessors filters writers postprocessorsnbconvert-5.3.1/docs/source/api/nbconvertapp.rst000066400000000000000000000007571315361605600217730ustar00rootroot00000000000000NbConvertApp ============ .. module:: nbconvert.nbconvertapp .. seealso:: :doc:`/config_options` Configurable options for the nbconvert application .. autoclass:: NbConvertApp .. automethod:: init_notebooks .. automethod:: convert_notebooks .. automethod:: convert_single_notebook .. automethod:: init_single_notebook_resources .. automethod:: export_single_notebook .. automethod:: write_single_notebook .. automethod:: postprocess_single_notebooknbconvert-5.3.1/docs/source/api/postprocessors.rst000066400000000000000000000005431315361605600223730ustar00rootroot00000000000000Postprocessors ============== .. module:: nbconvert.postprocessors .. seealso:: :doc:`/config_options` Configurable options for the nbconvert application .. autoclass:: PostProcessorBase .. automethod:: postprocess Specialized postprocessors -------------------------- .. autoclass:: ServePostProcessor .. automethod:: postprocess nbconvert-5.3.1/docs/source/api/preprocessors.rst000066400000000000000000000013561315361605600221770ustar00rootroot00000000000000Preprocessors ============= .. module:: nbconvert.preprocessors .. seealso:: :doc:`/config_options` Configurable options for the nbconvert application .. autoclass:: Preprocessor .. automethod:: __init__ .. automethod:: preprocess .. automethod:: preprocess_cell Specialized preprocessors ------------------------- .. autoclass:: ConvertFiguresPreprocessor .. autoclass:: SVG2PDFPreprocessor .. autoclass:: ExtractOutputPreprocessor .. autoclass:: LatexPreprocessor .. autoclass:: CSSHTMLHeaderPreprocessor .. autoclass:: HighlightMagicsPreprocessor .. autoclass:: ClearOutputPreprocessor .. autoclass:: RegexRemovePreprocessor .. autoclass:: ExecutePreprocessor :members: .. autofunction:: coalesce_streams nbconvert-5.3.1/docs/source/api/writers.rst000066400000000000000000000005411315361605600207600ustar00rootroot00000000000000Writers ======= .. module:: nbconvert.writers .. seealso:: :doc:`/config_options` Configurable options for the nbconvert application .. autoclass:: WriterBase .. automethod:: __init__ .. automethod:: write Specialized writers ------------------- .. autoclass:: DebugWriter .. autoclass:: FilesWriter .. autoclass:: StdoutWriternbconvert-5.3.1/docs/source/architecture.rst000066400000000000000000000173121315361605600211760ustar00rootroot00000000000000.. _architecture: ========================= Architecture of nbconvert ========================= This is a high-level outline of the basic workflow, structures and objects in nbconvert. Specifically, this exposition has a two-fold goal: #. to alert you to the affordances available for customisation or direct contributions #. to provide a map of where and when different events occur, which should aid in tracking down bugs. A detailed pipeline exploration =============================== Nbconvert takes in a notebook, which is a JSON object, and operates on that object. This can include operations that take a notebook and return a notebook. For example, that operation could be to execute the notebook as though it were a continuous script; if it were executed ``--in-place`` then it would overwite the current notebook. Or it could be that we wish to systematically alter the notebook, for example by clearing all output cells. Format agnostic operations on cell content that do not violate the nbformat spec can be interpreted as a notebook to notebook conversion step; such operations can be performed as part of the preprocessing step. But often we want to have the notebook's structured content in a different format. Importantly, in many cases the structure of the notebook should be reflected in the structure of the output, adapted to the output's format. For that purpose, the original JSON structure of the document is crucial scaffolding needed to support this kind of structured output. In order to maintain structured, it can be useful to apply our conversion programmatically on the structure itself. To do so, when converting to formats other than the notebook, we use the `jinja`_ templating engine. The basic unit of structure in a notebook is the cell. Accordingly, since our templating engine is capable of expressing structure, the basic unit in our templates will often be specified at the cell level. Each cell has a certain type; the three most important cell types for our purposes are code, markdown, and raw NbConvert. Code cells can be split further into their input and their output. Operations can also occur separately on input and output and their respective subcomponents. Markdown cells and raw NbConvert cells do not have analogous substructure. The template's structure then can be seen as a mechanism for selecting content on which to operate. Because the template operates on individual cells, this has some upsides and drawbacks. One upside is that this allows the template to have access to the individual cell's metadata, which enables intelligently transforming the appropriate content. The transformations occur as a series of replacement rules and filters. For many purposes these filters take the form of external calls to `pandoc`_, which is a utility for converting between many different document formats. One downside is that this makes operations that require global coördination (e.g., cross referencing across cells) somewhat challenging to implement as filters inside templates. Note that all that we've described is happening in memory. This is crucial in order to ensure that this functionality is available when writing files is more challenging. Nonetheless, the reason for using nbconvert almost always involves producing some kind of output file. We take the in-memory object and write a file appropriate for the output type. The entirety of heretofore described process can be described as part of an ``Exporter``. ``Exporter``\s often involves ``Preprocessor``\s, ``filters``, ``templates`` and ``Writer``\s. These classes and functions are described in greater detail below. Finally, one can apply a ``Postprocessor`` after the writing has occurred. For example, it is common when converting to slides to start a webserver and open a browser window with the newly created document (``--to slides --post serve``). Classes ======= .. _exporters: Exporters --------- The primary class in nbconvert is the :class:`.Exporter`. Exporters encapsulate the operation of turning a notebook into another format. There is one Exporter for each format supported in nbconvert. The first thing an Exporter does is load a notebook, usually from a file via :mod:`nbformat`. Most of what a typical Exporter does is select and configure preprocessors, filters, and templates. If you want to convert notebooks to additional formats, a new Exporter is probably what you are looking for. .. seealso:: :ref:`Writing a custom Exporter ` Once the notebook is loaded, it is preprocessed... .. _preprocessors: Preprocessors ------------- A :class:`.Preprocessor` is an object that transforms the content of the notebook to be exported. The result of a preprocessor being applied to a notebook is always a notebook. These operations include re-executing the cells, stripping output, removing bundled outputs to separate files, etc. If you want to add operations that modify a notebook before exporting, a preprocessor is the place to start. .. seealso:: `Custom Preprocessors `_ Once a notebook is preprocessed, it's time to convert the notebook into the destination format. .. _templates_and_filters: Templates and Filters --------------------- Most Exporters in nbconvert are a subclass of :class:`.TemplateExporter`, which means they use a `jinja`_ template to render a notebook into the destination format. If you want to change how an exported notebook looks in an existing format, a custom template is the place to start. A jinja template is composed of blocks that look like this (taken from nbconvert's default html template): .. sourcecode:: html {% block stream_stdout -%}
    {{- output.text | ansi2html -}}
    
{%- endblock stream_stdout %} This block determines how text output on ``stdout`` is displayed in HTML. The ``{{- output.text | ansi2html -}}`` bit means "Take the output text and pass it through ansi2html, then include the result here." In this example, ``ansi2html`` is a `filter`_. Filters are a jinja concept; they are Python callables which take something (typically text) as an input, and produce a text output. If you want to perform new or more complex transformations of particular outputs, a filter may be what you need. Typically, filters are pure functions. However, if you have a filter that itself requires some configuration, it can be an instance of a callable, configurable class. .. seealso:: - :doc:`customizing` - :ref:`jinja:filters` Once it has passed through the template, an Exporter is done with the notebook, and returns the file data. At this point, we have the file data as text or bytes and we can decide where it should end up. When you are using nbconvert as a library, as opposed to the command-line application, this is typically where you would stop, take your exported data, and go on your way. .. _writers: Writers ------- A :class:`.Writer` takes care of writing the resulting file(s) where they should end up. There are two basic Writers in nbconvert: 1. stdout - writes the result to stdout (for pipe-style workflows) 2. Files (default) - writes the result to the filesystem Once the output is written, nbconvert has done its job. .. _postprocessors: Postprocessors -------------- A :class:`.Postprocessor` is something that runs after everything is exported and written to the filesystem. The only postprocessor in nbconvert at this point is the :class:`.ServePostProcessor`, which is used for serving `reveal.js`_ HTML slideshows. .. links: .. _jinja: http://jinja.pocoo.org/ .. _filter: http://jinja.pocoo.org/docs/dev/templates/#filters .. _reveal.js: http://lab.hakim.se/reveal-js .. _pandoc: http://pandoc.org/ nbconvert-5.3.1/docs/source/changelog.rst000066400000000000000000000232011315361605600204350ustar00rootroot00000000000000.. _changelog: ==================== Changes in nbconvert ==================== 5.3.1 ----- `5.3.1 on Github `__ - MANIFEST.in updated to include ``LICENSE`` and ``scripts/`` when creating sdist. #666 5.3 --- `5.3 on Github `__ Major features ~~~~~~~~~~~~~~ Tag Based Element Filtering +++++++++++++++++++++++++++ For removing individual elements we need a way to signal that, with this release we introduce the use of tags for that purpose. Tags are user-defined strings attached to cells or outputs. They are stored in cell or output metadata. For more on tags see the `nbformat docs on cell metadata `__. **Usage**: 1. Apply tags to the elements that you want to remove. For removing an entire cell, the cell input, or all cell outputs apply the tag to the cell. For removing individual outputs, put the tag in the output metadata using a call like ``display(your_output_element, metadata={tags=[]})``. *NB*: Use different tags depending on whether you want to remove the entire cell, the input, all outputs, or individual outputs. 2. Add the tags for removing the different kinds of elements to the following traitlets. Which kind of element you want to remove determines which traitlet you add the tags to. The following traitlets remove elements of different kinds: - ``remove_cell_tags``: removes cells - ``remove_input_tags``: removes inputs - ``remove_all_outputs_tag``: removes all outputs - ``remove_single_output_tag``: removes individual outputs Comprehensive notes ~~~~~~~~~~~~~~~~~~~ - new: configurable ``browser`` in ServePostProcessor #618 - new: ``--clear-output`` command line flag to clear output in-place #619 - new: remove elements based on tags with ``TagRemovePreprocessor``. #640, #643 - new: CellExecutionError can now be imported from ``nbconvert.preprocessors`` #656 - new: slides now can enable scrolling and custom transitions #600 - docs: Release instructions for nbviewer-deploy - docs: improved instructions for handling errors using the ``ExecutePreprocessor`` #656 - tests: better height/width metadata testing for images in rst & html #601 #602 - tests: normalise base64 output data to avoid false positives #650 - tests: normalise ipython traceback messages to handle old and new style #631 - bug: mathjax obeys ``\\(\\)`` & ``\\[\\]`` (both nbconvert & pandoc) #609 #617 - bug: specify default templates using extensions #639 - bug: fix pandoc version number #638 - bug: require recent mistune version #630 - bug: catch errors from IPython ``execute_reply`` and ``error`` messages #642 - nose completely removed & dependency dropped #595 #660 - mathjax processing in mistune now only uses inline grammar #611 - removeRegex now enabled by default on all TemplateExporters, does not remove cells with outputs #616 - validate notebook after applying each preprocessor (allowing additional attributes) #645 - changed COPYING.md to LICENSE for more standard licensing that GitHub knows how to read #654 5.2.1 ----- `5.2 on GitHub `__ Major features ~~~~~~~~~~~~~~ In this release (along with the usual bugfixes and documentation improvements, which are legion) we have a few new major features that have been requested for a long time: Global Content Filtering ++++++++++++++++++++++++ You now have the ability to remove input or output from code cells, markdown cells and the input and output prompts. The easiest way to access all of these is by using traitlets like TemplateExporter.exclude_input = True (or, for example HTMLExporter.exclude_markdown = True if you wanted to make it specific to HTML output). On the command line if you just want to not have input or output prompts just use --no-prompt. Execute notebooks from a function +++++++++++++++++++++++++++++++++ You can now use the executenb function to execute notebooks as though you ran the execute preprocessor on the notebooks. It returns the standard notebook and resources options. Remove cells based on regex pattern +++++++++++++++++++++++++++++++++++ This removes cells based on their matching a regex pattern (by default, empty cells). This is the RegexRemovePreprocessor. Script exporter entrypoints for nonpython scripts +++++++++++++++++++++++++++++++++++++++++++++++++ Now there is an entrypoint for having an exporter specific to the type of script that is being exported. While designed for use with the IRkernel in particular (with a script exporter focused on exporting R scripts) other non-python kernels that wish to have a language specific exporter can now surface that directly. Comprehensive notes ~~~~~~~~~~~~~~~~~~~ - new: configurable ExecutePreprocessor.startup_timeout configurable #583 - new: RemoveCell preprocessor based on cell content (defaults to empty cell) #575 - new: function for executing notebooks: `executenb` #573 - new: global filtering to remove inputs, outputs, markdown cells (&c.), this works on all templates #554 - new: script exporter entrypoint #531 - new: configurable anchor link text (previously ¶) `HTMLExporter.anchor_link_text` #522 - new: configurable values for slides exporter #542 #558 - improved releases (how-to documentation, version-number generation and checking) #593 - doc improvements #593 #580 #565 #554 - language information from cell magics (for highlighting) is now included in more formats #586 - mathjax upgrades and cdn fixes #584 #567 - better CI #571 #540 - better traceback behaviour when execution errs #521 - deprecated nose test features removed #519 - bug fixed: we now respect width and height metadata on jpeg and png mimetype outputs #588 - bug fixed: now we respect the `resolve_references` filter in `report.tplx` #577 - bug fixed: output metadata now is removed by ClearOutputPreprocessor #569 - bug fixed: display id respected in execute preproessor #563 - bug fixed: dynamic defaults for optional jupyter_client import #559 - bug fixed: don't self-close non-void HTML tags #548 - buf fixed: upgrade jupyter_client dependency to 4.2 #539 - bug fixed: LaTeX output through md→LaTeX conversion shouldn't be touched #535 - bug fixed: now we escape `<` inside math formulas when converting to html #514 Credits ~~~~~~~ This release has been larger than previous releases. In it 33 authors contributed a total of 546 commits. Many thanks to the following individuals who contributed to this release (in alphabetical order): - Adam Chainz - Andreas Mueller - Bartosz T - Benjamin Ragan-Kelley - Carol Willing - Damián Avila - Elliot Marsden - Gao, Xiang - Jaeho Shin - Jan Schulz - Jeremy Kun - Jessica B. Hamrick - John B Nelson - juhasch - Livia Barazzetti - M Pacer - Matej Urbas - Matthias Bussonnier - Matthias Geier - Maximilian Albert - Michael Scott Cuthbert - Nicholas Bollweg - Paul Gowder - Paulo Villegas - Peter Parente - Philipp A - Scott Sanderson - Srinivas Reddy Thatiparthy - Sylvain Corlay - Thomas Kluyver - Till Hoffmann - Xiang Gao - YuviPanda 5.1.1 ----- `5.1.1 on GitHub `__ - fix version numbering because of incomplete previous version number 5.1 --- `5.1 on GitHub `__ - improved CSS (specifically tables, in line with notebook) #498 - improve in-memory templates handling #491 - test improvements #516 #509 #505 - new configuration option: IOPub timeout #513 - doc improvements #489 #500 #493 #506 - newly customizable: output prompt #500 - more python2/3 compatibile unicode handling #502 5.0 --- `5.0 on GitHub `__ - Use :command:`xelatex` by default for latex export, improving unicode and font support. - Use entrypoints internally to access Exporters, allowing for packages to declare custom exporters more easily. - New ASCIIDoc Exporter. - New preprocessor for sanitised html output. - New general ``convert_pandoc`` filter to reduce the need to hard-code lists of filters in templates. - Use pytest, nose dependency to be removed. - Refactored Exporter code to avoid ambiguity and cyclic dependencies. - Update to traitlets 4.2 API. - Fixes for Unicode errors when showing execution errors on Python 2. - Default math font matches default Palatino body text font. - General documentation improvements. For example, testing, installation, custom exporters. - Improved link handling for LaTeX output - Refactored the automatic id generation. - New kernel_manager_class configuration option for allowing systems to be set up to resolve kernels in different ways. - Kernel errors now will be logged for debugging purposes when executing notebooks. 4.3 --- `4.3 on GitHub `_ - added live widget rendering for html output, nbviewer by extension 4.2 --- `4.2 on GitHub `_ - :ref:`Custom Exporters ` can be provided by external packages, and registered with nbconvert via setuptools entrypoints. - allow nbconvert reading from stdin with ``--stdin`` option (write into ``notebook`` basename) - Various ANSI-escape fixes and improvements - Various LaTeX/PDF export fixes - Various fixes and improvements for executing notebooks with ``--execute``. 4.1 --- `4.1 on GitHub `_ - setuptools fixes for entrypoints on Windows - various fixes for exporters, including slides, latex, and PDF - fixes for exceptions met during execution - include markdown outputs in markdown/html exports 4.0 --- `4.0 on GitHub `_ nbconvert-5.3.1/docs/source/conf.py000066400000000000000000000251701315361605600172620ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # nbconvert documentation build configuration file, created by # sphinx-quickstart on Tue Jun 9 17:11:30 2015. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) if os.environ.get('READTHEDOCS', ''): # RTD doesn't use the repo's Makefile to build docs. We run # autogen_config.py to create the config docs (i.e. Configuration Options # page). import sys, subprocess # subprocess.run([sys.executable,'-m','pip','install','-e','../../.']) with open('../autogen_config.py') as f: exec(compile(f.read(), 'autogen_config.py', 'exec'), {}) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.napoleon', 'nbsphinx', 'IPython.sphinxext.ipython_console_highlighting', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] source_suffix = ['.rst', '.ipynb'] # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'nbconvert' from datetime import date year = date.today().year copyright = '2015-%s, Jupyter Development Team' % year author = 'Jupyter Development Team' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # Get information from _version.py and use it to generate version and release _version_py = '../../nbconvert/_version.py' version_ns = {} exec(compile(open(_version_py).read(), _version_py, 'exec'), version_ns) # The short X.Y version. version = '%i.%i' % version_ns['version_info'][:2] # The full version, including alpha/beta/rc tags. release = version_ns['__version__'] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['.ipynb_checkpoints', 'example.ipynb'] # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # Set on_rtd to whether we are building on readthedocs.org. We get this line of # code grabbed from docs.readthedocs.org on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if not on_rtd: # only import and set the theme if we're building docs locally import sphinx_rtd_theme html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # otherwise, readthedocs.org uses their default theme, so no need to specify it # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. #html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. #html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' #html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value #html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. #html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. htmlhelp_basename = 'nbconvertdoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', # Latex figure (float) alignment #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'nbconvert.tex', 'nbconvert Documentation', 'Jupyter Development Team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'nbconvert', 'nbconvert Documentation', [author], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'nbconvert', 'nbconvert Documentation', author, 'nbconvert', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('https://docs.python.org/3.5', None), 'jinja': ('http://jinja.pocoo.org/docs/dev', None), } nbconvert-5.3.1/docs/source/customizing.ipynb000066400000000000000000031055721315361605600214110ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Customizing nbconvert" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Under the hood, nbconvert uses [Jinja templates](https://jinja2.readthedocs.io/en/latest/intro.html) to specify how the notebooks should be formatted. These templates can be fully customized, allowing you to use nbconvert to create notebooks in different formats with different styles as well." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Converting a notebook to an (I)Python script and printing to stdout\n", "\n", "Out of the box, nbconvert can be used to convert notebooks to plain Python files. For example, the following command converts the `example.ipynb` notebook to Python and prints out the result:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[NbConvertApp] Converting notebook example.ipynb to python\n", "\n", "# coding: utf-8\n", "\n", "# # Example notebook\n", "\n", "# ### Markdown cells\n", "# \n", "# This is an example notebook that can be converted with `nbconvert` to different formats. This is an example of a markdown cell.\n", "\n", "# ### LaTeX Equations\n", "# \n", "# Here is an equation:\n", "# \n", "# $$\n", "# y = \\sin(x)\n", "# $$\n", "\n", "# ### Code cells\n", "\n", "# In[1]:\n", "\n", "\n", "print(\"This is a code cell that produces some output\")\n", "\n", "\n", "# ### Inline figures\n", "\n", "# In[1]:\n", "\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "plt.ion()\n", "\n", "x = np.linspace(0, 2 * np.pi, 100)\n", "y = np.sin(x)\n", "plt.plot(x, y)\n", "\n" ] } ], "source": [ "!jupyter nbconvert --to python 'example.ipynb' --stdout" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the code, you can see that non-code cells are also exported. If you wanted to change that behaviour, you would first look to nbconvert [configuration options page](./config_options.rst) to see if there is an option available that can give you your desired behaviour. \n", "\n", "In this case, if you wanted to remove code cells from the output, you could use the `TemplateExporter.exclude_markdown` traitlet directly, as below. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[NbConvertApp] Converting notebook example.ipynb to python\n", "\n", "# coding: utf-8\n", "\n", "# In[1]:\n", "\n", "\n", "print(\"This is a code cell that produces some output\")\n", "\n", "\n", "# In[1]:\n", "\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "plt.ion()\n", "\n", "x = np.linspace(0, 2 * np.pi, 100)\n", "y = np.sin(x)\n", "plt.plot(x, y)\n", "\n" ] } ], "source": [ "!jupyter nbconvert --to python 'example.ipynb' --stdout --TemplateExporter.exclude_markdown=True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Custom Templates \n", "\n", "As mentioned above, if you want to change this behavior, you can use a custom template. The custom template inherits from the Python template and overwrites the markdown blocks so that they are empty. \n", "\n", "Below is an example of a custom template, which we write to a file called `simplepython.tpl`. This template removes markdown cells from the output, and also changes how the execution count numbers are formatted:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting simplepython.tpl\n" ] } ], "source": [ "%%writefile simplepython.tpl\n", "\n", "{% extends 'python.tpl'%}\n", "\n", "## remove markdown cells\n", "{% block markdowncell -%}\n", "{% endblock markdowncell %}\n", "\n", "## change the appearance of execution count\n", "{% block in_prompt %}\n", "# [{{ cell.execution_count if cell.execution_count else ' ' }}]:\n", "{% endblock in_prompt %}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using this template, we see that the resulting Python code does not contain anything that was previously in a markdown cell, and only displays execution counts (i.e., `[#]:` not `In[#]:`):" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[NbConvertApp] Converting notebook example.ipynb to python\n", "\n", "\n", "# coding: utf-8\n", "\n", "# [1]:\n", "\n", "print(\"This is a code cell that produces some output\")\n", "\n", "\n", "# [1]:\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "plt.ion()\n", "\n", "x = np.linspace(0, 2 * np.pi, 100)\n", "y = np.sin(x)\n", "plt.plot(x, y)\n", "\n" ] } ], "source": [ "!jupyter nbconvert --to python 'example.ipynb' --stdout --template=simplepython.tpl" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Template structure\n", "\n", "Nbconvert templates consist of a set of nested blocks. When defining a new\n", "template, you extend an existing template by overriding some of the blocks.\n", "\n", "All the templates shipped in nbconvert have the basic structure described here,\n", "though some may define additional blocks." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from IPython.display import HTML, display\n", "with open('template_structure.html') as f:\n", " display(HTML(f.read()))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A few gotchas\n", "\n", "Jinja blocks use `{% %}` by default which does not play nicely with LaTeX, so those are replaced by `((* *))` in LaTeX templates." ] }, { "cell_type": "markdown", "metadata": { "tags": [ "Hard" ] }, "source": [ "## Templates using cell tags\n", "\n", "The notebook file format supports attaching arbitrary JSON metadata to each cell. In addition, every cell has a special `tags` metadata field that accepts a list of strings that indicate the cell's tags. To apply these, go to the `View → CellToolbar → Tags` option which will create a Tag editor at the top of every cell. \n", "\n", "First choose a notebook you want to convert to html, and apply the tags: `\"Easy\"`, `\"Medium\"`, or \n", "`\"Hard\"`. \n", "\n", "With this in place, the notebook can be converted using a custom template.\n", "\n", "Design your template in the cells provided below.\n", "\n", "Hint: tags are located at `cell.metadata.tags`, the following Python code collects the value of the tag: \n", "\n", "```python\n", "cell['metadata'].get('tags', [])\n", "```\n", "\n", "Which you can then use inside a Jinja template as in the following:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting mytemplate.tpl\n" ] } ], "source": [ "%%writefile mytemplate.tpl\n", "\n", "{% extends 'full.tpl'%}\n", "{% block any_cell %}\n", "{% if 'Hard' in cell['metadata'].get('tags', []) %}\n", "
\n", " {{ super() }}\n", "
\n", "{% elif 'Medium' in cell['metadata'].get('tags', []) %}\n", "
\n", " {{ super() }}\n", "
\n", "{% elif 'Easy' in cell['metadata'].get('tags', []) %}\n", "
\n", " {{ super() }}\n", "
\n", "{% else %}\n", " {{ super() }}\n", "{% endif %}\n", "{% endblock any_cell %}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, if we collect the result of using nbconvert with this template, and display the resulting html, we see the following:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "example\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", " \n", "\n", "
\n", "
\n", "\n", "\n", " \n", "
\n", "
\n", "
\n", "
\n", "

Example notebook

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", " \n", "
\n", "
\n", "
\n", "
\n", "

Markdown cells

This is an example notebook that can be converted with nbconvert to different formats. This is an example of a markdown cell.

\n", "\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "
\n", "
\n", "
\n", "

LaTeX Equations

Here is an equation:

\n", "$$\n", "y = \\sin(x)\n", "$$\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", " \n", "
\n", "
\n", "
\n", "
\n", "

Code cells

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "
\n", "
In [1]:
\n", "
\n", "
\n", "
print("This is a code cell that produces some output")\n",
       "
\n", "\n", "
\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "\n", "
\n", "\n", "
\n", "\n", "\n", "
\n", "
This is a code cell that produces some output\n",
       "
\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "\n", "\n", " \n", "
\n", "
\n", "
\n", "
\n", "

Inline figures

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "
\n", "
In [1]:
\n", "
\n", "
\n", "
import matplotlib.pyplot as plt\n",
       "import numpy as np\n",
       "plt.ion()\n",
       "\n",
       "x = np.linspace(0, 2 * np.pi, 100)\n",
       "y = np.sin(x)\n",
       "plt.plot(x, y)\n",
       "
\n", "\n", "
\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "\n", "
\n", "\n", "
Out[1]:
\n", "\n", "\n", "\n", "\n", "
\n", "
[<matplotlib.lines.Line2D at 0x1111b2160>]
\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "\n", "
\n", "
\n", "\n", "\n", " \n", "\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "example = !jupyter nbconvert --to html 'example.ipynb' --template=mytemplate.tpl --stdout\n", "example = example[3:] # have to remove the first three lines which are not proper html\n", "from IPython.display import HTML, display\n", "display(HTML('\\n'.join(example))) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Templates using custom cell metadata \n", "\n", "We demonstrated [above](#Templates-using-cell-tags) how to use cell tags in a template to apply custom styling to a notebook. But remember, the notebook file format supports attaching _arbitrary_ JSON metadata to each cell, not only cell tags. \n", "Here, we describe an exercise for using an `example.difficulty` metadata field (rather than cell tags) to do the same as before (to mark up different cells as being \"Easy\", \"Medium\" or \"Hard\").\n", "\n", "### How to edit cell metadata\n", "\n", "To edit the cell metadata from within the notebook, go to the menu item: `View → Cell Toolbar → Edit Metadata`. This will bring up a toolbar above each cell with a button that says \"Edit Metadata\". Click this button, and a field will pop up in which you will directly edit the cell metadata JSON. \n", "\n", "**NB**: Because it is JSON, you will need to ensure that what you write is valid JSON. \n", "\n", "### Template challenges: dealing with missing custom metadata fields\n", "\n", "One of the challenges of dealing with custom metadata is to handle the case where the metadata is not present on every cell. This can get somewhat tricky because of JSON objects tendency to be deeply nested coupled with Python's (and therefore Jinja's) approach to calling into dictionaries. Specifically, the following code will error:\n", "\n", "```python\n", "foo = {}\n", "foo[\"bar\"]\n", "```\n", "\n", "Accordingly, it is better to use the [`{}.get` method](https://docs.python.org/3.6/library/stdtypes.html#dict.get) which allows you to set a default value to return if no key is found as the second argument. \n", "\n", "Hint: if your metadata items are located at `cell.metadata.example.difficulty`, the following Python code would get the value defaulting to an empty string (`''`) if nothing is found:\n", "\n", "```python\n", "cell['metadata'].get('example', {}).get('difficulty', '')\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercise: Write a template for handling custom metadata\n", "Now, write a template that will look for `Easy`, `Medium` and `Hard` metadata values for the `cell.metadata.example.difficulty` field and wrap them in a div with a green, orange, or red thin solid border (respectively). \n", "\n", "**NB**: This is the same design and logic as used in the previous cell tag example.\n", "\n", "#### How to get `example.ipynb`\n", "\n", "We have provided an example file in `example.ipynb` in the nbconvert documentation that has already been marked up with both tags and the above metadata for you to test with. You can get it from [this link to the raw file]( https://raw.githubusercontent.com/jupyter/nbconvert/master/docs/source/example.ipynb) or by cloning the repository [from GitHub](https://github.com/jupyter/nbconvert) and navingating to `nbconvert/docs/source/example.ipynb`. \n", "\n", "#### Convert `example.ipynb` using cell tags \n", "\n", "First, make sure that you can reproduce the previous result using the cell tags template that we have provided above. \n", "\n", "**Easy**: If you want to make it easy on yourself, create a new file `my_template.tpl` in the same directory as `example.ipynb` and copy the contents of the cell we use to write `mytemplate.tpl` to the file system. \n", "\n", "Then run `jupyter nbconvert --to html 'example.ipynb' --template=mytemplate.tpl` and see if your \n", "\n", "**Moderate**: If you want more of a challenge, try recreating the jinja template by modifying the following jinja template file:\n", "\n", "```python\n", "{% extends 'full.tpl'%}\n", "{% block any_cell %}\n", "
\n", " {{ super() }}\n", "
\n", "{% endblock any_cell %}\n", "```\n", "\n", "**Hard**: If you want even more of a challenge, try recreating the jinja template from scratch. \n", "\n", "#### Write your template\n", "\n", "Once you've done at least the **Easy** version of the previous step, try modifying your template to use `cell.metadata.example.difficulty` fields rather than cell tags. \n", "\n", "#### Convert `example.ipynb` with formatting from custom metadata\n", "\n", "Once you've written your template, try converting `example.ipynb` using the following command (making sure that `your_template.tpl` is in your local directory where you are running the command):\n", "\n", "```bash\n", "jupyter nbconvert --to html 'example.ipynb' --template=your_template.tpl --stdout\n", "```\n", "\n", "The resulting display should pick out different cells to be bordered with green, orange, or red.\n", "\n", "If you do that successfullly, the resulting html document should look like the following cell's contents: " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "example\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", " \n", "\n", "
\n", "
\n", "\n", "\n", "
\n", " \n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Example notebook

\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", " \n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Markdown cells

This is an example notebook that can be converted with nbconvert to different formats. This is an example of a markdown cell.

\n", "\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", " \n", "
\n", "
\n", "
\n", "
\n", "
\n", "

LaTeX Equations

Here is an equation:

\n", "$$\n", "y = \\sin(x)\n", "$$\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Code cells

\n", "
\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", " \n", "
\n", "
\n", "
In [1]:
\n", "
\n", "
\n", "
print("This is a code cell that produces some output")\n",
    "
\n", "\n", "
\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "\n", "
\n", "\n", "
\n", "\n", "\n", "
\n", "
This is a code cell that produces some output\n",
    "
\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "
\n", "\n", "\n", "\n", " \n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Inline figures

\n", "
\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", " \n", "
\n", "
\n", "
In [1]:
\n", "
\n", "
\n", "
import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "plt.ion()\n",
    "\n",
    "x = np.linspace(0, 2 * np.pi, 100)\n",
    "y = np.sin(x)\n",
    "plt.plot(x, y)\n",
    "
\n", "\n", "
\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "\n", "
\n", "\n", "
Out[1]:
\n", "\n", "\n", "\n", "\n", "
\n", "
[<matplotlib.lines.Line2D at 0x1111b2160>]
\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "\n", "\n", " \n", "
\n", "
\n", "
In [ ]:
\n", "
\n", "
\n", "
 \n",
    "
\n", "\n", "
\n", "
\n", "
\n", "\n", "
\n", "\n", "\n", "
\n", "
\n", "\n", "\n", " \n", "\n", "\n", "" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" } }, "nbformat": 4, "nbformat_minor": 1 } nbconvert-5.3.1/docs/source/development_release.rst000066400000000000000000000042701315361605600225350ustar00rootroot00000000000000.. _nbconvert_release: Making an ``nbconvert`` release =============================== This document guides a contributor through creating a release of ``nbconvert``. Assign all merged PRs to milestones ----------------------------------- Go to GitHub and assign all PRs that have been merged to milestones. This will be helpful when you update the changelog. If you go to this `GitHub page `_ you will find all the PRs that currently have no milestones. .. _GitHub no milestones: https://github.com/jupyter/nbconvert/pulls?utf8=%E2%9C%93&q=is%3Amerged%20is%3Apr%20no%3Amilestone%20 Check installed tools --------------------- Review ``CONTRIBUTING.md``, particularly the testing and release sections. Clean the repository -------------------- You can remove all non-tracked files with: .. code:: bash git clean -xfdi This would ask you for confirmation before removing all untracked files. Make sure the ``dist/`` folder is clean and avoid stale builds from previous attempts. Create the release ------------------ #. Update the :doc:`changelog ` to account for all the PRs assigned to this milestone. #. Update version number in ``notebook/_version.py``. #. Commit and tag the release with the current version number: .. code:: bash git commit -am "release $VERSION" git tag $VERSION #. You are now ready to build the ``sdist`` and ``wheel``: .. code:: bash python setup.py sdist python setup.py bdist_wheel #. You can now test the ``wheel`` and the ``sdist`` locally before uploading to PyPI. Make sure to use `twine `_ to upload the archives over SSL. .. code:: bash twine upload dist/* Release the new version ----------------------- Push directly on master, including --tags separately .. code:: bash git push upstream git push upstream --tags Update nbviewer --------------- On nbviewer-deploy run `invoke trigger_build` and then once it's built on dockerhub run `invoke doitall`. Return to development state --------------------------- If all went well, change the ``notebook/_version.py`` back adding the ``.dev`` suffix. nbconvert-5.3.1/docs/source/example.ipynb000066400000000000000000000456201315361605600204630ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": { "example": { "difficulty": "Hard" } }, "source": [ "# Example notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Markdown cells\n", "\n", "This is an example notebook that can be converted with `nbconvert` to different formats. This is an example of a markdown cell." ] }, { "cell_type": "markdown", "metadata": { "tags": [ "Medium" ] }, "source": [ "### LaTeX Equations\n", "\n", "Here is an equation:\n", "\n", "$$\n", "y = \\sin(x)\n", "$$" ] }, { "cell_type": "markdown", "metadata": { "example": { "difficulty": "Easy" } }, "source": [ "### Code cells" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "tags": [ "Easy" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a code cell that produces some output\n" ] } ], "source": [ "print(\"This is a code cell that produces some output\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Inline figures" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "example": { "difficulty": "Medium" }, "tags": [ "Hard" ] }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "plt.ion()\n", "\n", "x = np.linspace(0, 2 * np.pi, 100)\n", "y = np.sin(x)\n", "plt.plot(x, y)" ] } ], "metadata": { "celltoolbar": "Edit Metadata", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 1 } nbconvert-5.3.1/docs/source/execute_api.rst000066400000000000000000000153271315361605600210130ustar00rootroot00000000000000Executing notebooks =================== .. module:: nbconvert.preprocessors Jupyter notebooks are often saved with output cells that have been cleared. nbconvert provides a convenient way to execute the input cells of an .ipynb notebook file and save the results, both input and output cells, as a .ipynb file. In this section we show how to execute a ``.ipynb`` notebook document saving the result in notebook format. If you need to export notebooks to other formats, such as reStructured Text or Markdown (optionally executing them) see section :doc:`nbconvert_library`. Executing notebooks can be very helpful, for example, to run all notebooks in Python library in one step, or as a way to automate the data analysis in projects involving more than one notebook. Executing notebooks from the command line ----------------------------------------- The same functionality of executing notebooks is exposed through a :doc:`command line interface ` or a Python API interface. As an example, a notebook can be executed from the command line with:: jupyter nbconvert --to notebook --execute mynotebook.ipynb Executing notebooks using the Python API interface -------------------------------------------------- This section will illustrate the Python API interface. Example ~~~~~~~ Let's start with a complete quick example, leaving detailed explanations to the following sections. **Import**: First we import nbconvert and the :class:`ExecutePreprocessor` class:: import nbformat from nbconvert.preprocessors import ExecutePreprocessor **Load**: Assuming that ``notebook_filename`` contains the path of a notebook, we can load it with:: with open(notebook_filename) as f: nb = nbformat.read(f, as_version=4) **Configure**: Next, we configure the notebook execution mode:: ep = ExecutePreprocessor(timeout=600, kernel_name='python3') We specified two (optional) arguments ``timeout`` and ``kernel_name``, which define respectively the cell execution timeout and the execution kernel. The option to specify **kernel_name** is new in nbconvert 4.2. When not specified or when using nbconvert <4.2, the default Python kernel is chosen. **Execute/Run (preprocess)**: To actually run the notebook we call the method ``preprocess``:: ep.preprocess(nb, {'metadata': {'path': 'notebooks/'}}) Hopefully, we will not get any errors during the notebook execution (see the last section for error handling). Note that ``path`` specifies in which folder to execute the notebook. **Save**: Finally, save the resulting notebook with:: with open('executed_notebook.ipynb', 'wt') as f: nbformat.write(nb, f) That's all. Your executed notebook will be saved in the current folder in the file ``executed_notebook.ipynb``. Execution arguments (traitlets) ------------------------------- The arguments passed to :class:`ExecutePreprocessor` are configuration options called `traitlets `_. There are many cool things about traitlets. For example, they enforce the input type, and they can be accessed/modified as class attributes. Moreover, each traitlet is automatically exposed as command-line options. For example, we can pass the timeout from the command-line like this:: jupyter nbconvert --ExecutePreprocessor.timeout=600 --to notebook --execute mynotebook.ipynb Let's now discuss in more detail the two traitlets we used. The ``timeout`` traitlet defines the maximum time (in seconds) each notebook cell is allowed to run, if the execution takes longer an exception will be raised. The default is 30 s, so in cases of long-running cells you may want to specify an higher value. The ``timeout`` option can also be set to ``None`` or ``-1`` to remove any restriction on execution time. The second traitlet, ``kernel_name``, allows specifying the name of the kernel to be used for the execution. By default, the kernel name is obtained from the notebook metadata. The traitlet ``kernel_name`` allows specifying a user-defined kernel, overriding the value in the notebook metadata. A common use case is that of a Python 2/3 library which includes documentation/testing notebooks. These notebooks will specify either a python2 or python3 kernel in their metadata (depending on the kernel used the last time the notebook was saved). In reality, these notebooks will work on both Python 2 and Python 3, and, for testing, it is important to be able to execute them programmatically on both versions. Here the traitlet ``kernel_name`` helps simplify and maintain consistency: we can just run a notebook twice, specifying first "python2" and then "python3" as the kernel name. Handling errors and exceptions ------------------------------ In the previous sections we saw how to save an executed notebook, assuming there are no execution errors. But, what if there are errors? Execution until first error ~~~~~~~~~~~~~~~~~~~~~~~~~~~ An error during the notebook execution, by default, will stop the execution and raise a ``CellExecutionError``. Conveniently, the source cell causing the error and the original error name and message are also printed. After an error, we can still save the notebook as before:: with open('executed_notebook.ipynb', mode='wt') as f: nbformat.write(nb, f) The saved notebook contains the output up until the failing cell, and includes a full stack-trace and error (which can help debugging). Handling errors ~~~~~~~~~~~~~~~ A useful pattern to execute notebooks while handling errors is the following:: from nbconvert.preprocessors import CellExecutionError try: out = ep.preprocess(nb, {'metadata': {'path': run_path}}) except CellExecutionError: out = None msg = 'Error executing the notebook "%s".\n\n' % notebook_filename msg += 'See notebook "%s" for the traceback.' % notebook_filename_out print(msg) raise finally: with open(notebook_filename_out, mode='wt') as f: nbformat.write(nb, f) This will save the executed notebook regardless of execution errors. In case of errors, however, an additional message is printed and the ``CellExecutionError`` is raised. The message directs the user to the saved notebook for further inspection. Execute and save all errors ~~~~~~~~~~~~~~~~~~~~~~~~~~~ As a last scenario, it is sometimes useful to execute notebooks which raise exceptions, for example to show an error condition. In this case, instead of stopping the execution on the first error, we can keep executing the notebook using the traitlet ``allow_errors`` (default is False). With ``allow_errors=True``, the notebook is executed until the end, regardless of any error encountered during the execution. The output notebook, will contain the stack-traces and error messages for **all** the cells raising exceptions. nbconvert-5.3.1/docs/source/external_exporters.rst000066400000000000000000000174171315361605600224570ustar00rootroot00000000000000.. _external_exporters: Customizing exporters ===================== .. versionadded:: 4.2 You can now use the ``--to`` flag to use custom export formats defined outside nbconvert. The command-line syntax to run the ``nbconvert`` script is:: jupyter nbconvert --to FORMAT notebook.ipynb This will convert the Jupyter document file ``notebook.ipynb`` into the output format designated by the ``FORMAT`` string as explained below. Extending the built-in format exporters --------------------------------------- A few built-in formats are available by default: `html`, `pdf`, `script`, `latex`. Each of these has its own *exporter* with many configuration options that can be extended. Having the option to point to a different *exporter* allows authors to create their own fully customized templates or export formats. A custom *exporter* must be an importable Python object. We recommend that these be distributed as Python libraries. .. _entrypoints: Registering a custom exporter as an entry point ----------------------------------------------- Additional exporters may be registered as named `entry_points`_. nbconvert uses the ``nbconvert.exporters`` entry point to find exporters from any package you may have installed. If you are writing a Python package that provides custom exporters, you can register the custom exporters in your package's :file:`setup.py`. For example, your package may contain two custom exporters, named "simple" and "detail", and can be registered in your package's :file:`setup.py` as follows: .. sourcecode:: python setup( ... entry_points = { 'nbconvert.exporters': [ 'simple = mymodule:SimpleExporter', 'detail = mymodule:DetailExporter', ], } ) Now people who have installed your Python package containing the two custom exporters can call the entry point name:: jupyter nbconvert --to detail mynotebook.ipynb instead of having to specify the full import name of the custom exporter. .. _entry_points: https://packaging.python.org/en/latest/distributing/#entry-points Using a custom exporter without entrypoints ------------------------------------------- We encourage registering custom exporters as entry points as described in the previous section. Registering a custom exporter with an entry point simplifies using the exporter. If a custom exporter has not been registered with an entry point, the exporter can still be used by providing the fully qualified name of this exporter as the argument of the ``--to`` flag when running from the command line:: $ jupyter nbconvert --to notebook.ipynb For example, assuming a library `tcontrib` has a custom exporter name `TExporter`, you would convert to this custom format using the following:: $ jupyter nbconvert --to tcontrib.TExporter notebook.ipynb A library can contain multiple exporters. Creators of custom exporters should make sure that all other flags of the command line behave the same for the custom exporters as for built-in exporters. Parameters controlled by an external exporter ============================================= An external exporter can control almost any parameter of the notebook conversion process, from simple parameters such as the output file extension, to more complex ones such as the execution of the notebook or a custom rendering template. All external exporters can expose custom options using the ``traitlets`` configurable API. Refer to the library that provides these exporters for details on how these configuration options works. You can use the Jupyter configuration files to configure an external exporter. As for any ``nbconvert`` exporters you can use either the configuration file syntax of ``c.MyExporter.config_option=value`` or the command line flag form ``--MyExporter.config_option=value``. Writing a custom ``Exporter`` ============================= Under the hood exporters are python classes that expose a certain interface. Any importable classes that expose this interface can be use as an exporter for nbconvert. For simplicity we expose basic classes that implement all the relevant methods that you have to subclass and overwrite just the relevant methods to provide a custom exporter. Below we show you the step to create a custom exporter that provides a custom file extension, and a custom template that inserts before and after each markdown cell. We will lay out files to be ready for Python packaging and distributing on PyPI, although the exact art of Python packaging is beyond the scope of this explanation. We will use the following layout for our package to expose a custom exporter:: mypackage ├── LICENSE.md ├── setup.py └── mypackage ├── __init__.py └── templates └── test_template.tpl If you wished to create this same directory structure you could use the following commands when you are at the directory under which you wish to build your ``mypackage`` package: .. code-block:: bash mkdir -p mypackage/mypackage/templates touch mypackage/LICENSE.md touch mypackage/setup.py touch mypackage/mypackage/__init__.py touch mypackage/mypackage/templates/test_template.tpl .. important:: You should not publish this package without adding content to your ``LICENSE.md`` file. For example, ``nbconvert`` follows the Jupyter Project convention of using a Modified BSD License (also known as New or Revised or 3-Clause BSD). For a guide on picking the right license for your use case, please see `choose a license `_. If you do not specify the license, your code may be `unusable by many open source projects`_. .. _`unusable by many open source projects`: http://choosealicense.com/no-license/ As you can see the layout is relatively simple, in the case where a template is not needed we would actually have only one file with an Exporter implementation. Of course you can change the layout of your package to have a more fine-grained structure of the subpackage. But lets see what a minimum example looks like. We are going to write an exporter that: - exports to html, so we will reuse the built-in html exporter - changes the file extension to `.test_ext` .. code-block:: python # file __init__.py import os import os.path from traitlets.config import Config from nbconvert.exporters.html import HTMLExporter #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- class MyExporter(HTMLExporter): """ My custom exporter """ def _file_extension_default(self): """ The new file extension is `.test_ext` """ return '.test_ext' @property def template_path(self): """ We want to inherit from HTML template, and have template under `./templates/` so append it to the search path. (see next section) """ return super().template_path+[os.path.join(os.path.dirname(__file__), "templates")] def _template_file_default(self): """ We want to use the new template we ship with our library. """ return 'test_template' # full And the template file, that inherits from the html `full` template and prepend/append text to each markdown cell (see Jinja2 docs for template syntax):: {% extends "full.tpl" %} {% block markdowncell -%} ## this is a markdown cell {super()} ## THIS IS THE END {% endblock markdowncell %} Assuming you install this package locally, or from PyPI, you can now use:: jupyter nbconvert --to mypackage.MyEporter notebook.ipynb nbconvert-5.3.1/docs/source/index.rst000066400000000000000000000043431315361605600176230ustar00rootroot00000000000000============================================= nbconvert: Convert Notebooks to other formats ============================================= Using ``nbconvert`` enables: - **presentation** of information in familiar formats, such as PDF. - **publishing** of research using LaTeX and opens the door for embedding notebooks in papers. - **collaboration** with others who may not use the notebook in their work. - **sharing** contents with many people via the web using HTML. Overall, notebook conversion and the ``nbconvert`` tool give scientists and researchers the flexibility to deliver information in a timely way across different formats. Primarily, the ``nbconvert`` tool allows you to convert a Jupyter ``.ipynb`` notebook document file into another static format including HTML, LaTeX, PDF, Markdown, reStructuredText, and more. ``nbconvert`` can also add productivity to your workflow when used to execute notebooks programmatically. If used as a Python library (``import nbconvert``), ``nbconvert`` adds notebook conversion within a project. For example, ``nbconvert`` is used to implement the "Download as" feature within the Jupyter Notebook web application. When used as a command line tool (invoked as ``jupyter nbconvert ...``), users can conveniently convert just one or a batch of notebook files to another format. **Contents:** .. toctree:: :maxdepth: 2 :caption: User Documentation install usage nbconvert_library latex_citations execute_api .. toctree:: :maxdepth: 2 :caption: Configuration config_options customizing external_exporters .. toctree:: :maxdepth: 2 :caption: Developer Documentation architecture api/index development_release .. toctree:: :maxdepth: 2 :caption: About nbconvert changelog .. toctree:: :maxdepth: 1 :caption: Questions? Suggestions? Jupyter mailing list Jupyter website Stack Overflow - Jupyter Stack Overflow - Jupyter-notebook Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` nbconvert-5.3.1/docs/source/install.rst000066400000000000000000000052721315361605600201640ustar00rootroot00000000000000Installation ============ .. seealso:: `Installing Jupyter `__ Nbconvert is part of the Jupyter ecosystem. Installing nbconvert -------------------- Nbconvert is packaged for both pip and conda, so you can install it with:: pip install nbconvert # OR conda install nbconvert If you're new to Python, we recommend installing `Anaconda `_, a Python distribution which includes nbconvert and the other Jupyter components. .. important:: To unlock nbconvert's full capabilities requires Pandoc and TeX (specifically, XeLaTeX). These must be installed separately. Installing Pandoc ----------------- For converting markdown to formats other than HTML, nbconvert uses `Pandoc `_ (1.12.1 or later). To install pandoc on Linux, you can generally use your package manager:: sudo apt-get install pandoc On other platforms, you can get pandoc from `their website `_. Installing TeX -------------- For converting to PDF, nbconvert uses the TeX document preparation ecosystem. It produces an intermediate ``.tex`` file which is compiled by the XeTeX engine with the LaTeX2e format (via the ``xelatex`` command) to produce PDF output. .. versionadded:: 5.0 We use XeTeX as the rendering engine rather than pdfTeX (as in earlier versions). XeTeX can access fonts through native operating system libraries, it has better support for OpenType formatted fonts and Unicode characters. To install a complete TeX environment (including XeLaTeX and the necessary supporting packages) by hand can be tricky. Fortunately, there are packages that make this much easier. These packages are specific to different operating systems: * Linux: `TeX Live `_ * macOS (OS X): `MacTeX `_. * Windows: `MikTex `_ Because nbconvert depends on packages and fonts included in standard TeX distributions, if you do not have a complete installation, you may not be able to use nbconvert's standard tooling to convert notebooks to PDF. PDF conversion on a limited TeX environment ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you are only able to install a limited TeX environment, there are two main routes you could take to convert to PDF: 1. Using TeX by hand a. You could convert to ``.tex`` directly; this requires Pandoc. b. edit the file to accord with your local environment c. run ``xelatex`` directly. 2. Custom exporter a. You could write a :ref:`custom exporter ` that takes your system's limitations into account. nbconvert-5.3.1/docs/source/latex_citations.rst000066400000000000000000000011171315361605600217020ustar00rootroot00000000000000LaTeX citations =============== ``nbconvert`` now has support for LaTeX citations. With this capability you can: * Manage citations using BibTeX. * Cite those citations in Markdown cells using HTML data attributes. * Have ``nbconvert`` generate proper LaTeX citations and run BibTeX. For an example of how this works, please see the `citations example`_ in the nbconvert-examples_ repository. .. _nbconvert-examples: https://github.com/jupyter/nbconvert-examples .. _citations example: https://nbviewer.jupyter.org/github/jupyter/nbconvert-examples/blob/master/citations/Tutorial.ipynb nbconvert-5.3.1/docs/source/nbconvert_library.ipynb000066400000000000000000001714211315361605600225530ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using nbconvert as a library\n", "\n", "In this notebook, you will be introduced to the programmatic API of nbconvert and how it can be used in various contexts. \n", "\n", "A great [blog post](http://jakevdp.github.io/blog/2013/04/15/code-golf-in-python-sudoku/) by [@jakevdp](https://github.com/jakevdp) will be used to demonstrate. This notebook will not focus on using the command line tool. The attentive reader will point-out that no data is read from or written to disk during the conversion process. This is because nbconvert has been designed to work in memory so that it works well in a database or web-based environment too." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Quick overview" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Credit: Jonathan Frederic (@jdfreder on github)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The main principle of nbconvert is to instantiate an `Exporter` that controls the pipeline through which notebooks are converted.\n", "\n", "First, download @jakevdp's notebook (if you do not have `requests`, install it by running `pip install requests`, or if you don't have pip installed, you can find it on PYPI):" ] }, { "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": [ "from urllib.request import urlopen\n", "\n", "url = 'http://jakevdp.github.com/downloads/notebooks/XKCD_plots.ipynb'\n", "response = urlopen(url).read().decode()\n", "response[0:60] + ' ...'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The response is a JSON string which represents a Jupyter notebook. \n", "\n", "Next, we will read the response using nbformat. Doing this will guarantee that the notebook structure is valid. Note that the in-memory format and on disk format are slightly different. In particual, on disk, multiline strings might be split into a list of strings." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{'cell_type': 'markdown',\n", " 'metadata': {},\n", " 'source': '# XKCD plots in Matplotlib'}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import nbformat\n", "jake_notebook = nbformat.reads(response, as_version=4)\n", "jake_notebook.cells[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The nbformat API returns a special type of dictionary. For this example, you don't need to worry about the details of the structure (if you are interested, please see the [nbformat documentation](https://nbformat.readthedocs.io/en/latest/)).\n", "\n", "The nbconvert API exposes some basic exporters for common formats and defaults. You will start by using one of them. First, you will import one of these exporters (specifically, the HTML exporter), then instantiate it using most of the defaults, and then you will use it to process the notebook we downloaded earlier." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from traitlets.config import Config\n", "\n", "# 1. Import the exporter\n", "from nbconvert import HTMLExporter\n", "\n", "# 2. Instantiate the exporter. We use the `basic` template for now; we'll get into more details\n", "# later about how to customize the exporter further.\n", "html_exporter = HTMLExporter()\n", "html_exporter.template_file = 'basic'\n", "\n", "# 3. Process the notebook we loaded earlier\n", "(body, resources) = html_exporter.from_notebook_node(jake_notebook)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The exporter returns a tuple containing the source of the converted notebook, as well as a resources dict. In this case, the source is just raw HTML:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "
\n", "
\n", "
\n", "
\n", "
\n", "

XKCD plots in Matplotlib

\n", "
\n", "
\n", "
\n", "
\n", "
`__\n", "by Jake Vanderplas.\n", "\n", ".. raw:: html\n", "\n", " \n", "\n", "*Update: the matplotlib pull request has been merged! See* `*This\n", "post* `__\n", "*for a description of the XKCD functionality now built-in to\n", "matplotlib!*\n", "\n", "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", "\n", ".. code:: python\n", "\n", " from IPython.display import Image\n", " Image('http://jakevdp.github.com/figures/xkcd_version.png')\n", "\n", "\n", "\n", "\n", ".. image:: output_3_0.png\n", "\n", "\n", "\n", "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", "matp...\n", "[.....]\n", "image:: output_3_0.png\n", "\n", "\n", "\n", "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", "\n", ".. code:: python\n", "\n", " Image('http://jakevdp.github.com/figures/mpl_version.png')\n", "\n", "\n", "\n", "\n", ".. imag...\n" ] } ], "source": [ "# Import the RST exproter\n", "from nbconvert import RSTExporter\n", "# Instantiate it\n", "rst_exporter = RSTExporter()\n", "# Convert the notebook to RST format\n", "(body, resources) = rst_exporter.from_notebook_node(jake_notebook)\n", "\n", "print(body[:970] + '...')\n", "print('[.....]')\n", "print(body[800:1200] + '...')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that base64 images are not embeded, but instead there are filename-like strings, such as `output_3_0.png`. The strings actually are (configurable) keys that map to the binary data in the resources dict.\n", "\n", "Note, if you write an RST Plugin, you are responsible for writing all the files to the disk (or uploading, etc...) in the right location. Of course, the naming scheme is configurable.\n", "\n", "As an exercise, this notebook will show you how to get one of those images. First, take a look at the `'outputs'` of the returned resources dictionary. This is a dictionary that contains a key for each extracted resource, with values corresponding to the actual base64 encoding:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['output_13_1.png',\n", " 'output_16_0.png',\n", " 'output_18_1.png',\n", " 'output_3_0.png',\n", " 'output_5_0.png']" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sorted(resources['outputs'].keys())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case, there are 5 extracted binary figures, all `png`s. We can use the Image display object to actually display one of the images:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\nRU5ErkJggg==\n", "text/plain": [ "" ] }, "execution_count": 8, "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": [ "Note that this image is being rendered without ever reading or writing to the disk." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extracting Figures using the HTML Exporter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As mentioned above, by default, the HTML exporter does not extract images -- it just leaves them as inline base64 encodings. However, this is not always what you might want. For example, here is a use case from @jakevdp:\n", "\n", "> I write an [awesome blog](http://jakevdp.github.io/) using Jupyter notebooks converted to HTML, and I want the images to be cached. Having one html file with all of the images base64 encoded inside it is nice when sharing with a coworker, but for a website, not so much. I need an HTML exporter, and I want it to extract the figures!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Some theory\n", "\n", "Before we get into actually extracting the figures, it will be helpful to give a high-level overview of the process of converting a notebook to a another format:\n", "\n", "1. Retrieve the notebook and it's accompanying resources (you are responsible for this).\n", "2. Feed the notebook into the `Exporter`, which:\n", " 1. Sequentially feeds the notebook into an array of `Preprocessor`s. Preprocessors only act on the **structure** of the notebook, and have unrestricted access to it. \n", " 2. Feeds the notebook into the Jinja templating engine, which converts it to a particular format depending on which template is selected.\n", "3. The exporter returns the converted notebook and other relevant resources as a tuple.\n", "4. You write the data to the disk using the built-in `FilesWriter` (which writes the notebook and any extracted files to disk), or elsewhere using a custom `Writer`.\n", "\n", "### Using different preprocessors\n", "\n", "To extract the figures when using the HTML exporter, we will want to change which `Preprocessor`s we are using. There are several preprocessors that come with nbconvert, including one called the `ExtractOutputPreprocessor`.\n", "\n", "The `ExtractOutputPreprocessor` is responsible for crawling the notebook, finding all of the figures, and putting them into the resources directory, as well as choosing the key (i.e. `filename_xx_y.extension`) that can replace the figure inside the template. To enable the `ExtractOutputPreprocessor`, we must add it to the exporter's list of preprocessors:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['nbconvert.preprocessors.ExtractOutputPreprocessor']" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# create a configuration object that changes the preprocessors\n", "from traitlets.config import Config\n", "c = Config()\n", "c.HTMLExporter.preprocessors = ['nbconvert.preprocessors.ExtractOutputPreprocessor']\n", "\n", "# create the new exporter using the custom config\n", "html_exporter_with_figs = HTMLExporter(config=c)\n", "html_exporter_with_figs.preprocessors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can compare the result of converting the notebook using the original HTML exporter and our new customized one:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "resources without figures:\n", "['inlining', 'metadata', 'output_extension', 'raw_mimetypes']\n", "\n", "resources with extracted figures (notice that there's one more field called 'outputs'):\n", "['inlining', 'metadata', 'output_extension', 'outputs', 'raw_mimetypes']\n", "\n", "the actual figures are:\n", "['output_13_1.png', 'output_16_0.png', 'output_18_1.png', 'output_3_0.png', 'output_5_0.png']\n" ] } ], "source": [ "(_, resources) = html_exporter.from_notebook_node(jake_notebook)\n", "(_, resources_with_fig) = html_exporter_with_figs.from_notebook_node(jake_notebook)\n", "\n", "print(\"resources without figures:\")\n", "print(sorted(resources.keys()))\n", "\n", "print(\"\\nresources with extracted figures (notice that there's one more field called 'outputs'):\")\n", "print(sorted(resources_with_fig.keys()))\n", "\n", "print(\"\\nthe actual figures are:\")\n", "print(sorted(resources_with_fig['outputs'].keys()))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Custom Preprocessors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are an endless number of transformations that you may want to apply to a notebook. In particularly complicated cases, you may want to actually create your own `Preprocessor`. Above, when we customized the list of preprocessors accepted by the `HTMLExporter`, we passed in a string -- this can be any valid module name. So, if you create your own preprocessor, you can include it in that same list and it will be used by the exporter.\n", "\n", "To create your own preprocessor, you will need to subclass from `nbconvert.preprocessors.Preprocessor` and overwrite either the `preprocess` and/or `preprocess_cell` methods." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following demonstration adds the ability to exclude a cell by index. \n", "\n", "Note: injecting cells is similar, and won't be covered here. If you want to inject static content at the beginning/end of a notebook, use a custom template." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from traitlets import Integer\n", "from nbconvert.preprocessors import Preprocessor\n", "\n", "class PelicanSubCell(Preprocessor):\n", " \"\"\"A Pelican specific preprocessor to remove some of the cells of a notebook\"\"\"\n", " \n", " # I could also read the cells from nb.metadata.pelican if someone wrote a JS extension,\n", " # but for now I'll stay with configurable value. \n", " start = Integer(0, help=\"first cell of notebook to be converted\")\n", " end = Integer(-1, help=\"last cell of notebook to be converted\")\n", " start.tag(config='True')\n", " end.tag(config='True')\n", " \n", " def preprocess(self, nb, resources):\n", " self.log.info(\"I'll keep only cells from %d to %d\", self.start, self.end)\n", " nb.cells = nb.cells[self.start:self.end] \n", " return nb, resources" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here a Pelican exporter is created that takes `PelicanSubCell` preprocessors and a `config` object as parameters. This may seem redundant, but with the configuration system you can register an inactive preprocessor on all of the exporters and activate it from config files or the command line. " ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "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", "\n", ".. code:: python\n", "\n", " Image('http://jakevdp.github.com/figures/mpl_version.png')\n", "\n", "\n", "\n", "\n", ".. image:: output_5_0.png\n", "\n", "\n", "\n" ] } ], "source": [ "# Create a new config object that configures both the new preprocessor, as well as the exporter\n", "c = Config()\n", "c.PelicanSubCell.start = 4\n", "c.PelicanSubCell.end = 6\n", "c.RSTExporter.preprocessors = [PelicanSubCell]\n", "\n", "# Create our new, customized exporter that uses our custom preprocessor\n", "pelican = RSTExporter(config=c)\n", "\n", "# Process the notebook\n", "print(pelican.from_notebook_node(jake_notebook)[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Programatically creating templates" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "
\n", "
\n", "FOOOOOOOOTEEEEER\n", "\n" ] } ], "source": [ "from jinja2 import DictLoader\n", "\n", "dl = DictLoader({'full.tpl': \n", "\"\"\"\n", "{%- extends 'basic.tpl' -%} \n", "\n", "{% block footer %}\n", "FOOOOOOOOTEEEEER\n", "{% endblock footer %}\n", "\"\"\"})\n", "\n", "\n", "exportHTML = HTMLExporter(extra_loaders=[dl])\n", "(body, resources) = exportHTML.from_notebook_node(jake_notebook)\n", "for l in body.split('\\n')[-4:]:\n", " print(l)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Real World Uses" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "@jakevdp uses Pelican and Jupyter 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's blog post." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "@damianavila wrote the Nikola Plugin to [write blog post as Notebooks](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 via one click from the web app." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

As @Mbussonn requested... easieeeeer! Deploy your Nikola site with just a click in the IPython notebook! http://t.co/860sJunZvj cc @ralsina

— Damián Avila (@damian_avila) August 21, 2013
\n", "
" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 1 } nbconvert-5.3.1/docs/source/template_structure.html000066400000000000000000000075331315361605600226070ustar00rootroot00000000000000 nbconvert-5.3.1/docs/source/usage.rst000066400000000000000000000146341315361605600176240ustar00rootroot00000000000000Using as a command line tool ============================ The command-line syntax to run the ``nbconvert`` script is:: $ jupyter nbconvert --to FORMAT notebook.ipynb This will convert the Jupyter notebook file ``notebook.ipynb`` into the output format given by the ``FORMAT`` string. Default output format - HTML ---------------------------- The default output format is HTML, for which the ``--to`` argument may be omitted:: $ jupyter nbconvert notebook.ipynb .. _supported_output: Supported output formats ------------------------ The currently supported output formats are: - :ref:`HTML `, - :ref:`LaTeX `, - :ref:`PDF `, - :ref:`Reveal.js HTML slideshow `, - :ref:`Markdown `, - :ref:`reStructuredText `, - :ref:`executable script `, - :ref:`notebook `. Jupyter also provides a few templates for output formats. These can be specified via an additional ``--template`` argument and are listed in the sections below. .. _convert_html: HTML ~~~~ * ``--to html`` - ``--template full`` (default) A full static HTML render of the notebook. This looks very similar to the interactive view. - ``--template basic`` Simplified HTML, useful for embedding in webpages, blogs, etc. This excludes HTML headers. .. _convert_latex: LaTeX ~~~~~ * ``--to latex`` Latex export. This generates ``NOTEBOOK_NAME.tex`` file, ready for export. - ``--template article`` (default) Latex article, derived from Sphinx's howto template. - ``--template report`` Latex report, providing a table of contents and chapters. - ``--template basic`` Very basic latex output - mainly meant as a starting point for custom templates. .. note:: nbconvert uses pandoc_ to convert between various markup languages, so pandoc is a dependency when converting to latex or reStructuredText. .. _convert_pdf: PDF ~~~ * ``--to pdf`` Generates a PDF via latex. Supports the same templates as ``--to latex``. .. _convert_revealjs: Reveal.js HTML slideshow ~~~~~~~~~~~~~~~~~~~~~~~~ * ``--to slides`` This generates a Reveal.js HTML slideshow. It must be served by an HTTP server. The easiest way to do this is adding ``--post serve`` on the command-line. The ``serve`` post-processor proxies Reveal.js requests to a CDN if no local Reveal.js library is present. To make slides that don't require an internet connection, just place the Reveal.js library in the same directory where your_talk.slides.html is located, or point to another directory using the ``--reveal-prefix`` alias. .. note:: In order to designate a mapping from notebook cells to Reveal.js slides, from within the Jupyter notebook, select menu item View --> Cell Toolbar --> Slideshow. That will reveal a drop-down menu on the upper-right of each cell. From it, one may choose from "Slide," "Sub-Slide", "Fragment", "Skip", and "Notes." On conversion, cells designated as "skip" will not be included, "notes" will be included only in presenter notes, etc. .. _convert_markdown: Markdown ~~~~~~~~ * ``--to markdown`` Simple markdown output. Markdown cells are unaffected, and code cells indented 4 spaces. .. _convert_rst: reStructuredText ~~~~~~~~~~~~~~~~ * ``--to rst`` Basic reStructuredText output. Useful as a starting point for embedding notebooks in Sphinx docs. .. note:: nbconvert uses pandoc_ to convert between various markup languages, so pandoc is a dependency when converting to latex or reStructuredText. .. _convert_script: Executable script ~~~~~~~~~~~~~~~~~ * ``--to script`` Convert a notebook to an executable script. This is the simplest way to get a Python (or other language, depending on the kernel) script out of a notebook. If there were any magics in an Jupyter notebook, this may only be executable from a Jupyter session. For example, to convert a Julia notebook to a Julia executable script:: jupyter nbconvert --to script my_julia_notebook.ipynb .. _convert_notebook: Notebook and preprocessors ~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``--to notebook`` .. versionadded:: 3.0 This doesn't convert a notebook to a different format *per se*, instead it allows the running of nbconvert preprocessors on a notebook, and/or conversion to other notebook formats. For example:: jupyter nbconvert --to notebook --execute mynotebook.ipynb This will open the notebook, execute it, capture new output, and save the result in :file:`mynotebook.nbconvert.ipynb`. By default, ``nbconvert`` will abort conversion if any exceptions occur during execution of a cell. If you specify ``--allow-errors`` (in addition to the ``--execute`` flag) then conversion will continue and the output from any exception will be included in the cell output. The following command:: jupyter nbconvert --to notebook --nbformat 3 mynotebook will create a copy of :file:`mynotebook.ipynb` in :file:`mynotebook.v3.ipynb` in version 3 of the notebook format. If you want to convert a notebook in-place, you can specify the ouptut file to be the same as the input file:: jupyter nbconvert --to notebook mynb --output mynb Be careful with that, since it will replace the input file. .. note:: nbconvert uses pandoc_ to convert between various markup languages, so pandoc is a dependency when converting to latex or reStructuredText. .. _pandoc: http://pandoc.org/ The output file created by ``nbconvert`` will have the same base name as the notebook and will be placed in the current working directory. Any supporting files (graphics, etc) will be placed in a new directory with the same base name as the notebook, suffixed with ``_files``:: $ jupyter nbconvert notebook.ipynb $ ls notebook.ipynb notebook.html notebook_files/ For simple single-file output, such as html, markdown, etc., the output may be sent to standard output with:: $ jupyter nbconvert --to markdown notebook.ipynb --stdout Converting multiple notebooks ----------------------------- Multiple notebooks can be specified from the command line:: $ jupyter nbconvert notebook*.ipynb $ jupyter nbconvert notebook1.ipynb notebook2.ipynb or via a list in a configuration file, say ``mycfg.py``, containing the text:: c = get_config() c.NbConvertApp.notebooks = ["notebook1.ipynb", "notebook2.ipynb"] and using the command:: $ jupyter nbconvert --config mycfg.py nbconvert-5.3.1/nbconvert/000077500000000000000000000000001315361605600155265ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/__init__.py000077500000000000000000000003671315361605600176500ustar00rootroot00000000000000"""Utilities for converting notebooks to and from different formats.""" from ._version import version_info, __version__ from .exporters import * from . import filters from . import preprocessors from . import postprocessors from . import writers nbconvert-5.3.1/nbconvert/__main__.py000066400000000000000000000000461315361605600176200ustar00rootroot00000000000000from .nbconvertapp import main main() nbconvert-5.3.1/nbconvert/_version.py000066400000000000000000000036741315361605600177360ustar00rootroot00000000000000version_info = (5, 3, 1) pre_info = '' dev_info = '' def create_valid_version(release_info, epoch=None, pre_input='', dev_input=''): ''' Creates a pep440 valid version of version number given a tuple integers and optional epoch, prerelease and developmental info. Parameters ---------- release_info : Tuple(Int) epoch : Int, default None pre_input : Str, default '' dev_input : Str, default '' ''' pep440_err = "The version number is not a pep 440 compliant version number" if epoch is not None: epoch_seg = str(epoch) + '!' else: epoch_seg = '' release_seg = '.'.join(map(str, release_info)) _magic_pre = ['a','b','rc'] if pre_input!='' and not any([pre_input.startswith(prefix) for prefix in _magic_pre]): raise ValueError(pep440_err + "\n please fix your prerelease segment.") else: pre_seg = pre_input if dev_input=='': dev_seg = dev_input elif not dev_input.startswith('.') and dev_input.startswith('dev'): dev_seg = ''.join(['.', dev_input]) elif dev_input.startswith('.dev'): dev_seg = dev_input elif dev_input!='': raise ValueError(pep440_err + "\n please fix your development segment.") if dev_input!='' and not any([dev_seg.endswith(str(n)) for n in range(10)]): dev_seg = ''.join([dev_seg,'0']) out_version = ''.join([epoch_seg, release_seg, pre_seg, dev_seg]) import re def is_canonical(version): return re.match(r'^([1-9]\d*!)?(0|[1-9]\d*)' r'(\.(0|[1-9]\d*))*((a|b|rc)(0|[1-9]\d*))?' r'(\.post(0|[1-9]\d*))?(\.dev(0|[1-9]\d*))?$', version ) is not None if is_canonical(out_version): return out_version else: raise ValueError(pep440_err) __version__ = create_valid_version(version_info, pre_input=pre_info, dev_input=dev_info) nbconvert-5.3.1/nbconvert/exporters/000077500000000000000000000000001315361605600175615ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/exporters/__init__.py000066400000000000000000000011101315361605600216630ustar00rootroot00000000000000from .base import (export, get_exporter, ExporterNameError, get_export_names) from .exporter_locator import export_by_name from .html import HTMLExporter from .slides import SlidesExporter from .templateexporter import TemplateExporter from .latex import LatexExporter from .markdown import MarkdownExporter from .asciidoc import ASCIIDocExporter from .notebook import NotebookExporter from .pdf import PDFExporter from .python import PythonExporter from .rst import RSTExporter from .exporter import Exporter, FilenameExtension from .script import ScriptExporter nbconvert-5.3.1/nbconvert/exporters/asciidoc.py000066400000000000000000000027601315361605600217160ustar00rootroot00000000000000"""ASCIIDoc Exporter class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from traitlets import default from traitlets.config import Config from .templateexporter import TemplateExporter class ASCIIDocExporter(TemplateExporter): """ Exports to an ASCIIDoc document (.asciidoc) """ @default('file_extension') def _file_extension_default(self): return '.asciidoc' @default('template_file') def _template_file_default(self): return 'asciidoc' output_mimetype = 'text/asciidoc' @default('raw_mimetypes') def _raw_mimetypes_default(self): return ['text/asciidoc/', 'text/markdown', 'text/html', ''] @property def default_config(self): c = Config({ 'NbConvertBase': { 'display_data_priority': ['text/html', 'text/markdown', 'image/svg+xml', 'image/png', 'image/jpeg', 'text/plain', 'text/latex' ] }, 'ExtractOutputPreprocessor': {'enabled': True}, 'HighlightMagicsPreprocessor': { 'enabled':True }, }) c.merge(super(ASCIIDocExporter, self).default_config) return c nbconvert-5.3.1/nbconvert/exporters/base.py000066400000000000000000000072101315361605600210450ustar00rootroot00000000000000"""Module containing single call export functions.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import warnings import entrypoints from traitlets.log import get_logger from traitlets.utils.importstring import import_item from nbformat import NotebookNode from ipython_genutils.py3compat import string_types from .exporter import Exporter #----------------------------------------------------------------------------- # Functions #----------------------------------------------------------------------------- __all__ = [ 'export', 'Exporter', 'get_exporter', 'get_export_names', 'ExporterNameError', ] class ExporterNameError(NameError): pass def export(exporter, nb, **kw): """ Export a notebook object using specific exporter class. Parameters ---------- exporter : :class:`~nbconvert.exporters.exporter.Exporter` class or instance Class or instance of the exporter that should be used. If the method initializes its own instance of the class, it is ASSUMED that the class type provided exposes a constructor (``__init__``) with the same signature as the base Exporter class. nb : :class:`~nbformat.NotebookNode` The notebook to export. config : config (optional, keyword arg) User configuration instance. resources : dict (optional, keyword arg) Resources used in the conversion process. Returns ------- tuple output : str The resulting converted notebook. resources : dictionary Dictionary of resources used prior to and during the conversion process. """ #Check arguments if exporter is None: raise TypeError("Exporter is None") elif not isinstance(exporter, Exporter) and not issubclass(exporter, Exporter): raise TypeError("exporter does not inherit from Exporter (base)") if nb is None: raise TypeError("nb is None") #Create the exporter resources = kw.pop('resources', None) if isinstance(exporter, Exporter): exporter_instance = exporter else: exporter_instance = exporter(**kw) #Try to convert the notebook using the appropriate conversion function. if isinstance(nb, NotebookNode): output, resources = exporter_instance.from_notebook_node(nb, resources) elif isinstance(nb, string_types): output, resources = exporter_instance.from_filename(nb, resources) else: output, resources = exporter_instance.from_file(nb, resources) return output, resources def get_exporter(name): """Given an exporter name or import path, return a class ready to be instantiated Raises ValueError if exporter is not found """ try: return entrypoints.get_single('nbconvert.exporters', name).load() except entrypoints.NoSuchEntryPoint: try: return entrypoints.get_single('nbconvert.exporters', name.lower()).load() except entrypoints.NoSuchEntryPoint: pass if '.' in name: try: return import_item(name) except ImportError: log = get_logger() log.error("Error importing %s" % name, exc_info=True) raise ValueError('Unknown exporter "%s", did you mean one of: %s?' % (name, ', '.join(get_export_names()))) def get_export_names(): """Return a list of the currently supported export targets Exporters can be found in external packages by registering them as an nbconvert.exporter entrypoint. """ return sorted(entrypoints.get_group_named('nbconvert.exporters')) nbconvert-5.3.1/nbconvert/exporters/export.py000066400000000000000000000005531315361605600214570ustar00rootroot00000000000000"""Deprecated as of 5.0 use nbconvert.exporters.base.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import warnings warnings.warn("""`nbconvert.exporters.export` has been deprecated in favor of `nbconvert.exporters.base` since nbconvert 5.0.""", DeprecationWarning) from .exporter_locator import * nbconvert-5.3.1/nbconvert/exporters/exporter.py000066400000000000000000000261321315361605600220070ustar00rootroot00000000000000"""This module defines a base Exporter class. For Jinja template-based export, see templateexporter.py. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function, absolute_import import io import os import copy import collections import datetime import nbformat from traitlets.config.configurable import LoggingConfigurable from traitlets.config import Config from traitlets import HasTraits, Unicode, List, TraitError from traitlets.utils.importstring import import_item from ipython_genutils import text, py3compat class ResourcesDict(collections.defaultdict): def __missing__(self, key): return '' class FilenameExtension(Unicode): """A trait for filename extensions.""" default_value = u'' info_text = 'a filename extension, beginning with a dot' def validate(self, obj, value): # cast to proper unicode value = super(FilenameExtension, self).validate(obj, value) # check that it starts with a dot if value and not value.startswith('.'): msg = "FileExtension trait '{}' does not begin with a dot: {!r}" raise TraitError(msg.format(self.name, value)) return value class Exporter(LoggingConfigurable): """ Class containing methods that sequentially run a list of preprocessors on a NotebookNode object and then return the modified NotebookNode object and accompanying resources dict. """ file_extension = FilenameExtension('.txt', help="Extension of the file that should be written to disk" ).tag(config=True) # MIME type of the result file, for HTTP response headers. # This is *not* a traitlet, because we want to be able to access it from # the class, not just on instances. output_mimetype = '' #Configurability, allows the user to easily add filters and preprocessors. preprocessors = List( help="""List of preprocessors, by name or namespace, to enable.""" ).tag(config=True) _preprocessors = List() default_preprocessors = List([ 'nbconvert.preprocessors.TagRemovePreprocessor', 'nbconvert.preprocessors.RegexRemovePreprocessor', 'nbconvert.preprocessors.ClearOutputPreprocessor', 'nbconvert.preprocessors.ExecutePreprocessor', 'nbconvert.preprocessors.coalesce_streams', 'nbconvert.preprocessors.SVG2PDFPreprocessor', 'nbconvert.preprocessors.CSSHTMLHeaderPreprocessor', 'nbconvert.preprocessors.LatexPreprocessor', 'nbconvert.preprocessors.HighlightMagicsPreprocessor', 'nbconvert.preprocessors.ExtractOutputPreprocessor', ], help="""List of preprocessors available by default, by name, namespace, instance, or type.""" ).tag(config=True) def __init__(self, config=None, **kw): """ Public constructor Parameters ---------- config : :class:`~traitlets.config.Config` User configuration instance. `**kw` Additional keyword arguments passed to parent __init__ """ with_default_config = self.default_config if config: with_default_config.merge(config) super(Exporter, self).__init__(config=with_default_config, **kw) self._init_preprocessors() @property def default_config(self): return Config() def from_notebook_node(self, nb, resources=None, **kw): """ Convert a notebook from a notebook node instance. Parameters ---------- nb : :class:`~nbformat.NotebookNode` Notebook node (dict-like with attr-access) resources : dict Additional resources that can be accessed read/write by preprocessors and filters. `**kw` Ignored """ nb_copy = copy.deepcopy(nb) resources = self._init_resources(resources) if 'language' in nb['metadata']: resources['language'] = nb['metadata']['language'].lower() # Preprocess nb_copy, resources = self._preprocess(nb_copy, resources) return nb_copy, resources def from_filename(self, filename, resources=None, **kw): """ Convert a notebook from a notebook file. Parameters ---------- filename : str Full filename of the notebook file to open and convert. resources : dict Additional resources that can be accessed read/write by preprocessors and filters. `**kw` Ignored """ # Convert full filename string to unicode # In python 2.7.x if filename comes as unicode string, # just skip converting it. if isinstance(filename, str): filename = py3compat.str_to_unicode(filename) # Pull the metadata from the filesystem. if resources is None: resources = ResourcesDict() if not 'metadata' in resources or resources['metadata'] == '': resources['metadata'] = ResourcesDict() path, basename = os.path.split(filename) notebook_name = basename[:basename.rfind('.')] resources['metadata']['name'] = notebook_name resources['metadata']['path'] = path modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename)) resources['metadata']['modified_date'] = modified_date.strftime(text.date_format) with io.open(filename, encoding='utf-8') as f: return self.from_file(f, resources=resources, **kw) def from_file(self, file_stream, resources=None, **kw): """ Convert a notebook from a notebook file. Parameters ---------- file_stream : file-like object Notebook file-like object to convert. resources : dict Additional resources that can be accessed read/write by preprocessors and filters. `**kw` Ignored """ return self.from_notebook_node(nbformat.read(file_stream, as_version=4), resources=resources, **kw) def register_preprocessor(self, preprocessor, enabled=False): """ Register a preprocessor. Preprocessors are classes that act upon the notebook before it is passed into the Jinja templating engine. preprocessors are also capable of passing additional information to the Jinja templating engine. Parameters ---------- preprocessor : :class:`~nbconvert.preprocessors.Preprocessor` A dotted module name, a type, or an instance enabled : bool Mark the preprocessor as enabled """ if preprocessor is None: raise TypeError('preprocessor must not be None') isclass = isinstance(preprocessor, type) constructed = not isclass # Handle preprocessor's registration based on it's type if constructed and isinstance(preprocessor, py3compat.string_types): # Preprocessor is a string, import the namespace and recursively call # this register_preprocessor method preprocessor_cls = import_item(preprocessor) return self.register_preprocessor(preprocessor_cls, enabled) if constructed and hasattr(preprocessor, '__call__'): # Preprocessor is a function, no need to construct it. # Register and return the preprocessor. if enabled: preprocessor.enabled = True self._preprocessors.append(preprocessor) return preprocessor elif isclass and issubclass(preprocessor, HasTraits): # Preprocessor is configurable. Make sure to pass in new default for # the enabled flag if one was specified. self.register_preprocessor(preprocessor(parent=self), enabled) elif isclass: # Preprocessor is not configurable, construct it self.register_preprocessor(preprocessor(), enabled) else: # Preprocessor is an instance of something without a __call__ # attribute. raise TypeError('preprocessor must be callable or an importable constructor, got %r' % preprocessor) def _init_preprocessors(self): """ Register all of the preprocessors needed for this exporter, disabled unless specified explicitly. """ self._preprocessors = [] # Load default preprocessors (not necessarly enabled by default). for preprocessor in self.default_preprocessors: self.register_preprocessor(preprocessor) # Load user-specified preprocessors. Enable by default. for preprocessor in self.preprocessors: self.register_preprocessor(preprocessor, enabled=True) def _init_resources(self, resources): #Make sure the resources dict is of ResourcesDict type. if resources is None: resources = ResourcesDict() if not isinstance(resources, ResourcesDict): new_resources = ResourcesDict() new_resources.update(resources) resources = new_resources #Make sure the metadata extension exists in resources if 'metadata' in resources: if not isinstance(resources['metadata'], ResourcesDict): new_metadata = ResourcesDict() new_metadata.update(resources['metadata']) resources['metadata'] = new_metadata else: resources['metadata'] = ResourcesDict() if not resources['metadata']['name']: resources['metadata']['name'] = 'Notebook' #Set the output extension resources['output_extension'] = self.file_extension return resources def _preprocess(self, nb, resources): """ Preprocess the notebook before passing it into the Jinja engine. To preprocess the notebook is to successively apply all the enabled preprocessors. Output from each preprocessor is passed along to the next one. Parameters ---------- nb : notebook node notebook that is being exported. resources : a dict of additional resources that can be accessed read/write by preprocessors """ # Do a copy.deepcopy first, # we are never safe enough with what the preprocessors could do. nbc = copy.deepcopy(nb) resc = copy.deepcopy(resources) #Run each preprocessor on the notebook. Carry the output along #to each preprocessor for preprocessor in self._preprocessors: nbc, resc = preprocessor(nbc, resc) try: nbformat.validate(nbc, relax_add_props=True) except nbformat.ValidationError: self.log.error('Notebook is invalid after preprocessor {}', preprocessor) raise return nbc, resc nbconvert-5.3.1/nbconvert/exporters/exporter_locator.py000066400000000000000000000052231315361605600235300ustar00rootroot00000000000000"""Deprecated as of 5.0. Module containing hard-coded exporting functions.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import warnings from .base import (export, get_exporter, get_export_names , ExporterNameError) from .exporter import Exporter from .templateexporter import TemplateExporter from .html import HTMLExporter from .slides import SlidesExporter from .latex import LatexExporter from .pdf import PDFExporter from .markdown import MarkdownExporter from .python import PythonExporter from .rst import RSTExporter from .notebook import NotebookExporter from .script import ScriptExporter #----------------------------------------------------------------------------- # Functions #----------------------------------------------------------------------------- warnings.warn("""`nbconvert.exporters.exporter_locator` is deprecated in favor of `nbconvert.exporters.base` since nbconvert 5.0.""", DeprecationWarning) __all__ = [ 'export', 'export_by_name', 'get_exporter', 'get_export_names', 'ExporterNameError', 'exporter_map', ] exporter_map = dict( custom=TemplateExporter, html=HTMLExporter, slides=SlidesExporter, latex=LatexExporter, pdf=PDFExporter, markdown=MarkdownExporter, python=PythonExporter, rst=RSTExporter, notebook=NotebookExporter, script=ScriptExporter, ) def _make_exporter(name, E): """make an export_foo function from a short key and Exporter class E""" def _export(nb, **kw): return export(E, nb, **kw) _export.__doc__ = """DEPRECATED: Export a notebook object to {0} format""".format(name) return _export g = globals() # These specific functions are deprecated as of 5.0 for name, E in exporter_map.items(): g['export_%s' % name] = _make_exporter(name, E) __all__.append('export_%s' % name) def export_by_name(format_name, nb, **kw): """ Deprecated since version 5.0. Export a notebook object to a template type by its name. Reflection (Inspect) is used to find the template's corresponding explicit export method defined in this module. That method is then called directly. Parameters ---------- format_name : str Name of the template style to export to. """ warnings.warn("export_by_name is deprecated since nbconvert 5.0. Instead, use export(get_exporter(format_name), nb, **kw)).", DeprecationWarning, stacklevel=2) try: Exporter = get_exporter(format_name) return export(Exporter, nb, **kw) except ValueError: raise ExporterNameError("Exporter for `%s` not found" % format_name) nbconvert-5.3.1/nbconvert/exporters/html.py000066400000000000000000000062211315361605600211000ustar00rootroot00000000000000# -*- coding: utf-8 -*- """HTML Exporter class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import os from traitlets import default, Unicode from traitlets.config import Config from nbconvert.filters.highlight import Highlight2HTML from nbconvert.filters.markdown_mistune import IPythonRenderer, MarkdownWithMath from .templateexporter import TemplateExporter class HTMLExporter(TemplateExporter): """ Exports a basic HTML document. This exporter assists with the export of HTML. Inherit from it if you are writing your own HTML template and need custom preprocessors/filters. If you don't need custom preprocessors/ filters, just change the 'template_file' config option. """ anchor_link_text = Unicode(u'¶', help="The text used as the text for anchor links.").tag(config=True) @default('file_extension') def _file_extension_default(self): return '.html' @default('default_template_path') def _default_template_path_default(self): return os.path.join("..", "templates", "html") @default('template_file') def _template_file_default(self): return 'full.tpl' output_mimetype = 'text/html' @property def default_config(self): c = Config({ 'NbConvertBase': { 'display_data_priority' : ['application/vnd.jupyter.widget-state+json', 'application/vnd.jupyter.widget-view+json', 'application/javascript', 'text/html', 'text/markdown', 'image/svg+xml', 'text/latex', 'image/png', 'image/jpeg', 'text/plain' ] }, 'CSSHTMLHeaderPreprocessor':{ 'enabled':True }, 'HighlightMagicsPreprocessor': { 'enabled':True } }) c.merge(super(HTMLExporter,self).default_config) return c def markdown2html(self, source): """Markdown to HTML filter respecting the anchor_link_text setting""" renderer = IPythonRenderer(escape=False, anchor_link_text=self.anchor_link_text) return MarkdownWithMath(renderer=renderer).render(source) def default_filters(self): for pair in super(HTMLExporter, self).default_filters(): yield pair yield ('markdown2html', self.markdown2html) def from_notebook_node(self, nb, resources=None, **kw): langinfo = nb.metadata.get('language_info', {}) lexer = langinfo.get('pygments_lexer', langinfo.get('name', None)) self.register_filter('highlight_code', Highlight2HTML(pygments_lexer=lexer, parent=self)) return super(HTMLExporter, self).from_notebook_node(nb, resources, **kw) nbconvert-5.3.1/nbconvert/exporters/latex.py000066400000000000000000000065331315361605600212570ustar00rootroot00000000000000"""LaTeX Exporter class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import os from traitlets import Unicode, default from traitlets.config import Config from nbconvert.filters.highlight import Highlight2Latex from nbconvert.filters.filter_links import resolve_references from .templateexporter import TemplateExporter class LatexExporter(TemplateExporter): """ Exports to a Latex template. Inherit from this class if your template is LaTeX based and you need custom tranformers/filters. Inherit from it if you are writing your own HTML template and need custom tranformers/filters. If you don't need custom tranformers/filters, just change the 'template_file' config option. Place your template in the special "/latex" subfolder of the "../templates" folder. """ @default('file_extension') def _file_extension_default(self): return '.tex' @default('template_file') def _template_file_default(self): return 'article.tplx' # Latex constants @default('default_template_path') def _default_template_path_default(self): return os.path.join("..", "templates", "latex") @default('template_skeleton_path') def _template_skeleton_path_default(self): return os.path.join("..", "templates", "latex", "skeleton") #Extension that the template files use. template_extension = Unicode(".tplx").tag(config=True) output_mimetype = 'text/latex' def default_filters(self): for x in super(LatexExporter, self).default_filters(): yield x yield ('resolve_references', resolve_references) @property def default_config(self): c = Config({ 'NbConvertBase': { 'display_data_priority' : ['text/latex', 'application/pdf', 'image/png', 'image/jpeg', 'image/svg+xml', 'text/markdown', 'text/plain'] }, 'ExtractOutputPreprocessor': { 'enabled':True }, 'SVG2PDFPreprocessor': { 'enabled':True }, 'LatexPreprocessor': { 'enabled':True }, 'SphinxPreprocessor': { 'enabled':True }, 'HighlightMagicsPreprocessor': { 'enabled':True } }) c.merge(super(LatexExporter,self).default_config) return c def from_notebook_node(self, nb, resources=None, **kw): langinfo = nb.metadata.get('language_info', {}) lexer = langinfo.get('pygments_lexer', langinfo.get('name', None)) self.register_filter('highlight_code', Highlight2Latex(pygments_lexer=lexer, parent=self)) return super(LatexExporter, self).from_notebook_node(nb, resources, **kw) def _create_environment(self): environment = super(LatexExporter, self)._create_environment() # Set special Jinja2 syntax that will not conflict with latex. environment.block_start_string = "((*" environment.block_end_string = "*))" environment.variable_start_string = "(((" environment.variable_end_string = ")))" environment.comment_start_string = "((=" environment.comment_end_string = "=))" return environment nbconvert-5.3.1/nbconvert/exporters/markdown.py000066400000000000000000000027251315361605600217630ustar00rootroot00000000000000"""Markdown Exporter class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from traitlets import default from traitlets.config import Config from .templateexporter import TemplateExporter class MarkdownExporter(TemplateExporter): """ Exports to a markdown document (.md) """ @default('file_extension') def _file_extension_default(self): return '.md' @default('template_file') def _template_file_default(self): return 'markdown.tpl' output_mimetype = 'text/markdown' @default('raw_mimetypes') def _raw_mimetypes_default(self): return ['text/markdown', 'text/html', ''] @property def default_config(self): c = Config({ 'ExtractOutputPreprocessor': {'enabled': True}, 'NbConvertBase': { 'display_data_priority': ['text/html', 'text/markdown', 'image/svg+xml', 'text/latex', 'image/png', 'image/jpeg', 'text/plain' ] }, 'HighlightMagicsPreprocessor': { 'enabled':True }, }) c.merge(super(MarkdownExporter, self).default_config) return c nbconvert-5.3.1/nbconvert/exporters/notebook.py000066400000000000000000000025111315361605600217520ustar00rootroot00000000000000"""NotebookExporter class""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from .exporter import Exporter import nbformat from traitlets import Enum, default class NotebookExporter(Exporter): """Exports to an IPython notebook. This is useful when you want to use nbconvert's preprocessors to operate on a notebook (e.g. to execute it) and then write it back to a notebook file. """ nbformat_version = Enum(list(nbformat.versions), default_value=nbformat.current_nbformat, help="""The nbformat version to write. Use this to downgrade notebooks. """ ).tag(config=True) @default('file_extension') def _file_extension_default(self): return '.ipynb' output_mimetype = 'application/json' def from_notebook_node(self, nb, resources=None, **kw): nb_copy, resources = super(NotebookExporter, self).from_notebook_node(nb, resources, **kw) if self.nbformat_version != nb_copy.nbformat: resources['output_suffix'] = '.v%i' % self.nbformat_version else: resources['output_suffix'] = '.nbconvert' output = nbformat.writes(nb_copy, version=self.nbformat_version) if not output.endswith("\n"): output = output + "\n" return output, resources nbconvert-5.3.1/nbconvert/exporters/pdf.py000066400000000000000000000164101315361605600207060ustar00rootroot00000000000000"""Export to PDF via latex""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import subprocess import os import sys from ipython_genutils.py3compat import which, cast_bytes_py2, getcwd from traitlets import Integer, List, Bool, Instance, Unicode from testpath.tempdir import TemporaryWorkingDirectory from .latex import LatexExporter class LatexFailed(IOError): """Exception for failed latex run Captured latex output is in error.output. """ def __init__(self, output): self.output = output def __unicode__(self): return u"PDF creating failed, captured latex output:\n%s" % self.output def __str__(self): u = self.__unicode__() return cast_bytes_py2(u) class PDFExporter(LatexExporter): """Writer designed to write to PDF files. This inherits from :class:`LatexExporter`. It creates a LaTeX file in a temporary directory using the template machinery, and then runs LaTeX to create a pdf. """ latex_count = Integer(3, help="How many times latex will be called." ).tag(config=True) latex_command = List([u"xelatex", u"{filename}"], help="Shell command used to compile latex." ).tag(config=True) bib_command = List([u"bibtex", u"{filename}"], help="Shell command used to run bibtex." ).tag(config=True) verbose = Bool(False, help="Whether to display the output of latex commands." ).tag(config=True) temp_file_exts = List(['.aux', '.bbl', '.blg', '.idx', '.log', '.out'], help="File extensions of temp files to remove after running." ).tag(config=True) texinputs = Unicode(help="texinputs dir. A notebook's directory is added") writer = Instance("nbconvert.writers.FilesWriter", args=()) _captured_output = List() def run_command(self, command_list, filename, count, log_function): """Run command_list count times. Parameters ---------- command_list : list A list of args to provide to Popen. Each element of this list will be interpolated with the filename to convert. filename : unicode The name of the file to convert. count : int How many times to run the command. Returns ------- success : bool A boolean indicating if the command was successful (True) or failed (False). """ command = [c.format(filename=filename) for c in command_list] # On windows with python 2.x there is a bug in subprocess.Popen and # unicode commands are not supported if sys.platform == 'win32' and sys.version_info < (3,0): #We must use cp1252 encoding for calling subprocess.Popen #Note that sys.stdin.encoding and encoding.DEFAULT_ENCODING # could be different (cp437 in case of dos console) command = [c.encode('cp1252') for c in command] # This will throw a clearer error if the command is not found cmd = which(command_list[0]) if cmd is None: link = "https://nbconvert.readthedocs.io/en/latest/install.html#installing-tex" raise OSError("{formatter} not found on PATH, if you have not installed " "{formatter} you may need to do so. Find further instructions " "at {link}.".format(formatter=command_list[0], link=link)) times = 'time' if count == 1 else 'times' self.log.info("Running %s %i %s: %s", command_list[0], count, times, command) shell = (sys.platform == 'win32') if shell: command = subprocess.list2cmdline(command) env = os.environ.copy() env['TEXINPUTS'] = os.pathsep.join([ cast_bytes_py2(self.texinputs), env.get('TEXINPUTS', ''), ]) with open(os.devnull, 'rb') as null: stdout = subprocess.PIPE if not self.verbose else None for index in range(count): p = subprocess.Popen(command, stdout=stdout, stderr=subprocess.STDOUT, stdin=null, shell=shell, env=env) out, _ = p.communicate() if p.returncode: if self.verbose: # verbose means I didn't capture stdout with PIPE, # so it's already been displayed and `out` is None. out = u'' else: out = out.decode('utf-8', 'replace') log_function(command, out) self._captured_output.append(out) return False # failure return True # success def run_latex(self, filename): """Run xelatex self.latex_count times.""" def log_error(command, out): self.log.critical(u"%s failed: %s\n%s", command[0], command, out) return self.run_command(self.latex_command, filename, self.latex_count, log_error) def run_bib(self, filename): """Run bibtex self.latex_count times.""" filename = os.path.splitext(filename)[0] def log_error(command, out): self.log.warn('%s had problems, most likely because there were no citations', command[0]) self.log.debug(u"%s output: %s\n%s", command[0], command, out) return self.run_command(self.bib_command, filename, 1, log_error) def clean_temp_files(self, filename): """Remove temporary files created by xelatex/bibtex.""" self.log.info("Removing temporary LaTeX files") filename = os.path.splitext(filename)[0] for ext in self.temp_file_exts: try: os.remove(filename+ext) except OSError: pass def from_notebook_node(self, nb, resources=None, **kw): latex, resources = super(PDFExporter, self).from_notebook_node( nb, resources=resources, **kw ) # set texinputs directory, so that local files will be found if resources and resources.get('metadata', {}).get('path'): self.texinputs = resources['metadata']['path'] else: self.texinputs = getcwd() self._captured_outputs = [] with TemporaryWorkingDirectory(): notebook_name = 'notebook' tex_file = self.writer.write(latex, resources, notebook_name=notebook_name) self.log.info("Building PDF") rc = self.run_latex(tex_file) if rc: rc = self.run_bib(tex_file) if rc: rc = self.run_latex(tex_file) pdf_file = notebook_name + '.pdf' if not os.path.isfile(pdf_file): raise LatexFailed('\n'.join(self._captured_output)) self.log.info('PDF successfully created') with open(pdf_file, 'rb') as f: pdf_data = f.read() # convert output extension to pdf # the writer above required it to be tex resources['output_extension'] = '.pdf' # clear figure outputs, extracted by latex export, # so we don't claim to be a multi-file export. resources.pop('outputs', None) return pdf_data, resources nbconvert-5.3.1/nbconvert/exporters/python.py000066400000000000000000000010251315361605600214520ustar00rootroot00000000000000"""Python script Exporter class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from traitlets import default from .templateexporter import TemplateExporter class PythonExporter(TemplateExporter): """ Exports a Python code file. """ @default('file_extension') def _file_extension_default(self): return '.py' @default('template_file') def _template_file_default(self): return 'python.tpl' output_mimetype = 'text/x-python' nbconvert-5.3.1/nbconvert/exporters/rst.py000066400000000000000000000016411315361605600207450ustar00rootroot00000000000000"""reStructuredText Exporter class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from traitlets import default from traitlets.config import Config from .templateexporter import TemplateExporter class RSTExporter(TemplateExporter): """ Exports reStructuredText documents. """ @default('file_extension') def _file_extension_default(self): return '.rst' @default('template_file') def _template_file_default(self): return 'rst.tpl' output_mimetype = 'text/restructuredtext' @property def default_config(self): c = Config({ 'ExtractOutputPreprocessor':{ 'enabled':True }, 'HighlightMagicsPreprocessor': { 'enabled':True }, }) c.merge(super(RSTExporter,self).default_config) return c nbconvert-5.3.1/nbconvert/exporters/script.py000066400000000000000000000050001315361605600214320ustar00rootroot00000000000000"""Generic script exporter class for any kernel language""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import entrypoints from .templateexporter import TemplateExporter from traitlets import Dict, default from .base import get_exporter class ScriptExporter(TemplateExporter): # Caches of already looked-up and instantiated exporters for delegation: _exporters = Dict() _lang_exporters = Dict() @default('template_file') def _template_file_default(self): return 'script.tpl' def _get_language_exporter(self, lang_name): """Find an exporter for the language name from notebook metadata. Uses the nbconvert.exporters.script group of entry points. Returns None if no exporter is found. """ if lang_name not in self._lang_exporters: try: Exporter = entrypoints.get_single( 'nbconvert.exporters.script', lang_name).load() except entrypoints.NoSuchEntryPoint: self._lang_exporters[lang_name] = None else: self._lang_exporters[lang_name] = Exporter(parent=self) return self._lang_exporters[lang_name] def from_notebook_node(self, nb, resources=None, **kw): langinfo = nb.metadata.get('language_info', {}) # delegate to custom exporter, if specified exporter_name = langinfo.get('nbconvert_exporter') if exporter_name and exporter_name != 'script': self.log.debug("Loading script exporter: %s", exporter_name) if exporter_name not in self._exporters: Exporter = get_exporter(exporter_name) self._exporters[exporter_name] = Exporter(parent=self) exporter = self._exporters[exporter_name] return exporter.from_notebook_node(nb, resources, **kw) # Look up a script exporter for this notebook's language lang_name = langinfo.get('name') if lang_name: self.log.debug("Using script exporter for language: %s", lang_name) exporter = self._get_language_exporter(lang_name) if exporter is not None: return exporter.from_notebook_node(nb, resources, **kw) # Fall back to plain script export self.file_extension = langinfo.get('file_extension', '.txt') self.output_mimetype = langinfo.get('mimetype', 'text/plain') return super(ScriptExporter, self).from_notebook_node(nb, resources, **kw) nbconvert-5.3.1/nbconvert/exporters/slides.py000066400000000000000000000132661315361605600214260ustar00rootroot00000000000000"""HTML slide show Exporter class""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from copy import deepcopy from warnings import warn from traitlets import Bool, Unicode, default from .html import HTMLExporter def prepare(nb): """Add some convenience metadata on cells for the slide template.""" nb = deepcopy(nb) for cell in nb.cells: # Make sure every cell has a slide_type cell.metadata.slide_type = cell.metadata.get('slideshow', {}).get('slide_type', '-') # Find the first visible cell for index, cell in enumerate(nb.cells): if cell.metadata.slide_type not in {'notes', 'skip'}: cell.metadata.slide_type = 'slide' cell.metadata.slide_start = True cell.metadata.subslide_start = True first_slide_ix = index break else: raise ValueError("All cells are hidden, cannot create slideshow") in_fragment = False for index, cell in enumerate(nb.cells[first_slide_ix+1:], start=(first_slide_ix+1)): previous_cell = nb.cells[index - 1] # Slides are
elements in the HTML, subslides (the vertically # stacked slides) are also
elements inside the slides, # and fragments are
s within subslides. Subslide and fragment # elements can contain content: #
#
# (content) #
(content)
#
#
# Get the slide type. If type is subslide or slide, # end the last slide/subslide/fragment as applicable. if cell.metadata.slide_type == 'slide': previous_cell.metadata.slide_end = True cell.metadata.slide_start = True if cell.metadata.slide_type in {'subslide', 'slide'}: previous_cell.metadata.fragment_end = in_fragment previous_cell.metadata.subslide_end = True cell.metadata.subslide_start = True in_fragment = False elif cell.metadata.slide_type == 'fragment': cell.metadata.fragment_start = True if in_fragment: previous_cell.metadata.fragment_end = True else: in_fragment = True # The last cell will always be the end of a slide nb.cells[-1].metadata.fragment_end = in_fragment nb.cells[-1].metadata.subslide_end = True nb.cells[-1].metadata.slide_end = True return nb class SlidesExporter(HTMLExporter): """Exports HTML slides with reveal.js""" reveal_url_prefix = Unicode( help="""The URL prefix for reveal.js. This can be a a relative URL for a local copy of reveal.js, or point to a CDN. For speaker notes to work, a local reveal.js prefix must be used. """ ).tag(config=True) @default('reveal_url_prefix') def _reveal_url_prefix_default(self): if 'RevealHelpPreprocessor.url_prefix' in self.config: warn("Please update RevealHelpPreprocessor.url_prefix to " "SlidesExporter.reveal_url_prefix in config files.") return self.config.RevealHelpPreprocessor.url_prefix return 'reveal.js' reveal_theme = Unicode('simple', help=""" Name of the reveal.js theme to use. We look for a file with this name under `reveal_url_prefix`/css/theme/`reveal_theme`.css. https://github.com/hakimel/reveal.js/tree/master/css/theme has list of themes that ship by default with reveal.js. """ ).tag(config=True) reveal_transition = Unicode('slide', help=""" Name of the reveal.js transition to use. The list of transitions that ships by default with reveal.js are: none, fade, slide, convex, concave and zoom. """ ).tag(config=True) reveal_scroll = Bool(False, help=""" If True, enable scrolling within each slide """ ).tag(config=True) require_js_url = Unicode( "https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js", help=""" URL to load require.js from. Defaults to loading from cdnjs. """ ).tag(config=True) jquery_url = Unicode( "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js", help=""" URL to load jQuery from. Defaults to loading from cdnjs. """ ).tag(config=True) font_awesome_url = Unicode( "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.css", help=""" URL to load font awesome from. Defaults to loading from cdnjs. """ ).tag(config=True) @default('file_extension') def _file_extension_default(self): return '.slides.html' @default('template_file') def _template_file_default(self): return 'slides_reveal.tpl' output_mimetype = 'text/html' def from_notebook_node(self, nb, resources=None, **kw): resources = self._init_resources(resources) if 'reveal' not in resources: resources['reveal'] = {} resources['reveal']['url_prefix'] = self.reveal_url_prefix resources['reveal']['theme'] = self.reveal_theme resources['reveal']['transition'] = self.reveal_transition resources['reveal']['scroll'] = self.reveal_scroll resources['reveal']['require_js_url'] = self.require_js_url resources['reveal']['jquery_url'] = self.jquery_url resources['reveal']['font_awesome_url'] = self.font_awesome_url nb = prepare(nb) return super(SlidesExporter, self).from_notebook_node(nb, resources=resources, **kw) nbconvert-5.3.1/nbconvert/exporters/templateexporter.py000066400000000000000000000346071315361605600235510ustar00rootroot00000000000000"""This module defines TemplateExporter, a highly configurable converter that uses Jinja2 to export notebook files into different formats. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function, absolute_import import os import uuid import json from traitlets import HasTraits, Unicode, List, Dict, Bool, default, observe from traitlets.config import Config from traitlets.utils.importstring import import_item from ipython_genutils import py3compat from jinja2 import ( TemplateNotFound, Environment, ChoiceLoader, FileSystemLoader, BaseLoader ) from nbconvert import filters from .exporter import Exporter # Jinja2 extensions to load. JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols'] default_filters = { 'indent': filters.indent, 'markdown2html': filters.markdown2html, 'markdown2asciidoc': filters.markdown2asciidoc, 'ansi2html': filters.ansi2html, 'filter_data_type': filters.DataTypeFilter, 'get_lines': filters.get_lines, 'highlight2html': filters.Highlight2HTML, 'highlight2latex': filters.Highlight2Latex, 'ipython2python': filters.ipython2python, 'posix_path': filters.posix_path, 'markdown2latex': filters.markdown2latex, 'markdown2rst': filters.markdown2rst, 'comment_lines': filters.comment_lines, 'strip_ansi': filters.strip_ansi, 'strip_dollars': filters.strip_dollars, 'strip_files_prefix': filters.strip_files_prefix, 'html2text': filters.html2text, 'add_anchor': filters.add_anchor, 'ansi2latex': filters.ansi2latex, 'wrap_text': filters.wrap_text, 'escape_latex': filters.escape_latex, 'citation2latex': filters.citation2latex, 'path2url': filters.path2url, 'add_prompts': filters.add_prompts, 'ascii_only': filters.ascii_only, 'prevent_list_blocks': filters.prevent_list_blocks, 'get_metadata': filters.get_metadata, 'convert_pandoc': filters.convert_pandoc, 'json_dumps': json.dumps, } class ExtensionTolerantLoader(BaseLoader): """A template loader which optionally adds a given extension when searching. Constructor takes two arguments: *loader* is another Jinja loader instance to wrap. *extension* is the extension, which will be added to the template name if finding the template without it fails. This should include the dot, e.g. '.tpl'. """ def __init__(self, loader, extension): self.loader = loader self.extension = extension def get_source(self, environment, template): try: return self.loader.get_source(environment, template) except TemplateNotFound: if template.endswith(self.extension): raise TemplateNotFound(template) return self.loader.get_source(environment, template+self.extension) def list_templates(self): return self.loader.list_templates() class TemplateExporter(Exporter): """ Exports notebooks into other file formats. Uses Jinja 2 templating engine to output new formats. Inherit from this class if you are creating a new template type along with new filters/preprocessors. If the filters/ preprocessors provided by default suffice, there is no need to inherit from this class. Instead, override the template_file and file_extension traits via a config file. Filters available by default for templates: {filters} """ # finish the docstring __doc__ = __doc__.format(filters='- ' + '\n - '.join( sorted(default_filters.keys()))) _template_cached = None def _invalidate_template_cache(self, change=None): self._template_cached = None @property def template(self): if self._template_cached is None: self._template_cached = self._load_template() return self._template_cached _environment_cached = None def _invalidate_environment_cache(self, change=None): self._environment_cached = None self._invalidate_template_cache() @property def environment(self): if self._environment_cached is None: self._environment_cached = self._create_environment() return self._environment_cached @property def default_config(self): c = Config({ 'RegexRemovePreprocessor': { 'enabled': True }, 'TagRemovePreprocessor': { 'enabled': True } }) c.merge(super(TemplateExporter, self).default_config) return c template_file = Unicode( help="Name of the template file to use" ).tag(config=True, affects_template=True) @observe('template_file') def _template_file_changed(self, change): new = change['new'] if new == 'default': self.template_file = self.default_template return # check if template_file is a file path # rather than a name already on template_path full_path = os.path.abspath(new) if os.path.isfile(full_path): template_dir, template_file = os.path.split(full_path) if template_dir not in [ os.path.abspath(p) for p in self.template_path ]: self.template_path = [template_dir] + self.template_path self.template_file = template_file @default('template_file') def _template_file_default(self): return self.default_template default_template = Unicode(u'').tag(affects_template=True) template_path = List(['.']).tag(config=True, affects_environment=True) default_template_path = Unicode( os.path.join("..", "templates"), help="Path where the template files are located." ).tag(affects_environment=True) template_skeleton_path = Unicode( os.path.join("..", "templates", "skeleton"), help="Path where the template skeleton files are located.", ).tag(affects_environment=True) #Extension that the template files use. template_extension = Unicode(".tpl").tag(config=True, affects_environment=True) exclude_input = Bool(False, help = "This allows you to exclude code cell inputs from all templates if set to True." ).tag(config=True) exclude_input_prompt = Bool(False, help = "This allows you to exclude input prompts from all templates if set to True." ).tag(config=True) exclude_output = Bool(False, help = "This allows you to exclude code cell outputs from all templates if set to True." ).tag(config=True) exclude_output_prompt = Bool(False, help = "This allows you to exclude output prompts from all templates if set to True." ).tag(config=True) exclude_code_cell = Bool(False, help = "This allows you to exclude code cells from all templates if set to True." ).tag(config=True) exclude_markdown = Bool(False, help = "This allows you to exclude markdown cells from all templates if set to True." ).tag(config=True) exclude_raw = Bool(False, help = "This allows you to exclude raw cells from all templates if set to True." ).tag(config=True) exclude_unknown = Bool(False, help = "This allows you to exclude unknown cells from all templates if set to True." ).tag(config=True) extra_loaders = List( help="Jinja loaders to find templates. Will be tried in order " "before the default FileSystem ones.", ).tag(affects_environment=True) filters = Dict( help="""Dictionary of filters, by name and namespace, to add to the Jinja environment.""" ).tag(config=True, affects_environment=True) raw_mimetypes = List( help="""formats of raw cells to be included in this Exporter's output.""" ).tag(config=True) @default('raw_mimetypes') def _raw_mimetypes_default(self): return [self.output_mimetype, ''] def __init__(self, config=None, **kw): """ Public constructor Parameters ---------- config : config User configuration instance. extra_loaders : list[of Jinja Loaders] ordered list of Jinja loader to find templates. Will be tried in order before the default FileSystem ones. template : str (optional, kw arg) Template to use when exporting. """ super(TemplateExporter, self).__init__(config=config, **kw) self.observe(self._invalidate_environment_cache, list(self.traits(affects_environment=True))) self.observe(self._invalidate_template_cache, list(self.traits(affects_template=True))) def _load_template(self): """Load the Jinja template object from the template file This is triggered by various trait changes that would change the template. """ if not self.template_file: raise ValueError("No template_file specified!") # First try to load the # template by name with extension added, then try loading the template # as if the name is explicitly specified. template_file = self.template_file self.log.debug("Attempting to load template %s", template_file) self.log.debug(" template_path: %s", os.pathsep.join(self.template_path)) return self.environment.get_template(template_file) def from_notebook_node(self, nb, resources=None, **kw): """ Convert a notebook from a notebook node instance. Parameters ---------- nb : :class:`~nbformat.NotebookNode` Notebook node resources : dict Additional resources that can be accessed read/write by preprocessors and filters. """ nb_copy, resources = super(TemplateExporter, self).from_notebook_node(nb, resources, **kw) resources.setdefault('raw_mimetypes', self.raw_mimetypes) resources['global_content_filter'] = { 'include_code': not self.exclude_code_cell, 'include_markdown': not self.exclude_markdown, 'include_raw': not self.exclude_raw, 'include_unknown': not self.exclude_unknown, 'include_input': not self.exclude_input, 'include_output': not self.exclude_output, 'include_input_prompt': not self.exclude_input_prompt, 'include_output_prompt': not self.exclude_output_prompt, 'no_prompt': self.exclude_input_prompt and self.exclude_output_prompt, } # Top level variables are passed to the template_exporter here. output = self.template.render(nb=nb_copy, resources=resources) return output, resources def _register_filter(self, environ, name, jinja_filter): """ Register a filter. A filter is a function that accepts and acts on one string. The filters are accessible within the Jinja templating engine. Parameters ---------- name : str name to give the filter in the Jinja engine filter : filter """ if jinja_filter is None: raise TypeError('filter') isclass = isinstance(jinja_filter, type) constructed = not isclass #Handle filter's registration based on it's type if constructed and isinstance(jinja_filter, py3compat.string_types): #filter is a string, import the namespace and recursively call #this register_filter method filter_cls = import_item(jinja_filter) return self._register_filter(environ, name, filter_cls) if constructed and hasattr(jinja_filter, '__call__'): #filter is a function, no need to construct it. environ.filters[name] = jinja_filter return jinja_filter elif isclass and issubclass(jinja_filter, HasTraits): #filter is configurable. Make sure to pass in new default for #the enabled flag if one was specified. filter_instance = jinja_filter(parent=self) self._register_filter(environ, name, filter_instance) elif isclass: #filter is not configurable, construct it filter_instance = jinja_filter() self._register_filter(environ, name, filter_instance) else: #filter is an instance of something without a __call__ #attribute. raise TypeError('filter') def register_filter(self, name, jinja_filter): """ Register a filter. A filter is a function that accepts and acts on one string. The filters are accessible within the Jinja templating engine. Parameters ---------- name : str name to give the filter in the Jinja engine filter : filter """ return self._register_filter(self.environment, name, jinja_filter) def default_filters(self): """Override in subclasses to provide extra filters. This should return an iterable of 2-tuples: (name, class-or-function). You should call the method on the parent class and include the filters it provides. If a name is repeated, the last filter provided wins. Filters from user-supplied config win over filters provided by classes. """ return default_filters.items() def _create_environment(self): """ Create the Jinja templating environment. """ here = os.path.dirname(os.path.realpath(__file__)) paths = self.template_path + \ [os.path.join(here, self.default_template_path), os.path.join(here, self.template_skeleton_path)] loaders = self.extra_loaders + [ ExtensionTolerantLoader(FileSystemLoader(paths), self.template_extension) ] environment = Environment( loader=ChoiceLoader(loaders), extensions=JINJA_EXTENSIONS ) environment.globals['uuid4'] = uuid.uuid4 # Add default filters to the Jinja2 environment for key, value in self.default_filters(): self._register_filter(environment, key, value) # Load user filters. Overwrite existing filters if need be. if self.filters: for key, user_filter in self.filters.items(): self._register_filter(environment, key, user_filter) return environment nbconvert-5.3.1/nbconvert/exporters/tests/000077500000000000000000000000001315361605600207235ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/exporters/tests/__init__.py000066400000000000000000000000001315361605600230220ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/exporters/tests/base.py000066400000000000000000000024211315361605600222060ustar00rootroot00000000000000"""Base TestCase class for testing Exporters""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import os from ...tests.base import TestsBase all_raw_mimetypes = { 'text/x-python', 'text/markdown', 'text/html', 'text/restructuredtext', 'text/latex', } class ExportersTestsBase(TestsBase): """Contains base test functions for exporters""" exporter_class = None should_include_raw = None def _get_notebook(self, nb_name='notebook2.ipynb'): return os.path.join(self._get_files_path(), nb_name) def test_raw_cell_inclusion(self): """test raw cell inclusion based on raw_mimetype metadata""" if self.should_include_raw is None: return exporter = self.exporter_class() (output, resources) = exporter.from_filename(self._get_notebook('rawtest.ipynb')) for inc in self.should_include_raw: self.assertIn('raw %s' % inc, output, "should include %s" % inc) self.assertIn('no raw_mimetype metadata', output) for exc in all_raw_mimetypes.difference(self.should_include_raw): self.assertNotIn('raw %s' % exc, output, "should exclude %s" % exc) self.assertNotIn('never be included', output) nbconvert-5.3.1/nbconvert/exporters/tests/cheese.py000066400000000000000000000027151315361605600225360ustar00rootroot00000000000000""" Contains CheesePreprocessor """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from ...preprocessors.base import Preprocessor #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- class CheesePreprocessor(Preprocessor): """ Adds a cheese tag to the resources object """ def __init__(self, **kw): """ Public constructor """ super(CheesePreprocessor, self).__init__(**kw) def preprocess(self, nb, resources): """ Sphinx preprocessing to apply on each notebook. Parameters ---------- nb : NotebookNode Notebook being converted resources : dictionary Additional resources used in the conversion process. Allows preprocessors to pass variables into the Jinja engine. """ resources['cheese'] = 'real' return nb, resources nbconvert-5.3.1/nbconvert/exporters/tests/files/000077500000000000000000000000001315361605600220255ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/exporters/tests/files/notebook2.ipynb000066400000000000000000000237761315361605600250110ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# NumPy and Matplotlib examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First import NumPy and Matplotlib:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Welcome to pylab, a matplotlib-based Python environment [backend: module://ipykernel.pylab.backend_inline].\n", "For more information, type 'help(pylab)'.\n" ] } ], "source": [ "%pylab inline" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we show some very basic examples of how they can be used." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "a = np.random.uniform(size=(100,100))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(100, 100)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.shape" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "tags": [ "remove_cell" ] }, "outputs": [], "source": [ "evs = np.linalg.eigvals(a)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "tags": [ "remove_output" ] }, "outputs": [ { "data": { "text/plain": [ "(100,)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evs.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is a cell that has both text and PNG output:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "tags": [ "remove_input" ] }, "outputs": [ { "data": { "text/plain": [ "(array([95, 4, 0, 0, 0, 0, 0, 0, 0, 1]),\n", " array([ -2.93566063, 2.35937011, 7.65440086, 12.9494316 ,\n", " 18.24446235, 23.53949309, 28.83452384, 34.12955458,\n", " 39.42458533, 44.71961607, 50.01464682]),\n", " )" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAD9CAYAAAC2l2x5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEhdJREFUeJzt3X1olfX/x/HXtVbT8CZDmsK6KmrubEu3U2xnZOpxLBnG\nOqsIE7RoE3QRZkT/yEAjcIh/LIs6i/BEGSU1CkxT0+pkFp1zMmsxZ5uUTIXoxm95lmdlef3+8Nep\ndbtz7exs16fnAw7sXNs5n/c14nmurl3naDmO4wgAYJy8sR4AADA6CDwAGIrAA4ChCDwAGIrAA4Ch\nCDwAGOofA9/U1KTCwkLNnj07vS2ZTCoUCsm2bTU2NmpgYCD9vccee0zFxcUqKyvTgQMHRm9qAMC/\n+sfA33PPPdq9e/eQbeFwWLZtq6+vT0VFRero6JAkffXVV3ryySf15ptvKhwOa/Xq1aM3NQDgX/1j\n4OfNm6dp06YN2RaPx9Xc3KyCggI1NTUpFotJkmKxmOrr62XbthYsWCDHcZRMJkdvcgDAP8r4HHwi\nkZDP55Mk+Xw+xeNxSecDX1pamv65kpKS9PcAALmXn+kDMvlkA8uyhrUNAPDvMv1kmYyP4KuqqtTT\n0yNJ6unpUVVVlSQpEAjo8OHD6Z87cuRI+nt/NaRXb+vWrRvzGZh/7Odgfu/dvDy747j7yLCMAx8I\nBBSJRJRKpRSJRFRTUyNJqq6u1p49e9Tf369oNKq8vDxNnjzZ1VAAgJH7x8AvXbpUN9xwg3p7e3X5\n5ZfrmWeeUUtLi/r7+1VSUqKTJ09q1apVkqTCwkK1tLSotrZW9957rzZv3pyTHQAA/DXLcXvs73ZB\ny3L9vxvjQTQaVTAYHOsxXGP+scX8Y8fLs0vu2kngAcAD3LSTjyoAAEMReAAwFIEHAEMReAAwFIEH\nAEP9ZwM/Zcqlsixr1G9Tplw61rsK4D/qP3uZ5PnPxMnFHONjfwF4G5dJAgDSCDwAGIrAA4ChCDwA\nGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrA\nA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChXAf+6aef1g03\n3KDrr79ea9askSQlk0mFQiHZtq3GxkYNDAxkbVAAQGZcBf7UqVPasGGD9u7dq0Qiod7eXu3Zs0fh\ncFi2bauvr09FRUXq6OjI9rwAgGFyFfiJEyfKcRx9//33SqVSOnPmjC655BLF43E1NzeroKBATU1N\nisVi2Z4XADBMrgMfDod15ZVXasaMGZo7d64CgYASiYR8Pp8kyefzKR6PZ3VYAMDw5bt50Ndff62W\nlhYdPnxY06ZN0x133KEdO3bIcZxhPX79+vXpr4PBoILBoJsxAMBY0WhU0Wh0RM9hOcOt8u/s3LlT\nW7du1bZt2yRJ4XBYx44d09GjR9Xa2iq/36+DBw+qra1NnZ2dQxe0rGG/EIwmy7Ik5WKO8bG/ALzN\nTTtdnaKZN2+ePvzwQ506dUo//vijdu3apUWLFikQCCgSiSiVSikSiaimpsbN0wMAssBV4KdMmaLW\n1lbdeuutuvHGG1VRUaGFCxeqpaVF/f39Kikp0cmTJ7Vq1apszwsAGCZXp2hGtCCnaAAgYzk7RQMA\nGP8IPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEI\nPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAY\nisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYynXgf/jhB919992a\nNWuWysrKFIvFlEwmFQqFZNu2GhsbNTAwkM1ZAQAZcB34devWybZtdXV1qaurSz6fT+FwWLZtq6+v\nT0VFRero6MjmrACADLgO/L59+7R27VpNmDBB+fn5mjp1quLxuJqbm1VQUKCmpibFYrFszgoAyICr\nwJ84cUKDg4NqaWlRIBDQxo0blUqllEgk5PP5JEk+n0/xeDyrwwIAhi/fzYMGBwfV29urTZs2qa6u\nTitXrtRLL70kx3GG9fj169envw4GgwoGg27GAABjRaNRRaPRET2H5Qy3yn9QWlqqnp4eSdKuXbv0\n3HPP6aefflJra6v8fr8OHjyotrY2dXZ2Dl3Qsob9QjCaLMuSlIs5xsf+AvA2N+10fQ6+uLhYsVhM\n586d086dO1VXV6dAIKBIJKJUKqVIJKKamhq3Tw8AGCHXR/C9vb266667NDg4qLq6Oj388MM6d+6c\nli1bpkOHDum6667T888/r0mTJg1dkCN4AMiYm3a6DrxbBB4AMpfTUzQAgPGNwAOAoQg8ABiKwAOA\n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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "hist(evs.real)" ] }, { "cell_type": "markdown", "metadata": { "tags": [ "remove_cell" ] }, "source": [ "This cell is just markdown testing whether an ASCIIDoc quirk is caught and whether [header links are rendered](#numpy-and-matplotlib-examples) even if they [don't resolve correctly now](#NumPy-and-Matplotlib-examples).\n", "\n", "one *test* two *tests*. three *tests*" ] } ], "metadata": { "celltoolbar": "Tags", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" } }, "nbformat": 4, "nbformat_minor": 1 } nbconvert-5.3.1/nbconvert/exporters/tests/files/pngmetadata.ipynb000066400000000000000000000406001315361605600253550ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": [ "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\n", "yXu7+0V77P9Cku7uixZ5/CxfVV2b5IM5ZGlfxRxlqGvaT063t+/e0d1fSvKRJE9Mst+asUWNwzCs\n", "4vv5J7u2DN9Cz4uq+vokb07ylu7+jUUdJCu3qPPiuiRPSfIrSXq6hvm1VXW9dcujtKjz4u4kX0ly\n", "dVU9+cwdVfUtmSyp+8DcR8uYLH2OMtRJ+4np9u4Z+++Zbq9a0TgMw1K/n1V1LMnOb9XvO8oYrMXC\n", "zovpOXBLkvuSvG7uI2OdFnVefPN0++UkH0/yn5O8KcmNSe6oql+vqqfMc6Cs1ELOi57cpf21mSyr\n", "/J2qekdVvamqfimTJRK3J/kHCzhexmPpc85jR/3AJdv530mz7oS68/x+78Rd1DgMw7K/n29O8qwk\n", "v9rd7z/iGKzeIs+LH0/yjZm8WejL8x4Ya7Wo8+KS6fY1Sf53kr+eyeT9eJJ/neR5Sd6dxysbw7aw\n", "vy+6+99U1SeT/PskLztj1yeS/Hx3f/bIR8kYLX3OOdTSDitVVT+U5EeS/J8k37fmw2ENpmtUfyzJ\n", "v+ru/7bu42Ewdn5O/r8kL+juO7r74e7+7SQvSvLpJN9qqcz2qap/kskvbD+XyS9xT0jyTUnuTfKL\n", "06vLwMIMddK+89vIrDdw7Dz/4IrGYRiW8v2sqn+c5C2ZVLST3e18GJe5z4vpsphfyOSSXK+f9bIj\n", "HR3rsqi/L3b2f6y7P3Xmju5+JJOlEMnjy2gYtoWcF9M3K745kzei/mh339fdj3b3xzL5Ze4zSV5d\n", "VVcs4JgZh6XPOYc6ab9zuj0xY//OeqBZ64YWPQ7DsPDvZ1W9KslbM7ke98nu/sOjHx5rsojz4oLp\n", "656Z5NEzbqj0WCZLZpLk302fu3HuI2YVFv1zZNYP2p3n/9wBj4v1WtR58Z3T7Yd275j+Mvc/Mplj\n", "feNhD5DRWvqcc6hr2nf+EFxXVdVnXJeyqi5Mck0ml9/66IrGYRgW+v2sqtdm8oayjyW5rt1ka6wW\n", "cV48msm61L2ugftNSf5Kkg9nUuLvWMRBs3SL+vvi1zI5L565e5ypvzzdnl7AMbN8izovvma6vWTG\n", "/oun268c9UAZnaXPOQdZ2rv73kzeeX1Fklfs2n1DJuvGbpn+NpuqOlZVz6iq4/OMw7At6ryY7vsX\n", "mUzYfyvJc03Yx2sR58X0f2v/QHe/fPcjk6uFJJM3lr28u9+9/K+KeS3w58inMjkH/lKSs+7dUFXP\n", "S/I3k3w+rjg1Cgv8OfJfp9uXV9VfOHNHVX17JhO0R+KX/I2zzjnnIG+ulCTT/xh3ZPJb7Hvz+K1g\n", "r82kdj1nesmlVNXlmbzx45PdfcVRx2H4FnFeVNXfyeSNQ3+a5KYkX9jjU53u7p9f1tfBYi3q74sZ\n", "Y5+KmyuN0gJ/jvzF6ThPy6S8fzyTH8wvzOTvke/p7luX/gWxEAv6OVKZvJ/h25J8McmtSf4gyddn\n", "snSmk7yqu29axdfEfKrqhZn8eU4md7t9Xibf9517dfxRd79m+trLs64552Fun7rqR5LLMrlt9P2Z\n", "XCP3dCZ3Kbxo1+suz+T2sPfOM47HOB7znheZvNHwsUx+2D424/HBdX+dHqs9L84z7uun58r3r/tr\n", "9FjfeZHJDZbemsk1/L+c5A+T/HKSv7bur9FjPedFJkuMr8/kzqgPZXKFoQeS/Kck37bur9HjUOfD\n", "mfOCMx+P7f7+r3POOdjSDgAATAxyTTsAAPA4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4\n", "k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YAABg4k3YA\n", "ABg4k3YAABi4/w/Y3UZ5IHmVbAAAAABJRU5ErkJggg==\n" ], "text/plain": [ "" ] }, "metadata": { "image/png": { "height": 255, "width": 374 } }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "%config InlineBackend.figure_formats = set(['retina'])\n", "import matplotlib.pyplot as plt\n", "plt.plot([0,1],[1,0])" ] } ], "metadata": { "kernelspec": { "display_name": "IPython mydev (Python 3)", "name": "python3_mydev" }, "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" } }, "nbformat": 4, "nbformat_minor": 0 }nbconvert-5.3.1/nbconvert/exporters/tests/files/prompt_numbers.ipynb000066400000000000000000000025601315361605600261470ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(100,)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evs = np.zeros(100)\n", "evs.shape" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ " " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ " " ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "collapsed": true }, "outputs": [], "source": [ " " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" } }, "nbformat": 4, "nbformat_minor": 1 } nbconvert-5.3.1/nbconvert/exporters/tests/files/rawtest.ipynb000066400000000000000000000022741315361605600245660ustar00rootroot00000000000000{ "cells": [ { "cell_type": "raw", "metadata": { "raw_mimetype": "text/html" }, "source": [ "raw html" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/markdown" }, "source": [ "* raw markdown\n", "* bullet\n", "* list" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "``raw rst``\n", "\n", ".. sourcecode:: python\n", "\n", " def foo(): pass\n" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/x-python" }, "source": [ "def bar():\n", " \"\"\"raw python\"\"\"\n", " pass" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/latex" }, "source": [ "\\LaTeX\n", "% raw latex" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "# no raw_mimetype metadata, should be included by default" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "doesnotexist" }, "source": [ "garbage format defined, should never be included" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }nbconvert-5.3.1/nbconvert/exporters/tests/test_asciidoc.py000066400000000000000000000025271315361605600241200ustar00rootroot00000000000000"""Tests for ASCIIDocExporter`""" #----------------------------------------------------------------------------- # Copyright (c) 2016, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from .base import ExportersTestsBase from ..asciidoc import ASCIIDocExporter from ipython_genutils.testing import decorators as dec #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- class TestASCIIDocExporter(ExportersTestsBase): """Tests for ASCIIDocExporter""" exporter_class = ASCIIDocExporter def test_constructor(self): """ Can a ASCIIDocExporter be constructed? """ ASCIIDocExporter() @dec.onlyif_cmds_exist('pandoc') def test_export(self): """ Can a ASCIIDocExporter export something? """ (output, resources) = ASCIIDocExporter().from_filename(self._get_notebook()) assert len(output) > 0 nbconvert-5.3.1/nbconvert/exporters/tests/test_export.py000066400000000000000000000055301315361605600236600ustar00rootroot00000000000000""" Module with tests for export.py """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import os import sys import nbformat import nbconvert.tests from .base import ExportersTestsBase from ..base import get_exporter, export, ExporterNameError, get_export_names from ..exporter import Exporter from ..exporter_locator import export_by_name from ..python import PythonExporter class TestExport(ExportersTestsBase): """Contains test functions for export.py""" def test_export_wrong_name(self): """ Is the right error thrown when a bad template name is used? """ try: export_by_name('not_a_name', self._get_notebook()) except ExporterNameError as e: pass def test_export_filename(self): """ Can a notebook be exported by filename? """ (output, resources) = export_by_name('python', self._get_notebook()) assert len(output) > 0 def test_export_nbnode(self): """ Can a notebook be exported by a notebook node handle? """ with open(self._get_notebook(), 'r') as f: notebook = nbformat.read(f, 4) (output, resources) = export_by_name('python', notebook) assert len(output) > 0 def test_export_filestream(self): """ Can a notebook be exported by a filesteam? """ with open(self._get_notebook(), 'r') as f: (output, resources) = export_by_name('python', f) assert len(output) > 0 def test_export_using_exporter(self): """ Can a notebook be exported using an instanciated exporter? """ (output, resources) = export(PythonExporter(), self._get_notebook()) assert len(output) > 0 def test_export_using_exporter_class(self): """ Can a notebook be exported using an exporter class type? """ (output, resources) = export(PythonExporter, self._get_notebook()) assert len(output) > 0 def test_export_resources(self): """ Can a notebook be exported along with a custom resources dict? """ (output, resources) = export(PythonExporter, self._get_notebook(), resources={}) assert len(output) > 0 def test_no_exporter(self): """ Is the right error thrown if no exporter is provided? """ try: (output, resources) = export(None, self._get_notebook()) except TypeError: pass def test_get_exporter_entrypoint(): p = os.path.join(os.path.dirname(nbconvert.tests.__file__), 'exporter_entrypoint') sys.path.insert(0, p) assert 'entrypoint_test' in get_export_names() try: cls = get_exporter('entrypoint_test') assert issubclass(cls, Exporter), cls finally: del sys.path[0] nbconvert-5.3.1/nbconvert/exporters/tests/test_exporter.py000066400000000000000000000035321315361605600242070ustar00rootroot00000000000000""" Module with tests for exporter.py """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from traitlets.config import Config from .base import ExportersTestsBase from ...preprocessors.base import Preprocessor from ..exporter import Exporter #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- class PizzaPreprocessor(Preprocessor): """Simple preprocessor that adds a 'pizza' entry to the NotebookNode. Used to test Exporter. """ def preprocess(self, nb, resources): nb['pizza'] = 'cheese' return nb, resources class TestExporter(ExportersTestsBase): """Contains test functions for exporter.py""" def test_constructor(self): """Can an Exporter be constructed?""" Exporter() def test_export(self): """Can an Exporter export something?""" exporter = Exporter() (notebook, resources) = exporter.from_filename(self._get_notebook()) assert isinstance(notebook, dict) def test_preprocessor(self): """Do preprocessors work?""" config = Config({'Exporter': {'preprocessors': [PizzaPreprocessor()]}}) exporter = Exporter(config=config) (notebook, resources) = exporter.from_filename(self._get_notebook()) self.assertEqual(notebook['pizza'], 'cheese') nbconvert-5.3.1/nbconvert/exporters/tests/test_html.py000066400000000000000000000054251315361605600233060ustar00rootroot00000000000000"""Tests for HTMLExporter""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from .base import ExportersTestsBase from ..html import HTMLExporter from nbformat import v4 import re class TestHTMLExporter(ExportersTestsBase): """Tests for HTMLExporter""" exporter_class = HTMLExporter should_include_raw = ['html'] def test_constructor(self): """ Can a HTMLExporter be constructed? """ HTMLExporter() def test_export(self): """ Can a HTMLExporter export something? """ (output, resources) = HTMLExporter().from_filename(self._get_notebook()) assert len(output) > 0 def test_export_basic(self): """ Can a HTMLExporter export using the 'basic' template? """ (output, resources) = HTMLExporter(template_file='basic').from_filename(self._get_notebook()) assert len(output) > 0 def test_export_full(self): """ Can a HTMLExporter export using the 'full' template? """ (output, resources) = HTMLExporter(template_file='full').from_filename(self._get_notebook()) assert len(output) > 0 def test_prompt_number(self): """ Does HTMLExporter properly format input and output prompts? """ (output, resources) = HTMLExporter(template_file='full').from_filename( self._get_notebook(nb_name="prompt_numbers.ipynb")) in_regex = r"In \[(.*)\]:" out_regex = r"Out\[(.*)\]:" ins = ["2", "10", " ", " ", "0"] outs = ["10"] assert re.findall(in_regex, output) == ins assert re.findall(out_regex, output) == outs def test_png_metadata(self): """ Does HTMLExporter with the 'basic' template treat pngs with width/height metadata correctly? """ (output, resources) = HTMLExporter(template_file='basic').from_filename( self._get_notebook(nb_name="pngmetadata.ipynb")) check_for_png = re.compile(r']*?)>') result = check_for_png.search(output) attr_string = result.group(1) assert 'width' in attr_string assert 'height' in attr_string def test_javascript_output(self): nb = v4.new_notebook( cells=[ v4.new_code_cell( outputs=[v4.new_output( output_type='display_data', data={ 'application/javascript': "javascript_output();" } )] ) ] ) (output, resources) = HTMLExporter(template_file='basic').from_notebook_node(nb) self.assertIn('javascript_output', output) nbconvert-5.3.1/nbconvert/exporters/tests/test_latex.py000066400000000000000000000112111315361605600234450ustar00rootroot00000000000000"""Tests for Latex exporter""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import os.path import textwrap import re from .base import ExportersTestsBase from ..latex import LatexExporter from nbformat import write from nbformat import v4 from ipython_genutils.testing.decorators import onlyif_cmds_exist from testpath.tempdir import TemporaryDirectory from jinja2 import DictLoader class TestLatexExporter(ExportersTestsBase): """Contains test functions for latex.py""" exporter_class = LatexExporter should_include_raw = ['latex'] def test_constructor(self): """ Can a LatexExporter be constructed? """ LatexExporter() @onlyif_cmds_exist('pandoc') def test_export(self): """ Can a LatexExporter export something? """ (output, resources) = LatexExporter().from_filename(self._get_notebook()) assert len(output) > 0 @onlyif_cmds_exist('pandoc') def test_export_book(self): """ Can a LatexExporter export using 'report' template? """ (output, resources) = LatexExporter(template_file='report').from_filename(self._get_notebook()) assert len(output) > 0 @onlyif_cmds_exist('pandoc') def test_export_basic(self): """ Can a LatexExporter export using 'article' template? """ (output, resources) = LatexExporter(template_file='article').from_filename(self._get_notebook()) assert len(output) > 0 @onlyif_cmds_exist('pandoc') def test_export_article(self): """ Can a LatexExporter export using 'article' template? """ (output, resources) = LatexExporter(template_file='article').from_filename(self._get_notebook()) assert len(output) > 0 @onlyif_cmds_exist('pandoc') def test_very_long_cells(self): """ Torture test that long cells do not cause issues """ lorem_ipsum_text = textwrap.dedent("""\ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec dignissim, ipsum non facilisis tempus, dui felis tincidunt metus, nec pulvinar neque odio eget risus. Nulla nisi lectus, cursus suscipit interdum at, ultrices sit amet orci. Mauris facilisis imperdiet elit, vitae scelerisque ipsum dignissim non. Integer consequat malesuada neque sit amet pulvinar. Curabitur pretium ut turpis eget aliquet. Maecenas sagittis lacus sed lectus volutpat, eu adipiscing purus pulvinar. Maecenas consequat luctus urna, eget cursus quam mollis a. Aliquam vitae ornare erat, non hendrerit urna. Sed eu diam nec massa egestas pharetra at nec tellus. Fusce feugiat lacus quis urna sollicitudin volutpat. Quisque at sapien non nibh feugiat tempus ac ultricies purus. """) lorem_ipsum_text = lorem_ipsum_text.replace("\n"," ") + "\n\n" large_lorem_ipsum_text = "".join([lorem_ipsum_text]*3000) notebook_name = "lorem_ipsum_long.ipynb" nb = v4.new_notebook( cells=[ v4.new_markdown_cell(source=large_lorem_ipsum_text) ] ) with TemporaryDirectory() as td: nbfile = os.path.join(td, notebook_name) with open(nbfile, 'w') as f: write(nb, f, 4) (output, resources) = LatexExporter(template_file='article').from_filename(nbfile) assert len(output) > 0 @onlyif_cmds_exist('pandoc') def test_prompt_number_color(self): """ Does LatexExporter properly format input and output prompts in color? """ (output, resources) = LatexExporter().from_filename( self._get_notebook(nb_name="prompt_numbers.ipynb")) in_regex = r"In \[\{\\color\{incolor\}(.*)\}\]:" out_regex = r"Out\[\{\\color\{outcolor\}(.*)\}\]:" ins = ["2", "10", " ", " ", "0"] outs = ["10"] assert re.findall(in_regex, output) == ins assert re.findall(out_regex, output) == outs def test_in_memory_template_tplx(self): # Loads in an in memory latex template (.tplx) using jinja2.DictLoader # creates a class that uses this template with the template_file argument # converts an empty notebook using this mechanism my_loader_tplx = DictLoader({'my_template': "{%- extends 'article.tplx' -%}"}) class MyExporter(LatexExporter): template_file = 'my_template' exporter = MyExporter(extra_loaders=[my_loader_tplx]) nb = v4.new_notebook() out, resources = exporter.from_notebook_node(nb) nbconvert-5.3.1/nbconvert/exporters/tests/test_markdown.py000066400000000000000000000024471315361605600241650ustar00rootroot00000000000000"""Tests for MarkdownExporter""" #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from .base import ExportersTestsBase from ..markdown import MarkdownExporter #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- class TestMarkdownExporter(ExportersTestsBase): """Tests for MarkdownExporter""" exporter_class = MarkdownExporter should_include_raw = ['markdown', 'html'] def test_constructor(self): """ Can a MarkdownExporter be constructed? """ MarkdownExporter() def test_export(self): """ Can a MarkdownExporter export something? """ (output, resources) = MarkdownExporter().from_filename(self._get_notebook()) assert len(output) > 0nbconvert-5.3.1/nbconvert/exporters/tests/test_notebook.py000066400000000000000000000023741315361605600241620ustar00rootroot00000000000000"""Tests for notebook.py""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import json from .base import ExportersTestsBase from ..notebook import NotebookExporter from nbformat import validate from nbconvert.tests.base import assert_big_text_equal class TestNotebookExporter(ExportersTestsBase): """Contains test functions for notebook.py""" exporter_class = NotebookExporter def test_export(self): """ Does the NotebookExporter return the file unchanged? """ with open(self._get_notebook()) as f: file_contents = f.read() (output, resources) = self.exporter_class().from_filename(self._get_notebook()) assert len(output) > 0 assert_big_text_equal(output, file_contents) def test_downgrade_3(self): exporter = self.exporter_class(nbformat_version=3) (output, resources) = exporter.from_filename(self._get_notebook()) nb = json.loads(output) validate(nb) def test_downgrade_2(self): exporter = self.exporter_class(nbformat_version=2) (output, resources) = exporter.from_filename(self._get_notebook()) nb = json.loads(output) self.assertEqual(nb['nbformat'], 2) nbconvert-5.3.1/nbconvert/exporters/tests/test_pdf.py000066400000000000000000000022561315361605600231120ustar00rootroot00000000000000"""Tests for PDF export""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import logging import os import shutil from ipython_genutils.testing import decorators as dec from testpath import tempdir from .base import ExportersTestsBase from ..pdf import PDFExporter #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- class TestPDF(ExportersTestsBase): """Test PDF export""" exporter_class = PDFExporter def test_constructor(self): """Can a PDFExporter be constructed?""" self.exporter_class() @dec.onlyif_cmds_exist('xelatex') @dec.onlyif_cmds_exist('pandoc') def test_export(self): """Smoke test PDFExporter""" with tempdir.TemporaryDirectory() as td: newpath = os.path.join(td, os.path.basename(self._get_notebook())) shutil.copy(self._get_notebook(), newpath) (output, resources) = self.exporter_class(latex_count=1).from_filename(newpath) self.assertIsInstance(output, bytes) assert len(output) > 0 nbconvert-5.3.1/nbconvert/exporters/tests/test_python.py000066400000000000000000000012651315361605600236610ustar00rootroot00000000000000"""Tests for PythonExporter""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from .base import ExportersTestsBase from ..python import PythonExporter class TestPythonExporter(ExportersTestsBase): """Tests for PythonExporter""" exporter_class = PythonExporter should_include_raw = ['python'] def test_constructor(self): """Can a PythonExporter be constructed?""" self.exporter_class() def test_export(self): """Can a PythonExporter export something?""" (output, resources) = self.exporter_class().from_filename(self._get_notebook()) self.assertIn("coding: utf-8", output) nbconvert-5.3.1/nbconvert/exporters/tests/test_rst.py000066400000000000000000000041521315361605600231460ustar00rootroot00000000000000"""Tests for RSTExporter""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import io import re import nbformat from nbformat import v4 from .base import ExportersTestsBase from ..rst import RSTExporter from ipython_genutils.testing.decorators import onlyif_cmds_exist class TestRSTExporter(ExportersTestsBase): """Tests for RSTExporter""" exporter_class = RSTExporter should_include_raw = ['rst'] def test_constructor(self): """ Can a RSTExporter be constructed? """ RSTExporter() @onlyif_cmds_exist('pandoc') def test_export(self): """ Can a RSTExporter export something? """ (output, resources) = RSTExporter().from_filename(self._get_notebook()) assert len(output) > 0 @onlyif_cmds_exist('pandoc') def test_empty_code_cell(self): """No empty code cells in rst""" nbname = self._get_notebook() with io.open(nbname, encoding='utf8') as f: nb = nbformat.read(f, 4) exporter = self.exporter_class() (output, resources) = exporter.from_notebook_node(nb) # add an empty code cell nb.cells.append( v4.new_code_cell(source="") ) (output2, resources) = exporter.from_notebook_node(nb) # adding an empty code cell shouldn't change output self.assertEqual(output.strip(), output2.strip()) @onlyif_cmds_exist('pandoc') def test_png_metadata(self): """ Does RSTExporter treat pngs with width/height metadata correctly? """ (output, resources) = RSTExporter().from_filename( self._get_notebook(nb_name="pngmetadata.ipynb")) assert len(output) > 0 check_for_png = re.compile( r'.. image::.*?\n\s+(.*?)\n\s*\n', re.DOTALL) result = check_for_png.search(output) assert result is not None attr_string = result.group(1) assert ':width:' in attr_string assert ':height:' in attr_string assert 'px' in attr_string nbconvert-5.3.1/nbconvert/exporters/tests/test_script.py000066400000000000000000000033221315361605600236400ustar00rootroot00000000000000"""Tests for ScriptExporter""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import os import sys from nbformat import v4 import nbconvert from .base import ExportersTestsBase from ..script import ScriptExporter class TestScriptExporter(ExportersTestsBase): """Tests for ScriptExporter""" exporter_class = ScriptExporter def test_constructor(self): """Construct ScriptExporter""" e = self.exporter_class() def test_export(self): """ScriptExporter can export something""" (output, resources) = self.exporter_class().from_filename(self._get_notebook()) assert len(output) > 0 def test_export_python(self): """delegate to custom exporter from language_info""" exporter = self.exporter_class() pynb = v4.new_notebook() (output, resources) = self.exporter_class().from_notebook_node(pynb) self.assertNotIn('# coding: utf-8', output) pynb.metadata.language_info = { 'name': 'python', 'mimetype': 'text/x-python', 'nbconvert_exporter': 'python', } (output, resources) = self.exporter_class().from_notebook_node(pynb) self.assertIn('# coding: utf-8', output) def test_script_exporter_entrypoint(): nb = v4.new_notebook() nb.metadata.language_info = { 'name': 'dummy', 'mimetype': 'text/x-dummy', } p = os.path.join(os.path.dirname(nbconvert.tests.__file__), 'exporter_entrypoint') sys.path.insert(0, p) try: output, _ = ScriptExporter().from_notebook_node(nb) assert output == 'dummy-script-exported' finally: sys.path.remove(p) nbconvert-5.3.1/nbconvert/exporters/tests/test_slides.py000066400000000000000000000055171315361605600236270ustar00rootroot00000000000000"""Tests for SlidesExporter""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from nbformat import v4 as nbformat from .base import ExportersTestsBase from ..slides import SlidesExporter, prepare class TestSlidesExporter(ExportersTestsBase): """Tests for SlidesExporter""" exporter_class = SlidesExporter should_include_raw = ['html'] def test_constructor(self): """ Can a SlidesExporter be constructed? """ SlidesExporter() def test_export(self): """ Can a SlidesExporter export something? """ (output, resources) = SlidesExporter().from_filename(self._get_notebook()) assert len(output) > 0 def test_export_reveal(self): """ Can a SlidesExporter export using the 'reveal' template? """ (output, resources) = SlidesExporter(template_file='slides_reveal').from_filename(self._get_notebook()) assert len(output) > 0 def build_notebook(self): """Build a reveal slides notebook in memory for use with tests.""" outputs = [nbformat.new_output(output_type="stream", name="stdout", text="a")] slide_metadata = {'slideshow' : {'slide_type': 'slide'}} subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}} fragment_metadata = {'slideshow' : {'slide_type': 'fragment'}} cells=[nbformat.new_code_cell(source="", execution_count=1, outputs=outputs), nbformat.new_markdown_cell(source="", metadata=slide_metadata), nbformat.new_code_cell(source="", execution_count=2, outputs=outputs), nbformat.new_markdown_cell(source="", metadata=slide_metadata), nbformat.new_markdown_cell(source="", metadata=subslide_metadata), nbformat.new_markdown_cell(source="", metadata=fragment_metadata), nbformat.new_code_cell(source="", execution_count=1, outputs=outputs)] return nbformat.new_notebook(cells=cells) def test_prepare(self): nb = self.build_notebook() nb = prepare(nb) cells = nb.cells # Make sure correct metadata tags are available on every cell. for cell in cells: assert 'slide_type' in cell.metadata # Make sure slide end is only applied to the cells preceeding slide # cells. assert not cells[1].metadata.get('slide_end', False) # Verify 'slide-end' assert cells[0].metadata['slide_end'] assert cells[2].metadata['slide_end'] assert cells[2].metadata['subslide_end'] assert not cells[3].metadata.get('slide_end', False) assert cells[3].metadata['subslide_end'] assert cells[-1].metadata['fragment_end'] assert cells[-1].metadata['subslide_end'] assert cells[-1].metadata['slide_end'] nbconvert-5.3.1/nbconvert/exporters/tests/test_templateexporter.py000066400000000000000000000243031315361605600257420ustar00rootroot00000000000000""" Module with tests for templateexporter.py """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import os from traitlets.config import Config from jinja2 import DictLoader, TemplateNotFound from nbformat import v4 from .base import ExportersTestsBase from .cheese import CheesePreprocessor from ..templateexporter import TemplateExporter from ..html import HTMLExporter from ..markdown import MarkdownExporter from testpath import tempdir import pytest class TestExporter(ExportersTestsBase): """Contains test functions for exporter.py""" def test_constructor(self): """ Can a TemplateExporter be constructed? """ TemplateExporter() def test_export(self): """ Can a TemplateExporter export something? """ exporter = self._make_exporter() (output, resources) = exporter.from_filename(self._get_notebook()) assert len(output) > 0 def test_extract_outputs(self): """ If the ExtractOutputPreprocessor is enabled, are outputs extracted? """ config = Config({'ExtractOutputPreprocessor': {'enabled': True}}) exporter = self._make_exporter(config=config) (output, resources) = exporter.from_filename(self._get_notebook()) assert resources is not None assert isinstance(resources['outputs'], dict) assert len(resources['outputs']) > 0 def test_preprocessor_class(self): """ Can a preprocessor be added to the preprocessors list by class type? """ config = Config({'Exporter': {'preprocessors': [CheesePreprocessor]}}) exporter = self._make_exporter(config=config) (output, resources) = exporter.from_filename(self._get_notebook()) assert resources is not None assert resources['cheese'] == 'real' def test_preprocessor_instance(self): """ Can a preprocessor be added to the preprocessors list by instance? """ config = Config({'Exporter': {'preprocessors': [CheesePreprocessor()]}}) exporter = self._make_exporter(config=config) (output, resources) = exporter.from_filename(self._get_notebook()) assert resources is not None assert resources['cheese'] == 'real' def test_preprocessor_dottedobjectname(self): """ Can a preprocessor be added to the preprocessors list by dotted object name? """ config = Config({'Exporter': {'preprocessors': ['nbconvert.exporters.tests.cheese.CheesePreprocessor']}}) exporter = self._make_exporter(config=config) (output, resources) = exporter.from_filename(self._get_notebook()) assert resources is not None assert resources['cheese'] == 'real' def test_preprocessor_via_method(self): """ Can a preprocessor be added via the Exporter convenience method? """ exporter = self._make_exporter() exporter.register_preprocessor(CheesePreprocessor, enabled=True) (output, resources) = exporter.from_filename(self._get_notebook()) assert resources is not None assert resources['cheese'] == 'real' def test_absolute_template_file(self): with tempdir.TemporaryDirectory() as td: template = os.path.join(td, 'abstemplate.tpl') test_output = 'absolute!' with open(template, 'w') as f: f.write(test_output) config = Config() config.TemplateExporter.template_file = template exporter = self._make_exporter(config=config) assert exporter.template.filename == template assert os.path.dirname(template) in exporter.template_path def test_relative_template_file(self): with tempdir.TemporaryWorkingDirectory() as td: os.mkdir('relative') template = os.path.abspath(os.path.join(td, 'relative', 'relative_template.tpl')) test_output = 'relative!' with open(template, 'w') as f: f.write(test_output) config = Config() config.TemplateExporter.template_file = template exporter = self._make_exporter(config=config) assert os.path.abspath(exporter.template.filename) == template assert os.path.dirname(template) in [os.path.abspath(d) for d in exporter.template_path] def test_in_memory_template(self): # Loads in an in memory template using jinja2.DictLoader # creates a class that uses this template with the template_file argument # converts an empty notebook using this mechanism my_loader = DictLoader({'my_template': "{%- extends 'rst.tpl' -%}"}) class MyExporter(TemplateExporter): template_file = 'my_template' exporter = MyExporter(extra_loaders=[my_loader]) nb = v4.new_notebook() out, resources = exporter.from_notebook_node(nb) def test_fail_to_find_template_file(self): # Create exporter with invalid template file, check that it doesn't # exist in the environment, try to convert empty notebook. Failure is # expected due to nonexistant template file. template = 'does_not_exist.tpl' exporter = TemplateExporter(template_file=template) assert template not in exporter.environment.list_templates(extensions=['tpl']) nb = v4.new_notebook() with pytest.raises(TemplateNotFound): out, resources = exporter.from_notebook_node(nb) def test_exclude_code_cell(self): no_io = { "TemplateExporter":{ "exclude_output": True, "exclude_input": True, "exclude_input_prompt": False, "exclude_output_prompt": False, "exclude_markdown": False, "exclude_code_cell": False, } } c_no_io = Config(no_io) exporter_no_io = TemplateExporter(config=c_no_io) exporter_no_io.template_file = 'markdown' nb_no_io, resources_no_io = exporter_no_io.from_filename(self._get_notebook()) assert not resources_no_io['global_content_filter']['include_input'] assert not resources_no_io['global_content_filter']['include_output'] no_code = { "TemplateExporter":{ "exclude_output": False, "exclude_input": False, "exclude_input_prompt": False, "exclude_output_prompt": False, "exclude_markdown": False, "exclude_code_cell": True, } } c_no_code = Config(no_code) exporter_no_code = TemplateExporter(config=c_no_code) exporter_no_code.template_file = 'markdown' nb_no_code, resources_no_code = exporter_no_code.from_filename(self._get_notebook()) assert not resources_no_code['global_content_filter']['include_code'] assert nb_no_io == nb_no_code def test_exclude_input_prompt(self): no_input_prompt = { "TemplateExporter":{ "exclude_output": False, "exclude_input": False, "exclude_input_prompt": True, "exclude_output_prompt": False, "exclude_markdown": False, "exclude_code_cell": False, } } c_no_input_prompt = Config(no_input_prompt) exporter_no_input_prompt = MarkdownExporter(config=c_no_input_prompt) nb_no_input_prompt, resources_no_input_prompt = exporter_no_input_prompt.from_filename(self._get_notebook()) assert not resources_no_input_prompt['global_content_filter']['include_input_prompt'] assert "# In[" not in nb_no_input_prompt def test_exclude_markdown(self): no_md= { "TemplateExporter":{ "exclude_output": False, "exclude_input": False, "exclude_input_prompt": False, "exclude_output_prompt": False, "exclude_markdown": True, "exclude_code_cell": False, } } c_no_md = Config(no_md) exporter_no_md = TemplateExporter(config=c_no_md) exporter_no_md.template_file = 'python' nb_no_md, resources_no_md = exporter_no_md.from_filename(self._get_notebook()) assert not resources_no_md['global_content_filter']['include_markdown'] assert "First import NumPy and Matplotlib" not in nb_no_md def test_exclude_output_prompt(self): no_output_prompt = { "TemplateExporter":{ "exclude_output": False, "exclude_input": False, "exclude_input_prompt": False, "exclude_output_prompt": True, "exclude_markdown": False, "exclude_code_cell": False, } } c_no_output_prompt = Config(no_output_prompt) exporter_no_output_prompt = HTMLExporter(config=c_no_output_prompt) nb_no_output_prompt, resources_no_output_prompt = exporter_no_output_prompt.from_filename(self._get_notebook()) assert not resources_no_output_prompt['global_content_filter']['include_output_prompt'] assert "Out[" not in nb_no_output_prompt def test_remove_elements_with_tags(self): conf = Config({ "TagRemovePreprocessor": { "remove_cell_tags": ["remove_cell"], "remove_all_outputs_tags": ["remove_output"], "remove_input_tags": ["remove_input"] }, }) exporter = MarkdownExporter(config=conf) nb, resources = exporter.from_filename(self._get_notebook()) assert "hist(evs.real)" not in nb assert "cell is just markdown testing whether" not in nb assert "(100,)" not in nb def _make_exporter(self, config=None): # Create the exporter instance, make sure to set a template name since # the base TemplateExporter doesn't have a template associated with it. exporter = TemplateExporter(config=config) if not exporter.template_file: # give it a default if not specified exporter.template_file = 'python' return exporter nbconvert-5.3.1/nbconvert/filters/000077500000000000000000000000001315361605600171765ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/filters/__init__.py000077500000000000000000000003771315361605600213210ustar00rootroot00000000000000from .ansi import * from .citation import * from .datatypefilter import * from .highlight import * from .latex import * from .markdown import * from .strings import * from .metadata import * from .pandoc import * from ipython_genutils.text import indent nbconvert-5.3.1/nbconvert/filters/ansi.py000066400000000000000000000157111315361605600205070ustar00rootroot00000000000000"""Filters for processing ANSI colors within Jinja templates.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import re import jinja2 __all__ = [ 'strip_ansi', 'ansi2html', 'ansi2latex' ] _ANSI_RE = re.compile('\x1b\\[(.*?)([@-~])') _ANSI_COLORS = ( 'ansi-black', 'ansi-red', 'ansi-green', 'ansi-yellow', 'ansi-blue', 'ansi-magenta', 'ansi-cyan', 'ansi-white', 'ansi-black-intense', 'ansi-red-intense', 'ansi-green-intense', 'ansi-yellow-intense', 'ansi-blue-intense', 'ansi-magenta-intense', 'ansi-cyan-intense', 'ansi-white-intense', ) def strip_ansi(source): """ Remove ANSI escape codes from text. Parameters ---------- source : str Source to remove the ANSI from """ return _ANSI_RE.sub('', source) def ansi2html(text): """ Convert ANSI colors to HTML colors. Parameters ---------- text : unicode Text containing ANSI colors to convert to HTML """ text = jinja2.utils.escape(text) return _ansi2anything(text, _htmlconverter) def ansi2latex(text): """ Convert ANSI colors to LaTeX colors. Parameters ---------- text : unicode Text containing ANSI colors to convert to LaTeX """ return _ansi2anything(text, _latexconverter) def _htmlconverter(fg, bg, bold): """ Return start and end tags for given foreground/background/bold. """ if (fg, bg, bold) == (None, None, False): return '', '' classes = [] styles = [] if isinstance(fg, int): classes.append(_ANSI_COLORS[fg] + '-fg') elif fg: styles.append('color: rgb({},{},{})'.format(*fg)) if isinstance(bg, int): classes.append(_ANSI_COLORS[bg] + '-bg') elif bg: styles.append('background-color: rgb({},{},{})'.format(*bg)) if bold: classes.append('ansi-bold') starttag = '' def _latexconverter(fg, bg, bold): """ Return start and end markup given foreground/background/bold. """ if (fg, bg, bold) == (None, None, False): return '', '' starttag, endtag = '', '' if isinstance(fg, int): starttag += r'\textcolor{' + _ANSI_COLORS[fg] + '}{' endtag = '}' + endtag elif fg: # See http://tex.stackexchange.com/a/291102/13684 starttag += r'\def\tcRGB{\textcolor[RGB]}\expandafter' starttag += r'\tcRGB\expandafter{\detokenize{%s,%s,%s}}{' % fg endtag = '}' + endtag if isinstance(bg, int): starttag += r'\setlength{\fboxsep}{0pt}\colorbox{' starttag += _ANSI_COLORS[bg] + '}{' endtag = r'\strut}' + endtag elif bg: starttag += r'\setlength{\fboxsep}{0pt}' # See http://tex.stackexchange.com/a/291102/13684 starttag += r'\def\cbRGB{\colorbox[RGB]}\expandafter' starttag += r'\cbRGB\expandafter{\detokenize{%s,%s,%s}}{' % bg endtag = r'\strut}' + endtag if bold: starttag += r'\textbf{' endtag = '}' + endtag return starttag, endtag def _ansi2anything(text, converter): r""" Convert ANSI colors to HTML or LaTeX. See https://en.wikipedia.org/wiki/ANSI_escape_code Accepts codes like '\x1b[32m' (red) and '\x1b[1;32m' (bold, red). The codes 1 (bold) and 5 (blinking) are selecting a bold font, code 0 and an empty code ('\x1b[m') reset colors and bold-ness. Unlike in most terminals, "bold" doesn't change the color. The codes 21 and 22 deselect "bold", the codes 39 and 49 deselect the foreground and background color, respectively. The codes 38 and 48 select the "extended" set of foreground and background colors, respectively. Non-color escape sequences (not ending with 'm') are filtered out. Ideally, this should have the same behavior as the function fixConsole() in notebook/notebook/static/base/js/utils.js. """ fg, bg = None, None bold = False numbers = [] out = [] while text: m = _ANSI_RE.search(text) if m: if m.group(2) == 'm': try: numbers = [int(n) if n else 0 for n in m.group(1).split(';')] except ValueError: pass # Invalid color specification else: pass # Not a color code chunk, text = text[:m.start()], text[m.end():] else: chunk, text = text, '' if chunk: if bold and fg in range(8): fg += 8 starttag, endtag = converter(fg, bg, bold) out.append(starttag) out.append(chunk) out.append(endtag) while numbers: n = numbers.pop(0) if n == 0: fg = bg = None bold = False elif n in (1, 5): bold = True elif n in (21, 22): bold = False elif 30 <= n <= 37: fg = n - 30 elif n == 38: try: fg = _get_extended_color(numbers) except ValueError: numbers.clear() elif n == 39: fg = None elif 40 <= n <= 47: bg = n - 40 elif n == 48: try: bg = _get_extended_color(numbers) except ValueError: numbers.clear() elif n == 49: bg = None elif 90 <= n <= 97: fg = n - 90 + 8 elif 100 <= n <= 107: bg = n - 100 + 8 else: pass # Unknown codes are ignored return ''.join(out) def _get_extended_color(numbers): n = numbers.pop(0) if n == 2 and len(numbers) >= 3: # 24-bit RGB r = numbers.pop(0) g = numbers.pop(0) b = numbers.pop(0) if not all(0 <= c <= 255 for c in (r, g, b)): raise ValueError() elif n == 5 and len(numbers) >= 1: # 256 colors idx = numbers.pop(0) if idx < 0: raise ValueError() elif idx < 16: # 16 default terminal colors return idx elif idx < 232: # 6x6x6 color cube, see http://stackoverflow.com/a/27165165/500098 r = (idx - 16) // 36 r = 55 + r * 40 if r > 0 else 0 g = ((idx - 16) % 36) // 6 g = 55 + g * 40 if g > 0 else 0 b = (idx - 16) % 6 b = 55 + b * 40 if b > 0 else 0 elif idx < 256: # grayscale, see http://stackoverflow.com/a/27165165/500098 r = g = b = (idx - 232) * 10 + 8 else: raise ValueError() else: raise ValueError() return r, g, b nbconvert-5.3.1/nbconvert/filters/citation.py000066400000000000000000000067761315361605600214020ustar00rootroot00000000000000"""Citation handling for LaTeX output.""" #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from ipython_genutils.py3compat import PY3 if PY3: from html.parser import HTMLParser else: from HTMLParser import HTMLParser #----------------------------------------------------------------------------- # Functions #----------------------------------------------------------------------------- __all__ = ['citation2latex'] def citation2latex(s): """Parse citations in Markdown cells. This looks for HTML tags having a data attribute names `data-cite` and replaces it by the call to LaTeX cite command. The tranformation looks like this: `(Granger, 2013)` Becomes `\\cite{granger}` Any HTML tag can be used, which allows the citations to be formatted in HTML in any manner. """ parser = CitationParser() parser.feed(s) parser.close() outtext = u'' startpos = 0 for citation in parser.citelist: outtext += s[startpos:citation[1]] outtext += '\\cite{%s}'%citation[0] startpos = citation[2] if len(citation)==3 else -1 outtext += s[startpos:] if startpos != -1 else '' return outtext #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- class CitationParser(HTMLParser): """Citation Parser Replaces html tags with data-cite attribute with respective latex \\cite. Inherites from HTMLParser, overrides: - handle_starttag - handle_endtag """ # number of open tags opentags = None # list of found citations citelist = None # active citation tag citetag = None def __init__(self): self.citelist = [] self.opentags = 0 HTMLParser.__init__(self) def get_offset(self): # Compute startposition in source lin, offset = self.getpos() pos = 0 for i in range(lin-1): pos = self.data.find('\n',pos) + 1 return pos + offset def handle_starttag(self, tag, attrs): # for each tag check if attributes are present and if no citation is active if self.opentags == 0 and len(attrs)>0: for atr, data in attrs: if atr.lower() == 'data-cite': self.citetag = tag self.opentags = 1 self.citelist.append([data, self.get_offset()]) return if tag == self.citetag: # found an open citation tag but not the starting one self.opentags += 1 def handle_endtag(self, tag): if tag == self.citetag: # found citation tag check if starting one if self.opentags == 1: pos = self.get_offset() self.citelist[-1].append(pos+len(tag)+3) self.opentags -= 1 def feed(self, data): self.data = data HTMLParser.feed(self, data) nbconvert-5.3.1/nbconvert/filters/datatypefilter.py000077500000000000000000000031371315361605600226000ustar00rootroot00000000000000"""Filter used to select the first preferred output format available. The filter contained in the file allows the converter templates to select the output format that is most valuable to the active export format. The value of the different formats is set via NbConvertBase.display_data_priority """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- from ..utils.base import NbConvertBase from warnings import warn __all__ = ['DataTypeFilter'] class DataTypeFilter(NbConvertBase): """ Returns the preferred display format """ def __call__(self, output): """ Return the first available format in the priority. Produces a UserWarning if no compatible mimetype is found. `output` is dict with structure {mimetype-of-element: value-of-element} """ for fmt in self.display_data_priority: if fmt in output: return [fmt] warn("Your element with mimetype(s) {mimetypes}" " is not able to be represented.".format( mimetypes=output.keys()) ) return [] nbconvert-5.3.1/nbconvert/filters/filter_links.py000066400000000000000000000025671315361605600222470ustar00rootroot00000000000000#!/usr/bin/env python3 """A pandoc filter used in converting notebooks to Latex. Converts links between notebooks to Latex cross-references. """ import re from pandocfilters import RawInline, applyJSONFilters def resolve_references(source): """ This applies the resolve_one_reference to the text passed in via the source argument. This expects content in the form of a string encoded JSON object as represented internally in ``pandoc``. """ return applyJSONFilters([resolve_one_reference], source) def resolve_one_reference(key, val, fmt, meta): """ This takes a tuple of arguments that are compatible with ``pandocfilters.walk()`` that allows identifying hyperlinks in the document and transforms them into valid LaTeX \\ref{} calls so that linking to headers between cells is possible. See the documentation in ``pandocfilters.walk()`` for further information on the meaning and specification of ``key``, ``val``, ``fmt``, and ``meta``. """ if key == 'Link': target = val[2][0] m = re.match(r'#(.+)$', target) if m: # pandoc automatically makes labels for headings. label = m.group(1).lower() label = re.sub(r'[^\w-]+', '', label) # Strip HTML entities return RawInline('tex', r'Section \ref{%s}' % label) # Other elements will be returned unchanged. nbconvert-5.3.1/nbconvert/filters/highlight.py000066400000000000000000000120321315361605600215150ustar00rootroot00000000000000""" Module containing filter functions that allow code to be highlighted from within Jinja templates. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. # pygments must not be imported at the module level # because errors should be raised at runtime if it's actually needed, # not import time, when it may not be needed. from nbconvert.utils.base import NbConvertBase from warnings import warn from traitlets import observe MULTILINE_OUTPUTS = ['text', 'html', 'svg', 'latex', 'javascript', 'json'] __all__ = [ 'Highlight2HTML', 'Highlight2Latex' ] class Highlight2HTML(NbConvertBase): def __init__(self, pygments_lexer=None, **kwargs): self.pygments_lexer = pygments_lexer or 'ipython3' super(Highlight2HTML, self).__init__(**kwargs) @observe('default_language') def _default_language_changed(self, change): warn('Setting default_language in config is deprecated as of 5.0, ' 'please use language_info metadata instead.') self.pygments_lexer = change['new'] def __call__(self, source, language=None, metadata=None): """ Return a syntax-highlighted version of the input source as html output. Parameters ---------- source : str source of the cell to highlight language : str language to highlight the syntax of metadata : NotebookNode cell metadata metadata of the cell to highlight """ from pygments.formatters import HtmlFormatter if not language: language=self.pygments_lexer return _pygments_highlight(source if len(source) > 0 else ' ', # needed to help post processors: HtmlFormatter(cssclass=" highlight hl-"+language), language, metadata) class Highlight2Latex(NbConvertBase): def __init__(self, pygments_lexer=None, **kwargs): self.pygments_lexer = pygments_lexer or 'ipython3' super(Highlight2Latex, self).__init__(**kwargs) @observe('default_language') def _default_language_changed(self, change): warn('Setting default_language in config is deprecated as of 5.0, ' 'please use language_info metadata instead.') self.pygments_lexer = change['new'] def __call__(self, source, language=None, metadata=None, strip_verbatim=False): """ Return a syntax-highlighted version of the input source as latex output. Parameters ---------- source : str source of the cell to highlight language : str language to highlight the syntax of metadata : NotebookNode cell metadata metadata of the cell to highlight strip_verbatim : bool remove the Verbatim environment that pygments provides by default """ from pygments.formatters import LatexFormatter if not language: language=self.pygments_lexer latex = _pygments_highlight(source, LatexFormatter(), language, metadata) if strip_verbatim: latex = latex.replace(r'\begin{Verbatim}[commandchars=\\\{\}]' + '\n', '') return latex.replace('\n\\end{Verbatim}\n', '') else: return latex def _pygments_highlight(source, output_formatter, language='ipython', metadata=None): """ Return a syntax-highlighted version of the input source Parameters ---------- source : str source of the cell to highlight output_formatter : Pygments formatter language : str language to highlight the syntax of metadata : NotebookNode cell metadata metadata of the cell to highlight """ from pygments import highlight from pygments.lexers import get_lexer_by_name from pygments.util import ClassNotFound # If the cell uses a magic extension language, # use the magic language instead. if language.startswith('ipython') \ and metadata \ and 'magics_language' in metadata: language = metadata['magics_language'] lexer = None if language == 'ipython2': try: from IPython.lib.lexers import IPythonLexer except ImportError: warn("IPython lexer unavailable, falling back on Python") language = 'python' else: lexer = IPythonLexer() elif language == 'ipython3': try: from IPython.lib.lexers import IPython3Lexer except ImportError: warn("IPython3 lexer unavailable, falling back on Python 3") language = 'python3' else: lexer = IPython3Lexer() if lexer is None: try: lexer = get_lexer_by_name(language, stripall=True) except ClassNotFound: warn("No lexer found for language %r. Treating as plain text." % language) from pygments.lexers.special import TextLexer lexer = TextLexer() return highlight(source, lexer, output_formatter) nbconvert-5.3.1/nbconvert/filters/latex.py000077500000000000000000000035141315361605600206730ustar00rootroot00000000000000"""Latex filters. Module of useful filters for processing Latex within Jinja latex templates. """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import re from nbconvert.utils.pandoc import pandoc #----------------------------------------------------------------------------- # Globals and constants #----------------------------------------------------------------------------- LATEX_RE_SUBS = ( (re.compile(r'\.\.\.+'), r'{\\ldots}'), ) # Latex substitutions for escaping latex. # see: http://stackoverflow.com/questions/16259923/how-can-i-escape-latex-special-characters-inside-django-templates LATEX_SUBS = { '&': r'\&', '%': r'\%', '$': r'\$', '#': r'\#', '_': r'\_', '{': r'\{', '}': r'\}', '~': r'\textasciitilde{}', '^': r'\^{}', '\\': r'\textbackslash{}', } #----------------------------------------------------------------------------- # Functions #----------------------------------------------------------------------------- __all__ = ['escape_latex'] def escape_latex(text): """ Escape characters that may conflict with latex. Parameters ---------- text : str Text containing characters that may conflict with Latex """ text = ''.join(LATEX_SUBS.get(c, c) for c in text) for pattern, replacement in LATEX_RE_SUBS: text = pattern.sub(replacement, text) return text nbconvert-5.3.1/nbconvert/filters/markdown.py000077500000000000000000000055571315361605600214110ustar00rootroot00000000000000"""Markdown filters This file contains a collection of utility filters for dealing with markdown within Jinja templates. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function import re try: from .markdown_mistune import markdown2html_mistune except ImportError as e: # store in variable for Python 3 _mistune_import_error = e def markdown2html_mistune(source): """mistune is unavailable, raise ImportError""" raise ImportError("markdown2html requires mistune: %s" % _mistune_import_error) from .pandoc import convert_pandoc __all__ = [ 'markdown2html', 'markdown2html_pandoc', 'markdown2html_mistune', 'markdown2latex', 'markdown2rst', 'markdown2asciidoc', ] def markdown2latex(source, markup='markdown', extra_args=None): """ Convert a markdown string to LaTeX via pandoc. This function will raise an error if pandoc is not installed. Any error messages generated by pandoc are printed to stderr. Parameters ---------- source : string Input string, assumed to be valid markdown. markup : string Markup used by pandoc's reader default : pandoc extended markdown (see http://pandoc.org/README.html#pandocs-markdown) Returns ------- out : string Output as returned by pandoc. """ return convert_pandoc(source, markup, 'latex', extra_args=extra_args) def markdown2html_pandoc(source, extra_args=None): """ Convert a markdown string to HTML via pandoc. """ extra_args = extra_args or ['--mathjax'] return convert_pandoc(source, 'markdown', 'html', extra_args=extra_args) def markdown2asciidoc(source, extra_args=None): """Convert a markdown string to asciidoc via pandoc""" extra_args = extra_args or ['--atx-headers'] asciidoc = convert_pandoc(source, 'markdown', 'asciidoc', extra_args=extra_args) # workaround for https://github.com/jgm/pandoc/issues/3068 if "__" in asciidoc: asciidoc = re.sub(r'\b__([\w \n-]+)__([:,.\n\)])', r'_\1_\2', asciidoc) # urls / links: asciidoc = re.sub(r'\(__([\w\/-:\.]+)__\)', r'(_\1_)', asciidoc) return asciidoc # The mistune renderer is the default, because it's simple to depend on it markdown2html = markdown2html_mistune def markdown2rst(source, extra_args=None): """ Convert a markdown string to ReST via pandoc. This function will raise an error if pandoc is not installed. Any error messages generated by pandoc are printed to stderr. Parameters ---------- source : string Input string, assumed to be valid markdown. Returns ------- out : string Output as returned by pandoc. """ return convert_pandoc(source, 'markdown', 'rst', extra_args=extra_args) nbconvert-5.3.1/nbconvert/filters/markdown_mistune.py000066400000000000000000000064471315361605600231510ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Markdown filters with mistune Used from markdown.py """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function import re import cgi import mistune from pygments import highlight from pygments.lexers import get_lexer_by_name from pygments.formatters import HtmlFormatter from pygments.util import ClassNotFound from nbconvert.filters.strings import add_anchor class MathInlineGrammar(mistune.InlineGrammar): inline_math = re.compile(r"^\$(.+?)\$|^\\\\\((.+?)\\\\\)", re.DOTALL) block_math = re.compile(r"^\$\$(.*?)\$\$|^\\\\\[(.*?)\\\\\]", re.DOTALL) latex_environment = re.compile(r"^\\begin\{([a-z]*\*?)\}(.*?)\\end\{\1\}", re.DOTALL) text = re.compile(r'^[\s\S]+?(?=[\\%s\n' % \ mistune.escape(code) formatter = HtmlFormatter() return highlight(code, lexer, formatter) def header(self, text, level, raw=None): html = super(IPythonRenderer, self).header(text, level, raw=raw) anchor_link_text = self.options.get('anchor_link_text', u'¶') return add_anchor(html, anchor_link_text=anchor_link_text) # We must be careful here for compatibility # html.escape() is not availale on python 2.7 # For more details, see: # https://wiki.python.org/moin/EscapingHtml def escape_html(self, text): return cgi.escape(text) def block_math(self, text): return '$$%s$$' % self.escape_html(text) def latex_environment(self, name, text): name = self.escape_html(name) text = self.escape_html(text) return r'\begin{%s}%s\end{%s}' % (name, text, name) def inline_math(self, text): return '$%s$' % self.escape_html(text) def markdown2html_mistune(source): """Convert a markdown string to HTML using mistune""" return MarkdownWithMath(renderer=IPythonRenderer( escape=False)).render(source) nbconvert-5.3.1/nbconvert/filters/metadata.py000066400000000000000000000007401315361605600213310ustar00rootroot00000000000000"""filters for metadata""" def get_metadata(output, key, mimetype=None): """Resolve an output metadata key If mimetype given, resolve at mimetype level first, then fallback to top-level. Otherwise, just resolve at top-level. Returns None if no data found. """ md = output.get('metadata') or {} if mimetype and mimetype in md: value = md[mimetype].get(key) if value is not None: return value return md.get(key) nbconvert-5.3.1/nbconvert/filters/pandoc.py000066400000000000000000000012521315361605600210140ustar00rootroot00000000000000from nbconvert.utils.pandoc import pandoc def convert_pandoc(source, from_format, to_format, extra_args=None): """Convert between any two formats using pandoc. This function will raise an error if pandoc is not installed. Any error messages generated by pandoc are printed to stderr. Parameters ---------- source : string Input string, assumed to be valid in from_format. from_format : string Pandoc format of source. to_format : string Pandoc format for output. Returns ------- out : string Output as returned by pandoc. """ return pandoc(source, from_format, to_format, extra_args=extra_args) nbconvert-5.3.1/nbconvert/filters/strings.py000077500000000000000000000143311315361605600212460ustar00rootroot00000000000000# coding: utf-8 """String filters. Contains a collection of useful string manipulation filters for use in Jinja templates. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import os import re import textwrap import warnings try: from urllib.parse import quote # Py 3 except ImportError: from urllib2 import quote # Py 2 from xml.etree import ElementTree from ipython_genutils import py3compat __all__ = [ 'wrap_text', 'html2text', 'add_anchor', 'strip_dollars', 'strip_files_prefix', 'comment_lines', 'get_lines', 'ipython2python', 'posix_path', 'path2url', 'add_prompts', 'ascii_only', 'prevent_list_blocks', ] def wrap_text(text, width=100): """ Intelligently wrap text. Wrap text without breaking words if possible. Parameters ---------- text : str Text to wrap. width : int, optional Number of characters to wrap to, default 100. """ split_text = text.split('\n') wrp = map(lambda x:textwrap.wrap(x,width), split_text) wrpd = map('\n'.join, wrp) return '\n'.join(wrpd) def html2text(element): """extract inner text from html Analog of jQuery's $(element).text() """ if isinstance(element, py3compat.string_types): try: element = ElementTree.fromstring(element) except Exception: # failed to parse, just return it unmodified return element text = element.text or "" for child in element: text += html2text(child) text += (element.tail or "") return text def _convert_header_id(header_contents): """Convert header contents to valid id value. Takes string as input, returns string. Note: this may be subject to change in the case of changes to how we wish to generate ids. For use on markdown headings. """ return header_contents.replace(' ', '-') def add_anchor(html, anchor_link_text=u'¶'): """Add an id and an anchor-link to an html header For use on markdown headings """ try: h = ElementTree.fromstring(py3compat.cast_bytes_py2(html, encoding='utf-8')) except Exception: # failed to parse, just return it unmodified return html link = _convert_header_id(html2text(h)) h.set('id', link) a = ElementTree.Element("a", {"class" : "anchor-link", "href" : "#" + link}) a.text = anchor_link_text h.append(a) # Known issue of Python3.x, ElementTree.tostring() returns a byte string # instead of a text string. See issue http://bugs.python.org/issue10942 # Workaround is to make sure the bytes are casted to a string. return py3compat.decode(ElementTree.tostring(h), 'utf-8') def add_prompts(code, first='>>> ', cont='... '): """Add prompts to code snippets""" new_code = [] code_list = code.split('\n') new_code.append(first + code_list[0]) for line in code_list[1:]: new_code.append(cont + line) return '\n'.join(new_code) def strip_dollars(text): """ Remove all dollar symbols from text Parameters ---------- text : str Text to remove dollars from """ return text.strip('$') files_url_pattern = re.compile(r'(src|href)\=([\'"]?)/?files/') markdown_url_pattern = re.compile(r'(!?)\[(?P.*?)\]\(/?files/(?P.*?)\)') def strip_files_prefix(text): """ Fix all fake URLs that start with `files/`, stripping out the `files/` prefix. Applies to both urls (for html) and relative paths (for markdown paths). Parameters ---------- text : str Text in which to replace 'src="files/real...' with 'src="real...' """ cleaned_text = files_url_pattern.sub(r"\1=\2", text) cleaned_text = markdown_url_pattern.sub(r'\1[\2](\3)', cleaned_text) return cleaned_text def comment_lines(text, prefix='# '): """ Build a Python comment line from input text. Parameters ---------- text : str Text to comment out. prefix : str Character to append to the start of each line. """ #Replace line breaks with line breaks and comment symbols. #Also add a comment symbol at the beginning to comment out #the first line. return prefix + ('\n'+prefix).join(text.split('\n')) def get_lines(text, start=None,end=None): """ Split the input text into separate lines and then return the lines that the caller is interested in. Parameters ---------- text : str Text to parse lines from. start : int, optional First line to grab from. end : int, optional Last line to grab from. """ # Split the input into lines. lines = text.split("\n") # Return the right lines. return "\n".join(lines[start:end]) #re-join def ipython2python(code): """Transform IPython syntax to pure Python syntax Parameters ---------- code : str IPython code, to be transformed to pure Python """ try: from IPython.core.inputsplitter import IPythonInputSplitter except ImportError: warnings.warn( "IPython is needed to transform IPython syntax to pure Python." " Install ipython if you need this functionality." ) return code else: isp = IPythonInputSplitter(line_input_checker=False) return isp.transform_cell(code) def posix_path(path): """Turn a path into posix-style path/to/etc Mainly for use in latex on Windows, where native Windows paths are not allowed. """ if os.path.sep != '/': return path.replace(os.path.sep, '/') return path def path2url(path): """Turn a file path into a URL""" parts = path.split(os.path.sep) return '/'.join(quote(part) for part in parts) def ascii_only(s): """ensure a string is ascii""" s = py3compat.cast_unicode(s) return s.encode('ascii', 'replace').decode('ascii') def prevent_list_blocks(s): """ Prevent presence of enumerate or itemize blocks in latex headings cells """ out = re.sub('(^\s*\d*)\.', '\\1\.', s) out = re.sub('(^\s*)\-', '\\1\-', out) out = re.sub('(^\s*)\+', '\\1\+', out) out = re.sub('(^\s*)\*', '\\1\*', out) return out nbconvert-5.3.1/nbconvert/filters/tests/000077500000000000000000000000001315361605600203405ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/filters/tests/__init__.py000066400000000000000000000000001315361605600224370ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/filters/tests/test_ansi.py000066400000000000000000000057651315361605600227200ustar00rootroot00000000000000# coding: utf-8 """ Module with tests for ansi filters """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import unicode_literals from ...tests.base import TestsBase from ..ansi import strip_ansi, ansi2html, ansi2latex class TestAnsi(TestsBase): """Contains test functions for ansi.py""" def test_strip_ansi(self): """strip_ansi test""" correct_outputs = { '\x1b[32m\x1b[1m\x1b[0;44m\x1b[38;2;255;0;255m\x1b[;m\x1b[m': '', 'hello\x1b[000;34m': 'hello', 'he\x1b[1;33m\x1b[;36mllo': 'hello', '\x1b[;34mhello': 'hello', '\x1b[31mh\x1b[31me\x1b[31ml\x1b[31ml\x1b[31mo\x1b[31m': 'hello', 'hel\x1b[;00;;032;;;32mlo': 'hello', 'hello': 'hello', } for inval, outval in correct_outputs.items(): self.assertEqual(outval, strip_ansi(inval)) def test_ansi2html(self): """ansi2html test""" correct_outputs = { '\x1b[31m': '', 'hello\x1b[34m': 'hello', 'he\x1b[32m\x1b[36mllo': 'hello', '\x1b[1;33mhello': 'hello', '\x1b[37mh\x1b[0;037me\x1b[;0037ml\x1b[00;37ml\x1b[;;37mo': 'hello', 'hel\x1b[0;32mlo': 'hello', 'hellø': 'hellø', '\x1b[1mhello\x1b[33mworld\x1b[0m': 'helloworld', } for inval, outval in correct_outputs.items(): self.assertEqual(outval, ansi2html(inval)) def test_ansi2latex(self): """ansi2latex test""" correct_outputs = { '\x1b[31m': '', 'hello\x1b[34m': 'hello', 'he\x1b[32m\x1b[36mllo': r'he\textcolor{ansi-cyan}{llo}', '\x1b[1;33mhello': r'\textcolor{ansi-yellow-intense}{\textbf{hello}}', '\x1b[37mh\x1b[0;037me\x1b[;0037ml\x1b[00;37ml\x1b[;;37mo': r'\textcolor{ansi-white}{h}\textcolor{ansi-white}{e}\textcolor{ansi-white}{l}\textcolor{ansi-white}{l}\textcolor{ansi-white}{o}', 'hel\x1b[0;32mlo': r'hel\textcolor{ansi-green}{lo}', 'hello': 'hello', 'hello\x1b[34mthere\x1b[mworld': r'hello\textcolor{ansi-blue}{there}world', 'hello\x1b[mthere': 'hellothere', 'hello\x1b[01;34mthere': r'hello\textcolor{ansi-blue-intense}{\textbf{there}}', 'hello\x1b[001;34mthere': r'hello\textcolor{ansi-blue-intense}{\textbf{there}}', '\x1b[1mhello\x1b[33mworld\x1b[0m': r'\textbf{hello}\textcolor{ansi-yellow-intense}{\textbf{world}}', } for inval, outval in correct_outputs.items(): self.assertEqual(outval, ansi2latex(inval)) nbconvert-5.3.1/nbconvert/filters/tests/test_citation.py000066400000000000000000000103011315361605600235560ustar00rootroot00000000000000#----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from ..citation import citation2latex import pytest #----------------------------------------------------------------------------- # Tests #----------------------------------------------------------------------------- test_md = {""" # My Heading Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ac magna non augue porttitor scelerisque ac id diam Granger. Mauris elit velit, lobortis sed interdum at, vestibulum vitae libero Perez. Lorem ipsum dolor sit amet, consectetur adipiscing elit Thomas. Quisque iaculis ligula ut ipsum mattis viverra.

Here is a plain paragraph that should be unaffected. It contains simple relations like 1<2 & 4>5.

* One Jonathan. * Two Matthias. * Three Paul. """: """ # My Heading Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ac magna non augue porttitor scelerisque ac id diam \cite{granger}. Mauris elit velit, lobortis sed interdum at, vestibulum vitae libero \cite{fperez}. Lorem ipsum dolor sit amet, consectetur adipiscing elit \cite{takluyver}. Quisque iaculis ligula ut ipsum mattis viverra.

Here is a plain paragraph that should be unaffected. It contains simple relations like 1<2 & 4>5.

* One \cite{jdfreder}. * Two \cite{carreau}. * Three \cite{ivanov}. """, # No citations r"""The quick brown fox jumps over the lazy dog.""": r"""The quick brown fox jumps over the lazy dog.""", # Simple inline r"""Foo Text bar""": r"""Foo \cite{asdf} bar""", # Multiline r"""Text Foo""": r"""\cite{ewqr}Foo""", # Nested tags r"""
Text
Bar""": r"""
\cite{Foo}
Bar""", # Including Maths r"""Foo $3*2*1$
Text
Bar""": r"""Foo $3*2*1$ \cite{Foo} Bar""", # Missing end tag r"""Test Foo""": r"""\cite{asdf}""", r"""Test Foo""": r"""\cite{asdf}""", r"""Test Foo""": r"""\cite{asdf}""", # Multiple arguments r"""Test Foo""": r"""\cite{asdf} Foo""", # Wrong capitalization r"""Test Foo""": r"""\cite{asdf} Foo""", r"""Test Foo""": r"""\cite{asdf} Foo""", # Wrong end tag r""" ksjfs sdf ds """: r"""\cite{wer}""", r"""""": r"""\cite{wer}""", # Invalid tag names r""" """: r""" \cite{wer}""", # Non-nested tags r"""

Test Foo

""": r"""

\cite{asdf}Test Foo

""", # LXML errors r"""Foo \begin{eqnarray} 1 & bar1 \\ 3 & 4 \\ \end{eqnarray}""": r"""Foo \begin{eqnarray} 1 & \cite{bar} \\ 3 & 4 \\ \end{eqnarray}""", r""" 1<2 is true, but 3>4 is false. $1<2$ is true, but $3>4$ is false. 1<2 it is even worse if it is alone in a line.""": r""" 1<2 is true, but 3>4 is false. $1<2$ is true, but $3>4$ is false. 1<2 it is even worse if it is alone in a line.""", r""" 1 < 2 is true, but 3 > 4 is false $1 < 2$ is true, but $3 > 4$ is false 1 < 2 it is even worse if it is alone in a line. """: r""" 1 < 2 is true, but 3 > 4 is false $1 < 2$ is true, but $3 > 4$ is false 1 < 2 it is even worse if it is alone in a line. """} @pytest.mark.parametrize(["in_arg", "out_arg"], [ (in_arg, out_arg) for (in_arg, out_arg) in test_md.items()]) def test_citation2latex(in_arg, out_arg): """Are citations parsed properly?""" assert citation2latex(in_arg)==out_arg nbconvert-5.3.1/nbconvert/filters/tests/test_datatypefilter.py000066400000000000000000000021371315361605600247750ustar00rootroot00000000000000"""Module with tests for DataTypeFilter""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from ...tests.base import TestsBase from ..datatypefilter import DataTypeFilter class TestDataTypeFilter(TestsBase): """Contains test functions for datatypefilter.py""" def test_constructor(self): """Can an instance of a DataTypeFilter be created?""" DataTypeFilter() def test_junk_types(self): """Can the DataTypeFilter pickout a useful type from a dict with junk types as keys?""" filter = DataTypeFilter() assert "image/png" in filter({"hair":"1", "water":2, "image/png":3, "rock":4.0}) assert "application/pdf" in filter({"application/pdf":"file_path", "hair":2, "water":"yay", "png":'not a png', "rock":'is a rock'}) self.assertEqual(filter({"hair":"this is not", "water":"going to return anything", "rock":"or is it"}), []) def test_null(self): """Will the DataTypeFilter fail if no types are passed in?""" filter = DataTypeFilter() self.assertEqual(filter({}), []) nbconvert-5.3.1/nbconvert/filters/tests/test_highlight.py000066400000000000000000000051461315361605600237260ustar00rootroot00000000000000""" Module with tests for Highlight """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from ...tests.base import TestsBase from ..highlight import Highlight2HTML, Highlight2Latex from traitlets.config import Config import xml #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- highlight2html = Highlight2HTML() highlight2latex = Highlight2Latex() highlight2html_ruby = Highlight2HTML(pygments_lexer='ruby') class TestHighlight(TestsBase): """Contains test functions for highlight.py""" #Hello world test, magics test, blank string test tests = [ """ #Hello World Example import foo def say(text): foo.bar(text) end say('Hello World!') """, """ %%pylab plot(x,y, 'r') """ ] tokens = [ ['Hello World Example', 'say', 'text', 'import', 'def'], ['pylab', 'plot']] def test_highlight2html(self): """highlight2html test""" for index, test in enumerate(self.tests): self._try_highlight(highlight2html, test, self.tokens[index]) def test_highlight2latex(self): """highlight2latex test""" for index, test in enumerate(self.tests): self._try_highlight(highlight2latex, test, self.tokens[index]) def test_parse_html_many_lang(self): ht = highlight2html(self.tests[0]) rb = highlight2html_ruby(self.tests[0]) for lang,tkns in [ ( ht, ('def', )), ( rb, ('def','end' ) ) ]: print(tkns) print(lang) root = xml.etree.ElementTree.fromstring(lang) self.assertEqual(self._extract_tokens(root,'k'), set(tkns)) def _extract_tokens(self, root, cls): return set(map(lambda x:x.text,root.findall(".//*[@class='"+cls+"']"))) def _try_highlight(self, method, test, tokens): """Try highlighting source, look for key tokens""" results = method(test) for token in tokens: assert token in results nbconvert-5.3.1/nbconvert/filters/tests/test_latex.py000066400000000000000000000030161315361605600230660ustar00rootroot00000000000000""" Module with tests for Latex """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from ...tests.base import TestsBase from ..latex import escape_latex #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- class TestLatex(TestsBase): def test_escape_latex(self): """escape_latex test""" tests = [ (r'How are \you doing today?', r'How are \textbackslash{}you doing today?'), (r'\escapechar=`\A\catcode`\|=0 |string|foo', r'\textbackslash{}escapechar=`\textbackslash{}A\textbackslash{}catcode`\textbackslash{}|=0 |string|foo'), (r'# $ % & ~ _ ^ \ { }', r'\# \$ \% \& \textasciitilde{} \_ \^{} \textbackslash{} \{ \}'), ('...', r'{\ldots}'), ('','')] for test in tests: self._try_escape_latex(test[0], test[1]) def _try_escape_latex(self, test, result): """Try to remove latex from string""" self.assertEqual(escape_latex(test), result) nbconvert-5.3.1/nbconvert/filters/tests/test_markdown.py000066400000000000000000000210331315361605600235720ustar00rootroot00000000000000# coding: utf-8 """Tests for conversions from markdown to other formats""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import re from copy import copy from functools import partial from ipython_genutils.py3compat import string_types from ipython_genutils.testing import decorators as dec from ...tests.base import TestsBase from ..pandoc import convert_pandoc from ..markdown import markdown2html from jinja2 import Environment class TestMarkdown(TestsBase): tests = [ '*test', '**test', '*test*', '_test_', '__test__', '__*test*__', '**test**', '#test', '##test', 'test\n----', 'test [link](https://google.com/)', ] tokens = [ '*test', '**test', 'test', 'test', 'test', 'test', 'test', 'test', 'test', 'test', ('test', 'https://google.com/'), ] @dec.onlyif_cmds_exist('pandoc') def test_markdown2latex(self): """markdown2latex test""" for index, test in enumerate(self.tests): self._try_markdown( partial( convert_pandoc, from_format='markdown', to_format='latex'), test, self.tokens[index]) @dec.onlyif_cmds_exist('pandoc') def test_markdown2latex_markup(self): """markdown2latex with markup kwarg test""" # This string should be passed through unaltered with pandoc's # markdown_strict reader s = '1) arabic number with parenthesis' self.assertEqual(convert_pandoc(s, 'markdown_strict', 'latex'), s) # This string should be passed through unaltered with pandoc's # markdown_strict+tex_math_dollars reader s = r'$\alpha$ latex math' # sometimes pandoc uses $math$, sometimes it uses \(math\) expected = re.compile(r'(\$|\\\()\\alpha(\$|\\\)) latex math') try: # py3 assertRegex = self.assertRegex except AttributeError: # py2 assertRegex = self.assertRegexpMatches assertRegex( convert_pandoc(s, 'markdown_strict+tex_math_dollars', 'latex'), expected) @dec.onlyif_cmds_exist('pandoc') def test_pandoc_extra_args(self): # pass --no-wrap s = '\n'.join([ "#latex {{long_line | md2l(['--no-wrap'])}}", "#rst {{long_line | md2r(['--columns', '5'])}}", ]) long_line = ' '.join(['long'] * 30) env = Environment() env.filters.update({ 'md2l': lambda code, extra_args: convert_pandoc( code, from_format='markdown', to_format='latex', extra_args=extra_args), 'md2r': lambda code, extra_args: convert_pandoc( code, from_format='markdown', to_format='rst', extra_args=extra_args), }) tpl = env.from_string(s) rendered = tpl.render(long_line=long_line) _, latex, rst = rendered.split('#') self.assertEqual(latex.strip(), 'latex %s' % long_line) self.assertEqual(rst.strip(), 'rst %s' % long_line.replace(' ', '\n')) def test_markdown2html(self): """markdown2html test""" for index, test in enumerate(self.tests): self._try_markdown(markdown2html, test, self.tokens[index]) def test_markdown2html_heading_anchors(self): for md, tokens in [('# test', ('test', 'id="test"', u'¶
', "anchor-link")), ('###test head space', ('test head space', 'id="test-head-space"', u'¶', "anchor-link"))]: self._try_markdown(markdown2html, md, tokens) def test_markdown2html_math(self): # Mathematical expressions not containing <, >, & # should be passed through unaltered # all the "<", ">", "&" must be escaped correctly cases = [( "\\begin{equation*}\n" + ("\\left( \\sum_{k=1}^n a_k b_k \\right)^2 " "\\leq \\left( \\sum_{k=1}^n a_k^2 \\right) " "\\left( \\sum_{k=1}^n b_k^2 \\right)\n") + "\\end{equation*}"), ("$$\n" "a = 1 *3* 5\n" "$$"), "$ a = 1 *3* 5 $", "$s_i = s_{i}\n$", "$aa;a-b<0$", "$$", "$$aa;a-b<0$$", "$$$$", """$ \\begin{tabular}{ l c r } 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ \\end{tabular}$"""] for case in cases: result = markdown2html(case) # find the equation in the generated texts search_result = re.search("\$.*\$", result, re.DOTALL) if search_result is None: search_result = re.search( "\\\\begin\\{equation.*\\}.*\\\\end\\{equation.*\\}", result, re.DOTALL) math = search_result.group(0) # the resulting math part can not contain "<", ">" or # "&" not followed by "lt;", "gt;", or "amp;". self.assertNotIn("<", math) self.assertNotIn(">", math) # python 2.7 has assertNotRegexpMatches instead of assertNotRegex if not hasattr(self, 'assertNotRegex'): self.assertNotRegex = self.assertNotRegexpMatches self.assertNotRegex(math, "&(?![gt;|lt;|amp;])") # the result should be able to be unescaped correctly self.assertEquals(case, self._unescape(math)) def test_markdown2html_math_mixed(self): """ensure markdown between inline and inline-block math works and test multiple LaTeX markup syntaxes. """ case = """The entries of \\\\(C\\\\) are given by the exact formula: $$ C_{ik} = \sum_{j=1}^n A_{ij} B_{jk}, $$ but you can _implement_ this computation in many ways. $\approx 2mnp$ flops are needed for \\\\[ C_{ik} = \sum_{j=1}^n A_{ij} B_{jk} \\\\].""" output_check = (case.replace("_implement_", "implement") .replace("\\\\(", "$").replace("\\\\)", "$") .replace("\\\\[", "$$").replace("\\\\]", "$$")) # these replacements are needed because we use $ and $$ in our html output self._try_markdown(markdown2html, case, output_check) def test_markdown2html_math_paragraph(self): """these should all parse without modification""" cases = [ # https://github.com/ipython/ipython/issues/6724 """Water that is stored in $t$, $s_t$, must equal the storage content of the previous stage, $s_{t-1}$, plus a stochastic inflow, $I_t$, minus what is being released in $t$, $r_t$. With $s_0$ defined as the initial storage content in $t=1$, we have""", # https://github.com/jupyter/nbviewer/issues/420 """$C_{ik}$ $$ C_{ik} = \sum_{j=1} $$ $C_{ik}$""", """$m$ $$ C = \begin{pmatrix} 0 & 0 & 0 & \cdots & 0 & 0 & -c_0 \\ 0 & 0 & 0 & \cdots & 0 & 1 & -c_{m-1} \end{pmatrix} $$ $x^m$""", """$r=\overline{1,n}$ $$ {\bf b}_{i}^{r}(t)=(1-t)\,{\bf b}_{i}^{r-1}(t)+t\,{\bf b}_{i+1}^{r-1}(t),\: i=\overline{0,n-r}, $$ i.e. the $i^{th}$""" ] for case in cases: s = markdown2html(case) self.assertIn(case, self._unescape(s)) @dec.onlyif_cmds_exist('pandoc') def test_markdown2rst(self): """markdown2rst test""" #Modify token array for rst, escape asterik tokens = copy(self.tokens) tokens[0] = r'\*test' tokens[1] = r'\*\*test' for index, test in enumerate(self.tests): self._try_markdown( partial( convert_pandoc, from_format='markdown', to_format='rst'), test, tokens[index]) def _try_markdown(self, method, test, tokens): results = method(test) if isinstance(tokens, string_types): self.assertIn(tokens, results) else: for token in tokens: self.assertIn(token, results) def _unescape(self, s): # undo cgi.escape() manually # We must be careful here for compatibility # html.unescape() is not availale on python 2.7 # For more information, see: # https://wiki.python.org/moin/EscapingHtml s = s.replace("<", "<") s = s.replace(">", ">") s = s.replace("&", "&") return s nbconvert-5.3.1/nbconvert/filters/tests/test_metadata.py000066400000000000000000000011471315361605600235340ustar00rootroot00000000000000from nbconvert.filters import get_metadata def test_get_metadata(): output = { 'metadata': { 'width': 1, 'height': 2, 'image/png': { 'unconfined': True, 'height': 3, } } } assert get_metadata(output, 'nowhere') is None assert get_metadata(output, 'height') == 2 assert get_metadata(output, 'unconfined') == None assert get_metadata(output, 'unconfined', 'image/png') == True assert get_metadata(output, 'width', 'image/png') == 1 assert get_metadata(output, 'height', 'image/png') == 3 nbconvert-5.3.1/nbconvert/filters/tests/test_strings.py000066400000000000000000000143721315361605600234510ustar00rootroot00000000000000""" Module with tests for Strings """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import os from ...tests.base import TestsBase from ..strings import (wrap_text, html2text, add_anchor, strip_dollars, strip_files_prefix, get_lines, comment_lines, ipython2python, posix_path, add_prompts, prevent_list_blocks ) #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- class TestStrings(TestsBase): def test_wrap_text(self): """wrap_text test""" test_text = """ Tush! never tell me; I take it much unkindly That thou, Iago, who hast had my purse As if the strings were thine, shouldst know of this. """ for length in [30,5,1]: self._confirm_wrap_text(test_text, length) def _confirm_wrap_text(self, text, length): for line in wrap_text(text, length).split('\n'): assert len(line) <= length def test_html2text(self): """html2text test""" #TODO: More tests self.assertEqual(html2text('joe'), 'joe') def test_add_anchor(self): """add_anchor test""" #TODO: More tests results = add_anchor('Hello World!') assert 'Hello World!' in results assert 'id="' in results assert 'class="anchor-link"' in results assert '' in results def test_add_anchor_fail(self): """add_anchor does nothing when it fails""" html = '

Hello
World!

' results = add_anchor(html) self.assertEqual(html, results) def test_strip_dollars(self): """strip_dollars test""" tests = [ ('', ''), ('$$', ''), ('$H$', 'H'), ('$He', 'He'), ('H$el', 'H$el'), ('Hell$', 'Hell'), ('Hello', 'Hello'), ('W$o$rld', 'W$o$rld')] for test in tests: self._try_strip_dollars(test[0], test[1]) def _try_strip_dollars(self, test, result): self.assertEqual(strip_dollars(test), result) def test_strip_files_prefix(self): """strip_files_prefix test""" tests = [ ('', ''), ('/files', '/files'), ('test="/files"', 'test="/files"'), ('My files are in `files/`', 'My files are in `files/`'), ('files/test.html', 'files/test.html'), ('files/test.html', 'files/test.html'), ("files/test.html", "files/test.html"), ('', ''), ('', ''), ('hello![caption]', 'hello![caption]'), ('hello![caption](/url/location.gif)', 'hello![caption](/url/location.gif)'), ('hello![caption](url/location.gif)', 'hello![caption](url/location.gif)'), ('hello![caption](url/location.gif)', 'hello![caption](url/location.gif)'), ('hello![caption](files/url/location.gif)', 'hello![caption](url/location.gif)'), ('hello![caption](/files/url/location.gif)', 'hello![caption](url/location.gif)'), ('hello [text](/files/url/location.gif)', 'hello [text](url/location.gif)'), ('hello [text space](files/url/location.gif)', 'hello [text space](url/location.gif)'), ] for test in tests: self._try_files_prefix(test[0], test[1]) def _try_files_prefix(self, test, result): self.assertEqual(strip_files_prefix(test), result) def test_comment_lines(self): """comment_lines test""" for line in comment_lines('hello\nworld\n!').split('\n'): assert line.startswith('# ') for line in comment_lines('hello\nworld\n!', 'beep').split('\n'): assert line.startswith('beep') def test_get_lines(self): """get_lines test""" text = "hello\nworld\n!" self.assertEqual(get_lines(text, start=1), "world\n!") self.assertEqual(get_lines(text, end=2), "hello\nworld") self.assertEqual(get_lines(text, start=2, end=5), "!") self.assertEqual(get_lines(text, start=-2), "world\n!") def test_ipython2python(self): """ipython2python test""" #TODO: More tests results = ipython2python(u'%%pylab\nprint("Hello-World")').replace("u'", "'") self.fuzzy_compare(results, u"get_ipython().run_cell_magic('pylab', '', 'print(\"Hello-World\")')", ignore_spaces=True, ignore_newlines=True) def test_posix_path(self): """posix_path test""" path_list = ['foo', 'bar'] expected = '/'.join(path_list) native = os.path.join(*path_list) filtered = posix_path(native) self.assertEqual(filtered, expected) def test_add_prompts(self): """add_prompts test""" text1 = """for i in range(10):\n i += 1\n print i""" text2 = """>>> for i in range(10):\n... i += 1\n... print i""" self.assertEqual(text2, add_prompts(text1)) def test_prevent_list_blocks(self): """prevent_list_blocks test""" tests = [ ('1. arabic point', '1\\. arabic point'), ('* bullet asterisk', '\\* bullet asterisk'), ('+ bullet Plus Sign', '\\+ bullet Plus Sign'), ('- bullet Hyphen-Minus', '\\- bullet Hyphen-Minus'), (' 1. spaces + arabic point', ' 1\\. spaces + arabic point'), ] for test in tests: self.assertEqual(prevent_list_blocks(test[0]), test[1]) nbconvert-5.3.1/nbconvert/nbconvertapp.py000077500000000000000000000446071315361605600206170ustar00rootroot00000000000000#!/usr/bin/env python """NbConvert is a utility for conversion of .ipynb files. Command-line interface for the NbConvert conversion utility. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function import logging import sys import os import glob from jupyter_core.application import JupyterApp, base_aliases, base_flags from traitlets.config import catch_config_error, Configurable from traitlets import ( Unicode, List, Instance, DottedObjectName, Type, Bool, default, observe, ) from traitlets.utils.importstring import import_item from .exporters.base import get_export_names, get_exporter from nbconvert import exporters, preprocessors, writers, postprocessors, __version__ from .utils.base import NbConvertBase from .utils.exceptions import ConversionException from .utils.io import unicode_stdin_stream #----------------------------------------------------------------------------- #Classes and functions #----------------------------------------------------------------------------- class DottedOrNone(DottedObjectName): """A string holding a valid dotted object name in Python, such as A.b3._c Also allows for None type. """ default_value = u'' def validate(self, obj, value): if value is not None and len(value) > 0: return super(DottedOrNone, self).validate(obj, value) else: return value nbconvert_aliases = {} nbconvert_aliases.update(base_aliases) nbconvert_aliases.update({ 'to' : 'NbConvertApp.export_format', 'template' : 'TemplateExporter.template_file', 'writer' : 'NbConvertApp.writer_class', 'post': 'NbConvertApp.postprocessor_class', 'output': 'NbConvertApp.output_base', 'output-dir': 'FilesWriter.build_directory', 'reveal-prefix': 'SlidesExporter.reveal_url_prefix', 'nbformat': 'NotebookExporter.nbformat_version', }) nbconvert_flags = {} nbconvert_flags.update(base_flags) nbconvert_flags.update({ 'execute' : ( {'ExecutePreprocessor' : {'enabled' : True}}, "Execute the notebook prior to export." ), 'allow-errors' : ( {'ExecutePreprocessor' : {'allow_errors' : True}}, ("Continue notebook execution even if one of the cells throws " "an error and include the error message in the cell output " "(the default behaviour is to abort conversion). This flag " "is only relevant if '--execute' was specified, too.") ), 'stdin' : ( {'NbConvertApp' : { 'from_stdin' : True, } }, "read a single notebook file from stdin. Write the resulting notebook with default basename 'notebook.*'" ), 'stdout' : ( {'NbConvertApp' : {'writer_class' : "StdoutWriter"}}, "Write notebook output to stdout instead of files." ), 'inplace' : ( { 'NbConvertApp' : { 'use_output_suffix' : False, 'export_format' : 'notebook', }, 'FilesWriter' : {'build_directory': ''}, }, """Run nbconvert in place, overwriting the existing notebook (only relevant when converting to notebook format)""" ), 'clear-output' : ( { 'NbConvertApp' : { 'use_output_suffix' : False, 'export_format' : 'notebook', }, 'FilesWriter' : {'build_directory': ''}, 'ClearOutputPreprocessor' : {'enabled' : True}, }, """Clear output of current file and save in place, overwriting the existing notebook. """ ), 'no-prompt' : ( {'TemplateExporter' : { 'exclude_input_prompt' : True, 'exclude_output_prompt' : True, } }, "Exclude input and output prompts from converted document." ), }) class NbConvertApp(JupyterApp): """Application used to convert from notebook file type (``*.ipynb``)""" version = __version__ name = 'jupyter-nbconvert' aliases = nbconvert_aliases flags = nbconvert_flags @default('log_level') def _log_level_default(self): return logging.INFO classes = List() @default('classes') def _classes_default(self): classes = [NbConvertBase] for pkg in (exporters, preprocessors, writers, postprocessors): for name in dir(pkg): cls = getattr(pkg, name) if isinstance(cls, type) and issubclass(cls, Configurable): classes.append(cls) return classes description = Unicode( u"""This application is used to convert notebook files (*.ipynb) to various other formats. WARNING: THE COMMANDLINE INTERFACE MAY CHANGE IN FUTURE RELEASES.""") output_base = Unicode('', help='''overwrite base name use for output files. can only be used when converting one notebook at a time. ''').tag(config=True) use_output_suffix = Bool( True, help="""Whether to apply a suffix prior to the extension (only relevant when converting to notebook format). The suffix is determined by the exporter, and is usually '.nbconvert'.""" ).tag(config=True) output_files_dir = Unicode('{notebook_name}_files', help='''Directory to copy extra files (figures) to. '{notebook_name}' in the string will be converted to notebook basename''' ).tag(config=True) examples = Unicode(u""" The simplest way to use nbconvert is > jupyter nbconvert mynotebook.ipynb which will convert mynotebook.ipynb to the default format (probably HTML). You can specify the export format with `--to`. Options include {0} > jupyter nbconvert --to latex mynotebook.ipynb Both HTML and LaTeX support multiple output templates. LaTeX includes 'base', 'article' and 'report'. HTML includes 'basic' and 'full'. You can specify the flavor of the format used. > jupyter nbconvert --to html --template basic mynotebook.ipynb You can also pipe the output to stdout, rather than a file > jupyter nbconvert mynotebook.ipynb --stdout PDF is generated via latex > jupyter nbconvert mynotebook.ipynb --to pdf You can get (and serve) a Reveal.js-powered slideshow > jupyter nbconvert myslides.ipynb --to slides --post serve Multiple notebooks can be given at the command line in a couple of different ways: > jupyter nbconvert notebook*.ipynb > jupyter nbconvert notebook1.ipynb notebook2.ipynb or you can specify the notebooks list in a config file, containing:: c.NbConvertApp.notebooks = ["my_notebook.ipynb"] > jupyter nbconvert --config mycfg.py """.format(get_export_names())) # Writer specific variables writer = Instance('nbconvert.writers.base.WriterBase', help="""Instance of the writer class used to write the results of the conversion.""", allow_none=True) writer_class = DottedObjectName('FilesWriter', help="""Writer class used to write the results of the conversion""").tag(config=True) writer_aliases = {'fileswriter': 'nbconvert.writers.files.FilesWriter', 'debugwriter': 'nbconvert.writers.debug.DebugWriter', 'stdoutwriter': 'nbconvert.writers.stdout.StdoutWriter'} writer_factory = Type(allow_none=True) @observe('writer_class') def _writer_class_changed(self, change): new = change['new'] if new.lower() in self.writer_aliases: new = self.writer_aliases[new.lower()] self.writer_factory = import_item(new) # Post-processor specific variables postprocessor = Instance('nbconvert.postprocessors.base.PostProcessorBase', help="""Instance of the PostProcessor class used to write the results of the conversion.""", allow_none=True) postprocessor_class = DottedOrNone( help="""PostProcessor class used to write the results of the conversion""" ).tag(config=True) postprocessor_aliases = {'serve': 'nbconvert.postprocessors.serve.ServePostProcessor'} postprocessor_factory = Type(None, allow_none=True) @observe('postprocessor_class') def _postprocessor_class_changed(self, change): new = change['new'] if new.lower() in self.postprocessor_aliases: new = self.postprocessor_aliases[new.lower()] if new: self.postprocessor_factory = import_item(new) export_format = Unicode( 'html', allow_none=False, help="""The export format to be used, either one of the built-in formats, or a dotted object name that represents the import path for an `Exporter` class""" ).tag(config=True) notebooks = List([], help="""List of notebooks to convert. Wildcards are supported. Filenames passed positionally will be added to the list. """ ).tag(config=True) from_stdin = Bool(False, help="read a single notebook from stdin.").tag(config=True) @catch_config_error def initialize(self, argv=None): """Initialize application, notebooks, writer, and postprocessor""" self.init_syspath() super(NbConvertApp, self).initialize(argv) self.init_notebooks() self.init_writer() self.init_postprocessor() def init_syspath(self): """Add the cwd to the sys.path ($PYTHONPATH)""" sys.path.insert(0, os.getcwd()) def init_notebooks(self): """Construct the list of notebooks. If notebooks are passed on the command-line, they override (rather than add) notebooks specified in config files. Glob each notebook to replace notebook patterns with filenames. """ # Specifying notebooks on the command-line overrides (rather than # adds) the notebook list if self.extra_args: patterns = self.extra_args else: patterns = self.notebooks # Use glob to replace all the notebook patterns with filenames. filenames = [] for pattern in patterns: # Use glob to find matching filenames. Allow the user to convert # notebooks without having to type the extension. globbed_files = glob.glob(pattern) globbed_files.extend(glob.glob(pattern + '.ipynb')) if not globbed_files: self.log.warn("pattern %r matched no files", pattern) for filename in globbed_files: if not filename in filenames: filenames.append(filename) self.notebooks = filenames def init_writer(self): """Initialize the writer (which is stateless)""" self._writer_class_changed({ 'new': self.writer_class }) self.writer = self.writer_factory(parent=self) if hasattr(self.writer, 'build_directory') and self.writer.build_directory != '': self.use_output_suffix = False def init_postprocessor(self): """Initialize the postprocessor (which is stateless)""" self._postprocessor_class_changed({'new': self.postprocessor_class}) if self.postprocessor_factory: self.postprocessor = self.postprocessor_factory(parent=self) def start(self): """Run start after initialization process has completed""" super(NbConvertApp, self).start() self.convert_notebooks() def init_single_notebook_resources(self, notebook_filename): """Step 1: Initialize resources This initializes the resources dictionary for a single notebook. Returns ------- dict resources dictionary for a single notebook that MUST include the following keys: - config_dir: the location of the Jupyter config directory - unique_key: the notebook name - output_files_dir: a directory where output files (not including the notebook itself) should be saved """ basename = os.path.basename(notebook_filename) notebook_name = basename[:basename.rfind('.')] if self.output_base: # strip duplicate extension from output_base, to avoid Basename.ext.ext if getattr(self.exporter, 'file_extension', False): base, ext = os.path.splitext(self.output_base) if ext == self.exporter.file_extension: self.output_base = base notebook_name = self.output_base self.log.debug("Notebook name is '%s'", notebook_name) # first initialize the resources we want to use resources = {} resources['config_dir'] = self.config_dir resources['unique_key'] = notebook_name output_files_dir = (self.output_files_dir .format(notebook_name=notebook_name)) resources['output_files_dir'] = output_files_dir return resources def export_single_notebook(self, notebook_filename, resources, input_buffer=None): """Step 2: Export the notebook Exports the notebook to a particular format according to the specified exporter. This function returns the output and (possibly modified) resources from the exporter. Parameters ---------- notebook_filename : str name of notebook file. resources : dict input_buffer : readable file-like object returning unicode. if not None, notebook_filename is ignored Returns ------- output dict resources (possibly modified) """ try: if input_buffer is not None: output, resources = self.exporter.from_file(input_buffer, resources=resources) else: output, resources = self.exporter.from_filename(notebook_filename, resources=resources) except ConversionException: self.log.error("Error while converting '%s'", notebook_filename, exc_info=True) self.exit(1) return output, resources def write_single_notebook(self, output, resources): """Step 3: Write the notebook to file This writes output from the exporter to file using the specified writer. It returns the results from the writer. Parameters ---------- output : resources : dict resources for a single notebook including name, config directory and directory to save output Returns ------- file results from the specified writer output of exporter """ if 'unique_key' not in resources: raise KeyError("unique_key MUST be specified in the resources, but it is not") notebook_name = resources['unique_key'] if self.use_output_suffix and not self.output_base: notebook_name += resources.get('output_suffix', '') write_results = self.writer.write( output, resources, notebook_name=notebook_name) return write_results def postprocess_single_notebook(self, write_results): """Step 4: Post-process the written file Only used if a postprocessor has been specified. After the converted notebook is written to a file in Step 3, this post-processes the notebook. """ # Post-process if post processor has been defined. if hasattr(self, 'postprocessor') and self.postprocessor: self.postprocessor(write_results) def convert_single_notebook(self, notebook_filename, input_buffer=None): """Convert a single notebook. Performs the following steps: 1. Initialize notebook resources 2. Export the notebook to a particular format 3. Write the exported notebook to file 4. (Maybe) postprocess the written file Parameters ---------- notebook_filename : str input_buffer : If input_buffer is not None, conversion is done and the buffer is used as source into a file basenamed by the notebook_filename argument. """ if input_buffer is None: self.log.info("Converting notebook %s to %s", notebook_filename, self.export_format) else: self.log.info("Converting notebook into %s", self.export_format) resources = self.init_single_notebook_resources(notebook_filename) output, resources = self.export_single_notebook(notebook_filename, resources, input_buffer=input_buffer) write_results = self.write_single_notebook(output, resources) self.postprocess_single_notebook(write_results) def convert_notebooks(self): """Convert the notebooks in the self.notebook traitlet """ # check that the output base isn't specified if there is more than # one notebook to convert if self.output_base != '' and len(self.notebooks) > 1: self.log.error( """ UsageError: --output flag or `NbConvertApp.output_base` config option cannot be used when converting multiple notebooks. """ ) self.exit(1) # initialize the exporter cls = get_exporter(self.export_format) self.exporter = cls(config=self.config) # no notebooks to convert! if len(self.notebooks) == 0 and not self.from_stdin: self.print_help() sys.exit(-1) # convert each notebook if not self.from_stdin: for notebook_filename in self.notebooks: self.convert_single_notebook(notebook_filename) else: input_buffer = unicode_stdin_stream() # default name when conversion from stdin self.convert_single_notebook("notebook.ipynb", input_buffer=input_buffer) #----------------------------------------------------------------------------- # Main entry point #----------------------------------------------------------------------------- main = launch_new_instance = NbConvertApp.launch_instance nbconvert-5.3.1/nbconvert/postprocessors/000077500000000000000000000000001315361605600206365ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/postprocessors/__init__.py000066400000000000000000000002271315361605600227500ustar00rootroot00000000000000from .base import PostProcessorBase # protect against unavailable tornado try: from .serve import ServePostProcessor except ImportError: pass nbconvert-5.3.1/nbconvert/postprocessors/base.py000066400000000000000000000020571315361605600221260ustar00rootroot00000000000000""" Basic post processor """ #----------------------------------------------------------------------------- #Copyright (c) 2013, the IPython Development Team. # #Distributed under the terms of the Modified BSD License. # #The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from ..utils.base import NbConvertBase #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- class PostProcessorBase(NbConvertBase): def __call__(self, input): """ See def postprocess() ... """ self.postprocess(input) def postprocess(self, input): """ Post-process output from a writer. """ raise NotImplementedError('postprocess') nbconvert-5.3.1/nbconvert/postprocessors/serve.py000066400000000000000000000107251315361605600223410ustar00rootroot00000000000000"""PostProcessor for serving reveal.js HTML slideshows.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function import os import webbrowser import threading from tornado import web, ioloop, httpserver, log from tornado.httpclient import AsyncHTTPClient from traitlets import Bool, Unicode, Int from .base import PostProcessorBase class ProxyHandler(web.RequestHandler): """handler the proxies requests from a local prefix to a CDN""" @web.asynchronous def get(self, prefix, url): """proxy a request to a CDN""" proxy_url = "/".join([self.settings['cdn'], url]) client = self.settings['client'] client.fetch(proxy_url, callback=self.finish_get) def finish_get(self, response): """finish the request""" # rethrow errors response.rethrow() for header in ["Content-Type", "Cache-Control", "Date", "Last-Modified", "Expires"]: if header in response.headers: self.set_header(header, response.headers[header]) self.finish(response.body) class ServePostProcessor(PostProcessorBase): """Post processor designed to serve files Proxies reveal.js requests to a CDN if no local reveal.js is present """ open_in_browser = Bool(True, help="""Should the browser be opened automatically?""" ).tag(config=True) browser = Unicode(u'', help="""Specify what browser should be used to open slides. See https://docs.python.org/3/library/webbrowser.html#webbrowser.register to see how keys are mapped to browser executables. If not specified, the default browser will be determined by the `webbrowser` standard library module, which allows setting of the BROWSER environment variable to override it. """).tag(config=True) reveal_cdn = Unicode("https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.5.0", help="""URL for reveal.js CDN.""").tag(config=True) reveal_prefix = Unicode("reveal.js", help="URL prefix for reveal.js").tag(config=True) ip = Unicode("127.0.0.1", help="The IP address to listen on.").tag(config=True) port = Int(8000, help="port for the server to listen on.").tag(config=True) def postprocess(self, input): """Serve the build directory with a webserver.""" dirname, filename = os.path.split(input) handlers = [ (r"/(.+)", web.StaticFileHandler, {'path' : dirname}), (r"/", web.RedirectHandler, {"url": "/%s" % filename}) ] if ('://' in self.reveal_prefix or self.reveal_prefix.startswith("//")): # reveal specifically from CDN, nothing to do pass elif os.path.isdir(os.path.join(dirname, self.reveal_prefix)): # reveal prefix exists self.log.info("Serving local %s", self.reveal_prefix) else: self.log.info("Redirecting %s requests to %s", self.reveal_prefix, self.reveal_cdn) handlers.insert(0, (r"/(%s)/(.*)" % self.reveal_prefix, ProxyHandler)) app = web.Application(handlers, cdn=self.reveal_cdn, client=AsyncHTTPClient(), ) # hook up tornado logging to our logger log.app_log = self.log http_server = httpserver.HTTPServer(app) http_server.listen(self.port, address=self.ip) url = "http://%s:%i/%s" % (self.ip, self.port, filename) print("Serving your slides at %s" % url) print("Use Control-C to stop this server") if self.open_in_browser: try: browser = webbrowser.get(self.browser or None) b = lambda: browser.open(url, new=2) threading.Thread(target=b).start() except webbrowser.Error as e: self.log.warning('No web browser found: %s.' % e) browser = None try: ioloop.IOLoop.instance().start() except KeyboardInterrupt: print("\nInterrupted") def main(path): """allow running this module to serve the slides""" server = ServePostProcessor() server(path) if __name__ == '__main__': import sys main(sys.argv[1]) nbconvert-5.3.1/nbconvert/postprocessors/tests/000077500000000000000000000000001315361605600220005ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/postprocessors/tests/__init__.py000066400000000000000000000000001315361605600240770ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/postprocessors/tests/test_serve.py000066400000000000000000000012361315361605600245370ustar00rootroot00000000000000""" Module with tests for the serve post-processor """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import pytest from ...tests.base import TestsBase class TestServe(TestsBase): """Contains test functions for serve.py""" def test_constructor(self): """Can a ServePostProcessor be constructed?""" pytest.importorskip("tornado") try: from ..serve import ServePostProcessor except ImportError: print("Something weird is happening.\n" "Tornado is sometimes present, sometimes not.") raise ServePostProcessor() nbconvert-5.3.1/nbconvert/preprocessors/000077500000000000000000000000001315361605600204375ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/preprocessors/__init__.py000077500000000000000000000012001315361605600225440ustar00rootroot00000000000000# Class base Preprocessors from .base import Preprocessor from .convertfigures import ConvertFiguresPreprocessor from .svg2pdf import SVG2PDFPreprocessor from .extractoutput import ExtractOutputPreprocessor from .latex import LatexPreprocessor from .csshtmlheader import CSSHTMLHeaderPreprocessor from .highlightmagics import HighlightMagicsPreprocessor from .clearoutput import ClearOutputPreprocessor from .execute import ExecutePreprocessor, CellExecutionError from .regexremove import RegexRemovePreprocessor from .tagremove import TagRemovePreprocessor # decorated function Preprocessors from .coalescestreams import coalesce_streams nbconvert-5.3.1/nbconvert/preprocessors/base.py000077500000000000000000000055061315361605600217340ustar00rootroot00000000000000"""Base class for preprocessors""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from ..utils.base import NbConvertBase from traitlets import Bool class Preprocessor(NbConvertBase): """ A configurable preprocessor Inherit from this class if you wish to have configurability for your preprocessor. Any configurable traitlets this class exposed will be configurable in profiles using c.SubClassName.attribute = value you can overwrite :meth:`preprocess_cell` to apply a transformation independently on each cell or :meth:`preprocess` if you prefer your own logic. See corresponding docstring for informations. Disabled by default and can be enabled via the config by 'c.YourPreprocessorName.enabled = True' """ enabled = Bool(False).tag(config=True) def __init__(self, **kw): """ Public constructor Parameters ---------- config : Config Configuration file structure `**kw` Additional keyword arguments passed to parent """ super(Preprocessor, self).__init__(**kw) def __call__(self, nb, resources): if self.enabled: self.log.debug("Applying preprocessor: %s", self.__class__.__name__) return self.preprocess(nb, resources) else: return nb, resources def preprocess(self, nb, resources): """ Preprocessing to apply on each notebook. Must return modified nb, resources. If you wish to apply your preprocessing to each cell, you might want to override preprocess_cell method instead. Parameters ---------- nb : NotebookNode Notebook being converted resources : dictionary Additional resources used in the conversion process. Allows preprocessors to pass variables into the Jinja engine. """ for index, cell in enumerate(nb.cells): nb.cells[index], resources = self.preprocess_cell(cell, resources, index) return nb, resources def preprocess_cell(self, cell, resources, index): """ Override if you want to apply some preprocessing to each cell. Must return modified cell and resource dictionary. Parameters ---------- cell : NotebookNode cell Notebook cell being processed resources : dictionary Additional resources used in the conversion process. Allows preprocessors to pass variables into the Jinja engine. index : int Index of the cell being processed """ raise NotImplementedError('should be implemented by subclass') return cell, resources nbconvert-5.3.1/nbconvert/preprocessors/clearoutput.py000066400000000000000000000016561315361605600233700ustar00rootroot00000000000000"""Module containing a preprocessor that removes the outputs from code cells""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from traitlets import Set from .base import Preprocessor class ClearOutputPreprocessor(Preprocessor): """ Removes the output from all code cells in a notebook. """ remove_metadata_fields = Set( {'collapsed', 'scrolled'} ).tag(config=True) def preprocess_cell(self, cell, resources, cell_index): """ Apply a transformation on each cell. See base.py for details. """ if cell.cell_type == 'code': cell.outputs = [] cell.execution_count = None # Remove metadata associated with output if 'metadata' in cell: for field in self.remove_metadata_fields: cell.metadata.pop(field, None) return cell, resources nbconvert-5.3.1/nbconvert/preprocessors/coalescestreams.py000066400000000000000000000043641315361605600241750ustar00rootroot00000000000000"""Preprocessor for merging consecutive stream outputs for easier handling.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import re import functools from traitlets.log import get_logger def cell_preprocessor(function): """ Wrap a function to be executed on all cells of a notebook The wrapped function should have these parameters: cell : NotebookNode cell Notebook cell being processed resources : dictionary Additional resources used in the conversion process. Allows preprocessors to pass variables into the Jinja engine. index : int Index of the cell being processed """ @functools.wraps(function) def wrappedfunc(nb, resources): get_logger().debug( "Applying preprocessor: %s", function.__name__ ) for index, cell in enumerate(nb.cells): nb.cells[index], resources = function(cell, resources, index) return nb, resources return wrappedfunc cr_pat = re.compile(r'.*\r(?=[^\n])') @cell_preprocessor def coalesce_streams(cell, resources, index): """ Merge consecutive sequences of stream output into single stream to prevent extra newlines inserted at flush calls Parameters ---------- cell : NotebookNode cell Notebook cell being processed resources : dictionary Additional resources used in the conversion process. Allows transformers to pass variables into the Jinja engine. index : int Index of the cell being processed """ outputs = cell.get('outputs', []) if not outputs: return cell, resources last = outputs[0] new_outputs = [last] for output in outputs[1:]: if (output.output_type == 'stream' and last.output_type == 'stream' and last.name == output.name ): last.text += output.text else: new_outputs.append(output) last = output # process \r characters for output in new_outputs: if output.output_type == 'stream' and '\r' in output.text: output.text = cr_pat.sub('', output.text) cell.outputs = new_outputs return cell, resources nbconvert-5.3.1/nbconvert/preprocessors/convertfigures.py000066400000000000000000000026521315361605600240630ustar00rootroot00000000000000"""Module containing a preprocessor that converts outputs in the notebook from one format to another. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from .base import Preprocessor from traitlets import Unicode class ConvertFiguresPreprocessor(Preprocessor): """ Converts all of the outputs in a notebook from one format to another. """ from_format = Unicode(help='Format the converter accepts').tag(config=True) to_format = Unicode(help='Format the converter writes').tag(config=True) def __init__(self, **kw): """ Public constructor """ super(ConvertFiguresPreprocessor, self).__init__(**kw) def convert_figure(self, data_format, data): raise NotImplementedError() def preprocess_cell(self, cell, resources, cell_index): """ Apply a transformation on each cell, See base.py """ # Loop through all of the datatypes of the outputs in the cell. for output in cell.get('outputs', []): if output.output_type in {'execute_result', 'display_data'} \ and self.from_format in output.data \ and self.to_format not in output.data: output.data[self.to_format] = self.convert_figure( self.from_format, output.data[self.from_format]) return cell, resources nbconvert-5.3.1/nbconvert/preprocessors/csshtmlheader.py000077500000000000000000000120061315361605600236410ustar00rootroot00000000000000"""Module that pre-processes the notebook for export to HTML. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import os import io import hashlib import nbconvert.resources from traitlets import Unicode from ipython_genutils.py3compat import str_to_bytes from .base import Preprocessor try: from notebook import DEFAULT_STATIC_FILES_PATH except ImportError: DEFAULT_STATIC_FILES_PATH = None class CSSHTMLHeaderPreprocessor(Preprocessor): """ Preprocessor used to pre-process notebook for HTML output. Adds IPython notebook front-end CSS and Pygments CSS to HTML output. """ highlight_class = Unicode('.highlight', help="CSS highlight class identifier" ).tag(config=True) def __init__(self, *pargs, **kwargs): Preprocessor.__init__(self, *pargs, **kwargs) self._default_css_hash = None def preprocess(self, nb, resources): """Fetch and add CSS to the resource dictionary Fetch CSS from IPython and Pygments to add at the beginning of the html files. Add this css in resources in the "inlining.css" key Parameters ---------- nb : NotebookNode Notebook being converted resources : dictionary Additional resources used in the conversion process. Allows preprocessors to pass variables into the Jinja engine. """ resources['inlining'] = {} resources['inlining']['css'] = self._generate_header(resources) return nb, resources def _generate_header(self, resources): """ Fills self.header with lines of CSS extracted from IPython and Pygments. """ from pygments.formatters import HtmlFormatter header = [] # Construct path to Jupyter CSS sheet_filename = os.path.join( os.path.dirname(nbconvert.resources.__file__), 'style.min.css', ) # Load style CSS file. with io.open(sheet_filename, encoding='utf-8') as f: header.append(f.read()) # Add pygments CSS formatter = HtmlFormatter() pygments_css = formatter.get_style_defs(self.highlight_class) header.append(pygments_css) # These ANSI CSS definitions will be part of style.min.css with the # Notebook release 5.0 and shall be removed afterwards! # See https://github.com/jupyter/nbconvert/pull/259 header.append(""" /* Temporary definitions which will become obsolete with Notebook release 5.0 */ .ansi-black-fg { color: #3E424D; } .ansi-black-bg { background-color: #3E424D; } .ansi-black-intense-fg { color: #282C36; } .ansi-black-intense-bg { background-color: #282C36; } .ansi-red-fg { color: #E75C58; } .ansi-red-bg { background-color: #E75C58; } .ansi-red-intense-fg { color: #B22B31; } .ansi-red-intense-bg { background-color: #B22B31; } .ansi-green-fg { color: #00A250; } .ansi-green-bg { background-color: #00A250; } .ansi-green-intense-fg { color: #007427; } .ansi-green-intense-bg { background-color: #007427; } .ansi-yellow-fg { color: #DDB62B; } .ansi-yellow-bg { background-color: #DDB62B; } .ansi-yellow-intense-fg { color: #B27D12; } .ansi-yellow-intense-bg { background-color: #B27D12; } .ansi-blue-fg { color: #208FFB; } .ansi-blue-bg { background-color: #208FFB; } .ansi-blue-intense-fg { color: #0065CA; } .ansi-blue-intense-bg { background-color: #0065CA; } .ansi-magenta-fg { color: #D160C4; } .ansi-magenta-bg { background-color: #D160C4; } .ansi-magenta-intense-fg { color: #A03196; } .ansi-magenta-intense-bg { background-color: #A03196; } .ansi-cyan-fg { color: #60C6C8; } .ansi-cyan-bg { background-color: #60C6C8; } .ansi-cyan-intense-fg { color: #258F8F; } .ansi-cyan-intense-bg { background-color: #258F8F; } .ansi-white-fg { color: #C5C1B4; } .ansi-white-bg { background-color: #C5C1B4; } .ansi-white-intense-fg { color: #A1A6B2; } .ansi-white-intense-bg { background-color: #A1A6B2; } .ansi-bold { font-weight: bold; } """) # Load the user's custom CSS and IPython's default custom CSS. If they # differ, assume the user has made modifications to his/her custom CSS # and that we should inline it in the nbconvert output. config_dir = resources['config_dir'] custom_css_filename = os.path.join(config_dir, 'custom', 'custom.css') if os.path.isfile(custom_css_filename): if DEFAULT_STATIC_FILES_PATH and self._default_css_hash is None: self._default_css_hash = self._hash(os.path.join(DEFAULT_STATIC_FILES_PATH, 'custom', 'custom.css')) if self._hash(custom_css_filename) != self._default_css_hash: with io.open(custom_css_filename, encoding='utf-8') as f: header.append(f.read()) return header def _hash(self, filename): """Compute the hash of a file.""" md5 = hashlib.md5() with open(filename) as f: md5.update(str_to_bytes(f.read())) return md5.digest() nbconvert-5.3.1/nbconvert/preprocessors/execute.py000066400000000000000000000361741315361605600224660ustar00rootroot00000000000000"""Module containing a preprocessor that executes the code cells and updates outputs""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from textwrap import dedent try: from queue import Empty # Py 3 except ImportError: from Queue import Empty # Py 2 from traitlets import List, Unicode, Bool, Enum, Any, Type, Dict, default from nbformat.v4 import output_from_msg from .base import Preprocessor from ..utils.exceptions import ConversionException from traitlets import Integer class CellExecutionError(ConversionException): """ Custom exception to propagate exceptions that are raised during notebook execution to the caller. This is mostly useful when using nbconvert as a library, since it allows to deal with failures gracefully. """ def __init__(self, traceback): super(CellExecutionError, self).__init__(traceback) self.traceback = traceback def __str__(self): s = self.__unicode__() if not isinstance(s, str): s = s.encode('utf8', 'replace') return s def __unicode__(self): return self.traceback @classmethod def from_cell_and_msg(cls, cell, msg): """Instantiate from a code cell object and a message contents (message is either execute_reply or error) """ tb = '\n'.join(msg.get('traceback', [])) return cls(exec_err_msg.format(cell=cell, traceback=tb, ename=msg.get('ename', ''), evalue=msg.get('evalue', '') )) exec_err_msg = u"""\ An error occurred while executing the following cell: ------------------ {cell.source} ------------------ {traceback} {ename}: {evalue} """ class ExecutePreprocessor(Preprocessor): """ Executes all the cells in a notebook """ timeout = Integer(30, allow_none=True, help=dedent( """ The time to wait (in seconds) for output from executions. If a cell execution takes longer, an exception (TimeoutError on python 3+, RuntimeError on python 2) is raised. `None` or `-1` will disable the timeout. If `timeout_func` is set, it overrides `timeout`. """ ) ).tag(config=True) timeout_func = Any( default_value=None, allow_none=True, help=dedent( """ A callable which, when given the cell source as input, returns the time to wait (in seconds) for output from cell executions. If a cell execution takes longer, an exception (TimeoutError on python 3+, RuntimeError on python 2) is raised. Returning `None` or `-1` will disable the timeout for the cell. Not setting `timeout_func` will cause the preprocessor to default to using the `timeout` trait for all cells. The `timeout_func` trait overrides `timeout` if it is not `None`. """ ) ).tag(config=True) interrupt_on_timeout = Bool(False, help=dedent( """ If execution of a cell times out, interrupt the kernel and continue executing other cells rather than throwing an error and stopping. """ ) ).tag(config=True) startup_timeout = Integer(60, help=dedent( """ The time to wait (in seconds) for the kernel to start. If kernel startup takes longer, a RuntimeError is raised. """ ) ).tag(config=True) allow_errors = Bool(False, help=dedent( """ If `False` (default), when a cell raises an error the execution is stopped and a `CellExecutionError` is raised. If `True`, execution errors are ignored and the execution is continued until the end of the notebook. Output from exceptions is included in the cell output in both cases. """ ) ).tag(config=True) extra_arguments = List(Unicode()) kernel_name = Unicode('', help=dedent( """ Name of kernel to use to execute the cells. If not set, use the kernel_spec embedded in the notebook. """ ) ).tag(config=True) raise_on_iopub_timeout = Bool(False, help=dedent( """ If `False` (default), then the kernel will continue waiting for iopub messages until it receives a kernel idle message, or until a timeout occurs, at which point the currently executing cell will be skipped. If `True`, then an error will be raised after the first timeout. This option generally does not need to be used, but may be useful in contexts where there is the possibility of executing notebooks with memory-consuming infinite loops. """ ) ).tag(config=True) iopub_timeout = Integer(4, allow_none=False, help=dedent( """ The time to wait (in seconds) for IOPub output. This generally doesn't need to be set, but on some slow networks (such as CI systems) the default timeout might not be long enough to get all messages. """ ) ).tag(config=True) shutdown_kernel = Enum(['graceful', 'immediate'], default_value='graceful', help=dedent( """ If `graceful` (default), then the kernel is given time to clean up after executing all cells, e.g., to execute its `atexit` hooks. If `immediate`, then the kernel is signaled to immediately terminate. """ ) ).tag(config=True) kernel_manager_class = Type( config=True, help='The kernel manager class to use.' ) @default('kernel_manager_class') def _km_default(self): """Use a dynamic default to avoid importing jupyter_client at startup""" try: from jupyter_client import KernelManager except ImportError: raise ImportError("`nbconvert --execute` requires the jupyter_client package: `pip install jupyter_client`") return KernelManager # mapping of locations of outputs with a given display_id # tracks cell index and output index within cell.outputs for # each appearance of the display_id # { # 'display_id': { # cell_idx: [output_idx,] # } # } _display_id_map = Dict() def preprocess(self, nb, resources): """ Preprocess notebook executing each code cell. The input argument `nb` is modified in-place. Parameters ---------- nb : NotebookNode Notebook being executed. resources : dictionary Additional resources used in the conversion process. For example, passing ``{'metadata': {'path': run_path}}`` sets the execution path to ``run_path``. Returns ------- nb : NotebookNode The executed notebook. resources : dictionary Additional resources used in the conversion process. """ path = resources.get('metadata', {}).get('path', '') if path == '': path = None # clear display_id map self._display_id_map = {} # from jupyter_client.manager import start_new_kernel def start_new_kernel(startup_timeout=60, kernel_name='python', **kwargs): km = self.kernel_manager_class(kernel_name=kernel_name) km.start_kernel(**kwargs) kc = km.client() kc.start_channels() try: kc.wait_for_ready(timeout=startup_timeout) except RuntimeError: kc.stop_channels() km.shutdown_kernel() raise return km, kc kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python') if self.kernel_name: kernel_name = self.kernel_name self.log.info("Executing notebook with kernel: %s" % kernel_name) self.km, self.kc = start_new_kernel( startup_timeout=self.startup_timeout, kernel_name=kernel_name, extra_arguments=self.extra_arguments, cwd=path) self.kc.allow_stdin = False self.nb = nb try: nb, resources = super(ExecutePreprocessor, self).preprocess(nb, resources) finally: self.kc.stop_channels() self.km.shutdown_kernel(now=self.shutdown_kernel == 'immediate') delattr(self, 'nb') return nb, resources def preprocess_cell(self, cell, resources, cell_index): """ Executes a single code cell. See base.py for details. To execute all cells see :meth:`preprocess`. """ if cell.cell_type != 'code': return cell, resources reply, outputs = self.run_cell(cell, cell_index) cell.outputs = outputs if not self.allow_errors: for out in outputs: if out.output_type == 'error': raise CellExecutionError.from_cell_and_msg(cell, out) if (reply is not None) and reply['content']['status'] == 'error': raise CellExecutionError.from_cell_and_msg(cell, reply['content']) return cell, resources def _update_display_id(self, display_id, msg): """Update outputs with a given display_id""" if display_id not in self._display_id_map: self.log.debug("display id %r not in %s", display_id, self._display_id_map) return if msg['header']['msg_type'] == 'update_display_data': msg['header']['msg_type'] = 'display_data' try: out = output_from_msg(msg) except ValueError: self.log.error("unhandled iopub msg: " + msg['msg_type']) return for cell_idx, output_indices in self._display_id_map[display_id].items(): cell = self.nb['cells'][cell_idx] outputs = cell['outputs'] for output_idx in output_indices: outputs[output_idx]['data'] = out['data'] outputs[output_idx]['metadata'] = out['metadata'] def _wait_for_reply(self, msg_id, cell): # wait for finish, with timeout while True: try: if self.timeout_func is not None: timeout = self.timeout_func(cell) else: timeout = self.timeout if not timeout or timeout < 0: timeout = None msg = self.kc.shell_channel.get_msg(timeout=timeout) except Empty: self.log.error( "Timeout waiting for execute reply (%is)." % self.timeout) if self.interrupt_on_timeout: self.log.error("Interrupting kernel") self.km.interrupt_kernel() break else: try: exception = TimeoutError except NameError: exception = RuntimeError raise exception("Cell execution timed out") if msg['parent_header'].get('msg_id') == msg_id: return msg else: # not our reply continue def run_cell(self, cell, cell_index=0): msg_id = self.kc.execute(cell.source) self.log.debug("Executing cell:\n%s", cell.source) exec_reply = self._wait_for_reply(msg_id, cell) outs = cell.outputs = [] while True: try: # We've already waited for execute_reply, so all output # should already be waiting. However, on slow networks, like # in certain CI systems, waiting < 1 second might miss messages. # So long as the kernel sends a status:idle message when it # finishes, we won't actually have to wait this long, anyway. msg = self.kc.iopub_channel.get_msg(timeout=self.iopub_timeout) except Empty: self.log.warn("Timeout waiting for IOPub output") if self.raise_on_iopub_timeout: raise RuntimeError("Timeout waiting for IOPub output") else: break if msg['parent_header'].get('msg_id') != msg_id: # not an output from our execution continue msg_type = msg['msg_type'] self.log.debug("output: %s", msg_type) content = msg['content'] # set the prompt number for the input and the output if 'execution_count' in content: cell['execution_count'] = content['execution_count'] if msg_type == 'status': if content['execution_state'] == 'idle': break else: continue elif msg_type == 'execute_input': continue elif msg_type == 'clear_output': outs[:] = [] # clear display_id mapping for this cell for display_id, cell_map in self._display_id_map.items(): if cell_index in cell_map: cell_map[cell_index] = [] continue elif msg_type.startswith('comm'): continue display_id = None if msg_type in {'execute_result', 'display_data', 'update_display_data'}: display_id = msg['content'].get('transient', {}).get('display_id', None) if display_id: self._update_display_id(display_id, msg) if msg_type == 'update_display_data': # update_display_data doesn't get recorded continue try: out = output_from_msg(msg) except ValueError: self.log.error("unhandled iopub msg: " + msg_type) continue if display_id: # record output index in: # _display_id_map[display_id][cell_idx] cell_map = self._display_id_map.setdefault(display_id, {}) output_idx_list = cell_map.setdefault(cell_index, []) output_idx_list.append(len(outs)) outs.append(out) return exec_reply, outs def executenb(nb, cwd=None, **kwargs): """Execute a notebook's code, updating outputs within the notebook object. This is a convenient wrapper around ExecutePreprocessor. It returns the modified notebook object. Parameters ---------- nb : NotebookNode The notebook object to be executed cwd : str, optional If supplied, the kernel will run in this directory kwargs : Any other options for ExecutePreprocessor, e.g. timeout, kernel_name """ resources = {} if cwd is not None: resources['metadata'] = {'path': cwd} ep = ExecutePreprocessor(**kwargs) return ep.preprocess(nb, resources)[0] nbconvert-5.3.1/nbconvert/preprocessors/extractoutput.py000077500000000000000000000104151315361605600237500ustar00rootroot00000000000000"""A preprocessor that extracts all of the outputs from the notebook file. The extracted outputs are returned in the 'resources' dictionary. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from binascii import a2b_base64 import sys import os from mimetypes import guess_extension from traitlets import Unicode, Set from .base import Preprocessor def guess_extension_without_jpe(mimetype): """ This function fixes a problem with '.jpe' extensions of jpeg images which are then not recognised by latex. For any other case, the function works in the same way as mimetypes.guess_extension """ ext = guess_extension(mimetype) if ext==".jpe": ext=".jpeg" return ext class ExtractOutputPreprocessor(Preprocessor): """ Extracts all of the outputs from the notebook file. The extracted outputs are returned in the 'resources' dictionary. """ output_filename_template = Unicode( "{unique_key}_{cell_index}_{index}{extension}" ).tag(config=True) extract_output_types = Set( {'image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf'} ).tag(config=True) def preprocess_cell(self, cell, resources, cell_index): """ Apply a transformation on each cell, Parameters ---------- cell : NotebookNode cell Notebook cell being processed resources : dictionary Additional resources used in the conversion process. Allows preprocessors to pass variables into the Jinja engine. cell_index : int Index of the cell being processed (see base.py) """ #Get the unique key from the resource dict if it exists. If it does not #exist, use 'output' as the default. Also, get files directory if it #has been specified unique_key = resources.get('unique_key', 'output') output_files_dir = resources.get('output_files_dir', None) #Make sure outputs key exists if not isinstance(resources['outputs'], dict): resources['outputs'] = {} #Loop through all of the outputs in the cell for index, out in enumerate(cell.get('outputs', [])): if out.output_type not in {'display_data', 'execute_result'}: continue #Get the output in data formats that the template needs extracted for mime_type in self.extract_output_types: if mime_type in out.data: data = out.data[mime_type] #Binary files are base64-encoded, SVG is already XML if mime_type in {'image/png', 'image/jpeg', 'application/pdf'}: # data is b64-encoded as text (str, unicode), # we want the original bytes data = a2b_base64(data) elif sys.platform == 'win32': data = data.replace('\n', '\r\n').encode("UTF-8") else: data = data.encode("UTF-8") ext = guess_extension_without_jpe(mime_type) if ext is None: ext = '.' + mime_type.rsplit('/')[-1] filename = self.output_filename_template.format( unique_key=unique_key, cell_index=cell_index, index=index, extension=ext) # On the cell, make the figure available via # cell.outputs[i].metadata.filenames['mime/type'] # where # cell.outputs[i].data['mime/type'] contains the data if output_files_dir is not None: filename = os.path.join(output_files_dir, filename) out.metadata.setdefault('filenames', {}) out.metadata['filenames'][mime_type] = filename #In the resources, make the figure available via # resources['outputs']['filename'] = data resources['outputs'][filename] = data return cell, resources nbconvert-5.3.1/nbconvert/preprocessors/highlightmagics.py000066400000000000000000000062631315361605600241530ustar00rootroot00000000000000"""This preprocessor detect cells using a different language through magic extensions such as `%%R` or `%%octave`. Cell's metadata is marked so that the appropriate highlighter can be used in the `highlight` filter. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function, absolute_import import re from .base import Preprocessor from traitlets import Dict class HighlightMagicsPreprocessor(Preprocessor): """ Detects and tags code cells that use a different languages than Python. """ # list of magic language extensions and their associated pygment lexers default_languages = Dict({ '%%R': 'r', '%%bash': 'bash', '%%cython': 'cython', '%%javascript': 'javascript', '%%julia': 'julia', '%%latex': 'latex', '%%octave': 'octave', '%%perl': 'perl', '%%ruby': 'ruby', '%%sh': 'sh', }) # user defined language extensions languages = Dict( help=("Syntax highlighting for magic's extension languages. " "Each item associates a language magic extension such as %%R, " "with a pygments lexer such as r.") ).tag(config=True) def __init__(self, config=None, **kw): """Public constructor""" super(HighlightMagicsPreprocessor, self).__init__(config=config, **kw) # Update the default languages dict with the user configured ones self.default_languages.update(self.languages) # build a regular expression to catch language extensions and choose # an adequate pygments lexer any_language = "|".join(self.default_languages.keys()) self.re_magic_language = re.compile( r'^\s*({0})\s+'.format(any_language)) def which_magic_language(self, source): """ When a cell uses another language through a magic extension, the other language is returned. If no language magic is detected, this function returns None. Parameters ---------- source: str Source code of the cell to highlight """ m = self.re_magic_language.match(source) if m: # By construction of the re, the matched language must be in the # languages dictionary return self.default_languages[m.group(1)] else: return None def preprocess_cell(self, cell, resources, cell_index): """ Tags cells using a magic extension language Parameters ---------- cell : NotebookNode cell Notebook cell being processed resources : dictionary Additional resources used in the conversion process. Allows preprocessors to pass variables into the Jinja engine. cell_index : int Index of the cell being processed (see base.py) """ # Only tag code cells if cell.cell_type == "code": magic_language = self.which_magic_language(cell.source) if magic_language: cell['metadata']['magics_language'] = magic_language return cell, resources nbconvert-5.3.1/nbconvert/preprocessors/latex.py000077500000000000000000000033361315361605600221360ustar00rootroot00000000000000"""Module that allows latex output notebooks to be conditioned before they are converted. """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from __future__ import print_function, absolute_import from .base import Preprocessor #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- class LatexPreprocessor(Preprocessor): """Preprocessor for latex destined documents. Mainly populates the `latex` key in the resources dict, adding definitions for pygments highlight styles. """ def preprocess(self, nb, resources): """Preprocessing to apply on each notebook. Parameters ---------- nb : NotebookNode Notebook being converted resources : dictionary Additional resources used in the conversion process. Allows preprocessors to pass variables into the Jinja engine. """ # Generate Pygments definitions for Latex from pygments.formatters import LatexFormatter resources.setdefault("latex", {}) resources["latex"].setdefault("pygments_definitions", LatexFormatter().get_style_defs()) return nb, resources nbconvert-5.3.1/nbconvert/preprocessors/regexremove.py000066400000000000000000000053531315361605600233470ustar00rootroot00000000000000""" Module containing a preprocessor that removes cells if they match one or more regular expression. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import re from traitlets import List, Unicode from .base import Preprocessor class RegexRemovePreprocessor(Preprocessor): """ Removes cells from a notebook that match one or more regular expression. For each cell, the preprocessor checks whether its contents match the regular expressions in the `patterns` traitlet which is a list of unicode strings. If the contents match any of the patterns, the cell is removed from the notebook. By default, `patterns = [r'\Z']` which matches the empty string such that strictly empty cells are removed. To modify the list of matched patterns, modify the patterns traitlet. For example, execute the following command to convert a notebook to html and remove cells containing only whitespace: > jupyter nbconvert --RegexRemovePreprocessor.enabled=True \ --RegexRemovePreprocessor.patterns="['\\s*\\Z']" mynotebook.ipynb The first command line argument enables the preprocessor and the second sets the list of patterns to '\\s*\\Z' which matches an arbitrary number of whitespace characters followed by the end of the string. See https://regex101.com/ for an interactive guide to regular expressions (make sure to select the python flavor). See https://docs.python.org/library/re.html for the official regular expression documentation in python. """ patterns = List(Unicode, default_value=[r'\Z']).tag(config=True) def check_conditions(self, cell): """ Checks that a cell matches the pattern and that (if a code cell) it does not have any outputs. Returns: Boolean. True means cell should *not* be removed. """ # Compile all the patterns into one: each pattern is first wrapped # by a non-capturing group to ensure the correct order of precedence # and the patterns are joined with a logical or pattern = re.compile('|'.join('(?:%s)' % pattern for pattern in self.patterns)) # Filter out cells that meet the pattern and have no outputs return cell.get('outputs') or not pattern.match(cell.source) def preprocess(self, nb, resources): """ Preprocessing to apply to each notebook. See base.py for details. """ # Skip preprocessing if the list of patterns is empty if not self.patterns: return nb, resources # Filter out cells that meet the conditions nb.cells = [cell for cell in nb.cells if self.check_conditions(cell)] return nb, resources nbconvert-5.3.1/nbconvert/preprocessors/sanitize.py000066400000000000000000000077421315361605600226510ustar00rootroot00000000000000""" NBConvert Preprocessor for sanitizing HTML rendering of notebooks. """ from bleach import ( ALLOWED_ATTRIBUTES, ALLOWED_STYLES, ALLOWED_TAGS, clean, ) from traitlets import ( Any, Bool, List, Set, Unicode, ) from .base import Preprocessor class SanitizeHTML(Preprocessor): # Bleach config. attributes = Any( config=True, default_value=ALLOWED_ATTRIBUTES, help="Allowed HTML tag attributes", ) tags = List( Unicode, config=True, default_value=ALLOWED_TAGS, help="List of HTML tags to allow", ) styles = List( Unicode, config=True, default_value=ALLOWED_STYLES, help="Allowed CSS styles if ' }), nbformat.new_output('stream', name='stdout', text="wat"), nbformat.new_output('stream', name='stdout', text="") ] nb.cells[0].outputs = outputs res = self.build_resources() nb, res = preprocessor(nb, res) expected_output = [ { 'data': { 'text/html': '<script>more evil</script>', 'text/plain': 'b' }, 'metadata': {}, 'output_type': 'display_data', }, { 'name': 'stdout', 'output_type': 'stream', 'text': 'wat' }, { 'name': 'stdout', 'output_type': 'stream', 'text': '' } ] self.assertEqual(nb.cells[0].outputs, expected_output) def test_tag_whitelist(self): """Test tag whitelisting""" preprocessor = self.build_preprocessor() self.assertEqual( self.preprocess_source( 'markdown', '_A_ few ', preprocessor ), '_A_ few <script>tags</script>' ) nbconvert-5.3.1/nbconvert/preprocessors/tests/test_svg2pdf.py000066400000000000000000000044401315361605600245670ustar00rootroot00000000000000"""Tests for the svg2pdf preprocessor""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from ipython_genutils.testing import decorators as dec from nbformat import v4 as nbformat from .base import PreprocessorTestsBase from ..svg2pdf import SVG2PDFPreprocessor class Testsvg2pdf(PreprocessorTestsBase): """Contains test functions for svg2pdf.py""" simple_svg = """ """ def build_notebook(self): """Build a reveal slides notebook in memory for use with tests. Overrides base in PreprocessorTestsBase""" outputs = [nbformat.new_output(output_type='display_data', data={'image/svg+xml':self.simple_svg}) ] cells=[nbformat.new_code_cell(source="", execution_count=1, outputs=outputs)] return nbformat.new_notebook(cells=cells) def build_preprocessor(self): """Make an instance of a preprocessor""" preprocessor = SVG2PDFPreprocessor() preprocessor.enabled = True return preprocessor def test_constructor(self): """Can a SVG2PDFPreprocessor be constructed?""" self.build_preprocessor() @dec.onlyif_cmds_exist('inkscape') def test_output(self): """Test the output of the SVG2PDFPreprocessor""" nb = self.build_notebook() res = self.build_resources() preprocessor = self.build_preprocessor() nb, res = preprocessor(nb, res) self.assertIn('application/pdf', nb.cells[0].outputs[0].data) nbconvert-5.3.1/nbconvert/preprocessors/tests/test_tagremove.py000066400000000000000000000056671315361605600252210ustar00rootroot00000000000000""" Module with tests for the TagRemovePreprocessor. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from nbformat import v4 as nbformat from .base import PreprocessorTestsBase from ..tagremove import TagRemovePreprocessor class TestTagRemove(PreprocessorTestsBase): """Contains test functions for tagremove.py""" def build_notebook(self): """ Build a notebook to have metadata tags for cells, output_areas, and individual outputs. """ notebook = super(TestTagRemove, self).build_notebook() # Add a few empty cells notebook.cells[0].outputs.extend( [nbformat.new_output("display_data", data={'text/plain': 'i'}, metadata={'tags': ["hide_one_output"]} ), ]) outputs_to_be_removed = [ nbformat.new_output("display_data", data={'text/plain': "remove_my_output"}), ] outputs_to_be_kept = [ nbformat.new_output("stream", name="stdout", text="remove_my_output", ), ] notebook.cells.extend( [nbformat.new_code_cell(source="display('remove_my_output')", execution_count=2, outputs=outputs_to_be_removed, metadata={"tags": ["hide_all_outputs"]}), nbformat.new_code_cell(source="print('remove this cell')", execution_count=3, outputs=outputs_to_be_kept, metadata={"tags": ["hide_this_cell"]}), ] ) return notebook def build_preprocessor(self): """Make an instance of a preprocessor""" preprocessor = TagRemovePreprocessor() preprocessor.enabled = True return preprocessor def test_constructor(self): """Can a TagRemovePreprocessor be constructed?""" self.build_preprocessor() def test_output(self): """Test the output of the TagRemovePreprocessor""" nb = self.build_notebook() res = self.build_resources() preprocessor = self.build_preprocessor() preprocessor.remove_cell_tags.add("hide_this_cell") preprocessor.remove_all_outputs_tags.add('hide_all_outputs') preprocessor.remove_single_output_tags.add('hide_one_output') nb, res = preprocessor(nb, res) # checks that we can remove entire cells self.assertEqual(len(nb.cells), 3) # checks that we can remove output areas self.assertEqual(len(nb.cells[-1].outputs), 0) # checks that we can remove individual outputs self.assertEqual(len(nb.cells[0].outputs), 8) nbconvert-5.3.1/nbconvert/resources/000077500000000000000000000000001315361605600175405ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/resources/__init__.py000066400000000000000000000000001315361605600216370ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/templates/000077500000000000000000000000001315361605600175245ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/templates/README.md000066400000000000000000000004761315361605600210120ustar00rootroot00000000000000README FIRST ============ Please do not add new templates for nbconvert here. In order to speed up the distribution of nbconvert templates and make it simpler to share such contributions, we encourage [sharing those links on our wiki page](https://github.com/ipython/ipython/wiki/Cookbook:%20nbconvert%20templates). nbconvert-5.3.1/nbconvert/templates/asciidoc.tpl000066400000000000000000000043731315361605600220320ustar00rootroot00000000000000{% extends 'display_priority.tpl' %} {% block input %} {% if resources.global_content_filter.include_input_prompt %} {% if cell.execution_count is defined -%} +*In[{{ cell.execution_count|replace(None, " ") }}]:*+ {% else %} +*In[]:*+ {%- endif -%} {%- endif -%} [source {%- if 'magics_language' in cell.metadata -%} , {{ cell.metadata.magics_language}} {%- elif 'pygments_lexer' in nb.metadata.get('language_info', {}) -%} , {{ nb.metadata.language_info.pygments_lexer }} {%- elif 'name' in nb.metadata.get('language_info', {}) -%} , {{ nb.metadata.language_info.name }} {%- endif -%}] ---- {{ cell.source}} ---- {% endblock input %} {% block output_group %} {% if resources.global_content_filter.include_output_prompt %} {% if cell.execution_count is defined -%} +*Out[{{ cell.execution_count|replace(None, " ") }}]:*+ {%- else -%} +*Out[]:*+ {%- endif -%} {%- endif %} ---- {{- super() -}} ---- {% endblock output_group %} {% block error %} {{ super() }} {% endblock error %} {% block traceback_line %} {{ line | indent | strip_ansi }} {% endblock traceback_line %} {%- block execute_result %} {%- block data_priority scoped %} {{- super() -}} {%- endblock %} {%- endblock execute_result %} {% block stream %} {{ output.text -}} {% endblock stream %} {% block data_svg %} ![svg]({{ output.metadata.filenames['image/svg+xml'] | path2url }}) {% endblock data_svg %} {% block data_png %} ![png]({{ output.metadata.filenames['image/png'] | path2url }}) {% endblock data_png %} {% block data_jpg %} ![jpeg]({{ output.metadata.filenames['image/jpeg'] | path2url }}) {% endblock data_jpg %} {% block data_latex %} {{ output.data['text/latex'] | convert_pandoc(from_format="latex", to_format="asciidoc")}} {% endblock data_latex %} {% block data_html scoped %} {{ output.data['text/html'] | convert_pandoc(from_format='html', to_format='asciidoc')}} {% endblock data_html %} {% block data_markdown scoped %} {{ output.data['text/markdown'] | markdown2asciidoc}} {% endblock data_markdown %} {% block data_text scoped %} {{-output.data['text/plain']-}} {% endblock data_text %} {% block markdowncell scoped %} {{ cell.source | markdown2asciidoc}} {% endblock markdowncell %} {% block unknowncell scoped %} unknown type {{ cell.type }} {% endblock unknowncell %} nbconvert-5.3.1/nbconvert/templates/html/000077500000000000000000000000001315361605600204705ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/templates/html/basic.tpl000066400000000000000000000152531315361605600223000ustar00rootroot00000000000000{%- extends 'display_priority.tpl' -%} {% block codecell %}
{{ super() }}
{%- endblock codecell %} {% block input_group -%}
{{ super() }}
{% endblock input_group %} {% block output_group %}
{{ super() }}
{% endblock output_group %} {% block in_prompt -%}
{%- if cell.execution_count is defined -%} {%- if resources.global_content_filter.include_input_prompt-%} In [{{ cell.execution_count|replace(None, " ") }}]: {%- else -%} In [ ]: {%- endif -%} {%- endif -%}
{%- endblock in_prompt %} {% block empty_in_prompt -%} {%- if resources.global_content_filter.include_input_prompt-%}
{% endif %} {%- endblock empty_in_prompt %} {# output_prompt doesn't do anything in HTML, because there is a prompt div in each output area (see output block) #} {% block output_prompt %} {% endblock output_prompt %} {% block input %}
{{ cell.source | highlight_code(metadata=cell.metadata) }}
{%- endblock input %} {% block output %}
{% if resources.global_content_filter.include_output_prompt %} {% block output_area_prompt %} {%- if output.output_type == 'execute_result' -%}
{%- if cell.execution_count is defined -%} Out[{{ cell.execution_count|replace(None, " ") }}]: {%- else -%} Out[ ]: {%- endif -%} {%- else -%}
{%- endif -%}
{% endblock output_area_prompt %} {% endif %} {{ super() }}
{% endblock output %} {% block markdowncell scoped %}
{%- if resources.global_content_filter.include_input_prompt-%} {{ self.empty_in_prompt() }} {%- endif -%}
{{ cell.source | markdown2html | strip_files_prefix }}
{%- endblock markdowncell %} {% block unknowncell scoped %} unknown type {{ cell.type }} {% endblock unknowncell %} {% block execute_result -%} {%- set extra_class="output_execute_result" -%} {% block data_priority scoped %} {{ super() }} {% endblock %} {%- set extra_class="" -%} {%- endblock execute_result %} {% block stream_stdout -%}
{{- output.text | ansi2html -}}
{%- endblock stream_stdout %} {% block stream_stderr -%}
{{- output.text | ansi2html -}}
{%- endblock stream_stderr %} {% block data_svg scoped -%}
{%- if output.svg_filename %} {%- endblock data_svg %} {% block data_html scoped -%}
{{ output.data['text/html'] }}
{%- endblock data_html %} {% block data_markdown scoped -%}
{{ output.data['text/markdown'] | markdown2html }}
{%- endblock data_markdown %} {% block data_png scoped %}
{%- if 'image/png' in output.metadata.get('filenames', {}) %}
{%- endblock data_png %} {% block data_jpg scoped %}
{%- if 'image/jpeg' in output.metadata.get('filenames', {}) %}
{%- endblock data_jpg %} {% block data_latex scoped %}
{{ output.data['text/latex'] }}
{%- endblock data_latex %} {% block error -%}
{{- super() -}}
{%- endblock error %} {%- block traceback_line %} {{ line | ansi2html }} {%- endblock traceback_line %} {%- block data_text scoped %}
{{- output.data['text/plain'] | ansi2html -}}
{%- endblock -%} {%- block data_javascript scoped %} {% set div_id = uuid4() %}
{%- endblock -%} {%- block data_widget_state scoped %} {% set div_id = uuid4() %} {% set datatype_list = output.data | filter_data_type %} {% set datatype = datatype_list[0]%}
{%- endblock data_widget_state -%} {%- block data_widget_view scoped %} {% set div_id = uuid4() %} {% set datatype_list = output.data | filter_data_type %} {% set datatype = datatype_list[0]%}
{%- endblock data_widget_view -%} {%- block footer %} {% set mimetype = 'application/vnd.jupyter.widget-state+json'%} {% if mimetype in nb.metadata.get("widgets",{})%} {% endif %} {{ super() }} {%- endblock footer-%} nbconvert-5.3.1/nbconvert/templates/html/full.tpl000066400000000000000000000032361315361605600221570ustar00rootroot00000000000000{%- extends 'basic.tpl' -%} {% from 'mathjax.tpl' import mathjax %} {%- block header -%} {%- block html_head -%} {{resources['metadata']['name']}} {%- if "widgets" in nb.metadata -%} {%- endif-%} {% for css in resources.inlining.css -%} {% endfor %} {{ mathjax() }} {%- endblock html_head -%} {%- endblock header -%} {% block body %}
{{ super() }}
{%- endblock body %} {% block footer %} {{ super() }} {% endblock footer %} nbconvert-5.3.1/nbconvert/templates/html/mathjax.tpl000066400000000000000000000015641315361605600226530ustar00rootroot00000000000000{%- macro mathjax(url='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML') -%} {%- endmacro %} nbconvert-5.3.1/nbconvert/templates/html/slides_reveal.tpl000066400000000000000000000160201315361605600240310ustar00rootroot00000000000000{%- extends 'basic.tpl' -%} {% from 'mathjax.tpl' import mathjax %} {%- block any_cell scoped -%} {%- if cell.metadata.get('slide_start', False) -%}
{%- endif -%} {%- if cell.metadata.get('subslide_start', False) -%}
{%- endif -%} {%- if cell.metadata.get('fragment_start', False) -%}
{%- endif -%} {%- if cell.metadata.slide_type == 'notes' -%} {%- elif cell.metadata.slide_type == 'skip' -%} {%- else -%} {{ super() }} {%- endif -%} {%- if cell.metadata.get('fragment_end', False) -%}
{%- endif -%} {%- if cell.metadata.get('subslide_end', False) -%}
{%- endif -%} {%- if cell.metadata.get('slide_end', False) -%}
{%- endif -%} {%- endblock any_cell -%} {% block header %} {{resources['metadata']['name']}} slides {{ mathjax() }} {% for css in resources.inlining.css -%} {% endfor %} {% endblock header%} {% block body %} {% block pre_slides %} {% endblock pre_slides %}
{{ super() }}
{% block post_slides %} {% endblock post_slides %} {% endblock body %} {% block footer %} {% endblock footer %} nbconvert-5.3.1/nbconvert/templates/latex/000077500000000000000000000000001315361605600206415ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/templates/latex/article.tplx000066400000000000000000000007261315361605600232020ustar00rootroot00000000000000 % Default to the notebook output style ((* if not cell_style is defined *)) ((* set cell_style = 'style_ipython.tplx' *)) ((* endif *)) % Inherit from the specified cell style. ((* extends cell_style *)) %=============================================================================== % Latex Article %=============================================================================== ((* block docclass *)) \documentclass[11pt]{article} ((* endblock docclass *)) nbconvert-5.3.1/nbconvert/templates/latex/base.tplx000066400000000000000000000203621315361605600224670ustar00rootroot00000000000000((= Latex base template (must inherit) This template builds upon the abstract template, adding common latex output functions. Figures, data_text, This template does not define a docclass, the inheriting class must define this.=)) ((*- extends 'document_contents.tplx' -*)) %=============================================================================== % Abstract overrides %=============================================================================== ((* block header *)) ((* block docclass *))((* endblock docclass *)) ((* block packages *)) \usepackage[T1]{fontenc} % Nicer default font (+ math font) than Computer Modern for most use cases \usepackage{mathpazo} % Basic figure setup, for now with no caption control since it's done % automatically by Pandoc (which extracts ![](path) syntax from Markdown). \usepackage{graphicx} % We will generate all images so they have a width \maxwidth. This means % that they will get their normal width if they fit onto the page, but % are scaled down if they would overflow the margins. \makeatletter \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth \else\Gin@nat@width\fi} \makeatother \let\Oldincludegraphics\includegraphics % Set max figure width to be 80% of text width, for now hardcoded. \renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=.8\maxwidth]{#1}} % Ensure that by default, figures have no caption (until we provide a % proper Figure object with a Caption API and a way to capture that % in the conversion process - todo). \usepackage{caption} \DeclareCaptionLabelFormat{nolabel}{} \captionsetup{labelformat=nolabel} \usepackage{adjustbox} % Used to constrain images to a maximum size \usepackage{xcolor} % Allow colors to be defined \usepackage{enumerate} % Needed for markdown enumerations to work \usepackage{geometry} % Used to adjust the document margins \usepackage{amsmath} % Equations \usepackage{amssymb} % Equations \usepackage{textcomp} % defines textquotesingle % Hack from http://tex.stackexchange.com/a/47451/13684: \AtBeginDocument{% \def\PYZsq{\textquotesingle}% Upright quotes in Pygmentized code } \usepackage{upquote} % Upright quotes for verbatim code \usepackage{eurosym} % defines \euro \usepackage[mathletters]{ucs} % Extended unicode (utf-8) support \usepackage[utf8x]{inputenc} % Allow utf-8 characters in the tex document \usepackage{fancyvrb} % verbatim replacement that allows latex \usepackage{grffile} % extends the file name processing of package graphics % to support a larger range % The hyperref package gives us a pdf with properly built % internal navigation ('pdf bookmarks' for the table of contents, % internal cross-reference links, web links for URLs, etc.) \usepackage{hyperref} \usepackage{longtable} % longtable support required by pandoc >1.10 \usepackage{booktabs} % table support for pandoc > 1.12.2 \usepackage[inline]{enumitem} % IRkernel/repr support (it uses the enumerate* environment) \usepackage[normalem]{ulem} % ulem is needed to support strikethroughs (\sout) % normalem makes italics be italics, not underlines ((* endblock packages *)) ((* block definitions *)) % Colors for the hyperref package \definecolor{urlcolor}{rgb}{0,.145,.698} \definecolor{linkcolor}{rgb}{.71,0.21,0.01} \definecolor{citecolor}{rgb}{.12,.54,.11} % ANSI colors \definecolor{ansi-black}{HTML}{3E424D} \definecolor{ansi-black-intense}{HTML}{282C36} \definecolor{ansi-red}{HTML}{E75C58} \definecolor{ansi-red-intense}{HTML}{B22B31} \definecolor{ansi-green}{HTML}{00A250} \definecolor{ansi-green-intense}{HTML}{007427} \definecolor{ansi-yellow}{HTML}{DDB62B} \definecolor{ansi-yellow-intense}{HTML}{B27D12} \definecolor{ansi-blue}{HTML}{208FFB} \definecolor{ansi-blue-intense}{HTML}{0065CA} \definecolor{ansi-magenta}{HTML}{D160C4} \definecolor{ansi-magenta-intense}{HTML}{A03196} \definecolor{ansi-cyan}{HTML}{60C6C8} \definecolor{ansi-cyan-intense}{HTML}{258F8F} \definecolor{ansi-white}{HTML}{C5C1B4} \definecolor{ansi-white-intense}{HTML}{A1A6B2} % commands and environments needed by pandoc snippets % extracted from the output of `pandoc -s` \providecommand{\tightlist}{% \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} % Add ',fontsize=\small' for more characters per line \newenvironment{Shaded}{}{} \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}} \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}} \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}} \newcommand{\RegionMarkerTok}[1]{{#1}} \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} \newcommand{\NormalTok}[1]{{#1}} % Additional commands for more recent versions of Pandoc \newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{{#1}}} \newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} \newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} \newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{{#1}}} \newcommand{\ImportTok}[1]{{#1}} \newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{{#1}}}} \newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} \newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} \newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{{#1}}} \newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} \newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{{#1}}} \newcommand{\BuiltInTok}[1]{{#1}} \newcommand{\ExtensionTok}[1]{{#1}} \newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{{#1}}} \newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{{#1}}} \newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} \newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} % Define a nice break command that doesn't care if a line doesn't already % exist. \def\br{\hspace*{\fill} \\* } % Math Jax compatability definitions \def\gt{>} \def\lt{<} % Document parameters ((* block title *))\title{((( resources.metadata.name | ascii_only | escape_latex )))}((* endblock title *)) ((* block date *))((* endblock date *)) ((* block author *))((* endblock author *)) ((* endblock definitions *)) ((* block commands *)) % Prevent overflowing lines due to hard-to-break entities \sloppy % Setup hyperref package \hypersetup{ breaklinks=true, % so long urls are correctly broken across lines colorlinks=true, urlcolor=urlcolor, linkcolor=linkcolor, citecolor=citecolor, } % Slightly bigger margins than the latex defaults ((* block margins *)) \geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in} ((* endblock margins *)) ((* endblock commands *)) ((* endblock header *)) ((* block body *)) \begin{document} ((* block predoc *)) ((* block maketitle *))\maketitle((* endblock maketitle *)) ((* block abstract *))((* endblock abstract *)) ((* endblock predoc *)) ((( super() ))) % Add a bibliography block to the postdoc ((* block postdoc *)) ((* block bibliography *))((* endblock bibliography *)) ((* endblock postdoc *)) \end{document} ((* endblock body *)) nbconvert-5.3.1/nbconvert/templates/latex/document_contents.tplx000066400000000000000000000050041315361605600253040ustar00rootroot00000000000000((*- extends 'display_priority.tplx' -*)) %=============================================================================== % Support blocks %=============================================================================== % Displaying simple data text ((* block data_text *)) \begin{verbatim} ((( output.data['text/plain'] ))) \end{verbatim} ((* endblock data_text *)) % Display python error text as-is ((* block error *)) \begin{Verbatim}[commandchars=\\\{\}] ((( super() ))) \end{Verbatim} ((* endblock error *)) ((* block traceback_line *)) ((( line | indent | strip_ansi | escape_latex ))) ((* endblock traceback_line *)) % Display stream ouput with coloring ((* block stream *)) \begin{Verbatim}[commandchars=\\\{\}] ((( output.text | escape_latex | ansi2latex ))) \end{Verbatim} ((* endblock stream *)) % Display latex ((* block data_latex -*)) ((( output.data['text/latex'] | strip_files_prefix ))) ((* endblock data_latex *)) % Display markdown ((* block data_markdown -*)) ((( output.data['text/markdown'] | citation2latex | strip_files_prefix | convert_pandoc('markdown+tex_math_double_backslash', 'latex')))) ((* endblock data_markdown *)) % Default mechanism for rendering figures ((*- block data_png -*))((( draw_figure(output.metadata.filenames['image/png']) )))((*- endblock -*)) ((*- block data_jpg -*))((( draw_figure(output.metadata.filenames['image/jpeg']) )))((*- endblock -*)) ((*- block data_svg -*))((( draw_figure(output.metadata.filenames['image/svg+xml']) )))((*- endblock -*)) ((*- block data_pdf -*))((( draw_figure(output.metadata.filenames['application/pdf']) )))((*- endblock -*)) % Draw a figure using the graphicx package. ((* macro draw_figure(filename) -*)) ((* set filename = filename | posix_path *)) ((*- block figure scoped -*)) \begin{center} \adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{((( filename )))} \end{center} { \hspace*{\fill} \\} ((*- endblock figure -*)) ((*- endmacro *)) % Redirect execute_result to display data priority. ((* block execute_result scoped *)) ((* block data_priority scoped *)) ((( super() ))) ((* endblock *)) ((* endblock execute_result *)) % Render markdown ((* block markdowncell scoped *)) ((( cell.source | citation2latex | strip_files_prefix | convert_pandoc('markdown+tex_math_double_backslash', 'json',extra_args=[]) | resolve_references | convert_pandoc('json','latex')))) ((* endblock markdowncell *)) % Don't display unknown types ((* block unknowncell scoped *)) ((* endblock unknowncell *)) nbconvert-5.3.1/nbconvert/templates/latex/report.tplx000066400000000000000000000015711315361605600230710ustar00rootroot00000000000000 % Default to the notebook output style ((* if not cell_style is defined *)) ((* set cell_style = 'style_ipython.tplx' *)) ((* endif *)) % Inherit from the specified cell style. ((* extends cell_style *)) %=============================================================================== % Latex Book %=============================================================================== ((* block predoc *)) ((( super() ))) ((* block tableofcontents *))\tableofcontents((* endblock tableofcontents *)) ((* endblock predoc *)) ((* block docclass *)) \documentclass{report} ((* endblock docclass *)) ((* block markdowncell scoped *)) ((( cell.source | citation2latex | strip_files_prefix | convert_pandoc('markdown+tex_math_double_backslash', 'json',extra_args=[]) | resolve_references | convert_pandoc('json','latex', extra_args=["--chapters"]) ))) ((* endblock markdowncell *)) nbconvert-5.3.1/nbconvert/templates/latex/skeleton/000077500000000000000000000000001315361605600224655ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/templates/latex/skeleton/display_priority.tplx000066400000000000000000000034051315361605600270060ustar00rootroot00000000000000((= Auto-generated template file, DO NOT edit directly! To edit this file, please refer to ../../skeleton/README.md =)) ((*- extends 'null.tplx' -*)) ((=display data priority=)) ((*- block data_priority scoped -*)) ((*- for type in output.data | filter_data_type -*)) ((*- if type == 'application/pdf' -*)) ((*- block data_pdf -*)) ((*- endblock -*)) ((*- elif type == 'image/svg+xml' -*)) ((*- block data_svg -*)) ((*- endblock -*)) ((*- elif type == 'image/png' -*)) ((*- block data_png -*)) ((*- endblock -*)) ((*- elif type == 'text/html' -*)) ((*- block data_html -*)) ((*- endblock -*)) ((*- elif type == 'text/markdown' -*)) ((*- block data_markdown -*)) ((*- endblock -*)) ((*- elif type == 'image/jpeg' -*)) ((*- block data_jpg -*)) ((*- endblock -*)) ((*- elif type == 'text/plain' -*)) ((*- block data_text -*)) ((*- endblock -*)) ((*- elif type == 'text/latex' -*)) ((*- block data_latex -*)) ((*- endblock -*)) ((*- elif type == 'application/javascript' -*)) ((*- block data_javascript -*)) ((*- endblock -*)) ((*- elif type == 'application/vnd.jupyter.widget-state+json' -*)) ((*- block data_widget_state -*)) ((*- endblock -*)) ((*- elif type == 'application/vnd.jupyter.widget-view+json' -*)) ((*- block data_widget_view -*)) ((*- endblock -*)) ((*- else -*)) ((*- block data_other -*)) ((*- endblock -*)) ((*- endif -*)) ((*- endfor -*)) ((*- endblock data_priority -*)) nbconvert-5.3.1/nbconvert/templates/latex/skeleton/null.tplx000066400000000000000000000126071315361605600243560ustar00rootroot00000000000000((= Auto-generated template file, DO NOT edit directly! To edit this file, please refer to ../../skeleton/README.md =)) ((= DO NOT USE THIS AS A BASE, IF YOU ARE COPY AND PASTING THIS FILE YOU ARE PROBABLY DOING THINGS INCORRECTLY. Null template, does nothing except defining a basic structure To layout the different blocks of a notebook. Subtemplates can override blocks to define their custom representation. If one of the block you do overwrite is not a leave block, consider calling super. ((*- block nonLeaveBlock -*)) #add stuff at beginning ((( super() ))) #add stuff at end ((*- endblock nonLeaveBlock -*)) consider calling super even if it is a leave block, we might insert more blocks later. =)) ((*- block header -*)) ((*- endblock header -*)) ((*- block body -*)) ((*- for cell in nb.cells -*)) ((*- block any_cell scoped -*)) ((*- if cell.cell_type == 'code'-*)) ((*- if resources.global_content_filter.include_code -*)) ((*- block codecell scoped -*)) ((*- if resources.global_content_filter.include_input and not cell.get("transient",{}).get("remove_source", false) -*)) ((*- block input_group -*)) ((*- if resources.global_content_filter.include_input_prompt -*)) ((*- block in_prompt -*))((*- endblock in_prompt -*)) ((*- endif -*)) ((*- block input -*))((*- endblock input -*)) ((*- endblock input_group -*)) ((*- endif -*)) ((*- if cell.outputs and resources.global_content_filter.include_output -*)) ((*- block output_group -*)) ((*- if resources.global_content_filter.include_output_prompt -*)) ((*- block output_prompt -*))((*- endblock output_prompt -*)) ((*- endif -*)) ((*- block outputs scoped -*)) ((*- for output in cell.outputs -*)) ((*- block output scoped -*)) ((*- if output.output_type == 'execute_result' -*)) ((*- block execute_result scoped -*))((*- endblock execute_result -*)) ((*- elif output.output_type == 'stream' -*)) ((*- block stream scoped -*)) ((*- if output.name == 'stdout' -*)) ((*- block stream_stdout scoped -*)) ((*- endblock stream_stdout -*)) ((*- elif output.name == 'stderr' -*)) ((*- block stream_stderr scoped -*)) ((*- endblock stream_stderr -*)) ((*- endif -*)) ((*- endblock stream -*)) ((*- elif output.output_type == 'display_data' -*)) ((*- block display_data scoped -*)) ((*- block data_priority scoped -*)) ((*- endblock data_priority -*)) ((*- endblock display_data -*)) ((*- elif output.output_type == 'error' -*)) ((*- block error scoped -*)) ((*- for line in output.traceback -*)) ((*- block traceback_line scoped -*))((*- endblock traceback_line -*)) ((*- endfor -*)) ((*- endblock error -*)) ((*- endif -*)) ((*- endblock output -*)) ((*- endfor -*)) ((*- endblock outputs -*)) ((*- endblock output_group -*)) ((*- endif -*)) ((*- endblock codecell -*)) ((*- endif -*)) ((*- elif cell.cell_type in ['markdown'] -*)) ((*- if resources.global_content_filter.include_markdown and not cell.get("transient",{}).get("remove_source", false) -*)) ((*- block markdowncell scoped-*)) ((*- endblock markdowncell -*)) ((*- endif -*)) ((*- elif cell.cell_type in ['raw'] -*)) ((*- if resources.global_content_filter.include_raw and not cell.get("transient",{}).get("remove_source", false) -*)) ((*- block rawcell scoped -*)) ((*- if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) -*)) ((( cell.source ))) ((*- endif -*)) ((*- endblock rawcell -*)) ((*- endif -*)) ((*- else -*)) ((*- if resources.global_content_filter.include_unknown and not cell.get("transient",{}).get("remove_source", false) -*)) ((*- block unknowncell scoped-*)) ((*- endblock unknowncell -*)) ((*- endif -*)) ((*- endif -*)) ((*- endblock any_cell -*)) ((*- endfor -*)) ((*- endblock body -*)) ((*- block footer -*)) ((*- endblock footer -*)) nbconvert-5.3.1/nbconvert/templates/latex/style_bw_ipython.tplx000066400000000000000000000033571315361605600251640ustar00rootroot00000000000000((= Black&white ipython input/output style =)) ((*- extends 'base.tplx' -*)) %=============================================================================== % Input %=============================================================================== ((* block input scoped *)) ((*- if resources.global_content_filter.include_input_prompt *)) ((( add_prompt(cell.source, cell, 'In ') ))) ((* endif -*)) ((* endblock input *)) %=============================================================================== % Output %=============================================================================== ((* block execute_result scoped *)) ((*- for type in output.data | filter_data_type -*)) ((*- if resources.global_content_filter.include_output_prompt -*)) ((*- if type in ['text/plain'] *)) ((( add_prompt(output.data['text/plain'], cell, 'Out') ))) ((*- else -*)) \verb+Out[((( cell.execution_count )))]:+((( super() ))) ((*- endif -*)) ((*- endif -*)) ((*- endfor -*)) ((* endblock execute_result *)) %============================================================================== % Support Macros %============================================================================== % Name: draw_prompt % Purpose: Renders an output/input prompt ((* macro add_prompt(text, cell, prompt) -*)) ((*- if cell.execution_count is defined -*)) ((*- set execution_count = "" ~ (cell.execution_count | replace(None, " ")) -*)) ((*- else -*)) ((*- set execution_count = " " -*)) ((*- endif -*)) ((*- set indentation = " " * (execution_count | length + 7) -*)) \begin{verbatim} (((- text | add_prompts(first=prompt ~ '[' ~ execution_count ~ ']: ', cont=indentation) -))) \end{verbatim} ((*- endmacro *)) nbconvert-5.3.1/nbconvert/templates/latex/style_bw_python.tplx000066400000000000000000000007351315361605600250100ustar00rootroot00000000000000((= Black&white Python input/output style =)) ((*- extends 'base.tplx' -*)) %=============================================================================== % Input %=============================================================================== ((* block input scoped *)) \begin{verbatim} ((*- if resources.global_content_filter.include_input_prompt *)) ((( cell.source | add_prompts ))) ((* else *)) ((( cell.source ))) ((* endif *)) \end{verbatim} ((* endblock input *)) nbconvert-5.3.1/nbconvert/templates/latex/style_ipython.tplx000066400000000000000000000043671315361605600244760ustar00rootroot00000000000000((= IPython input/output style =)) ((*- extends 'base.tplx' -*)) % Custom definitions ((* block definitions *)) ((( super() ))) % Pygments definitions ((( resources.latex.pygments_definitions ))) % Exact colors from NB \definecolor{incolor}{rgb}{0.0, 0.0, 0.5} \definecolor{outcolor}{rgb}{0.545, 0.0, 0.0} ((* endblock definitions *)) %=============================================================================== % Input %=============================================================================== ((* block input scoped *)) ((*- if resources.global_content_filter.include_input_prompt *)) ((( add_prompt(cell.source | highlight_code(strip_verbatim=True, metadata=cell.metadata), cell, 'In ', 'incolor') ))) ((* endif *)) ((* endblock input *)) %=============================================================================== % Output %=============================================================================== ((* block execute_result scoped *)) ((*- for type in output.data | filter_data_type -*)) ((*- if resources.global_content_filter.include_output_prompt -*)) ((*- if type in ['text/plain'] *)) ((( add_prompt(output.data['text/plain'] | escape_latex, cell, 'Out', 'outcolor') ))) ((* else -*)) \texttt{\color{outcolor}Out[{\color{outcolor}((( cell.execution_count )))}]:}((( super() ))) ((*- endif -*)) ((*- endif -*)) ((*- endfor -*)) ((* endblock execute_result *)) %============================================================================== % Support Macros %============================================================================== % Name: draw_prompt % Purpose: Renders an output/input prompt ((* macro add_prompt(text, cell, prompt, prompt_color) -*)) ((*- if cell.execution_count is defined -*)) ((*- set execution_count = "" ~ (cell.execution_count | replace(None, " ")) -*)) ((*- else -*)) ((*- set execution_count = " " -*)) ((*- endif -*)) ((*- set indention = " " * (execution_count | length + 7) -*)) \begin{Verbatim}[commandchars=\\\{\}] ((( text | add_prompts(first='{\color{' ~ prompt_color ~ '}' ~ prompt ~ '[{\\color{' ~ prompt_color ~ '}' ~ execution_count ~ '}]:} ', cont=indention) ))) \end{Verbatim} ((*- endmacro *)) nbconvert-5.3.1/nbconvert/templates/latex/style_python.tplx000066400000000000000000000014301315361605600243110ustar00rootroot00000000000000((= Python input/output style =)) ((*- extends 'base.tplx' -*)) % Custom definitions ((* block definitions *)) ((( super() ))) % Pygments definitions ((( resources.latex.pygments_definitions ))) ((* endblock definitions *)) %=============================================================================== % Input %=============================================================================== ((* block input scoped *)) \begin{Verbatim}[commandchars=\\\{\}] ((*- if resources.global_content_filter.include_input_prompt *)) ((( cell.source | highlight_code(strip_verbatim=True, metadata=cell.metadata) | add_prompts ))) ((* else *)) ((( cell.source | highlight_code(strip_verbatim=True, metadata=cell.metadata) ))) ((* endif *)) \end{Verbatim} ((* endblock input *)) nbconvert-5.3.1/nbconvert/templates/markdown.tpl000066400000000000000000000031111315361605600220630ustar00rootroot00000000000000{% extends 'display_priority.tpl' %} {% block in_prompt %} {% endblock in_prompt %} {% block output_prompt %} {%- endblock output_prompt %} {% block input %} ``` {%- if 'magics_language' in cell.metadata -%} {{ cell.metadata.magics_language}} {%- elif 'name' in nb.metadata.get('language_info', {}) -%} {{ nb.metadata.language_info.name }} {%- endif %} {{ cell.source}} ``` {% endblock input %} {% block error %} {{ super() }} {% endblock error %} {% block traceback_line %} {{ line | indent | strip_ansi }} {% endblock traceback_line %} {% block execute_result %} {% block data_priority scoped %} {{ super() }} {% endblock %} {% endblock execute_result %} {% block stream %} {{ output.text | indent }} {% endblock stream %} {% block data_svg %} ![svg]({{ output.metadata.filenames['image/svg+xml'] | path2url }}) {% endblock data_svg %} {% block data_png %} ![png]({{ output.metadata.filenames['image/png'] | path2url }}) {% endblock data_png %} {% block data_jpg %} ![jpeg]({{ output.metadata.filenames['image/jpeg'] | path2url }}) {% endblock data_jpg %} {% block data_latex %} {{ output.data['text/latex'] }} {% endblock data_latex %} {% block data_html scoped %} {{ output.data['text/html'] }} {% endblock data_html %} {% block data_markdown scoped %} {{ output.data['text/markdown'] }} {% endblock data_markdown %} {% block data_text scoped %} {{ output.data['text/plain'] | indent }} {% endblock data_text %} {% block markdowncell scoped %} {{ cell.source }} {% endblock markdowncell %} {% block unknowncell scoped %} unknown type {{ cell.type }} {% endblock unknowncell %} nbconvert-5.3.1/nbconvert/templates/python.tpl000066400000000000000000000007011315361605600215640ustar00rootroot00000000000000{%- extends 'null.tpl' -%} {% block header %} # coding: utf-8 {% endblock header %} {% block in_prompt %} {% if resources.global_content_filter.include_input_prompt -%} # In[{{ cell.execution_count if cell.execution_count else ' ' }}]: {% endif %} {% endblock in_prompt %} {% block input %} {{ cell.source | ipython2python }} {% endblock input %} {% block markdowncell scoped %} {{ cell.source | comment_lines }} {% endblock markdowncell %} nbconvert-5.3.1/nbconvert/templates/rst.tpl000066400000000000000000000054271315361605600210650ustar00rootroot00000000000000{%- extends 'display_priority.tpl' -%} {% block in_prompt %} {% endblock in_prompt %} {% block output_prompt %} {% endblock output_prompt %} {% block input scoped%} {%- if cell.source.strip() -%} {{".. code:: "-}} {%- if 'magics_language' in cell.metadata -%} {{ cell.metadata.magics_language}} {%- elif 'pygments_lexer' in nb.metadata.get('language_info', {}) -%} {{ nb.metadata.language_info.pygments_lexer }} {%- elif 'name' in nb.metadata.get('language_info', {}) -%} {{ nb.metadata.language_info.name }} {%- endif %} {{ cell.source | indent}} {% endif -%} {% endblock input %} {% block error %} :: {{ super() }} {% endblock error %} {% block traceback_line %} {{ line | indent | strip_ansi }} {% endblock traceback_line %} {% block execute_result %} {% block data_priority scoped %} {{ super() }} {% endblock %} {% endblock execute_result %} {% block stream %} .. parsed-literal:: {{ output.text | indent }} {% endblock stream %} {% block data_svg %} .. image:: {{ output.metadata.filenames['image/svg+xml'] | urlencode }} {% endblock data_svg %} {% block data_png %} .. image:: {{ output.metadata.filenames['image/png'] | urlencode }} {%- set width=output | get_metadata('width', 'image/png') -%} {%- if width is not none %} :width: {{ width }}px {%- endif %} {%- set height=output | get_metadata('height', 'image/png') -%} {%- if height is not none %} :height: {{ height }}px {%- endif %} {% endblock data_png %} {% block data_jpg %} .. image:: {{ output.metadata.filenames['image/jpeg'] | urlencode }} {%- set width=output | get_metadata('width', 'image/jpeg') -%} {%- if width is not none %} :width: {{ width }}px {%- endif %} {%- set height=output | get_metadata('height', 'image/jpeg') -%} {%- if height is not none %} :height: {{ height }}px {%- endif %} {% endblock data_jpg %} {% block data_markdown %} {{ output.data['text/markdown'] | convert_pandoc("markdown", "rst") }} {% endblock data_markdown %} {% block data_latex %} .. math:: {{ output.data['text/latex'] | strip_dollars | indent }} {% endblock data_latex %} {% block data_text scoped %} .. parsed-literal:: {{ output.data['text/plain'] | indent }} {% endblock data_text %} {% block data_html scoped %} .. raw:: html {{ output.data['text/html'] | indent }} {% endblock data_html %} {% block markdowncell scoped %} {{ cell.source | convert_pandoc("markdown", "rst") }} {% endblock markdowncell %} {%- block rawcell scoped -%} {%- if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) %} {{cell.source}} {% endif -%} {%- endblock rawcell -%} {% block headingcell scoped %} {{ ("#" * cell.level + cell.source) | replace('\n', ' ') | convert_pandoc("markdown", "rst") }} {% endblock headingcell %} {% block unknowncell scoped %} unknown type {{cell.type}} {% endblock unknowncell %} nbconvert-5.3.1/nbconvert/templates/script.tpl000066400000000000000000000001251315361605600215470ustar00rootroot00000000000000{%- extends 'null.tpl' -%} {% block input %} {{ cell.source }} {% endblock input %} nbconvert-5.3.1/nbconvert/templates/skeleton/000077500000000000000000000000001315361605600213505ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/templates/skeleton/Makefile000066400000000000000000000012501315361605600230060ustar00rootroot00000000000000TPLS := $(patsubst %.tpl,../latex/skeleton/%.tplx,$(wildcard *.tpl)) all: clean $(TPLS) # Convert standard Jinja2 syntax to LaTeX safe Jinja2 # see http://flask.pocoo.org/snippets/55/ for more info ../latex/skeleton/%.tplx: %.tpl @echo 'generating tex equivalent of $^: $@' @echo '((= Auto-generated template file, DO NOT edit directly!\n' \ ' To edit this file, please refer to ../../skeleton/README.md' \ '=))\n\n' > $@ @sed \ -e 's/{%/((*/g' \ -e 's/%}/*))/g' \ -e 's/{{/(((/g' \ -e 's/}}/)))/g' \ -e 's/{#/((=/g' \ -e 's/#}/=))/g' \ -e "s/tpl'/tplx'/g" \ $^ >> $@ clean: @echo "cleaning generated tplx files..." @-rm ../latex/skeleton/*.tplx nbconvert-5.3.1/nbconvert/templates/skeleton/README.md000066400000000000000000000010011315361605600226170ustar00rootroot00000000000000## Template skeleton This directory contains the template skeleton files. Do not modify the contents of the `../latex/skeleton` folder. Instead, if you need to, make modifications to the files in this folder and then run `make` to generate the corresponding latex skeleton files in the `../latex/skeleton` folder. If you would like to share your resulting templates with others, we encourage [sharing those links on our wiki page](https://github.com/ipython/ipython/wiki/Cookbook:%20nbconvert%20templates). nbconvert-5.3.1/nbconvert/templates/skeleton/display_priority.tpl000066400000000000000000000030601315361605600254760ustar00rootroot00000000000000{%- extends 'null.tpl' -%} {#display data priority#} {%- block data_priority scoped -%} {%- for type in output.data | filter_data_type -%} {%- if type == 'application/pdf' -%} {%- block data_pdf -%} {%- endblock -%} {%- elif type == 'image/svg+xml' -%} {%- block data_svg -%} {%- endblock -%} {%- elif type == 'image/png' -%} {%- block data_png -%} {%- endblock -%} {%- elif type == 'text/html' -%} {%- block data_html -%} {%- endblock -%} {%- elif type == 'text/markdown' -%} {%- block data_markdown -%} {%- endblock -%} {%- elif type == 'image/jpeg' -%} {%- block data_jpg -%} {%- endblock -%} {%- elif type == 'text/plain' -%} {%- block data_text -%} {%- endblock -%} {%- elif type == 'text/latex' -%} {%- block data_latex -%} {%- endblock -%} {%- elif type == 'application/javascript' -%} {%- block data_javascript -%} {%- endblock -%} {%- elif type == 'application/vnd.jupyter.widget-state+json' -%} {%- block data_widget_state -%} {%- endblock -%} {%- elif type == 'application/vnd.jupyter.widget-view+json' -%} {%- block data_widget_view -%} {%- endblock -%} {%- else -%} {%- block data_other -%} {%- endblock -%} {%- endif -%} {%- endfor -%} {%- endblock data_priority -%} nbconvert-5.3.1/nbconvert/templates/skeleton/null.tpl000066400000000000000000000121311315361605600230410ustar00rootroot00000000000000{# DO NOT USE THIS AS A BASE, IF YOU ARE COPY AND PASTING THIS FILE YOU ARE PROBABLY DOING THINGS INCORRECTLY. Null template, does nothing except defining a basic structure To layout the different blocks of a notebook. Subtemplates can override blocks to define their custom representation. If one of the block you do overwrite is not a leave block, consider calling super. {%- block nonLeaveBlock -%} #add stuff at beginning {{ super() }} #add stuff at end {%- endblock nonLeaveBlock -%} consider calling super even if it is a leave block, we might insert more blocks later. #} {%- block header -%} {%- endblock header -%} {%- block body -%} {%- for cell in nb.cells -%} {%- block any_cell scoped -%} {%- if cell.cell_type == 'code'-%} {%- if resources.global_content_filter.include_code -%} {%- block codecell scoped -%} {%- if resources.global_content_filter.include_input and not cell.get("transient",{}).get("remove_source", false) -%} {%- block input_group -%} {%- if resources.global_content_filter.include_input_prompt -%} {%- block in_prompt -%}{%- endblock in_prompt -%} {%- endif -%} {%- block input -%}{%- endblock input -%} {%- endblock input_group -%} {%- endif -%} {%- if cell.outputs and resources.global_content_filter.include_output -%} {%- block output_group -%} {%- if resources.global_content_filter.include_output_prompt -%} {%- block output_prompt -%}{%- endblock output_prompt -%} {%- endif -%} {%- block outputs scoped -%} {%- for output in cell.outputs -%} {%- block output scoped -%} {%- if output.output_type == 'execute_result' -%} {%- block execute_result scoped -%}{%- endblock execute_result -%} {%- elif output.output_type == 'stream' -%} {%- block stream scoped -%} {%- if output.name == 'stdout' -%} {%- block stream_stdout scoped -%} {%- endblock stream_stdout -%} {%- elif output.name == 'stderr' -%} {%- block stream_stderr scoped -%} {%- endblock stream_stderr -%} {%- endif -%} {%- endblock stream -%} {%- elif output.output_type == 'display_data' -%} {%- block display_data scoped -%} {%- block data_priority scoped -%} {%- endblock data_priority -%} {%- endblock display_data -%} {%- elif output.output_type == 'error' -%} {%- block error scoped -%} {%- for line in output.traceback -%} {%- block traceback_line scoped -%}{%- endblock traceback_line -%} {%- endfor -%} {%- endblock error -%} {%- endif -%} {%- endblock output -%} {%- endfor -%} {%- endblock outputs -%} {%- endblock output_group -%} {%- endif -%} {%- endblock codecell -%} {%- endif -%} {%- elif cell.cell_type in ['markdown'] -%} {%- if resources.global_content_filter.include_markdown and not cell.get("transient",{}).get("remove_source", false) -%} {%- block markdowncell scoped-%} {%- endblock markdowncell -%} {%- endif -%} {%- elif cell.cell_type in ['raw'] -%} {%- if resources.global_content_filter.include_raw and not cell.get("transient",{}).get("remove_source", false) -%} {%- block rawcell scoped -%} {%- if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) -%} {{ cell.source }} {%- endif -%} {%- endblock rawcell -%} {%- endif -%} {%- else -%} {%- if resources.global_content_filter.include_unknown and not cell.get("transient",{}).get("remove_source", false) -%} {%- block unknowncell scoped-%} {%- endblock unknowncell -%} {%- endif -%} {%- endif -%} {%- endblock any_cell -%} {%- endfor -%} {%- endblock body -%} {%- block footer -%} {%- endblock footer -%} nbconvert-5.3.1/nbconvert/tests/000077500000000000000000000000001315361605600166705ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/tests/README.md000066400000000000000000000001501315361605600201430ustar00rootroot00000000000000To compare nbconvert html output to the notebook's native html see https://gist.github.com/9241376.git. nbconvert-5.3.1/nbconvert/tests/__init__.py000066400000000000000000000000001315361605600207670ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/tests/base.py000066400000000000000000000132111315361605600201520ustar00rootroot00000000000000"""Base test class for nbconvert""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import io import os import glob import shlex import shutil import sys import unittest import nbconvert from subprocess import Popen, PIPE from nbformat import v4, write from testpath.tempdir import TemporaryWorkingDirectory from ipython_genutils.py3compat import string_types, bytes_to_str class TestsBase(unittest.TestCase): """Base tests class. Contains useful fuzzy comparison and nbconvert functions.""" def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True, fuzzy_spacing=True, ignore_spaces=False, ignore_newlines=False, case_sensitive=False, leave_padding=False): """ Performs a fuzzy comparison of two strings. A fuzzy comparison is a comparison that ignores insignificant differences in the two comparands. The significance of certain differences can be specified via the keyword parameters of this method. """ if not leave_padding: a = a.strip() b = b.strip() if ignore_newlines: a = a.replace('\n', '') b = b.replace('\n', '') if newlines_are_spaces: a = a.replace('\n', ' ') b = b.replace('\n', ' ') if tabs_are_spaces: a = a.replace('\t', ' ') b = b.replace('\t', ' ') if ignore_spaces: a = a.replace(' ', '') b = b.replace(' ', '') if fuzzy_spacing: a = self.recursive_replace(a, ' ', ' ') b = self.recursive_replace(b, ' ', ' ') if not case_sensitive: a = a.lower() b = b.lower() self.assertEqual(a, b) def recursive_replace(self, text, search, replacement): """ Performs a recursive replacement operation. Replaces all instances of a search string in a text string with a replacement string until the search string no longer exists. Recursion is needed because the replacement string may generate additional search strings. For example: Replace "ii" with "i" in the string "Hiiii" yields "Hii" Another replacement cds "Hi" (the desired output) Parameters ---------- text : string Text to replace in. search : string String to search for within "text" replacement : string String to replace "search" with """ while search in text: text = text.replace(search, replacement) return text def create_temp_cwd(self, copy_filenames=None): temp_dir = TemporaryWorkingDirectory() #Copy the files if requested. if copy_filenames is not None: self.copy_files_to(copy_filenames, dest=temp_dir.name) #Return directory handler return temp_dir def create_empty_notebook(self, path): nb = v4.new_notebook() with io.open(path, 'w', encoding='utf-8') as f: write(nb, f, 4) def copy_files_to(self, copy_filenames, dest='.'): "Copy test files into the destination directory" if not os.path.isdir(dest): os.makedirs(dest) files_path = self._get_files_path() for pattern in copy_filenames: files = glob.glob(os.path.join(files_path, pattern)) assert files for match in files: shutil.copyfile(match, os.path.join(dest, os.path.basename(match))) def _get_files_path(self): #Get the relative path to this module in the IPython directory. names = self.__module__.split('.')[1:-1] names.append('files') #Build a path using the nbconvert directory and the relative path we just #found. path = os.path.dirname(nbconvert.__file__) return os.path.join(path, *names) def nbconvert(self, parameters, ignore_return_code=False, stdin=None): """ Run nbconvert as a shell command, listening for both Errors and non-zero return codes. Returns the tuple (stdout, stderr) of output produced during the nbconvert run. Parameters ---------- parameters : str, list(str) List of parameters to pass to IPython. ignore_return_code : optional bool (default False) Throw an OSError if the return code """ if isinstance(parameters, string_types): parameters = shlex.split(parameters) cmd = [sys.executable, '-m', 'nbconvert'] + parameters p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE) stdout, stderr = p.communicate(input=stdin) if not (p.returncode == 0 or ignore_return_code): raise OSError(bytes_to_str(stderr)) return stdout.decode('utf8', 'replace'), stderr.decode('utf8', 'replace') def assert_big_text_equal(a, b, chunk_size=80): """assert that large strings are equal Zooms in on first chunk that differs, to give better info than vanilla assertEqual for large text blobs. """ for i in range(0, len(a), chunk_size): chunk_a = a[i:i + chunk_size] chunk_b = b[i:i + chunk_size] assert chunk_a == chunk_b, "[offset: %i]\n%r != \n%r" % (i, chunk_a, chunk_b) if len(a) > len(b): raise AssertionError("Length doesn't match (%i > %i). Extra text:\n%r" % ( len(a), len(b), a[len(b):])) elif len(a) < len(b): raise AssertionError("Length doesn't match (%i < %i). Extra text:\n%r" % ( len(a), len(b), a[len(b):])) nbconvert-5.3.1/nbconvert/tests/exporter_entrypoint/000077500000000000000000000000001315361605600230335ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/tests/exporter_entrypoint/eptest-0.1.dist-info/000077500000000000000000000000001315361605600265265ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/tests/exporter_entrypoint/eptest-0.1.dist-info/entry_points.txt000066400000000000000000000001761315361605600320300ustar00rootroot00000000000000[nbconvert.exporters] entrypoint_test = eptest:DummyExporter [nbconvert.exporters.script] dummy = eptest:DummyScriptExporter nbconvert-5.3.1/nbconvert/tests/exporter_entrypoint/eptest.py000066400000000000000000000003461315361605600247140ustar00rootroot00000000000000from nbconvert.exporters import Exporter class DummyExporter(Exporter): pass class DummyScriptExporter(Exporter): def from_notebook_node(self, nb, resources=None, **kw): return 'dummy-script-exported', resources nbconvert-5.3.1/nbconvert/tests/fake_exporters.py000066400000000000000000000006721315361605600222700ustar00rootroot00000000000000""" Module that define a custom exporter just to test the ability to invoke nbconvert with full qualified name """ from traitlets import default from nbconvert.exporters.html import HTMLExporter class MyExporter(HTMLExporter): """ My custom exporter """ @default('file_extension') def _file_extension_default(self): """ The new file extension is `.test_ext` """ return '.test_ext' nbconvert-5.3.1/nbconvert/tests/files/000077500000000000000000000000001315361605600177725ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/tests/files/Widget_List.ipynb000066400000000000000000004647561315361605600233010ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden" }, "source": [ "[Index](Index.ipynb) - [Back](Widget Basics.ipynb) - [Next](Widget Events.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Widget List" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Complete list" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "For a complete list of the GUI widgets available to you, you can list the registered widget types. `Widget` and `DOMWidget`, not listed below, are base classes." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'Jupyter.Accordion': ipywidgets.widgets.widget_selectioncontainer.Accordion,\n", " 'Jupyter.BoundedFloatText': ipywidgets.widgets.widget_float.BoundedFloatText,\n", " 'Jupyter.BoundedIntText': ipywidgets.widgets.widget_int.BoundedIntText,\n", " 'Jupyter.Box': ipywidgets.widgets.widget_box.Box,\n", " 'Jupyter.Button': ipywidgets.widgets.widget_button.Button,\n", " 'Jupyter.Checkbox': ipywidgets.widgets.widget_bool.Checkbox,\n", " 'Jupyter.ColorPicker': ipywidgets.widgets.widget_color.ColorPicker,\n", " 'Jupyter.Controller': ipywidgets.widgets.widget_controller.Controller,\n", " 'Jupyter.ControllerAxis': ipywidgets.widgets.widget_controller.Axis,\n", " 'Jupyter.ControllerButton': ipywidgets.widgets.widget_controller.Button,\n", " 'Jupyter.Dropdown': ipywidgets.widgets.widget_selection.Dropdown,\n", " 'Jupyter.FloatProgress': ipywidgets.widgets.widget_float.FloatProgress,\n", " 'Jupyter.FloatRangeSlider': ipywidgets.widgets.widget_float.FloatRangeSlider,\n", " 'Jupyter.FloatSlider': ipywidgets.widgets.widget_float.FloatSlider,\n", " 'Jupyter.FloatText': ipywidgets.widgets.widget_float.FloatText,\n", " 'Jupyter.HBox': ipywidgets.widgets.widget_box.HBox,\n", " 'Jupyter.HTML': ipywidgets.widgets.widget_string.HTML,\n", " 'Jupyter.Image': ipywidgets.widgets.widget_image.Image,\n", " 'Jupyter.IntProgress': ipywidgets.widgets.widget_int.IntProgress,\n", " 'Jupyter.IntRangeSlider': ipywidgets.widgets.widget_int.IntRangeSlider,\n", " 'Jupyter.IntSlider': ipywidgets.widgets.widget_int.IntSlider,\n", " 'Jupyter.IntText': ipywidgets.widgets.widget_int.IntText,\n", " 'Jupyter.Label': ipywidgets.widgets.widget_string.Label,\n", " 'Jupyter.PlaceProxy': ipywidgets.widgets.widget_box.PlaceProxy,\n", " 'Jupyter.Play': ipywidgets.widgets.widget_int.Play,\n", " 'Jupyter.Proxy': ipywidgets.widgets.widget_box.Proxy,\n", " 'Jupyter.RadioButtons': ipywidgets.widgets.widget_selection.RadioButtons,\n", " 'Jupyter.Select': ipywidgets.widgets.widget_selection.Select,\n", " 'Jupyter.SelectMultiple': ipywidgets.widgets.widget_selection.SelectMultiple,\n", " 'Jupyter.SelectionSlider': ipywidgets.widgets.widget_selection.SelectionSlider,\n", " 'Jupyter.Tab': ipywidgets.widgets.widget_selectioncontainer.Tab,\n", " 'Jupyter.Text': ipywidgets.widgets.widget_string.Text,\n", " 'Jupyter.Textarea': ipywidgets.widgets.widget_string.Textarea,\n", " 'Jupyter.ToggleButton': ipywidgets.widgets.widget_bool.ToggleButton,\n", " 'Jupyter.ToggleButtons': ipywidgets.widgets.widget_selection.ToggleButtons,\n", " 'Jupyter.VBox': ipywidgets.widgets.widget_box.VBox,\n", " 'Jupyter.Valid': ipywidgets.widgets.widget_bool.Valid,\n", " 'jupyter.DirectionalLink': ipywidgets.widgets.widget_link.DirectionalLink,\n", " 'jupyter.Link': ipywidgets.widgets.widget_link.Link}" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import ipywidgets as widgets\n", "widgets.Widget.widget_types" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Numeric widgets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are 8 widgets distributed with IPython that are designed to display numeric values. Widgets exist for displaying integers and floats, both bounded and unbounded. The integer widgets share a similar naming scheme to their floating point counterparts. By replacing `Float` with `Int` in the widget name, you can find the Integer equivalent." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IntSlider" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "b59af7d27c594924957e1aa26257751f" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.IntSlider(\n", " value=7,\n", " min=0,\n", " max=10,\n", " step=1,\n", " description='Test:',\n", " disabled=False,\n", " continuous_update=False,\n", " orientation='horizontal',\n", " readout=True,\n", " readout_format='i',\n", " slider_color='white'\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### FloatSlider" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a7e2b9cc83b647cea830e0bf9c99a446" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.FloatSlider(\n", " value=7.5,\n", " min=0,\n", " max=10.0,\n", " step=0.1,\n", " description='Test:',\n", " disabled=False,\n", " continuous_update=False,\n", " orientation='horizontal',\n", " readout=True,\n", " readout_format='.1f',\n", " slider_color='white'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sliders can also be **displayed vertically**." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "5e54ffd534404973b0f98d8573716a3d" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.FloatSlider(\n", " value=7.5,\n", " min=0,\n", " max=10.0,\n", " step=0.1,\n", " description='Test:',\n", " disabled=False,\n", " continuous_update=False,\n", " orientation='vertical',\n", " readout=True,\n", " readout_format='.1f',\n", " slider_color='white'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IntRangeSlider" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "887e65a5714e483798a9b84f0d936a52" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.IntRangeSlider(\n", " value=[5, 7],\n", " min=0,\n", " max=10,\n", " step=1,\n", " description='Test:',\n", " disabled=False,\n", " continuous_update=False,\n", " orientation='horizontal',\n", " readout=True,\n", " readout_format='i',\n", " slider_color='white',\n", " color='black'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### FloatRangeSlider" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d332c8df94ee42afb4d079dce40785f3" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.FloatRangeSlider(\n", " value=[5, 7.5],\n", " min=0,\n", " max=10.0,\n", " step=0.1,\n", " description='Test:',\n", " disabled=False,\n", " continuous_update=False,\n", " orientation='horizontal',\n", " readout=True,\n", " readout_format='i',\n", " slider_color='white',\n", " color='black'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IntProgress" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6716ba9736a74e4a957e91902a418922" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.IntProgress(\n", " value=7,\n", " min=0,\n", " max=10,\n", " step=1,\n", " description='Loading:',\n", " bar_style='', # 'success', 'info', 'warning', 'danger' or ''\n", " orientation='horizontal'\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### FloatProgress" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "4a8d047af2e645beb6a06f3d3a87f415" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.FloatProgress(\n", " value=7.5,\n", " min=0,\n", " max=10.0,\n", " step=0.1,\n", " description='Loading:',\n", " bar_style='info',\n", " orientation='horizontal'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### BoundedIntText" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "78808aec127a42a68cc8578100bdd20a" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.BoundedIntText(\n", " value=7,\n", " min=0,\n", " max=10,\n", " step=1,\n", " description='Text:',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### BoundedFloatText" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6e06309ba65e41e4ab9a287ec3036d9c" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.BoundedFloatText(\n", " value=7.5,\n", " min=0,\n", " max=10.0,\n", " step=0.1,\n", " description='Text:',\n", " disabled=False,\n", " color='black'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IntText" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e47d8b43215e48d9bb8c532860d80216" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.IntText(\n", " value=7,\n", " description='Any:',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### FloatText" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "21b9cd5e4f0d43dab1dd0a3ccc8034d7" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.FloatText(\n", " value=7.5,\n", " description='Any:',\n", " disabled=False,\n", " color='black'\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Boolean widgets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are three widgets that are designed to display a boolean value." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ToggleButton" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8acf995f75ad4ddc86fa68ca00fd92c8" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.ToggleButton(\n", " value=False,\n", " description='Click me',\n", " disabled=False,\n", " button_style='', # 'success', 'info', 'warning', 'danger' or ''\n", " tooltip='Description',\n", " icon='check'\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Checkbox" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e3d375dec35c455d8029d9328d1a55a0" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Checkbox(\n", " value=False,\n", " description='Check me',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Valid\n", "\n", "The valid widget provides a read-only indicator." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "f91ffb7111314c72b41ea6dfc617e374" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Valid(\n", " value=False,\n", " description='Valid!',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Selection widgets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are four widgets that can be used to display single selection lists, and one that can be used to display multiple selection lists. All inherit from the same base class. You can specify the **enumeration of selectable options by passing a list**. You can **also specify the enumeration as a dictionary**, in which case the **keys will be used as the item displayed** in the list and the corresponding **value will be returned** when an item is selected." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Dropdown" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6e182a69a1cd4a4194639cee8d84099a" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Dropdown(\n", " options=['1', '2', '3'],\n", " value='2',\n", " description='Number:',\n", " disabled=False,\n", " button_style='' # 'success', 'info', 'warning', 'danger' or ''\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following is also valid:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "35544158b22549a4a6f904b33213252d" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Dropdown(\n", " options={'One': 1, 'Two': 2, 'Three': 3},\n", " value=2,\n", " description='Number:',\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### RadioButtons" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6fe505cb796242c9af5949d296e7d047" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.RadioButtons(\n", " options=['pepperoni', 'pineapple', 'anchovies'],\n", "# value='pineapple',\n", " description='Pizza topping:',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Select" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d669c4295cbf4833b0c096e39129b22c" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Select(\n", " options=['Linux', 'Windows', 'OSX'],\n", "# value='OSX',\n", " description='OS:',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### SelectionSlider" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7d73679710a4455c9c7609beac8da45f" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.SelectionSlider(\n", " options=['scrambled', 'sunny side up', 'poached', 'over easy'],\n", " value='sunny side up',\n", " description='I like my eggs ...',\n", " disabled=False,\n", " continuous_update=False,\n", " orientation='horizontal',\n", " readout=True,\n", "# readout_format='i',\n", "# slider_color='black'\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### ToggleButtons" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "fa12c076ae4b4ba68aa0dbaf1f6e9c80" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.ToggleButtons(\n", " options=['Slow', 'Regular', 'Fast'],\n", " description='Speed:',\n", " disabled=False,\n", " button_style='', # 'success', 'info', 'warning', 'danger' or ''\n", " tooltip='Description',\n", "# icon='check' \n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### SelectMultiple\n", "Multiple values can be selected with shift and/or ctrl (or command) pressed and mouse clicks or arrow keys." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c063c53a85a442f78ef47c9f62a83b8d" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.SelectMultiple(\n", " options=['Apples', 'Oranges', 'Pears'],\n", " value=['Oranges'],\n", " description='Fruits',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## String widgets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are 4 widgets that can be used to display a string value. Of those, the `Text` and `Textarea` widgets accept input. The `Label` and `HTML` widgets display the string as either Label or HTML respectively, but do not accept input." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Text" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "786e43e0ce2c44b99d13cbaf5569f637" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Text(\n", " value='Hello World',\n", " placeholder='Type something',\n", " description='String:',\n", " disabled=False \n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Textarea" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "15ece8b84daa470f8938a138c2433389" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Textarea(\n", " value='Hello World',\n", " placeholder='Type something',\n", " description='String:',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Label" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c96f1b7c2637417285865c724b2364ca" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Label(\n", " value=\"$$\\\\frac{n!}{k!(n-k)!} = \\\\binom{n}{k}$$\",\n", " placeholder='Some LaTeX',\n", " description='Some LaTeX',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## HTML" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "ba868fda4d02439a8deb8b680ce80cb9" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.HTML(\n", " value=\"Hello World\",\n", " placeholder='Some HTML',\n", " description='Some HTML',\n", " disabled=False\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Image" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "5faca03ffc1447d0bff708566d2c068e" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "file = open(\"images/WidgetArch.png\", \"rb\")\n", "image = file.read()\n", "widgets.Image(\n", " value=image,\n", " format='png',\n", " width=300,\n", " height=400\n", ")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Button" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "12a9cb1f7c6f429887047437349a1efd" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Button(\n", " description='Click me',\n", " disabled=False,\n", " button_style='', # 'success', 'info', 'warning', 'danger' or ''\n", " tooltip='Click me',\n", " icon='check'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Play (Animation) widget" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `Play` widget is useful to perform animations by iterating on a sequence of integers with a certain speed." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a388a02e48954671b68dc718f299bc2f" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "play = widgets.Play(\n", "# interval=10,\n", " value=50,\n", " min=0,\n", " max=100,\n", " step=1,\n", " description=\"Press play\",\n", " disabled=False\n", ")\n", "slider = widgets.IntSlider()\n", "widgets.jslink((play, 'value'), (slider, 'value'))\n", "widgets.HBox([play, slider])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Color picker" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "c056cc916b2e446dbb1692ee68810233" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.ColorPicker(\n", " concise=False,\n", " description='Pick a color',\n", " value='blue'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Controller" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e9b8104b92fd41b398562e22edffdb81" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "widgets.Controller(\n", " index=0,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Layout widgets" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Box" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### HBox" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "261e5c581b0447169eb939ec57ae2004" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "items = [widgets.Label(str(i)) for i in range(4)]\n", "widgets.HBox(items)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### VBox" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "53da5ce19e2440eeb48d9894da634e98" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "items = [widgets.Label(str(i)) for i in range(4)]\n", "widgets.HBox([widgets.VBox([items[0], items[1]]), widgets.VBox([items[2], items[3]])])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Accordion" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "453127d40389487cb3e36e95d8b59d60" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "accordion = widgets.Accordion(children=[widgets.IntSlider(), widgets.Text()])\n", "accordion.set_title(0, 'Slider')\n", "accordion.set_title(1, 'Text')\n", "accordion" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tabs" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3a305f92e48542b59098381a161fde9a" } }, "metadata": {}, "output_type": "display_data" } ], "source": [ "list = ['P0', 'P1', 'P2', 'P3', 'P4']\n", "children = [widgets.Text(description=name) for name in list]\n", "tab = widgets.Tab(children=children)\n", "tab" ] }, { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden" }, "source": [ "[Index](Index.ipynb) - [Back](Widget Basics.ipynb) - [Next](Widget Events.ipynb)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "016ea837a5d242c3840091b092e51f2d": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "", "disabled": false, "layout": "IPY_MODEL_d3a80abfb5a645558f4dfbd94304ffae", "msg_throttle": 1, "placeholder": "​", "value": "0" } }, "067da89376f04e298a72261d10c7650a": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "07e24822058240ba862e20fa6cf02a27": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "08cfa62812e245ec838c5c971696818f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "", "disabled": false, "layout": "IPY_MODEL_3832d950aa9e490cb1c6855448b0992f", "msg_throttle": 1, "placeholder": "​", "value": "2" } }, "0b2631a5ca9f45e59278df4f59394281": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "", "disabled": false, "layout": "IPY_MODEL_2a42b49ab17442aa9ca9d6770aa8af5c", "msg_throttle": 1, "placeholder": "​", "value": "1" } }, "0c1d7e6695354a2a958b21f255b7f29b": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "0c5f090e8288472f80cc7661fcad30b2": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "12a9cb1f7c6f429887047437349a1efd": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ButtonModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ButtonModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ButtonView", "button_style": "", "description": "Click me", "disabled": false, "icon": "check", "layout": "IPY_MODEL_26352c5321464787842fff0e4e8b3e5e", "msg_throttle": 1, "tooltip": "Click me" } }, "140f80d916a745ae956f06b4f8a8f73f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "15ece8b84daa470f8938a138c2433389": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TextareaModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TextareaModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TextareaView", "description": "String:", "disabled": false, "layout": "IPY_MODEL_35d5b43dae50413ca8256ad84fec0363", "msg_throttle": 1, "placeholder": "Type something", "value": "Hello World" } }, "1654741e7d0a4bfb9008b25ce5ae0b89": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TextView", "description": "", "disabled": false, "layout": "IPY_MODEL_f1a8e14609fb47c4b8865849488511f0", "msg_throttle": 1, "placeholder": "​", "value": "" } }, "165e9979258c48fd829666b0ba7aa7ca": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "", "disabled": false, "layout": "IPY_MODEL_38212e65eb0b43dfba113efa910f994f", "msg_throttle": 1, "placeholder": "​", "value": "3" } }, "209bfbc1dbab45ccaffdd3f14f9b0b0a": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "21b9cd5e4f0d43dab1dd0a3ccc8034d7": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "FloatTextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "FloatTextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "FloatTextView", "description": "Any:", "disabled": false, "layout": "IPY_MODEL_140f80d916a745ae956f06b4f8a8f73f", "msg_throttle": 1, "value": 7.5 } }, "2344fbaf3fe341458e7781ec178d1ed3": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "23c54815d17d4dd1a64534e350b88f1c": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LinkModel", "state": { "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LinkModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": null, "msg_throttle": 1, "source": [ "IPY_MODEL_8eb44729a8c04a41a6ed6bc20724afc8", "value" ], "target": [ "IPY_MODEL_418b7b263f654ed9af540ff708571f51", "value" ] } }, "261e5c581b0447169eb939ec57ae2004": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "HBoxModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_8656dfd33b1c46bfb3ebe65071038b84", "IPY_MODEL_e5dcca0da2484a68a6d7d2c4b6204545", "IPY_MODEL_08cfa62812e245ec838c5c971696818f", "IPY_MODEL_36cead4f09324a48901f8e3c8ca65220" ], "layout": "IPY_MODEL_78582a251f4b48e9b6a4fb0b79e318f6", "msg_throttle": 1, "overflow_x": "", "overflow_y": "" } }, "26352c5321464787842fff0e4e8b3e5e": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2a42b49ab17442aa9ca9d6770aa8af5c": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "2eceb520afd04cee88fa33fba5d277e8": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TextView", "description": "P0", "disabled": false, "layout": "IPY_MODEL_8c3fe85543944693831dd00b1c7e939f", "msg_throttle": 1, "placeholder": "​", "value": "" } }, "3404dfa67d2e4536bb9f64014724d5f7": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "35544158b22549a4a6f904b33213252d": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "DropdownModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "DropdownModel", "_options_labels": [ "Three", "One", "Two" ], "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "DropdownView", "button_style": "", "description": "Number:", "disabled": false, "layout": "IPY_MODEL_f23cfdd8a9bd4f4f881a7dba98a11ba4", "msg_throttle": 1, "value": "Two" } }, "35d5b43dae50413ca8256ad84fec0363": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "36ce07efb0af4b7bb8fa5ecc20a75446": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "36cead4f09324a48901f8e3c8ca65220": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "", "disabled": false, "layout": "IPY_MODEL_a15bf7e4a11c4fd2bd7befcd22954b2b", "msg_throttle": 1, "placeholder": "​", "value": "3" } }, "38212e65eb0b43dfba113efa910f994f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3832d950aa9e490cb1c6855448b0992f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "396043a6467e4cba8cdd244be57d9478": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TextView", "description": "P2", "disabled": false, "layout": "IPY_MODEL_ea82f97ebc8d4d11a41fb54b4c654a6d", "msg_throttle": 1, "placeholder": "​", "value": "" } }, "3a305f92e48542b59098381a161fde9a": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TabModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TabModel", "_titles": {}, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TabView", "box_style": "", "children": [ "IPY_MODEL_2eceb520afd04cee88fa33fba5d277e8", "IPY_MODEL_e06b0e2dc4184c1b932d2377256f1699", "IPY_MODEL_396043a6467e4cba8cdd244be57d9478", "IPY_MODEL_9588a3f4aea842a689483210e3e85af1", "IPY_MODEL_e84e0f448b9e45ecbbcf969244e3a881" ], "layout": "IPY_MODEL_b7a3a5eb23cf4b04a59db57f8046bbc8", "msg_throttle": 1, "overflow_x": "", "overflow_y": "", "selected_index": 0 } }, "3d53699ff99a4fdc87909434e78128e4": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3d64356313794db080d8cf770efcd8d3": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "3dc0d036b79f4356b66804e5350e5f1c": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "418b7b263f654ed9af540ff708571f51": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "IntSliderModel", "_range": false, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "IntSliderView", "continuous_update": true, "description": "", "disabled": false, "layout": "IPY_MODEL_36ce07efb0af4b7bb8fa5ecc20a75446", "max": 100, "min": 0, "msg_throttle": 1, "orientation": "horizontal", "readout": true, "readout_format": "d", "slider_color": null, "step": 1, "value": 50 } }, "453127d40389487cb3e36e95d8b59d60": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "AccordionModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "AccordionModel", "_titles": { "0": "Slider", "1": "Text" }, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "AccordionView", "box_style": "", "children": [ "IPY_MODEL_976e5fe5e6dd42f4a2a5446d3da4ad0d", "IPY_MODEL_1654741e7d0a4bfb9008b25ce5ae0b89" ], "layout": "IPY_MODEL_6bfc0caf794b4acfa60c1e2cc5a24d2e", "msg_throttle": 1, "overflow_x": "", "overflow_y": "", "selected_index": 0 } }, "4a8d047af2e645beb6a06f3d3a87f415": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ProgressModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ProgressModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ProgressView", "bar_style": "info", "description": "Loading:", "disabled": false, "layout": "IPY_MODEL_50b86474be2d46418972bc60423001dc", "max": 10, "min": 0, "msg_throttle": 1, "orientation": "horizontal", "step": 0.1, "value": 7.5 } }, "50b86474be2d46418972bc60423001dc": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "50bd83bb64f747538455f07b1c403130": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "53aea1b1788240b4a6fc7103923cbc61": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "53da5ce19e2440eeb48d9894da634e98": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "HBoxModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_bf0e7471d56b40389ed58a513ad7852b", "IPY_MODEL_b6253d1f165f4a689836ddbdab177a05" ], "layout": "IPY_MODEL_b6ac090042a54f00ac29523e2eaa6cd3", "msg_throttle": 1, "overflow_x": "", "overflow_y": "" } }, "5694e208e8484e84b6cb9b3912fa355a": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "5e54ffd534404973b0f98d8573716a3d": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "FloatSliderModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "FloatSliderModel", "_range": false, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "FloatSliderView", "continuous_update": false, "description": "Test:", "disabled": false, "layout": "IPY_MODEL_aa14e7ac85aa42898abc65809702244f", "max": 10, "min": 0, "msg_throttle": 1, "orientation": "vertical", "readout": true, "readout_format": ".1f", "slider_color": "white", "step": 0.1, "value": 7.5 } }, "5faca03ffc1447d0bff708566d2c068e": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ImageModel", "state": { "_b64value": "iVBORw0KGgoAAAANSUhEUgAAATIAAAGxCAYAAADh4jqzAAAKQWlDQ1BJQ0MgUHJvZmlsZQAASA2dlndUU9kWh8+9N73QEiIgJfQaegkg0jtIFQRRiUmAUAKGhCZ2RAVGFBEpVmRUwAFHhyJjRRQLg4Ji1wnyEFDGwVFEReXdjGsJ7601896a/cdZ39nnt9fZZ+9917oAUPyCBMJ0WAGANKFYFO7rwVwSE8vE9wIYEAEOWAHA4WZmBEf4RALU/L09mZmoSMaz9u4ugGS72yy/UCZz1v9/kSI3QyQGAApF1TY8fiYX5QKUU7PFGTL/BMr0lSkyhjEyFqEJoqwi48SvbPan5iu7yZiXJuShGlnOGbw0noy7UN6aJeGjjAShXJgl4GejfAdlvVRJmgDl9yjT0/icTAAwFJlfzOcmoWyJMkUUGe6J8gIACJTEObxyDov5OWieAHimZ+SKBIlJYqYR15hp5ejIZvrxs1P5YjErlMNN4Yh4TM/0tAyOMBeAr2+WRQElWW2ZaJHtrRzt7VnW5mj5v9nfHn5T/T3IevtV8Sbsz55BjJ5Z32zsrC+9FgD2JFqbHbO+lVUAtG0GQOXhrE/vIADyBQC03pzzHoZsXpLE4gwnC4vs7GxzAZ9rLivoN/ufgm/Kv4Y595nL7vtWO6YXP4EjSRUzZUXlpqemS0TMzAwOl89k/fcQ/+PAOWnNycMsnJ/AF/GF6FVR6JQJhIlou4U8gViQLmQKhH/V4X8YNicHGX6daxRodV8AfYU5ULhJB8hvPQBDIwMkbj96An3rWxAxCsi+vGitka9zjzJ6/uf6Hwtcim7hTEEiU+b2DI9kciWiLBmj34RswQISkAd0oAo0gS4wAixgDRyAM3AD3iAAhIBIEAOWAy5IAmlABLJBPtgACkEx2AF2g2pwANSBetAEToI2cAZcBFfADXALDIBHQAqGwUswAd6BaQiC8BAVokGqkBakD5lC1hAbWgh5Q0FQOBQDxUOJkBCSQPnQJqgYKoOqoUNQPfQjdBq6CF2D+qAH0CA0Bv0BfYQRmALTYQ3YALaA2bA7HAhHwsvgRHgVnAcXwNvhSrgWPg63whfhG/AALIVfwpMIQMgIA9FGWAgb8URCkFgkAREha5EipAKpRZqQDqQbuY1IkXHkAwaHoWGYGBbGGeOHWYzhYlZh1mJKMNWYY5hWTBfmNmYQM4H5gqVi1bGmWCesP3YJNhGbjS3EVmCPYFuwl7ED2GHsOxwOx8AZ4hxwfrgYXDJuNa4Etw/XjLuA68MN4SbxeLwq3hTvgg/Bc/BifCG+Cn8cfx7fjx/GvyeQCVoEa4IPIZYgJGwkVBAaCOcI/YQRwjRRgahPdCKGEHnEXGIpsY7YQbxJHCZOkxRJhiQXUiQpmbSBVElqIl0mPSa9IZPJOmRHchhZQF5PriSfIF8lD5I/UJQoJhRPShxFQtlOOUq5QHlAeUOlUg2obtRYqpi6nVpPvUR9Sn0vR5Mzl/OX48mtk6uRa5Xrl3slT5TXl3eXXy6fJ18hf0r+pvy4AlHBQMFTgaOwVqFG4bTCPYVJRZqilWKIYppiiWKD4jXFUSW8koGStxJPqUDpsNIlpSEaQtOledK4tE20Otpl2jAdRzek+9OT6cX0H+i99AllJWVb5SjlHOUa5bPKUgbCMGD4M1IZpYyTjLuMj/M05rnP48/bNq9pXv+8KZX5Km4qfJUilWaVAZWPqkxVb9UU1Z2qbapP1DBqJmphatlq+9Uuq43Pp893ns+dXzT/5PyH6rC6iXq4+mr1w+o96pMamhq+GhkaVRqXNMY1GZpumsma5ZrnNMe0aFoLtQRa5VrntV4wlZnuzFRmJbOLOaGtru2nLdE+pN2rPa1jqLNYZ6NOs84TXZIuWzdBt1y3U3dCT0svWC9fr1HvoT5Rn62fpL9Hv1t/ysDQINpgi0GbwaihiqG/YZ5ho+FjI6qRq9Eqo1qjO8Y4Y7ZxivE+41smsImdSZJJjclNU9jU3lRgus+0zwxr5mgmNKs1u8eisNxZWaxG1qA5wzzIfKN5m/krCz2LWIudFt0WXyztLFMt6ywfWSlZBVhttOqw+sPaxJprXWN9x4Zq42Ozzqbd5rWtqS3fdr/tfTuaXbDdFrtOu8/2DvYi+yb7MQc9h3iHvQ732HR2KLuEfdUR6+jhuM7xjOMHJ3snsdNJp9+dWc4pzg3OowsMF/AX1C0YctFx4bgccpEuZC6MX3hwodRV25XjWuv6zE3Xjed2xG3E3dg92f24+ysPSw+RR4vHlKeT5xrPC16Il69XkVevt5L3Yu9q76c+Oj6JPo0+E752vqt9L/hh/QL9dvrd89fw5/rX+08EOASsCegKpARGBFYHPgsyCRIFdQTDwQHBu4IfL9JfJFzUFgJC/EN2hTwJNQxdFfpzGC4sNKwm7Hm4VXh+eHcELWJFREPEu0iPyNLIR4uNFksWd0bJR8VF1UdNRXtFl0VLl1gsWbPkRoxajCCmPRYfGxV7JHZyqffS3UuH4+ziCuPuLjNclrPs2nK15anLz66QX8FZcSoeGx8d3xD/iRPCqeVMrvRfuXflBNeTu4f7kufGK+eN8V34ZfyRBJeEsoTRRJfEXYljSa5JFUnjAk9BteB1sl/ygeSplJCUoykzqdGpzWmEtPi000IlYYqwK10zPSe9L8M0ozBDuspp1e5VE6JA0ZFMKHNZZruYjv5M9UiMJJslg1kLs2qy3mdHZZ/KUcwR5vTkmuRuyx3J88n7fjVmNXd1Z752/ob8wTXuaw6thdauXNu5Tnddwbrh9b7rj20gbUjZ8MtGy41lG99uit7UUaBRsL5gaLPv5sZCuUJR4b0tzlsObMVsFWzt3WazrWrblyJe0fViy+KK4k8l3JLr31l9V/ndzPaE7b2l9qX7d+B2CHfc3em681iZYlle2dCu4F2t5czyovK3u1fsvlZhW3FgD2mPZI+0MqiyvUqvakfVp+qk6oEaj5rmvep7t+2d2sfb17/fbX/TAY0DxQc+HhQcvH/I91BrrUFtxWHc4azDz+ui6rq/Z39ff0TtSPGRz0eFR6XHwo911TvU1zeoN5Q2wo2SxrHjccdv/eD1Q3sTq+lQM6O5+AQ4ITnx4sf4H++eDDzZeYp9qukn/Z/2ttBailqh1tzWibakNml7THvf6YDTnR3OHS0/m/989Iz2mZqzymdLz5HOFZybOZ93fvJCxoXxi4kXhzpXdD66tOTSna6wrt7LgZevXvG5cqnbvfv8VZerZ645XTt9nX297Yb9jdYeu56WX+x+aem172296XCz/ZbjrY6+BX3n+l37L972un3ljv+dGwOLBvruLr57/17cPel93v3RB6kPXj/Mejj9aP1j7OOiJwpPKp6qP6391fjXZqm99Oyg12DPs4hnj4a4Qy//lfmvT8MFz6nPK0a0RupHrUfPjPmM3Xqx9MXwy4yX0+OFvyn+tveV0auffnf7vWdiycTwa9HrmT9K3qi+OfrW9m3nZOjk03dp76anit6rvj/2gf2h+2P0x5Hp7E/4T5WfjT93fAn88ngmbWbm3/eE8/syOll+AAAACXBIWXMAABcSAAAXEgFnn9JSAAAB1WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlBob3RvbWV0cmljSW50ZXJwcmV0YXRpb24+MjwvdGlmZjpQaG90b21ldHJpY0ludGVycHJldGF0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KsOMy3QAAQABJREFUeAHtXQe4FEW2LhRzQsyCIigGBHNW5HpNmIVdAyZQXMOiu4hZDKiL4ZneGteE7qorCqu4a06AcUXBRUxgQgUDgjkj9Dt/7TtlTc90z8y9U8305T/fd293VzhV/ff0P6eqTp1pFYkYChEgAkQgxwgskOO+s+tEgAgQAYsAiYwfBCJABHKPAIks94+QN0AEiACJjJ8BIkAEco8AiSz3j5A3QASIAImMnwEiQARyjwCJLPePkDdABIgAiYyfASJABHKPAIks94+QN0AEiACJjJ8BIkAEco8AiSz3j5A3QASIAImMnwEiQARyjwCJLPePkDdABIgAiYyfASJABHKPAIks94+QN0AEiACJjJ8BIkAEco8AiSz3j5A3QASIAImMnwEiQARyjwCJLPePkDdABIgAiYyfASJABHKPAIks94+QN0AEiACJjJ8BIkAEco9A69B3MGLECDN06FAze/bs0E1RPxEgAnWOQLt27czw4cNN27Zta9tT/K5lSGlsbMTvZvKPGPAzwM+A/QyMHDmy5pQT3CKbM2eOZd4hQ4aYHj161JaFqY0IEIHcIDBw4EAzceJEM3fu3Jr3OTiRaY+7dOliGhoa9JJHIkAE5jME2rRpE+yOOdkfDFoqJgJEICsESGRZIc12iAARCIYAiSwYtFRMBIhAVgiQyLJCmu0QASIQDAESWTBoqZgIEIGsECCRZYU02yECRCAYAiSyYNBSMREgAlkhQCLLCmm2QwSIQDAESGTBoKViIkAEskKARJYV0myHCBCBYAiQyIJBS8VEgAhkhQCJLCuk2Q4RIALBECCRBYOWiokAEcgKARJZVkizHSJABIIhQCILBi0VEwEikBUCJLKskGY7RIAIBEOARBYMWiomAkQgKwRIZFkhzXaIABEIhgCJLBi0VEwEiEBWCJDIskKa7RABIhAMARJZMGipmAgQgawQIJFlhTTbIQJEIBgCJLJg0FIxESACWSFAIssKabZDBIhAMARIZMGgpWIiQASyQoBElhXSbIcIEIFgCJDIgkFLxUSACGSFAIksK6TZDhEgAsEQIJEFg5aKiQARyAoBEllWSLMdIkAEgiHQOphmKm4SAj/88INZbLHFmlQ3iiLTqlWriurOmTPHoK1vv/3WzJo1y3zyySdmjTXWMGuuuWZF9fNY6Ouvv7bYLrTQQk3q/k8//WS+++47Az3A65dffjEbb7yxWWKJJZqkj5VqhwCJrHZYNkvTjz/+aDbffHPz/vvvmxtvvNEccMABFevDC7X33nubF1980bz66qtmpZVWMmPGjDEPPPCAeeuttyxRff755wZ/eBFBYKhTSo466ihz4YUXmp133tnWBTHq3wILLODOkabXW221lfnb3/5mllpqKavyzjvvNMOHDzfvvvuubQ/lWrdubV/4LbbYwuy4447mN7/5TVnSRf9POeUU880335i11lrLHHTQQeawww4zCy+8cKmuF6XNnTvX3H333WbYsGFm3Lhx5quvvjILLrig2XLLLc3AgQPNfvvt5+p88cUX5rbbbjPjx483H3/8scUKeH355ZcWL5AYvijisswyy5jnn3/erLfeevEsXmeJgDycoNKjRw88/Ug+UEHbybvy5557zuIErPbcc097O/LyRLfeemskZJR6e0Iaru79998f+dfQV83fgAEDohEjRlRVB/qvu+4628eHH364orq77bZbNGPGjMT7EosnEmIs0rX99ttHQvqJ9TRDLM1o3333LarvYyGEbYsLqUfrr79+alm/nn8upBpNnz5dm+UxBYGQXMA5MvlU1oPgm18Fwz3Iqaeeavr162e6du1qLQvNjx9hOajMnDnTvPbaa3pZcPSHnThfZZVV7B+GlLBSzj33XHP++eebZZddtqBeuYu1117bCPnaYlOnTnXFMew688wzzeGHH271L7300i7voYceMo2NjQaWTilBP2CJxeWpp54yffv2LWkdaVkhFiOEZ0aNGqVJJY/XXHONTYc1BissLj5eyEP/gdmqq65qhPhM7969zYMPPmiv43V5nS0CHFpmi3dia/5waYUVVrDlRo4caY942TGsAsFgyBcXDEtVZs+ebc477zxzzDHHGLF47HCuTZs2Bn+XXXaZOf30021RsaDM0UcfrdUKjj6RYc4Mw0YMoTA0A+HqHyphSLXtttu64V7btm2dLrS3ww47uGsMZ++9915zxRVX2OEYhsFnn322ufjii10ZnMiXurnnnntsGoalRxxxhJk0aZJ54YUXbNpdd91lNtlkEzvstAneP9w/2sSQWkWsP9OrVy+z8sorm5dfftmMHTvWDr1B4JDll1/efPTRR+add94xmDtUvDD3teSSS9qhZfv27c17771nh8i2Ev/VFwIplmBNskKakzXpYJ0oeeyxx9zQRkjIDp/EInBp8qmJhGAisXiKenzBBRe4ckI6RfmacPPNN7tyaC9J5IV25QYNGpRUrGT6448/7urK3FHJMjJ3Fe211162nBBFhKGdL0I2TofMFbqsm266KVJMhFgiIR2XpydiZbm6Mi8X3XHHHZpVcPz0008jWeQoSCt1sdpqq1l9QtalsplWBQIhuYBDyzr5XvGHUYsvvri1fuQzUtA7DIH69+9fNKzyLTLUTRKdjEd+WjnfIuvUqVOSupLp/vARq6GlBEM23AcEw2hYW748+eST7lLLIQHngwcPtnnTpk0zjzzyiCuHEyxkYEiqMnToUGvJ6rV/XHHFFY1vPfp5/rliloaXX57n8wYBEtm8wb2o1TiR+SSGuSQMfyBPPPGEueWWWwrq+yuQaa4biyyyiKuX5oLgk5G+yK5imRN/Xumzzz5LLC0WkcvDKqovuEfIoosuaue6/LzTTjvN6NBbFkL8LCMWm3WLQOJ2221nTj755IL8plwoZml4NUUv69QWARJZbfFssrY4kcFdQQUvLuabVGCV6IIA0jCPpJJGZP48nF9H6+rRt/Bef/11m4y5J/hOYd4tTeDyoJJEZLCmLr/8clsM81CbbbaZVjHff/+9GT16tL1GuhKJFkD5Qw891F5i4t8XuFioYKHEJ1VNr/aomKXhVa1Olq89Ar++AbXXTY1VIOATE4YxvgWAIRpe3g033NBqBKH4E+T+S5ZGZL6Vpy9oqS76fUE7IBOUx4odfNROPPHEUtVsmt9GnMgmT55sfdSwCotzyJFHHllwr7DG1EKDv1kp2XTTTW0ycMAKpYqSbocOHcwee+yhyc066v2k4dWsBli5JgiQyGoCY/OVpFlkIDJYFxdddJFrCBbahx9+aK996y2NyH7++WdXH6txSeL3BWX8erieMmUKDiXFt8jQx4022sj+wapcd911zRlnnGHn/1C5oaHBXHrppQV6xA/OXcPNwRcMobG6+Oyzz7rkl156yZ6jXSVHOBbXwhqDYr33NLxcZ3gyzxD4dfwyz7rAhoGATx6YG/LJSSfNe/bsaed+nnnmGWu1YGL7hhtuMMstt5wDUa0Zl+Cd6EuJpDQLw7fI4HbRvXt367UPIgG5HHfccZ7WwlO1YJAKcpk4cWJBgY4dOxpZsTS77LKLwf3A094XePOrYI7rkksuMRjqYlsQMPL1oxyIbJ999rF5eu/qVqF6mnNUzNLwao5+1q0NAiSy2uDYbC0+kWEo5w8tfYfXs846y+y66662vb/+9a/mnHPOMViBU8ELnyT6UiIfK3xJ4hMZ/Lmw2FCp+BYZfK8w6Q4rS3WCBMWlo6Q6OPL6Q0XcS9r9QIlaZCBc+H/Bx833ISvZUBWJilkaXlWoY9FACHBoGQjYatXGiQxDI537AgnAURMCSwb7FSF4ya6//nq3ioc0OK0mib6UyE8jCCUdlNtggw1wqFi0z6iAoSX2XcIJFcNKCBYqlHxsgvcP5XyB9QfHV3jpY74MzsC4d98VAk6yaqXphve4O4evs9pzxSwNr2p1snztESCR1R7TJmn0yQNDS4hvlfn5mGdSwUZn3x8q7YXTlxJ1feJUXXr029K0So9+n3XYiA3fY2QTO44YJu6+++4l59leeeUV1wx2J8A6wyZueOKLo6159NFHrXf/22+/bWDtQeBbhx0CECwiQLBZHe3VQhSzNLxq0Q51NA8BElnz8KtZbf9FUZcDf57MJyhEulALRzz9jU8AtbDI/GFU0l7IpBv3+4xVRRWsdsKBFf5wWM2EZekPI1HOn0/DPsYkweop9luqqBuG7zyLlVW11LRcU45KZD7+TdHDOmERIJGFxbdi7T55qFXjk4JPdBh2+vNM6u2Oxnzn2Hjj8AVT8fVpmh79eS5sQq9G/D7HN2JjlwDm3HB/CFeEuT5YVCo+kcnWIE0uefTn7XQVE4sS3bp1s+UnTJhgjj/+eDckjyuBFQfLVq25eL5eK2ZpeGlZHucdApzsn3fYF7TsuwsokekRBeMvEvzKsGoJFwyQgkqam4DfRlyf1sdRh7Y4R2y0Aw880A4JsegA4tEjSBPDWliH2JgNZ1W/z75FBl0QkA3m9bARHJP7iJqBYSMcbdXbH7sJ/N0F/61Z+B9zZyoSAklPrTc/YpZBEN0CLhlXXXWVs2CR/o9//MNadPjyAFFj5TdJFLM0vJLqMj07BEhk2WGd2pJuu0EhnfPSISbS1DLAOQRkg72E+tL+N9UYuDckib+6CQ/6JPH3WoIMNNxNUnmkg3jgWe9bZLpAEa+HsD5YWUQAR5AQAhxi65EKQuSUE6xQYpgKIgKRg1yBGwgelp3uhABJIkIHhrZwpMX8mu8Hp07GSe0BMwwr1bUjqRzT5y0CHFrOW/xd67o6iAlyeKZD/JA9OrntKsjJIYccYmNiaRqssW222UYvi45wTlXxfc80TY86PNPrSo6wbuBZDzcIlc6dO+tp0REkrBFa4TsmkTlcGV2VdQkJJ34/QVAq8D3r06ePXtojrD3EDvNJDKuiCO+TJoqZfrmklWXePERAJkSDSsjQHUE7nrHyN998MxJHzsgPmyNDr0hiaEXiAZ/YGxnyRBKrLBILJUIIm3IiIaYjce6M5IVOLSqEGMnHMhJijcRajLp06RLhWSJ6rSw2RAivI5PrkcwzRRIfLBKryOkTiysSKyiSYa9LK3UiK5hWD9oRUokk/lqEqK3iAFyqeFGaLB7YviG6qxBpQb4MeyOE/UG/ZXho7wXt4A/3IwErIxn6FtQpdSErppGQmC1fKp9plSMQkgtaoRvycIMJtqFg+Ryx0/UbOFhjLVAx5qHgm+X7Z5W6TUzQlyuj9eBekTaXhnLQp+Uq1av6qzni44dN4quvvrp1z6imLspWct/YGYGFB7QFywqrntXcE6xN+K7pfFm1fWT5/yIQkgs4R1bnnzJ/zimtq9W8mOVIDO1AX7kJ97T+VJoHcvBXICutp+UquW8Mo9OG0qor6YhFDEp9I8A5svp+PuwdESACFSBAIqsAJBYhAkSgvhEgkdX382HviAARqAABElkFILEIESAC9Y0Aiay+nw97RwSIQAUIkMgqAIlFiAARqG8ESGT1/XzYOyJABCpAgERWAUgsQgSIQH0jQCKr7+fD3hEBIlABAiSyCkBiESJABOobARJZfT8f9o4IEIEKECCRVQASixABIlDfCJDI6vv5sHdEgAhUgACJrAKQWIQIEIH6RoBEVt/Ph70jAkSgAgRIZBWAxCJEgAjUNwIksvp+PuwdESACFSBAIqsAJBYhAkSgvhEgkdX382HviAARqAABElkFILEIESAC9Y0Aiay+nw97RwSIQAUIkMgqAIlFiAARqG8ESGT1/XzYOyJABCpAgERWAUgsQgSIQH0jQCKr7+fD3hEBIlABAiSyCkBiESJABOobARJZfT8f9o4IEIEKEGhdQZmaFBk0aJAZMmRITXRRCREgAvlDYOrUqcE6HZzIOnXqZMaOHWumTZsW7CaomAgQgfwgAE6otbSKRGqt1Nc3e/ZsM27cOIMjhQgQgfkbgXbt2pnOnTvXHITgRFbzHlMhESACRCCGACf7Y4DwkggQgfwhQCLL3zNjj4kAEYghQCKLAcJLIkAE8ocAiSx/z4w9JgJEIIYAiSwGCC+JABHIHwIksvw9M/aYCBCBGAIkshggvCQCRCB/CJDI8vfM2GMiQARiCJDIYoDwkggQgfwhQCLL3zNjj4kAEYghQCKLAcJLIkAE8ocAiSx/z4w9JgJEIIYAiSwGCC+JABHIHwLB45GNGDHCDB06lGF88vfZYI+JQM0RQBif4cOHm7Zt29ZWN+KRhZTGxkbEO+MfMeBngJ8B+xkYOXJkzSknuEU2Z84cy7wIc92jR4/asjC1EQEikBsEBg4caCZOnGjmzp1b8z4HJzLtcZcuXUxDQ4Ne8kgEiMB8hkCbNm2C3TEn+4NBS8VEgAhkhQCJLCuk2Q4RIALBECCRBYOWiokAEcgKARJZVkizHSJABIIhQCILBi0VEwEikBUCJLKskGY7RIAIBEOARBYMWiomAkQgKwRIZFkhzXaIABEIhgCJLBi0VEwEiEBWCJDIskKa7RABIhAMARJZMGipmAgQgawQIJFlhTTbIQJEIBgCJLJg0FIxESACWSFAIssKabZDBIhAMARIZMGgpWIiQASyQoBElhXSbIcIEIFgCJDIgkFLxUSACGSFAIksK6TZDhEgAsEQIJEFg5aKiQARyAoBEllWSLMdIkAEgiFAIgsGLRUTASKQFQIksqyQZjtEgAgEQ4BEFgxaKiYCRCArBEhkWSHNdogAEQiGAIksGLRUTASIQFYIkMiyQprtEAEiEAwBElkwaKmYCBCBrBAgkWWFNNshAkQgGAIksmDQUjERIAJZIUAiywpptkMEiEAwBFoH00zFdYnADz/8YBZbbLG67FuoTv3000/mu+++M19//bX55JNPzC+//GI23nhjs8QSS4RqknozRoAWWcaAV9PceeedZzbYYAPz9NNPV1PNlv3222/N9ttvb/bbbz8zZ84cm3bjjTea5ZZbzmyzzTYu7aGHHjINDQ1mvfXWM+3atTNbbbWVOfjgg81ZZ51lRo8eXXW7P/74o7n99ttNr169zFprrWUWX3xxs+KKK5o999zT3HXXXSX1XXHFFWaVVVYxSy+9tGnTpo1ZdtllTdu2bW1fV1hhBVt/pZVWMiuvvLLVOXLkSKfniy++MFdeeaXp27ev2WWXXcxmm21mOnXqZOuDsBdYYAGz6KKLWl0dO3Y0W2+9tenevbu91zfeeMPpAcH96U9/Mttuu63p2rWr2Xvvvc3VV19tic8V4kn9IhAFlh49ekRy99Hdd98duKWWp75z584WOyGzqm/uzDPPtHWB/XPPPWfry4vu0l566SWbtvrqq7s0lI3/denSJZIXOhJrpmwfXn311UhIoEiHr1OItUjP+uuvn1rHr49zITSrQyyrqNq6qmvhhReOpk+fbvVMmzYtUqw1X48LLrhgNHjw4Ojnn38u6jcTqkMgJBfQIpNPbL0KhkSQV155xbz22msVd3P27Nnm+uuvd+Vbt/7vDMKXX37p0mCxwZr54IMPXFqrVq3M2muvbVZbbTWDc8jrr79ujjvuOANr5v7773dl4yd/+ctfzOabb26EzOJZBdcjRowouhdYYJUKLKw//vGPtjj6//HHHxdV1b5rBiw9WHyrrrqqEeIzvXv3Ng8++KC9Rpl99tnHvPXWW1rcWn1CYPYa1uzQoUPNHnvsYeS1dWV4Ul8IcI6svp5HQW/at2/viObRRx+1L2FBgYSLhx9+2Hz22Wc2d5FFFjHdunWz52KFuBoYsoEIfHn55ZfNhhtuaJNAdBha3nHHHQZDuVmzZpm99trLXHvttebYY4/1q1nS9NNAAocccojZYost7DDxP//5jxGr0P4hD2374hPZ+eefb4d1mMcC8eof+oNh8XbbbWc6dOhgqy+//PLmo48+Mu+8844dKmNYij/MfS255JIG84HA8L333jNK5n67OAeu48ePt8kgPFxvueWWZubMmWbAgAFGRhI277HHHrNfKIqPTeS/+kGgOuOw+tIhzcnqe5OvGkcffbQbcgmJVNz5I4880tXbaaedXD2Z/3HpMicUyRyRu5ZPZCQWoCvrnwgxRssss4wti6HWE0884bKhR8jD6RGLLpo4caLL909mzJgRTZkyxU+y54ceeqitL5ZU9NVXXxXlNyVBrEqrE/ecJn369HF9v+6664qKXnrppZF8GUS4L1kwKMpnQuUIhOQCDi3r5zulqCebbLKJS/v3v//tzsudwCJTwZBI5ZtvvtFTOwmPYZovOpzy03C+6667WqsM5xhqnX766Ti1csIJJ1irCRewkDBkwwJFKYElJnNRRVlqkcHiglVUC1lqqaWsGiw2pIlO+MNa7devX1HRE0880chcmrXGyukqqsyEzBDg0DIzqKtvCKtrKhgqTp061ayxxhqaVPKIYZRMXru83Xff3Z03lcigQL5N7XANQ7xx48aZN9980+q98847nf5bb73VrLnmmu660hMlLyWfSuullcOQGrLQQgulFXNzbCBZrG6WEhAspb4RKPxKru++zne9W3fdde28kN64rDTqaeLxqaeecnlwf8DkvYoSGawPWF++RRafINc6egQhyAqmXloi07klJMKlw7f+XMEKTuCyAcF8lwwt7Tl8vt5//32DhYumiM4H+vdYSo9aiLC6MEdIyScCJLI6fm4gF0xuq8jck54mHn2fszixwJqC6BDJJ6+kYaU2NHfuXKPDMKRhRRWT+CoYYibJ999/b1cFn3/+eQOixQqs+rahjvYLOuE/BhKSOTlrfWLy/tNPP01SnZguMzc2TwktqSD8z1R22203c9RRR9nFC/RViV/zeaxfBEhk9ftsbM/84SXcMMoJXkAVf1iJVUC1fJTIfGul3AsPtwr/xYYl4xMZHGnjAlLFiimGjLAMYbVhiAqH03XWWceuJqKOrxeE6VthIEF/qBxvI+la/L5sFlYv0+Twww83ihMIE07DxxxzjO0r5u4wPzhs2LCCPqbpY968QYBENm9w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DSo9evSIBLLo7rvvDtoOlVeHwEMPPRQtvfTS9tng+cT/2rVrF82cObOk0iuvvDJaZJFFiuoIEUavvvpqUZ29997bll155ZWjyZMnF+Vrwq233hotvPDCTu+NN95os1566aWoVatWNn3QoEFavOgohBltu+22rj7ugVI/CITkAlpkLeyLqZLbufrqq82ee+5pvv7668Ti06dPN6NGjSrKv+uuu8wf/vAH89NPP9m8BRb49SP0xRdfWL1fffWVqydkaB588EF7DYtsp512Mh9++KHLx4m8atYCgyX2888/uzxYZ5Dbb7/dlsH55Zdfbs4991ycFsibb75pttxyS/Pss8+6dNzD559/7q550nIR+PVT2HLvkXfmISBWjzn++OPNnDlzbCqGk0OGDDH33HOPueWWW0z//v2NWDI2b4011vBqGjN+/Hhz+OGHu7TTTz/dzqthSHnIIYfY9KlTpxYQzbhx4wqGiCCx3XbbzSjZ/fjjj6ZPnz7mggsucHr1REnIJyfkob833XSTFjOjR482W2+9tcFQOS6qI57O6xaGQGjDM6Q5GbrvLU3/Dz/8EK222mpu6NXQ0BCJlVR0mzI3FU2ZMqUg/fvvv4/at2/v6l500UUF+WJJRZtvvrnNX2ihhZzeq666ytWRV8edr7vuutF1110XdevWzaUhf8kll3TXJ5xwgm1jueWWc2mqY8EFF4wwzDzxxBOj1q1bu3yxEKPFFlvMXQthFvSTF/MOgZBcQIushX0xpd3Otdde64Z1Qmhm5MiRZqWVViqqIiRhOnfuXJA+fPhwM23aNJu2xx57mFNPPbUgX8jLWVWYcL/jjjts/qxZs1y53r17m2222cZeYyh47LHHmkmTJtlrmQMzZ555pnn66addee2bWlVLLLGEgRWIhQlYlBhmXnbZZc7iQ59ffvllO7yFEpSTeUCnjyctFwESWct9tgV3hhffH74NGzbMiKVTUCbtAquOKmeffbaeFhwx/7XhhhvaNAxhITqExTmGkBgG7r///rh0gpXS++67z5x//vkGQ02VFVdc0bp2iA1hkzDUxT3IQoVp06aNFrPHAw44wLz44otmgw02cHN/qE+ZPxBoPX/cJu8S80dqHW266aZ20r1SVDDPhfkxyFZbbWW22GKLxKp9+/Y1MuSzlhasI1hRKt99952RVUkD666xsdEuAkAf5uWUdNT6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we6Yk/3BoKViIkAEskKARJYV0myHCBCBYAiQyIJBS8VEgAhkhQCJLCuk2Q4RIALBECCRBYOWiokAEcgKARJZVkizHSJABIIhQCILBi0VEwEikBUCJLKskGY7RIAIBEOARBYMWiomAkQgKwRIZFkhzXaIABEIhgCJLBi0VEwEiEBWCJDIskKa7RABIhAMARJZMGipmAgQgawQIJFlhTTbIQJEIBgCJLJg0FIxESACWSGQWTyyrG6I7WSDgIT4NPhbYIGmfRf+8ssv5ttvvzUhY1TVGgkECf3hhx9sv2fNmmU++eQTs8Yaa5g111yz1k0V6HvrrbfMYostZtq3b1+QzotfEWjap/DX+i3+bPr06aZbt27myCOPtC9utTd8++232/r/+te/bNUrrrjCrLLKKmbppZe2L/Gyyy5r45cvt9xyZoUVVjArrriiWWmllczKK69s1lprLSNhgYuaBIHce++95ne/+51Ze+21bdl9993XphUVLpGAvvTt29fW3W677cyAAQPM6NGjK4rc+cYbb1gsll9+ebPMMsuYXr16mQ8++KBEK8VJ7777rjnllFPsi7/ooosa3DvuGe3PmDHDVRg3bpzp2bOn+fe//+3S4iefffaZ2WOPPcyoUaNc1ueff2423XRTiy36BpJEG8AW/VV8gS2eAfr+zTffuPpjxowxJ598sgGW3bt3N+uvv757VgsttJBp3bq1WWqppWxa165dzU477WSf0dFHH+104KQ5+BYokgvgveGGG9q+gDwpCQjUPHh2TKGEt7Zxuu++++5YTj4u77jjDhdr/p577qmq0/LBi+SFsvV32WUXW1deDqdPHknZc3npCtq8//77ow022CCxHtr5+OOPC+r4FxdffHFiXfRtwoQJfvGC8yuvvDJaZJFFiuoLWUSvvvpqQdn4xUMPPRQJeRfVVQzkRymimTNn2mq4B6Tvt99+cTX2evbs2ZF+rvbaay9XRn7oJlG/thM/Xnfddba+/CBG1XVVlxCx60Nz8HVKvJPf/OY3rl/yReDl5O9Un1kILoCVEVRCdj5ox/9f+bBhw9wH6be//W1VTYr15eruvvvutq5YQC5NX4SkowzbogsvvNC1+dJLL0WtWrUqqg9y8dM32mij6Ouvv3b19OSf//xnQV2QLIjSb18sj+jJJ5/UKu4Yf9HRN7+eDLGiL7/80pX3T6666qpo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", "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ImageModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ImageView", "format": "png", "height": "400", "layout": "IPY_MODEL_50bd83bb64f747538455f07b1c403130", "msg_throttle": 1, "width": "300" } }, "6716ba9736a74e4a957e91902a418922": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ProgressModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ProgressModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ProgressView", "bar_style": "", "description": "Loading:", "disabled": false, "layout": "IPY_MODEL_a4121d5b20b24abca54c26f690b8582a", "max": 10, "min": 0, "msg_throttle": 1, "orientation": "horizontal", "step": 1, "value": 7 } }, "675671fd9cb84dabbc494684c8563ca9": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6bfc0caf794b4acfa60c1e2cc5a24d2e": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "6e06309ba65e41e4ab9a287ec3036d9c": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "FloatTextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "FloatTextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "FloatTextView", "description": "Text:", "disabled": false, "layout": "IPY_MODEL_f2c8d102cd5342b99e42685c2da1058b", "max": 10, "min": 0, "msg_throttle": 1, "step": 0.1, "value": 7.5 } }, "6e182a69a1cd4a4194639cee8d84099a": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "DropdownModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "DropdownModel", "_options_labels": [ "1", "2", "3" ], "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "DropdownView", "button_style": "", "description": "Number:", "disabled": false, "layout": "IPY_MODEL_3404dfa67d2e4536bb9f64014724d5f7", "msg_throttle": 1, "value": "2" } }, "6fe505cb796242c9af5949d296e7d047": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "RadioButtonsModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "RadioButtonsModel", "_options_labels": [ "pepperoni", "pineapple", "anchovies" ], "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "RadioButtonsView", "button_style": "", "description": "Pizza topping:", "disabled": false, "icons": [], "layout": "IPY_MODEL_d013d8c173114f46abfa4269e5331f4d", "msg_throttle": 1, "tooltips": [], "value": "pepperoni" } }, "733615a32c09455baca0bb96342768f5": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "78582a251f4b48e9b6a4fb0b79e318f6": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "786e43e0ce2c44b99d13cbaf5569f637": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TextView", "description": "String:", "disabled": false, "layout": "IPY_MODEL_c0474bbb166a45cd8cc596428e418d03", "msg_throttle": 1, "placeholder": "Type something", "value": "Hello World" } }, "78808aec127a42a68cc8578100bdd20a": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "IntTextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "IntTextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "IntTextView", "description": "Text:", "disabled": false, "layout": "IPY_MODEL_0c1d7e6695354a2a958b21f255b7f29b", "max": 10, "min": 0, "msg_throttle": 1, "step": 1, "value": 7 } }, "7d73679710a4455c9c7609beac8da45f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "SelectionSliderModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "SelectionSliderModel", "_options_labels": [ "scrambled", "sunny side up", "poached", "over easy" ], "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "SelectionSliderView", "continuous_update": false, "description": "I like my eggs ...", "disabled": false, "layout": "IPY_MODEL_e807bc5903d3417bae8a4177e5b9c521", "msg_throttle": 1, "orientation": "horizontal", "readout": true, "value": "sunny side up" } }, "82a43dac4690465d9e8e66808ecdcc2d": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8656dfd33b1c46bfb3ebe65071038b84": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "", "disabled": false, "layout": "IPY_MODEL_a23626e48aa540d7b1117407ce9ad480", "msg_throttle": 1, "placeholder": "​", "value": "0" } }, "887e65a5714e483798a9b84f0d936a52": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "IntSliderModel", "_range": true, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "IntSliderView", "continuous_update": false, "description": "Test:", "disabled": false, "layout": "IPY_MODEL_f77c3280ee964579ae59ebbc8e39780e", "max": 10, "min": 0, "msg_throttle": 1, "orientation": "horizontal", "readout": true, "readout_format": "d", "slider_color": "white", "step": 1, "value": [ 5, 7 ] } }, "8acf995f75ad4ddc86fa68ca00fd92c8": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ToggleButtonModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ToggleButtonModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ToggleButtonView", "button_style": "", "description": "Click me", "disabled": false, "icon": "check", "layout": "IPY_MODEL_902d582f038a48cbbe9437c0e980c657", "msg_throttle": 1, "tooltip": "Description", "value": false } }, "8bceaa69a7a54522acf296c855079463": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8c3fe85543944693831dd00b1c7e939f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8d4e103dd42842dfb600d4db46352852": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "8eb44729a8c04a41a6ed6bc20724afc8": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "PlayModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "PlayModel", "_playing": false, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "PlayView", "description": "Press play", "disabled": false, "interval": 100, "layout": "IPY_MODEL_209bfbc1dbab45ccaffdd3f14f9b0b0a", "max": 100, "min": 0, "msg_throttle": 1, "step": 1, "value": 50 } }, "8f27c5c75ba24ab888f82bcc4f10ebe5": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "902d582f038a48cbbe9437c0e980c657": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "9588a3f4aea842a689483210e3e85af1": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TextView", "description": "P3", "disabled": false, "layout": "IPY_MODEL_3dc0d036b79f4356b66804e5350e5f1c", "msg_throttle": 1, "placeholder": "​", "value": "" } }, "976e5fe5e6dd42f4a2a5446d3da4ad0d": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "IntSliderModel", "_range": false, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "IntSliderView", "continuous_update": true, "description": "", "disabled": false, "layout": "IPY_MODEL_82a43dac4690465d9e8e66808ecdcc2d", "max": 100, "min": 0, "msg_throttle": 1, "orientation": "horizontal", "readout": true, "readout_format": "d", "slider_color": null, "step": 1, "value": 0 } }, "a15bf7e4a11c4fd2bd7befcd22954b2b": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a23626e48aa540d7b1117407ce9ad480": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a388a02e48954671b68dc718f299bc2f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "HBoxModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_8eb44729a8c04a41a6ed6bc20724afc8", "IPY_MODEL_418b7b263f654ed9af540ff708571f51" ], "layout": "IPY_MODEL_b9bf797e9f414fb69bf8104be73f9516", "msg_throttle": 1, "overflow_x": "", "overflow_y": "" } }, "a4121d5b20b24abca54c26f690b8582a": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "a7e2b9cc83b647cea830e0bf9c99a446": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "FloatSliderModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "FloatSliderModel", "_range": false, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "FloatSliderView", "continuous_update": false, "description": "Test:", "disabled": false, "layout": "IPY_MODEL_675671fd9cb84dabbc494684c8563ca9", "max": 10, "min": 0, "msg_throttle": 1, "orientation": "horizontal", "readout": true, "readout_format": ".1f", "slider_color": "white", "step": 0.1, "value": 7.5 } }, "aa14e7ac85aa42898abc65809702244f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b3f69ae7d10b4dd7a64ed26c47cd047b": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b59af7d27c594924957e1aa26257751f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "IntSliderModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "IntSliderModel", "_range": false, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "IntSliderView", "continuous_update": false, "description": "Test:", "disabled": false, "layout": "IPY_MODEL_0c5f090e8288472f80cc7661fcad30b2", "max": 10, "min": 0, "msg_throttle": 1, "orientation": "horizontal", "readout": true, "readout_format": "i", "slider_color": "white", "step": 1, "value": 7 } }, "b6253d1f165f4a689836ddbdab177a05": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "VBoxModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "VBoxModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_fd8e8ff9da1f4b028003c9afc4f9410f", "IPY_MODEL_165e9979258c48fd829666b0ba7aa7ca" ], "layout": "IPY_MODEL_07e24822058240ba862e20fa6cf02a27", "msg_throttle": 1, "overflow_x": "", "overflow_y": "" } }, "b6ac090042a54f00ac29523e2eaa6cd3": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b77e51cc846d49128532716088e935ad": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b7a3a5eb23cf4b04a59db57f8046bbc8": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "b9bf797e9f414fb69bf8104be73f9516": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "ba868fda4d02439a8deb8b680ce80cb9": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "HTMLModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "HTMLView", "description": "Some HTML", "disabled": false, "layout": "IPY_MODEL_e27db74b160b486c8e26c70af357c1a4", "msg_throttle": 1, "placeholder": "Some HTML", "value": "Hello World" } }, "bf0e7471d56b40389ed58a513ad7852b": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "VBoxModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "VBoxModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "VBoxView", "box_style": "", "children": [ "IPY_MODEL_016ea837a5d242c3840091b092e51f2d", "IPY_MODEL_0b2631a5ca9f45e59278df4f59394281" ], "layout": "IPY_MODEL_5694e208e8484e84b6cb9b3912fa355a", "msg_throttle": 1, "overflow_x": "", "overflow_y": "" } }, "c0474bbb166a45cd8cc596428e418d03": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "c056cc916b2e446dbb1692ee68810233": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ColorPickerModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ColorPickerModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ColorPickerView", "concise": false, "description": "Pick a color", "layout": "IPY_MODEL_b3f69ae7d10b4dd7a64ed26c47cd047b", "msg_throttle": 1, "value": "blue" } }, "c063c53a85a442f78ef47c9f62a83b8d": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "SelectMultipleModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "SelectMultipleModel", "_options_labels": [ "Apples", "Oranges", "Pears" ], "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "SelectMultipleView", "description": "Fruits", "disabled": false, "layout": "IPY_MODEL_3d64356313794db080d8cf770efcd8d3", "msg_throttle": 1, "value": [ "Oranges" ] } }, "c48163ca474341139e4cbeb0374f1d28": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "c96f1b7c2637417285865c724b2364ca": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "Some LaTeX", "disabled": false, "layout": "IPY_MODEL_53aea1b1788240b4a6fc7103923cbc61", "msg_throttle": 1, "placeholder": "Some LaTeX", "value": "$$\\frac{n!}{k!(n-k)!} = \\binom{n}{k}$$" } }, "ca01d3151fc24e0d90b8d9d4b05fcc50": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d013d8c173114f46abfa4269e5331f4d": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d332c8df94ee42afb4d079dce40785f3": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "FloatSliderModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "FloatSliderModel", "_range": true, "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "FloatSliderView", "continuous_update": false, "description": "Test:", "disabled": false, "layout": "IPY_MODEL_733615a32c09455baca0bb96342768f5", "max": 10, "min": 0, "msg_throttle": 1, "orientation": "horizontal", "readout": true, "readout_format": ".2f", "slider_color": "white", "step": 0.1, "value": [ 5, 7.5 ] } }, "d3a80abfb5a645558f4dfbd94304ffae": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "d669c4295cbf4833b0c096e39129b22c": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "SelectModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "SelectModel", "_options_labels": [ "Linux", "Windows", "OSX" ], "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "SelectView", "description": "OS:", "disabled": false, "layout": "IPY_MODEL_ca01d3151fc24e0d90b8d9d4b05fcc50", "msg_throttle": 1, "value": "Linux" } }, "e06b0e2dc4184c1b932d2377256f1699": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TextView", "description": "P1", "disabled": false, "layout": "IPY_MODEL_c48163ca474341139e4cbeb0374f1d28", "msg_throttle": 1, "placeholder": "​", "value": "" } }, "e27db74b160b486c8e26c70af357c1a4": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e3d375dec35c455d8029d9328d1a55a0": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "CheckboxModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "CheckboxModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "CheckboxView", "description": "Check me", "disabled": false, "layout": "IPY_MODEL_2344fbaf3fe341458e7781ec178d1ed3", "msg_throttle": 1, "value": false } }, "e47d8b43215e48d9bb8c532860d80216": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "IntTextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "IntTextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "IntTextView", "description": "Any:", "disabled": false, "layout": "IPY_MODEL_b77e51cc846d49128532716088e935ad", "msg_throttle": 1, "value": 7 } }, "e5dcca0da2484a68a6d7d2c4b6204545": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "", "disabled": false, "layout": "IPY_MODEL_8f27c5c75ba24ab888f82bcc4f10ebe5", "msg_throttle": 1, "placeholder": "​", "value": "1" } }, "e807bc5903d3417bae8a4177e5b9c521": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e84e0f448b9e45ecbbcf969244e3a881": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "TextModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "TextModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "TextView", "description": "P4", "disabled": false, "layout": "IPY_MODEL_8d4e103dd42842dfb600d4db46352852", "msg_throttle": 1, "placeholder": "​", "value": "" } }, "e9b8104b92fd41b398562e22edffdb81": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ControllerModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ControllerModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ControllerView", "axes": [], "buttons": [], "connected": false, "index": 0, "layout": "IPY_MODEL_067da89376f04e298a72261d10c7650a", "mapping": "", "msg_throttle": 1, "name": "", "timestamp": 0 } }, "ea82f97ebc8d4d11a41fb54b4c654a6d": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "ec8b67763ae344279d46f3717f3ce3c1": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f1a8e14609fb47c4b8865849488511f0": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f23cfdd8a9bd4f4f881a7dba98a11ba4": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f2c8d102cd5342b99e42685c2da1058b": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f77c3280ee964579ae59ebbc8e39780e": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LayoutModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LayoutModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "height": null, "justify_content": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "msg_throttle": 1, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f91ffb7111314c72b41ea6dfc617e374": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ValidModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ValidModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ValidView", "description": "Valid!", "disabled": false, "layout": "IPY_MODEL_ec8b67763ae344279d46f3717f3ce3c1", "msg_throttle": 1, "readout": "Invalid", "value": false } }, "fa12c076ae4b4ba68aa0dbaf1f6e9c80": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "ToggleButtonsModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "ToggleButtonsModel", "_options_labels": [ "Slow", "Regular", "Fast" ], "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "ToggleButtonsView", "button_style": "", "description": "Speed:", "disabled": false, "icons": [], "layout": "IPY_MODEL_3d53699ff99a4fdc87909434e78128e4", "msg_throttle": 1, "tooltips": [], "value": "Slow" } }, "fd8e8ff9da1f4b028003c9afc4f9410f": { "model_module": "jupyter-js-widgets", "model_module_version": "*", "model_name": "LabelModel", "state": { "_dom_classes": [], "_model_module": "jupyter-js-widgets", "_model_module_version": "*", "_model_name": "LabelModel", "_view_module": "jupyter-js-widgets", "_view_module_version": "*", "_view_name": "LabelView", "description": "", "disabled": false, "layout": "IPY_MODEL_8bceaa69a7a54522acf296c855079463", "msg_throttle": 1, "placeholder": "​", "value": "2" } } }, "version_major": 1, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 1 } nbconvert-5.3.1/nbconvert/tests/files/containerized_deployments.jpeg000066400000000000000000000307531315361605600261320ustar00rootroot00000000000000JFIFddExifMM*JR(iZddu8Photoshop 3.08BIM8BIM%ُ B~u" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC00D000D\DDDD\t\\\\\tttttttC"$$848`44`最 ?n;❊v83aBKb$ǥ8 E5&=) #u;e)1HbbW5%.=(F*r⥢E(KF(`t43@ #Ҝ%IJHZޓJL&:QHv\zQbLQҘ zӸ-p!dS;R@␊v)9i5J`EF)i 7RQNВ8.*l?ښjAHB Nz:sKӚĸґNiV 8@њSfށ.F)/36GzBhȱ@ұBR- GL.DW)ԇ\ړ!_Jiu1RRс@ bgҞi}(x=(⢥w&FM7 Ҁ:a`%.7A4)1J}3LBmm-~jAH?WƀqR*g5Xaq@4Σ5^KYOtpO30֊w6Zpz .=+,16=t?/fo[\sKxSsXsS)81O=VD3F_[&YjE\"@՛L$iF:\R()E(c(SqR D)h.E07cOUrl-/Ҁ 8 Z;ъ@4i֤EF)AJøRP1EIF(4sޜE&iQjlRJù4cҞVG+}ihbfQږw(⛊>+43K֘!<ӈG4sLGҲ8 SԌxRJ:PmFdـ9Jld'TsS% +܀S1j  EڤgUrA99=)n P[#Pu=Ji\c@ҧF95(98Y ~ue\ڵz-hۅ^O^ReSMJ1[ b5ѪbRZ) :S)T QQN(iA"pNh1 ֎i:@ 1KE1 h@ #қC#4y6NƁъqHbAJ0-Z,;4}jbL#֕q=>N LSzӈ#'֐%-% \QҘF)1Xӿb+viPzUYMn" By2yQU1E wJB R> b28=1HdQ?1 |^ UaiPqI^JwOU!气!ёASk6,44JGz`oZx !i):izS) =Mf84qs@ Fvh?Hj^\Y79/.8I oZ̊]r82"#0>yP"2GOzJ)x1ɠ*S]n| t2*p;'9B4!M0295)dTja3CR>g꣜o$s{X*0JIV8IgiErA '$ry|g>M8pp)IQ IԁEsѾ+V :U":(Fx4XUz@qґh#ҝy&!AڤS1ϵt#Ńu  I#jсȦVPZ\U~QSƀ͊VLnj2>^ݪp})tӚ&icifsob<L*p=5F^ N޵+ V6T1AXPԊ <׭_e 0jŎG";lj܃4&EfPԵiqX֐JQҘqRi"r)iqM:R 0(ɤE8sH=(ʍDmM^x7Ab[IcԱ,w v >ɰ3?Ҷ#+"a}jg||bCdt#oCrd( ՛u>ѱz,#<[ka9.< (FvX .Oj6BT'؋Ί6fv!n}h^pOB=2$jm}X=h<@ z:@OR;'{G4nq48H9)lM794sZd rMgC 1]D%^ZEnUGLR$yFC`ّ'99ڹi؞7bd)94{ 8 x&zbzS @AȨ=jJ:b3c ޞ<*n{R`[)$ޙqRɌgҀ"VGݪJ~*)Н1 (JJICH91H =jR`cIhCf4M<dvhUG EhRT+-e8u4>Qץ`h/(%'=)O`#қqGS)1Ni Чw!j?h"VRjU=*a0ޟxWD]ќRqYzU8N}*9% BGi1֫.9X/RЙP3ǽPI S#$L'H3S5!PE" <^C8@Wi)Ҝ[F9 4DF$i/8NV&aְmpH1ط%ǚI'cO$淴1Ҁ60D xNGN!;Xca\ ,z%lTdAQ)>BR)2YW&\}9W4foq978⠡iti")JL.+QMV?xqJ k_LPrQv%٤pXwj[2ys/(,hJ/nArhc v+2eF@&gڨj԰F0I>P2F)%8'j <v5p{O<jF`mO=8;[EqqʏGi1avX})I&m!'ڷR37z 0F2ҘpGZHۮT~ 2Vlâ~t\,j4e_=9=xe3b@_y9qOe MU< 1x4 e!Oj܌Q[YGQoPǞ)~9:Q2jX2zC3-t%`X`WKk {EJVF@ۚoƥHנlv,+ S[v@枭#)j,CJ Vphbp4iEIIli\ƪ6y45$Ȣ )Z:Q@Z1i1@i(S\q<ӇJN5[E͡2hݞC ?:EkSpT){a"&tQHIҸ?l+Wjw 4;Ojj3P"ɩL^Mv)^SP6$Зp,H1*,w8ajT]]͉rqWJug&\P(osIL(׳?V\Cl؉j9SJ\0<ȶ܄Av6֪]Zy·}R1dVF;VLrkF6,pk$a]pS5qE!,2M9M6ьFT rFhl2ݸ&4 J"wicB*7zc8z~tV\ӌҴ\H+`bZegW G&}J? =X {` CSB(@nO?Jr0*7$昌}j5#j Pj4MRUӽ h*5nBvU#ҹ3x!x*)hԸ╂E掟J)֓"R9(\ƃ3B GqRD=)q14f]4d 8=0 +ߨ>k/#uGAdPr ILBiM dtibi433YޢC,K*ƤXrLJkSN:v thHH`p)1&!@'GSsÉ'Bx4&$қǚ=*a) h 8!AI[QB{iVE g*pE_+2܅btJڇ>d|?cbi>1HA~}b!&9/W'Ny#ۭW,;@!*put4y:IMDч_T&5hUɨcsu;n?DZBO42)vֹ茌tR 5cތMR=) Cn1JG&if i=+pN84J N>ކjr+>N7'?#W=I9lg+IpA[^(;[Է6 :$֓znp#"\O"Կiր6E^M{py]&M!s$[So$ 8Xm?ހ)AdCI <) Kc"sc@M9<+6x+0GzƲ>*"ǿ5br{T)sVe=ֵd!xS1jhXZ3z<AR+`b2IlpD5^~͌FաXҥZ`^HNzQVi8 -^0œkwo?+0Qopb ]8o5~H9T o7^њ3p*(P*b6Gjٚ\F94*0A@㊔ zTY=X SY01PHd:P݂(X?Z"ZjQ'i 6AQ%Fr@H0{J,1P:U)a.M @5l##R e"ǥN}ֳhڌRx>.>&G4h<Zh@ E pކ)hʞѻh.Ĵ$s,pz`nFGn 9>V qgjr,M%|̃>t+LXb2it}I&[8u|P*F2  b)C2:*F0 FÊC*SM52kuR͚p8>~qQvơS5FbKfJWH$1 \U~rw$OJvzxbi , @]Ow8,#<7Uv*}ZZ-%-%QI@ M8iSJLTGʈj2is O֣,ibq zU a4bJjM0!ؙfj"ƛJ8}))q@ -o@br:T<&&Z<e)=g}9&5PE2cB`%?x5_dW`I4yȧwjSzMJs)Ms`t =)SM8s@ f(hR9HӚ{-RoEZ1qTe7F} R)MR.f; =j .QAhoaM2)0Dd&TD9P;UTiP: kmۗXW 2(£wXT4. X7;e9h7f9,rzT IqD5h͡$UTF3ըQ&4#dS2E.k2i$>Z"fͳng?QVQeMձE-% 8M i M8HcM4qCiM5 4iM%!J4Ї1J:Pi:r1RdҔ7cQrZYY}YIUuK+E2\M>*)cY=#VC3Z 4gd-QS? ͍IhR 'CR}3K?izus.py>g4vs@ց=3G:q@"L=*=LTR)0"}NV@³*V^vIOzWi܎)h N 1fN߽RCSBԬ`qUrM#dLM"HpC2R]vqwD2vFk=EFN+E6\WOtqwz,VSQ,=*8楍{h9R1AcwPGE&~V&He/?u5+bn]0ze(%-4PaL& >N&iiM4M4M4iO4R4iƒ;Ԩ80 JƙK֙@>$T/?ZzHTp٩:T.57(a\~U:1V >n-IWOQRX0}i3FhRCh:9O("im֌cZTpw- #P8e;"48#qR$QjeaѰ G+^Oj9Gr"4>2Uh\۩jWQ+].0ERk\.bYx S c\=1RŚ"Ppxpi &Fc#Ӛ`\zhBxnnש z:>zVU&85w{坑XDp˰bۂ#ʒd894^Кjy0 #M$ʋ10!^IX)Z ٍж8n5,bi&M!4O4R%%-#y4m d r޴FiVfwZ>"L ;\~t}zҨ'84Q!d8h |SRғ8mqzb C?n &qO8#ޙҹhZw=i%9x֚{3H;R qIKMc@3iÑ"VHWE殜xhЎj$(DK (DcL,:gji$sMFRz[**w&N@nGwZcH*=hV`SqS $Ɛ&)T  rzR sN1Ub 鴜PoCVPER<VNHZ)('ЩO*21,rz_aɪ$i;x ֧́ SYF!m5ѷ<{ֺt`Iqր7ScS[J=[S1OzTeZ=jܨ%Pn#:P~SIi*iteR2CHXҠq)ׯR&2H`ǽJ {TSS*ކ54k$j8jR֥CVsO+!8b&ụ4NÒ\ :VŠ\VŲ82qVqL"ܧңcqVd!EUg&TGZ@HYKe Kzզ'4޹h3@ zSbLЄV6aNp4HͻO ;)ң?-VL}+( vyP!2 s]O0kn [Kahb WۏS@ՒI&)(r9XRHL E#Ms5BpwړP![JI$Xbqy 5PL,7!pIz翭c\Ұ>\h^[t#jKJ蟺1M@SUrj@gqRƋy*@j WiZIzϜ0[1'?:&845+VNJbM5h>\ y䊤┛%&5+_W{IHR#ZIr&I8'JM74&<ޫw7*ȦN^ځ9^QU})["t4HzZJBE!iғ23Щ۩4Hģ=#jsR(<8U4 tOJ(;Ҏ9iOZjӍ1 4gt/jcbژ0zPM Ґu<@ҊKއ^ԇS}ý4hɤ4Unbconvert-5.3.1/nbconvert/tests/files/hello.py000066400000000000000000000003521315361605600214470ustar00rootroot00000000000000from nbconvert.writers.base import WriterBase class HelloWriter(WriterBase): def write(self, output, resources, notebook_name=None, **kw): with open('hello.txt', 'w') as outfile: outfile.write('hello world') nbconvert-5.3.1/nbconvert/tests/files/jupyter_nbconvert_config.py000066400000000000000000000002711315361605600254530ustar00rootroot00000000000000c = get_config() #Export all the notebooks in the current directory to the sphinx_howto format. c.NbConvertApp.notebooks = ['notebook1.ipynb'] c.NbConvertApp.export_format = 'python' nbconvert-5.3.1/nbconvert/tests/files/latex-linked-image.ipynb000066400000000000000000000010351315361605600244750ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "![image](testimage.png)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "", "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.3" } }, "nbformat": 4, "nbformat_minor": 0 } nbconvert-5.3.1/nbconvert/tests/files/markdown_display_priority.ipynb000066400000000000000000000207371315361605600263560ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nl+R3hty/P8mrSZ7uff3u5EedH+td0qIaWfJJLgP+APivwP8FnkzycFWdG1j6RFV9egozzpX1LmmR\nNSn5fcCPq+rvq+pN4E+BW4asG+uPzLaV9S5pGTTZk78SeLHv+j+wceIfdGOSM8B54EtVdXYC882F\n9S5pWUzq1TVPAburai8bWzsPTehxZ8p6l7RsmpT8eWB33/VdvdsuqqrX+i4/luQPk7yvql4ZfLC1\ntbWLlzudDp1OZ4sjT8fLL2/U+7PPWu+S5qvb7dLtdifyWKmqSy9Ifg74WzZ+8fqPwP8BPltVz/Wt\n2VlV673L+4ATVXXVkMeqUc83a1Vw4gQcPgwHD8KRI7Bjx7ynkqSfSUJVjfV7z5ElX1X/nuSLwF+w\nsb1zf1U9l+TQxt31R8CtSX4LeBP4F+C2cYaZNetd0rIbWfITfbKWlLz1LmmRTLXkl431LmmVrMxn\n11x45cx118GePb5yRtJqWImSt94lraqlLnnrXdKqW9qSt94laQlL3nqXpJ9ZqpK33iXp7Zai5K13\nSRpu4UveepekzS1syVvvkjTaQpa89S5JzSxUyVvvkrQ1C1Py1rskbV3rS956l6TxtbrkrXdJ2p5W\nlrz1LkmT0bqSt94laXJaU/LWuyRNXitK3nqXpOloVPJJbk5yLsnfJfmdTdbcm+THSc4k2dvkca13\nSZqukSf5JJcBfwB8Evgo8NkkHxlYcwDYU1VXA4eAo6Me9+WX4TOfgbW1jXr/6lfb88e0u93uvEdo\nxDknaxHmXIQZwTnbpEnJ7wN+XFV/X1VvAn8K3DKw5hbgAYCqOgVckWTnsAdbhHpflP/inXOyFmHO\nRZgRnLNNmuzJXwm82Hf9H9g48V9qzfnebeuDD/aZz7j3LkmzMvNfvO7ZA9/+dnu2ZiRpmaWqLr0g\nuQFYq6qbe9f/O1BV9dW+NUeBx6vqeO/6OWB/Va0PPNaln0ySNFRVZZzva1LyTwIfTvJB4B+B3wQ+\nO7DmJHAXcLz3Q+HVwRP8doaUJI1n5Em+qv49yReBv2DjF7X3V9VzSQ5t3F1/VFWPJvlUkueB14Ev\nTHdsSVITI7drJEmLayofazCtN09N2qg5k+xP8mqSp3tfvzuHGe9Psp7kry+xpg3H8pJztuRY7kry\ngyTPJvmbJHdvsm6ux7PJnC05npcnOZXkdG/OezZZN+/jOXLONhzP3hyX9Z7/5Cb3b/1YVtVEv9j4\nwfE88EHg54EzwEcG1hwAHuld/jjwo0nPMaE59wMnZz3bwAz/BdgL/PUm98/9WDacsw3H8j8De3uX\n3wv8bUv/t9lkzrkfz94c/6H3nz8H/AjY17bj2XDOthzP/wZ8e9gs4x7LaZT8RN88NUVN5gSY6y+L\nq+qHwP+7xJI2HMsmc8L8j+VLVXWmd/k14Dk23s/Rb+7Hs+GcMOfjCVBVb/QuXs7G7/gG93/nfjx7\nzz1qTpjz8UyyC/gU8CebLBnrWE7jJD/szVOD/wPd7M1Ts9RkToAbe/80eiTJtbMZbUvacCybas2x\nTHIVG//yODVwV6uO5yXmhBYcz972wmngJeD7VfXkwJJWHM8Gc8L8j+fvA19i+A8gGPNYtuajhlvq\nKWB3Ve1l4/N7HprzPIusNccyyXuBB4HDvVJupRFztuJ4VtVbVXU9sAv4+Lx/eG+mwZxzPZ5Jfh1Y\n7/0LLkzwXxXTOMmfB3b3Xd/Vu21wzS+OWDNtI+esqtcu/DOvqh4Dfj7J+2Y3YiNtOJYjteVYJnkX\nGyfOb1XVw0OWtOJ4jpqzLcezb55/Bh4Hbh64qxXH84LN5mzB8bwJ+HSSnwD/G/hEkgcG1ox1LKdx\nkr/45qkk72bjzVODvyk+CXweLr6jduibp6Zs5Jz9+11J9rHxktNXZjvmxtOz+U/2NhzLCzads0XH\n8hvA2ar6+ib3t+V4XnLONhzPJO9PckXv8nuAXwPODSyb+/FsMue8j2dVfbmqdlfVh9g4F/2gqj4/\nsGysYznxz66pBXnzVJM5gVuT/BbwJvAvwG2znjPJd4AO8J+S/BS4B3g3LTqWTeakHcfyJuBzwN/0\n9mcL+DIbr7BqzfFsMictOJ7AB4D/lY2PI78MON47fq36/3qTOWnH8XyHSRxL3wwlSUvMX7xK0hLz\nJC9JS8yTvCQtMU/ykrTEPMlL0hLzJC9JS8yTvCQtMU/ykrTE/j+33DZWsalW/QAAAABJRU5ErkJg\ngg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from IPython.display import set_matplotlib_formats\n", "# generate pdf and png images\n", "set_matplotlib_formats('pdf', 'png')\n", "\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "\n", "\n", "plt.plot(range(5))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python [Root]", "language": "python", "name": "Python [Root]" }, "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.5.2" } }, "nbformat": 4, "nbformat_minor": 0 } nbconvert-5.3.1/nbconvert/tests/files/notebook1.ipynb000066400000000000000000000131601315361605600227370ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# A simple SymPy example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we import SymPy and initialize printing:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from sympy import init_printing\n", "from sympy import *\n", " init_printing()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create a few symbols:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x,y,z = symbols('x y z')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is a basic expression:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAAKMAAAAZBAMAAACvE4OgAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\n", "me8Q6PJIAAACz0lEQVRIDa1UTWjUQBT+ZpvdzW7TGlrxItjYSg/C6vbiDwjmoCgUpHioPYhdqig9\n", "FJYiPYmW4klB14NgFGnw4EHpj7UgUtTFXhSEBgVBxIOFggWVrrUqiMY3mZkkLNIK7oN575vvvfky\n", "8yYJIGzgkSlRrULKrivVSkvq6LbxtcaSjV3aSo0lgWyl5pK69V+SRlEsPxNTGYhhDrV3M2Ue2etc\n", "EDmuMmM+IjolrCuHXNoLoQDNSAXdzbjsfFVKTY1vCgFXFIxenG4cFSSzRewAPnN0FugXjPDr45MQ\n", "JwoKtitgXL9zT+CsJeIHYG+Z4H1gwhRU4G/FcAQbbYU3KdDo+0sCK8lRU0guA72uKqMYk9RehHxP\n", "iDIu0NS2v90KGShJYi7T7tgvkrQ2vIT2XtRISWNra6lzGc8/PW3ji4PL7Vmge095YIX0iB71NCaZ\n", "5N3XyM0VCuNIyFNIyY3AMG/KDUvjn90DGmwq9wpIl5AyU5WsTYy0aJf6JFGB5An3Der5jExKHjNR\n", "4JKPge/EXqDBoOXpkxkmkJHFfAFRVhDIveWA0S57N2Me6yw+DSX1n1uCq3sIfCF2IcjNkjeWyKli\n", "ginHubboOB4vSNAjyaiXE26ygrkyTfod55Lj3CTE+n2P73ImJpnk6wJJKjYJSwt3OQbNJu4icM5s\n", "KGGbzMuD70N6JSbJD44x7pLDyJrbkfiLpOEhYVMJSVEj83x5YFLyNrAzJsmvJ+uhLrieXvcJDshy\n", "HtQuD54c2IWWEnSXfUTDZJJfAjcpOW5imp9aHvw4ZZ4NDV4FGjw0tzadKgbFwinJUd//AT0P1tdW\n", "BtuRU39oKdk9ONQ163fM+nvu/s4D/FX30otdQIZGlSnJKpq6KUxKVqV1WxGHFIhishjhEO1Gi3r4\n", "kZCMg+hH1henV8EjmFoly1PTMs/Uadaox+FceY2STpmvt9co/Pe0Jvt1GvgDK/Osw/4jQ4wAAAAA\n", "SUVORK5CYII=\n" ], "text/latex": [ "$$x^{2} + 2.0 y + \\sin{\\left (z \\right )}$$" ], "text/plain": [ " 2 \n", "x + 2.0\u22c5y + sin(z)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "e = x**2 + 2.0*y + sin(z); e" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAABQAAAAOBAMAAADd6iHDAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpm7MhCriUTv3c12\n", "VGZoascqAAAAgElEQVQIHWNgVDJ2YICAMAb2H1BmKgPDTChzFgNDvgOEvT8AzgQKrA9gPZPYUwNk\n", "cXxnCGd4dWA1kMllwFDKUB9wEchUZmAIYNgMZDDwJIDIPyDiEgOjAAPLFwZWBhYFBh6BqzwfGI4y\n", "SJUXZXH8Zf7A+IBh////v1hzjh5/xwAAW80hUDE8HYkAAAAASUVORK5CYII=\n" ], "text/latex": [ "$$2 x$$" ], "text/plain": [ "2\u22c5x" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "diff(e, x)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": [ "iVBORw0KGgoAAAANSUhEUgAAALsAAAAZBAMAAACbakK8AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\n", "me8Q6PJIAAADAklEQVRIDbVVS2gTURQ90/wmk0k6tCJCsR1SKShIsxE3CgNWBKUxq9qFmqFqShfF\n", "UKQrkaDiF0pcCKYgBBcuBLV+wIWKARe6kQ4UhNKKWdiF4KIptmA/xPvmzZuMxdYUzIPcd+655568\n", "vLlJAL6G32oOasQWNHz5Rvg6nrKh/mygfSzlX2ygPaBUGmov6//NXs1yq4sex2EPrsHemTd2snNg\n", "tkb+Cx1zBL6SqwxZLvQAKYHzKZaPY4fh4TeHd0S5Nox9OClItm/jiU9DrEwwVEawpiVis9VkimqX\n", "AOr4o2cCs/0BT2I5+FYJRhJbePQxgzcD7QLEqtV5gdnu2Icr3L45gcCyt74Z7neL4SLQ0nm4S+dM\n", "YCz1gSPHnhKZDWyHhcCCNKwjqaF/TkwGl0L6nClie/wc1D1xdoNsSLhT0IJkhi7Lzr22xb8keE/N\n", "Pm0Sc9yEuhRUyuiG9HzvFNeImCyq39SriOhtQI7IV/TiTqE8glqwohjE0NJwiANxOZTdZoxtfzSa\n", "x2tI8DtHcKQoQFmV6f1XT2swibxFL+6k5EgenhBCqKLTPX3ULnaYdDlaTMcCSd8zuXTvBq2bJUJr\n", "lE4WgSV5ZRdBzLFgO6nzhJp1ltvrlB2HCoWxQuG+jTvt2GxBWUZaU2mMApZNuSHA3vJpCliRhqqs\n", "ZtvbTrb9ZIk+i70Ut1OcnpgeKskTCFUwjaYy8Jhr3eiefq0HIfa7yC6HOwVyULRuNDn21JngbcL+\n", "E8A+MNnSxb+w59+Cj2tELJBbjEZr8SGwn0j2aLkTPdp08R2OcKV6fXB3ikPH3n8tM5WTfrETtZcw\n", "g3QWH0dH7nKNiMkszqo/EDafaHhJ5Bm6ee4UtdAabxnMcmUUl0SnYx+uVqs5XAGN9QGgdeCrASv0\n", "3TmCsJcOdhnozexD38goK9HXynEKr1OKDs9guhQD039kGySyIQpJAdbvJ9YTlPvyUl3/aLUf34G/\n", "uGxIyXpE37DoLbAHwJaU53t9MRCfrU8o/k4iRn36Lar8Wd5wAfgN4R6xelyy/ssAAAAASUVORK5C\n", "YII=\n" ], "text/latex": [ "$$x^{2} z + 2.0 y z - \\cos{\\left (z \\right )}$$" ], "text/plain": [ " 2 \n", "x \u22c5z + 2.0\u22c5y\u22c5z - cos(z)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "integrate(e, z)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }nbconvert-5.3.1/nbconvert/tests/files/notebook2.ipynb000066400000000000000000003647751315361605600227650ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# NumPy and Matplotlib examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First import NumPy and Matplotlib:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "module://ipykernel.pylab.backend_inline\n" ] } ], "source": [ "%matplotlib inline\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", "print(matplotlib.backends.backend)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from IPython.display import set_matplotlib_formats\n", "set_matplotlib_formats('png', 'pdf')\n", "matplotlib.rcParams['figure.figsize'] = (2,1)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "{matplotlib.figure.Figure: >}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ip.display_formatter.formatters['application/pdf'].type_printers" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we show some very basic examples of how they can be used." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a = np.random.uniform(size=(100,100))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(100, 100)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.shape" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [], "source": [ "evs = np.linalg.eigvals(a)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(100,)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "evs.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Here is a very long heading that pandoc will wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is a cell that has both text and PNG output:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(array([97, 2, 0, 0, 0, 0, 0, 0, 0, 1]),\n", " array([ -2.59479443, 2.67371141, 7.94221725, 13.21072308,\n", " 18.47922892, 23.74773476, 29.0162406 , 34.28474644,\n", " 39.55325228, 44.82175812, 50.09026395]),\n", " )" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "application/pdf": [ "JVBERi0xLjQKJazcIKu6CjEgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cgL1BhZ2VzIDIgMCBSID4+\n", "CmVuZG9iago4IDAgb2JqCjw8IC9YT2JqZWN0IDcgMCBSIC9QYXR0ZXJuIDUgMCBSCi9Qcm9jU2V0\n", "IFsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9FeHRHU3RhdGUgNCAwIFIK\n", "L1NoYWRpbmcgNiAwIFIgL0ZvbnQgMyAwIFIgPj4KZW5kb2JqCjEwIDAgb2JqCjw8IC9Hcm91cCA8\n", "PCAvQ1MgL0RldmljZVJHQiAvUyAvVHJhbnNwYXJlbmN5IC9UeXBlIC9Hcm91cCA+PiAvUGFyZW50\n", "IDIgMCBSCi9NZWRpYUJveCBbIDAgMCAxNTIuMzk4NDM3NSA4Ny4xOTIxODc1IF0gL1Jlc291cmNl\n", "cyA4IDAgUiAvVHlwZSAvUGFnZQovQ29udGVudHMgOSAwIFIgPj4KZW5kb2JqCjkgMCBvYmoKPDwg\n", "L0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAxMSAwIFIgPj4Kc3RyZWFtCnicxZi/btwwDMYz\n", "a+wTCJ3aRSEpiZLGHtAG6FbkgL5AmwTBXYCmQ16/dJycRcWq7SV3k81Pf76fzyZpo703l1/Q3v61\n", "ZL9bsE8W7ZUBOTpajOR8ycGnKOcHdZ6Tw0KY5fAgojq9Mw+yKA2Lgiv+9WdvZeCVoewCR6ZoCVyk\n", "jHIkewVw0IYPdTix8y/hao0qKvveiHOhcF5t6qJgqWDPRRXlkwmzm92vHp1g8rYzzf5on8xuby+/\n", "oUWw+xsjO2L0w+gk06Ld/zKfPn64wAv4bPf39uu+XeGZwITgAuSQCQMVZbtRlHWt1fYbZRNCIAdA\n", "5F/mnjAWEFiiEb0vlGNSCI2iELRWIzTKJoQYXSglJU7PcyeEpf9BDFAJWDhQZgXRKApCazVEo2yC\n", "SOiQ0efhCnANQQsQhRz5BNHHhEFBNIqC0FoN0SibICR5QCjxde4E4RcgELLDVAqCTPQ6nzSSwmjE\n", "mqOVNoEgkCuFwuvkiSQskVBwSDTejKhJGkmTaFGRNNI2Esyu5PLyp9QkcYlkLpHr/K4J5jK8Gr/R\n", "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\n", "c+tTOz5911Weq+KfyX7mK9f4ru2/9t5rv3Pdjs+e9Lmxz09d/+ANX/uTxTce/8W5N+Vv+sub/vam\n", "vTcdutm+uf/m3bc8sXXktk/dduNtk7d/4kuXfelzX/7Uf3vov/3sT/N/etmffvtPX9n2uW3T2/Zv\n", "e/eO+p32nVfe+fCdu+985c5Df9b1Zz/88xu+kv/K1r84/i+uu2vwbnH3GXdfdvef3f303b+455R7\n", "7tpe3X7a9s9tv2P7S9v3bP/ZvcvuPePej997yb1X33vjV6/56k1fveOr9311x32R+/L3dd83et9J\n", "951y30P3/eV9z973/P3x+8v3998/dv/i+z9y/7n3X3j/p+7/wv2333/X/Q/d/5f3P3v/8/f/8P7X\n", "vrb7a9//2itfe+Nrv35g9IGTHjjlgdUPfOKByx+MPJh/sPvB0QdPevCUB1d/fcnXV339Y1/f9PUr\n", "v37DQ2se2vjQ5oc+99DWb4x848RvTHzjrG9s+MZl3/jdw+Jh8+GtD08/vPfhAw//7hHxiPlI9pGu\n", "R0YeOfGRiUfOemTDI5c9cs0jNz1yxyP3PbLj0Tseve/RHY9OPrr7sfHHTntszWMbH9v82Od29O6Y\n", "u2N8x2k71uzYuGPzjjt23PH4xidGGLbLSFJ4/gGetwHbPiBGW4PDraHh1qDd6p5udQ/vSvvebQ3Z\n", "rebeXUXfu+KvvFqXb+CvmloO1KdpvoGR2fPnzUn19MydPzY2/yTvvLndjXog2DM2Nmc0nUryLwIG\n", "UplYLabheG3BPI8VTMfsZNg3VKkMBUaDp4yNLct1NwOB5w5t1P7hkLjq5JOvii3IWaVYNJOI6V2z\n", "B+eEJhYtP7E6r1FLJOc+7bn4vbs99703iiELoaJ1z196P+3phucXWhBe6XXEDh9qX2Fo6yYXGisN\n", "zxbajS2TO6PPRT3rpnZHp6P7ot51grZmHe3UOhqhdbQruETNkdlH2r240+5G2e6YbLe90NC2jFsP\n", "GDuN54wfGK8bbxuBde0rSnxSkk9KO0vPlX5Qer30dimwbmT2B4zzetneQPsKC29xgKJ9mKdvcxgL\n", "3bF0RoVGZs73nk47fyvbWdleFUPtK2KofQPIlIjZsWrMu2Vqd2w6ti/mxZ2aXavWvKhUY481Dc9q\n", "07V9NS9ewS3RXp9kX8Vj+/pop69/lH012wvz6Atk3dQD+Z355/Jo4Yq8bKGCFg73qha8sLDCczzs\n", "bhgxxID22XZzwDvQHhnAyzZIa8DeJXzvtu9o4qWRJu+CtJr2roD33ZawW8Y0Llrl6VZ5uL2qrK3b\n", "FfO+264ZzVj8uPbmQfTXEkvXtHLDhV0586S18qIfF/2Bk9YiAHm3beT6UbVlDO8Ke95t5exdaY3v\n", "h/n+wRoHqU3u8D7t9axrT3jR/R+8GIgewtm9CQjPNcmtSTw6QK5cTHIvyYEUL0nGiqh5C2Y8eWH1\n", "6ipqrq7ixltVPHqzAbKH5EddvASZWt11YdfVXQBidc+FPVf3gGcv95JnZ7Hrb7HrpTx7lGfvkAR4\n", "GeZw9kdxuYm93wMyeW3yNg7sIG9sSrlj2s+ON5G83HD6bP+Y5BV0M3/O6EkeqmZjnjqb5Wk0euaM\n", "lj1U0VQamhrBnR239ywZLZ17zp/fmZ/Tl9crJ865feKfBs8Y71504qlnx8YuPPuVxXZttLFsyYlW\n", "ebhu9PaWFsf7l4wef2bEE1j3kdjiRSMy0x05/C+exzx7RI/nlnY87B1oxe2WmG6J4fa4wHSmhbau\n", "FbZ3lQDnql6qXh8Frw9KurBvZR+mdn2fi24UgEZddP248APddiLqJ7KJ4VbU3pXV3m357V11gNvj\n", "j/J+z3B7ugdNbuiRILff1HBxWxBkbYhnJG9S59eS3Ebysk2wqD5XkXyX5FaSt0im43wAMnlbYnsC\n", "A3wGAtJ+ieQXJE9SXp5JvkhYniQsv+xgs5ZkO8mLJM+S/ILkSfkgDfIMyRMkvyJJ58CjN/KUMJK7\n", "SPaQvAMyGcin8zBpy+XzAm48WpgqoNv9Bb5awKvLebacZ29SOMcqyyp4flfVlZE0xXQ5zw5SPFZ0\n", "4XIHdXAtyXaSHLVxBcmzvHy8G+082/1SN9r5aTdvkLu/6qH4HiRvD5CFK2i+9pCPL4Nnk1fHbolx\n", "XOTfleTfGyQvk3yPPJN69aLLp8lnUi+mUH1H+iiuHCS5hnM9QHIKiZzpAVoaOQmpcPs5kwuaZEdz\n", "qol2pjjMPSQHMMxmxNuoz4LYn+SBV8oEZ+EyAtEve6gN8z2PxectWTm48tbzFyw4/9aVi28aXmh0\n", "z15QXHLZqb29p162pDh/3nByc2GkkVxw/tbTT996/oK5Jw7H6nl79KwrPvShK84aDWf7KlLue6Tc\n", "r/B+rj3YBVsX7BqkPAYhj5C+VmRvexvt+esgraDdSu5t/5oMKEeCqDZufLX8ZPmvy39X/mnZD7GE\n", "xWv3gbS67F3zYRHhkRdPtxYPT44vXrUYIjC9GM/KdmvF3vaqU6hFp9LjnbryVCrQqa4C9UFn+lwF\n", "WoGLFVCglrm3PQLMWrG9rRU0se2hvhUcKRx/n71rFBq1wt51IjRq0Yo+3l803N6wiIqwSGnU3Vnq\n", "Rw4dXly6toQOl9Op7KhTikjWkPPLwfnJH/e/1Y/nPxogSiS3knyP5J8GiTDI1L1DTww9OwST+HdD\n", "FCySF2bh5SdmPTsLL/9yFqVkmD2QvECylmQ7yTMk15H8gmT/XLw4f+7yuXD2n5l769y756Ldb82j\n", "JsxbNg+tPTqPtUhuJfkxydhxHC/JrSS3HM8qJMtJ7ia5ZyGaWLvw4oU0vQupwCTf5t0Xx18dp2qQ\n", "Q78iufpkvk9yN8ktSyinJHuWcvJLqTiPgIWT382+nPWsm7wlexd+2reAoe0pcvXu3GM5j6P73yO5\n", "Dm65fTEjjM+SHMPuZ0jOIc9vo2aeQsbv6d9Pxr9BTr9MckuH8W+S8XtIXiCrd5DVz856iaz+RYfV\n", "B0iu7XD5RZJzhwnK8LPDqLlgLplCcoBkBdl+7dzbwPb2VrL0aZIVJK+SvLWAsBy3/DiPw+M3XfZO\n", "3nr83cfj7pvk510kU2TqOQsvIqsf442Xxzl0krfI3mvI1AMk20m2krMHlxCIpa8u9azzZ5zgEy6t\n", "3jM/PWd0TDo8hqXzu3v+uB3I0Ez0aJd6QjGjPJyq9SXnDtn13nSvL5yMRtLh+Nyh/pP/MxtxgrQj\n", "hnGi5vX1dGXqqXC2K57M+SKWHvDHlgdixT9uP/ppXzQZjq8G+RbiJlPktMF2IgdLspOicT0I4xhG\n", "TbthQ1sJGSu119MiPkAiaPZ3F1zlj0DfI67yZ3GRdWKjVsTeZWjvUpWfZqxxHMnjJK/KIIihx708\n", "e9pHFEEmt/se9wGPp+k8V4R4I/R4CDde5Q0ZNT2l42yCZAfJcSTbSV4l0XVWoXtYTZcg/cKt9Aa3\n", "0gSuliEMyRRN/kSaKiKjomUkMipaJsfCtp4g+WuSFWzwGZJl6U6YMyO4YVTztS+f/pmV3d0rP3P6\n", "lyd+ufjmSxcvvvTmxb9cPPv0i+bPv+j02YsH1968Zu1Nawdl7MKYtQHeG+LClne4bYMT5HfLa7e0\n", "va3AdCswzNg0NN3S7FZ4b3snvN7k9dY2y+PwXAYpLs89uPC4PEeQEoBJ1f0emlQdYSkRmF9L1WI4\n", "+N8O7bOHPqQ9dehO7ZxDjy9e7PnO4t8sRhwux8TcQVgyDl8kdiEOb3DhZZ2YfNs8bHqcJAbpzBZ5\n", "WyY2bhx/7Psfle/Pbm8D36aG7YX2StuLBMl+zvYwiKcf57TaCxl3ro+iybejsrVOWxd32too21o3\n", "rg+bC82V5nrTt2Vc32Y+YO40nzN966ZeNzk+mOAoh7YBo5p6Pft29nCWt7JIlvTh7MLsyuz6rG/L\n", "5APZnbSDG+hdttH/PVc+ut8jc7he9jugHOqGKMVFZk0yf5JjXs/RHybZGXV4Ad2yHN2yRU27vV2o\n", "UbdoTK8HadUc3YICtQqdPMSaJo3sxeNWXNLkdHs9g+wHSEQDyZtEOw200y70VVxUXejTUt3aVrpK\n", "6K3hXTYykth0y2Jb1MIc5GzyOO8Kr8dRvJ+SfJNkAcX+HpJnSHI+1FwQmoDuTd4T2kEVfIYqmDta\n", "BaXi/ZTkmyRPZ6hkWSYTtCTdjDHP4dmt9C6r6VP2k3Qjf23fyrPVZbZHEHY3yN3JjjLOl8kKx3IX\n", "yQL2vp3kFJInSBawz1NIniV5hr2fxd5XEFrZ8RSbXk7yUfQ0Q3OpCMxTYh+owZrn0KGJFSs+QI9/\n", "MzamzXmfLhvAWhdntzTosuboMjTXu5eYQp2h18G97ZWGazK9gM3rYihwIRgvee1dPuAX9AoVz+0K\n", "UXXnNDqKO6E9eeh+7ZRDU1JnnRzovyMWbHpK7WQJOVDJ3hWCrR5OgguHafJaIK2kvSuGESXtVhPZ\n", "7nB7hE681eOOpo4B1I814G1Rz3IYYrhVt3d5IV5Ze5eF4SXU/cRwex+8w664MvAvIt2a/Kp4UjBE\n", "wXn72yQXMW5fQ3INyNRt2nbtcQ06+SJv/YHkpyTfJnncA/J3JHf5Qd4hCfghhvP9y/0Qw7HAsgAa\n", "fyfA+wHMbxnJVJgeP7w8TC8e5stcOtlD8g5JwEALy4zVhgcNGcsNtkDLtZqG4i2KZR/XGQ7Qr/XR\n", "r/VVQNaSrGHM38c8Zi2JTLffYArwsky3mQfc1XyUecDzzF+ealKA7+a0d5C8Kty57yB5gQy4WLtW\n", "u40MeIa3fiIfcsYvgkwe51+BebaXcRbzScY6U1lOspajPSjTFI52dSfXeqOThf+MA/kuyaMke9xx\n", "ad3dR2KQsfnzKPiBwMxsxXNp18bFbpgx/4Lex39z4rZFbq5y9mdHPIu7B91AopD5P4sPPdJounnK\n", "8IirB5+SPu3mlgE9AOPbq0hGQHaFIX+e6ZYhFWE98xTvNLKTXQHfu5PCsi1YpG10ctPWPji59iqL\n", "dtxyJVSDUGquhIZxEaaEejSussD9Udd808j2W8HplsfepVMmE3NitdicGLQn1tgwod04MXHoCxOe\n", "7xz6e23OeydqKw/tUmMWOzBmrzgNfUizvI9hyCrfBoQhk9f7twGRqYp/2L/QD+e12z9NhITftcVH\n", "6bEcJMYlVXbOjgl0Rp+yHMwJSJ+SdvyqCZ8ya/IB/86ZjcPF+g4z9llIc7feRxfrnMm1vcNv4+3c\n", "jHY+KtuZO3l9cFsQrz0HiziuV0LDoYWhlSHfFngqatBOkvUkb3NpApzn0iPGdfg3aCUjfWza8bGm\n", "XOO7Hh2ORx/w7fQ95/uB73UfhxVcN25EfRXfsG+hb6XPv6W90sb4rk/Lmumd6efSP0i/nn47fTiN\n", "mno0XUkPpxemfVvc2ID/l2r/c8bYr5d9DbtjFxhVezMImBA4TC1fSC1fTwXf6Zw5vlUTkcP/on0Z\n", "rE2Iv2mFhuW8J18PvQ0X1UrslZY3BD/IJT/av20pV4ak2LhY2biwpZWzw8rKyQWj9g1cNbKlvaNV\n", "6wXS7YvJvetINnEsB0CmQoFsoDfg3dK+hSHMLQwH7kGYOfVM/MX4q3Eo+BNxWoML+daFfGsr693m\n", "1ms/DTI/nZb+CEIqk4junnPCYyM9swvhicTwacet+IR559DcyuyFNe2N9w51nfqh3lNXuHp2HeYf\n", "0f5HyxymOp1MZP+K5DDJn5NsJhkHS6lnCDHPhDud/Ib3r7gO+T261rWMvu/xUmhS3qZ3nnepF7HR\n", "P3l/zhpfZI1fkwhUa/n2Tp7v+zQ1IuVr+qCqf6BkjlFGl5J4QcajN/ju8D3oa/l2+6Z9+yAyLVPi\n", "wDWIwN72z8i28wOfDnwxAPb8L/LkX0m8AHnqjsCDgRbvT/OW3whw9XQZjX+vf4EfpvtW/93UvEfJ\n", "z2+B0JBEptsVimHL/sBM5CjdNHBhBJyLIC6CEnyv4bg4fW97KVMHv9DZdQ9xf4qdcRDtFEkiRNXR\n", "2j+hwf4Vyd+TfIdc+g758Sbrf48kxPovMkTZG2Lw/LLnTQ9G/12/W4vpTGLOHG2OpjW0RiNGe6Hp\n", "2ocvOvRV7dpLDj1saBMT2p3anEPPHfq89slDf64+4pHYa7/FhV8cd2ze4NlL4xcc/oD8QHKCQaLo\n", "pALo7pRDl08w+pc65bRrib9GE60omqbowD770LqYbvnYQdtGxNuK2k6CAlz1vaTGtIDxg4LJ3iz0\n", "ZpnHsnobfV1FY5QP1zZurA9fEb4+vC38QNgPSQurtVrY7bbQiMDU82KP2C+862Dad3lwO6RrBMYr\n", "QjI2UpGSIa8mbzHugl+HxZ+fCjJOmhecNx8zfOUVzvGMMya0S55d9uzPFu9ftmyZdo/LR2+eOuTJ\n", "t4MhROcrGdeupBkSoaDqAdFbex/BvYFkFUkLRHJE29teyAmtJ5G+/FUQGB6ueT3H+ELu+2xzcySp\n", "B5G97T00AFMkZ5KMkEQ7aQTzHynN7etJHiCZJhn/YAkP4SIk5ThCPrQ/RQv2TyRnMxobE8sQjU2e\n", "LM4UUNm/4v19JLtp4yLINKc5YN902x+K8PXvQzInv+y/j4r2WUrpkyR7qZG67GDyy/p9Olr8vr5X\n", "Zx0G3U/qat7GdHuNrZbtnmInF5Mp2zWuuWovalzN4o0nSG5Ci5M/CrwBOz95QeAq/Ew9EvhW4LvU\n", "/7uCNEhTweeDe4L7gz5EkLRjj5Fsoj7tcNOAcf2Z0IuhV0MHQ6j0uM5lGf1VjGrqEv06/Xbd62Tu\n", "vyR5hGy+kOQukudJ9pOcE6GRfpDjvZPkRyRTJPtBmglGDw1qKBVU+x9vXz7hOSy64c4mLr/JM/7e\n", "iZ6N790nj+84dvkJxj9aue3VIVNVWthVTLlu8N5BqzrtyhAjfQ8kwj8NRR2PrfSv91/hZ7DBmOA5\n", "f2hLS0ccjwoGIqbh8cSIMW6sMjYYm40bjDuMB42WoW9hKr6F30JsmVxlbWDMdD1czBTjp19bmH6r\n", "EzxJ2/e+3Q3hp+2bukBcJW6GnrX/gBmPW7rIiT5xnFgh1orAlvZXeNN4EO3sFtNin/BLw+uZRljN\n", "vZGpHwReD7wN3MatSwLXBW4P3Bt4IvBsILCu/W8BtuYPpALNwLzA0sDZgcCWlp8rGiOzm3MYlimm\n", "ejZ4Js49dC7IZZ41YOjH33tI2jonF3+C+4KiqvYFNQsxQ7l9PfRpknk/pjxuyg1B7uwc7pMhgoc5\n", "kTeOnCgherTftMowSnvbgjtCmwnsuJDr2bvCMuvelUSyNN4LHrb6dnNPaCGb2tfHvc0+u6/a53UC\n", "vQbY1nB5KDcD6Uwa9i6/Jjf9oipemKBHANnSPo5n20kOMrbXPTkPlHABJeAAyQqS7Z21MGbm7f+Q\n", "Z3SoaUY+1IUpqsE7QeCTDjIVCi5nvDRGLXiUZD+jn0AoHeJuDW88RbKc1mwZjc+jJPtJ0hSXp3i2\n", "nDIzZi2jzNxFmdlj7bfegcxMBqw0A/F3qBtpbgzn6F8XcBFtBcl2bvq+GjsY+0MMtfVYLobaE4xn\n", "QDBnnh0kyfFyNdfYbiVZzcz8VpK1zFy2cpl5LclWpi9rJeHyyGrmK7eSrGaGems30SVPJxd4J6BB\n", "kwuCE5j/5Hxzuckfa7nFn9jyGH/iy+OedZpcg52x3CpDKzfPKXs832GC4yY6/P0IMxw30+Gv9gkm\n", "OW6yw18mOW6yg1+1xrMQPuRG+hDR0FbBMLcKeyd3Fp7jNtnbmKVc14nYuxJQ4+g07W1yr9r83paU\n", "eyLt62MyNW/Vp5GBj+sLmyub65tXNGHPtjVd3a1B1Gqu3KVwkaLc1eRGJP1yCiLMhdbptl1L0W/Z\n", "w7tiShb3UJqWM+y7yPsZMm++bznzi7tl7Ea7KDPNu0lkfvkYV03WSMKlmR1yC4BLJ0+XicM1bO8V\n", "kt+ThCixUoov7qwfbSc5hWQZ25+vu+0vZfty/+6AlAJ28jjJQRK5JrTf7am9AkRzMPTNmZNwli5d\n", "EHHqCR239OrVs8O5gaUbFi2f0PKH9mujhxZd+ufr+k7+5JeWa9869BPPjc0Vn1yeOmHhwtkVbeXi\n", "Q/+6eMmmLxy39uY1A1zrlDZC5iN1lZNpfcyl2pt7wa71vVf00rb0chdZ7p7v5P7xepqJt3sP89l6\n", "3ljofILwAe19VLY33r6C5mQVv0XYPICW7YHqgGfL1O6B6YF9A9Dp8UF+kaE2pllpIfdN3h5Ql0e3\n", "fXGn7Y2y7S6Ob93keO+qXuggx90e5+bI+NxVc3nj+D86tuvl+wva4+hx8sGB1gCcphjg0JDOTA/I\n", "+TpDwHwHDg941HDk6GQS5u3YWENkxBz/1nahjzGUnGwfQsQ+Z6GpNbq3PTLKmG+U4yMRvNwsz5qj\n", "jCleEj/hmtFlNM7XkjxDC92n1rEMWaf9Y4rPfpKrQPi9Rtfe1qjdmrO3bXbNYY2rXDs3+V3zZXqG\n", "T/DGPm5dby7cQJ1s0fKMcIVnFQgXXmn7M+r1VyiVnyWRS5j7SbLq0XXcQZvKPs8l43+mtDbU/a1c\n", "DjpAspGkW430Rdqtq0hmqxuXzGZ7s+lQ5tnzqvPA44XcJmzN281twn3zXE2fBeWe5Wr6KC5Gj13j\n", "lRdduOjixSy1KFeVvgeZDL9JmHxavEBmXkI+XkPyBokR9XIoL5OBt5BcSfIzElM9+h65tdV0lfRq\n", "ko0kGdlu+1Uy5DqSZ47wZxaXmSefyn6PrPm5ZE11Fmt/iQw5SHKBZI26+8IR1sg3FWt+PlsFjQs4\n", "0BUMW7eLxzmHAwwVT2EA2a8dr0Gk5zGpkkuDexioOquCQX8G+WH7akapexhYzg8s5wLCvDBqd4NM\n", "PhZ+iouDTS5FPcU5L+XE/oJkzFkJXDf5qDlFqemmk1xAMs864iSXcTHqMSbwb5EEeXm86xknD8R+\n", "z08Qsvw0SnrJV0mO4yWz/PbvSbJxrrzHV8Q9joc8TjrMBMhWesjHSf5A0p/m0mPGtcdvkfyeJMSV\n", "7WVcUv8FV7abXEOXS+pyIb3JhfRz6hjPssbqBnr5PVnfz88u3uFKZaCZboJPY/zcYjlJoBvkGcLx\n", "JMkabulme/iBEs/WUOG3khwg6ad1WsO93P5BJv0jnPwIxYkYZudws2DOxByuDMzBDR032v1zaNxu\n", "Jq5yUXSC5DgivECbYEbwOME9qP2B57rGJvwTzD10Ap1n8r8gMEEsZ8I4RQR7ieXZBE8GORK1+YTx\n", "bvMxwng2YVpKBB+1pojgft4I8IaKGdoX8UaaGP2YaP07yV8Ql38jSREtFU+0byMoa4mHnwA8SnPw\n", "VvbfKfMSjK3k/lb6rbVlcr++uo5H87lX/pbcMCcOEoztIJOhZpY4/IFBzg4yPtTB4fdk/FqSHHE4\n", "p/Mdw1skq8n9/SS3cjt9WQeCU0Amb579F7M9R5Z50/yjMs7XWD3znQ+v6t093Jrudpd852c867o+\n", "fjxjoEat0TkbnTXKSGjpNcOnNU9zzj8zclrTc3q1wWDouE19Tefsov6x2Td+mFHRQPfp9TOc8/6e\n", "0+sdv/PRjt/5R+l3CuOGvbS6dGTp+NJVS/0QkPX8WOHw0iN7Z4z7M3JfOqPV2rEMPIudgcXO2PIr\n", "UTHdXsjAKaZ2pZ/jhwwLcyv5IQN3rj8gTZYbZkx5UpE0Q6TUcPt17gHfAMIlkRnb1Ecim16SFzuh\n", "+SWd3bJNDG96GaRfy7OD7m6Zyk97GXkfZFB+QP8909GQntV7dVj9axkMvUhyK1P6W+T6YDfb/rFX\n", "GlqcXc3GLiK5lo31sbFLeHYN3+vTIZU/0X/B3LvAxapbbK4izdyM5rewXE7aceXIyb3xeO/JI1dO\n", "/MNln//8ZbdMaF9K1obyuaF6YvHH169ff+gp8noEznwAfjwl+rTX2nYAvJYrr6uYfxzmOIdp5xIB\n", "W8aWdiu1txUADghtbXtX1fvuZGtgNwMEMeAuiR+VbbpL4rsKYHOCy/+7morTa+UaJKe6lROUn8xt\n", "5SzXkqymet5Kspq5yEEujDxPHf2Wq57tR3nWzTO5v7+C5FF+ITeWXUbl3E+bmabKnuMYTmQ7OWY7\n", "uf25d3LMdnLpnGfL5PLcOfhpp/Pg7qvFg0W8+2Pq9Aska2hlV/Bse4nWqvQHfoek4+7kRHlNGa8f\n", "V15Rhh96tXwQP+013DiaqPMl2uKD9T/QGuTkjY4NeLVxEBZ6Um/kGug4RxudphVYRt2/q4dj7Nnf\n", "804Px9iT7kGdc2gQljHI20+SZii6vPcchH6i/T3yRXqa/UypfkzyFY74RyRvkjwPUqvNyILk95hz\n", "NCdHmufkTN6BQ5d++IsbxsY2fPHDp+F35Tl73juze2LT4kWbJrrxu2gxfsfOu3nlypvPG+Pvhu2z\n", "PFrfCZeeMXv2GZee4Py6Ony81OG8diG0kf/zii27LLWWGJHrwc9RzihsuxKQpoDdyk63ssPtP9C+\n", "hrLZrGdLK7e3naeJ/SZ1fGVuPXRc/Wxpv0s4TT48nqQPREpl1m5l9rZvgLkej41nVmU2ZDZnbsjc\n", "kXkw08qEtrRX8mvaneTQwiK/qChuK7pfVMgdAVdu5Rqm2h6wnBViWxoJrhnkudUud9Wzclc9T9U9\n", "wG2ji0PXcqf8dgpznhoql5+66WbGKKkX8MPaq5O38AvO5SkqPHdQLDW83ZnpzL5MAAbAzZZF+0DI\n", "tQWyzUtJDrDNiwj6VjQ31Z86PnVKyrtlhiHgwor6LD7R8DZ23ODaghsmfnLZ59et+f6av73miDV4\n", "7wue73x8/SkXhA61NLm/MHr4X7T/gE0Y8TzQjvR6B1q9dmtkb3snfc1hkitIXifZNkIL6n8XVXYF\n", "YYz5HTnhTe9t/wAz25XxS+NawaOVDPmvINk26lrpIXB5yGV5AhcJyfKhhMPyIbX0G1Y3wsPtTGKI\n", "Z5lhfpNEGMJ2q7F33NjZeK7xg8brjbcbfhlMbu0kE9vlAtaT4q/F34mfil8K/7r2e7y/yV2elOuS\n", "k89qLzEKeZWB5TJ9NS2sTF5Xd9ZQHqExesPmd9j21bbH+QZ1D2G4h87k8RTXJJ9NvZT6SeoXKd+6\n", "qQuzV2dvyXJp7NEs04c92f3Zd7KA10eBZYY9uaA2UfNwJbP2Yu3V2sGab93kpu5r+P3rq4wHXqE5\n", "+AmTqq39FK7+a/mp3cF+eiKSixkWHJRf3vGzuX8HmXpk5Fsj3x1BavnmCOXndwy3psTzDKi5pKk4\n", "w53pqae072k/5lb0L8mFPXKvQ3dnew7JDhnxcsqb7Gsw5XFjR+rp1AupV1IHUn7nc+Pf0cpenSWT\n", "j0wTDy+Sn26SBHNunLqgRhY9XXuh9krtACbbXsE1n2s41YtJftKZ9B5O+mXO8UKSt+QZJ/pjd6Lt\n", "x0a4q+2uErjxjbulNndWwI1ytJ3D5xbHBvJjq9avGus7+cz+RVf1LcqcsaAwNlCszFm0dNGcSs+i\n", "MwZO/ES/Z+XSaGV2bWRevTB0yvjIh+cWZy8Y7hmO1UYqzdm1dLo4sGj2nNNGs90jMq+WeiLz6iEZ\n", "35zz/zH2JvBtXdeZ+FuwcwMJYuUCkCAAghQJkCABQqJIiBJJUCtta7cZsrUtWf05lZjEizLJSP80\n", "sSVPMtK0iSylnUj/NNqcTgU+w9DSzkitLWpJfyMktTYbrdjakiU5E6mNrcWVybnfeXggKSnTOtHB\n", "e49vue++e88963e4nzD5poqUW6ZCQzC+BdKJQT8ItZcRknLI3yIEGX/Ucs+8rVUJqvqEQNEisqvs\n", "HL7DIEgnmMju7O6wtBlbRr2y1KrYlFE9EkWikhVDLeNNVYwVtFaZ3fzc+P8Rqv+P8J2urodlrAru\n", "TqKC8We2oiH1Bvy5Asu81InP62RMSglQKkpLuxEPvQnkOIK+O51LnMLjJK5ytlOOuVxWDs9Coiyg\n", "WMYoiDBQBrcVm9lFheX4c1FA2sZW+JF8WTS4kbUnDUvrFAkr+YLuVXBW4odyPJ8pO8A46RrOfznn\n", "kST56YUc47wJMlOnyAl03VbbQ1F85skoIDMTnso7mquqmjvKvxGP75mxMOJyRRbO2BO/pbE319c3\n", "2TX/+GfWQG8w2Bu0/g/2LZdO/EZYzfqygh9E3MMSJe5hJB8GfGOiPEPpLtK57LIzLN3CFq1Cg9jF\n", "UjRSoXqQ3FC5GaLEbuchxNJ3UpoLyDmQfkgWLqfy7fNZF+c/bNQnW2A+eyTWpeQ+IQWvY0QxQqf2\n", "iSlxVGRSRUTsnbSmpg5qj2rPwMRMxuSDuqPo6R3sgySvFd1BNpOmyFLkLWIy7PIiJne8ZtwB/ncV\n", "rG8HFGBLsRd2YAtWuFomqUu7sIDdALFjdwvYwC6s63abn63ryRv2+2wpT+ntdrvfzm67yg5N0Qs/\n", "GMnGtGBSSoQH139izX5qXrHlwmNeqWIfUMU2hdXmmc8v6X9upjleWuX3ewsLgBpSGud1M55dGoks\n", "fXYG/9fjC0N9zRVGtdpY0dwX4pOYv/TdaP42ZeMykHdUySVvVU5AlOuETjcItfpQdkvOsXr4OjkX\n", "rCF5qPI4LluCKzZU5xKVboEcAukEuxusUnK/5Pusy91Hzv2aGSvaXYlbnau8UomWaJVbohFL6rBV\n", "R2EXwUPB48FzwSvBW8GJoPbxbduUfSfpkCv7bGpF8lbVRJVAB8CQ+IkvGT9YQ/zo7tsoIl8vcWoV\n", "pqaK3KAxWJET4gk4scgbGoTIk4sPGBFExJ2CdXVCcSgCWQL5bhvIOQh5EA+CmIUxzEcXuFkRyDaw\n", "tD0gG+DEG9Pf1isshXzHyhAnXkfigQr+2eRT3LNY1JbBsdML8jJWtu9ivftj7qccllXFaaWiNAiB\n", "ZDXSOJar8XWu4oLlIMjc8YRMId7Nh/hG4fri8V/Hx3/bL3ukyD8Oo2eCbRYJ+ZLI5GTpCibVcUbA\n", "uAsyUhFsC3KArnSOoloLwNDYS3MF+TB23aNoMJDXQUbJEYsOhIs5uV3cw/oWbnxdBt00kNyg24xp\n", "eIJtj+jZbVR6cvGeZu1PtaniqpUqNmG34G3ugmjB+XyMwBerZUsIPKa9WtkNIRkEWPlSKw0vGF41\n", "iAMQXQszUhyq1QlGRorYOXsw8wYx85Zg5lGS3zaQEyBjxY8NXSQuRF8ln+yI31NsPNJ7IP8MopL/\n", "9F00cxYImilHTPyzinyhiCdgXEuflgwiddZN+Ax+QSFwjKTMBo+h1SAO49Qi+ox3cWMrPjtZleIQ\n", "YXQILriD76KBA+4TdO79XJx5BA8lJ0UbRJ17uTANCvEhh9o9WlwwFGeB3MPzdTAj3sUHjYNEQWxF\n", "YFd4eoQNGvxPdNP/Ql8I0nJJOND/y6WSIC39Zf8a8md+ZYpfk40lDZtrG+AnFo6Qnzh5SH8cAudx\n", "TIdbmASb9Ntw4E204r9heJwQ05h6nB49KQd7yGEob4HsBAmyd07wmVjRNn43f4g/zp/jr/C3eO1A\n", "zNTJL+EH+fX8Jl75m569E7pMy/PUqaqM1I+uuYTQrwJOZVS5VEFVTNWv0gxL2/GR1JlY8aSD+pz6\n", "ivqWWjcQMyN27WH3tWFY0sgt1WM8x/KUoLRBnZpJM+jlQZCLOiQoZWKmoDam7dcOaTdoN2u3a/do\n", "E1o9womy2ye0ae2YVjuAuxkysj+pE5/lArb2InQkj7Vu0jd+Ii+dN5bHWmc15rnyHvWd5w3Lgefw\n", "l0tLEHR4q2ACE9cJw24aR4OPd55PBg7lgQlJpRiB58Fz1nAvgx3tx2i8A6LBn1pBvpezw8ObDomA\n", "T0saLbzvUh/jlMkPNZ/CyvlzWK+Pac5i2w8OuoLCozhNNhxFnZb0tIMJ0IvB3oOBfXj6OF+Bca5H\n", "9HavegUs42RN1cB5HNeu1LIDGnDhVSB3MMA0GHZtIEcp1QFb5G+J52GYezjEz3LLEUJiQ6ueZoRn\n", "Q553i6KbF0N8++jq27xq8NLl1bx46/f4g3zZeGL8+/yc8eP8N/h+GvMT/8rG/EI25nV8YUIISOfA\n", "ONm6sg2xECqMABpsQ6oNKiWITP+4gDKBoiIktSAHATFFH4GkGnaDTs0SzaBmvWaTZptmt+aQ5rgG\n", "N1C25TAFtpLuxpAZBDmX3RoGHgVblUA2G5Sv/ljJWlKrEJgtdaNHl6mxCH9P/SP1XvU76pPq8+qr\n", "avaApWqEy4Gj4St9gkmFeEGOqUfqlHpUfUF9Ta2W45qlN9ktmITOh0xs6WEi+vjd1X//96vH7/JN\n", "/J+MS/zi8a9SnCb1Ha3p0aycsp/yMvAaTFjRT4BXdOZ0hEOK8pCNvcxevy53/XN0fTDLdlJX9LgF\n", "EwqL9E49E84OmY+bcdh8yzxhxmGz0yzIgZw8Z2X3MiPWnbcwCYGtg+vBRwN4myXYWoLXVyOJhX1T\n", "Psb380P8Bn4zv53fwyd4+qbZ7RN8mh9j7AmahZBGDC8i5f/DXxIPoXA3aQM+ZD9IEGQMC8Z2wx5D\n", "gi100hUM5AkQJ8RySqufjMKn+KmHg+QQPaol57qkzQkXPhDMa4rcQZZNWl447CBxECwm7JvziD/j\n", "q1qrhKLxZ/k/Hxf4n4y/wP+rsOXLY13tQk+XHNtC/UjftH2K7uiltkkb8kh4xIjszI1XRM0BJkWJ\n", "cfmM/1/8GGfkWvh/kSoDYn0iYBxRs7kxATHRyQRGBLmUqB8kjGn2p4Q1nbAGpFtMkkaatDstBZEu\n", "dyWM7glPS3I3PJTkPhn+ginQIme7twSS6ZaxFmFghBMeJOqMSu57qfBAssinWNjjLIyjBS0xC3w4\n", "dS0Q2z70fuoVyEbzEha2i+InUETe0Z5EWMsdCC3Eqi4WfAKGvAXK2veQuPuO+SQblckd5n3I36UU\n", "rosgv4V35im4zE7ClJansVgsXkvY0mNRs7tYPsGj4dxN7ijbB/1zH7SuN8lOCkPqZbhSboLUBvnh\n", "1NbgruBBWE/s8K7YmnCoaVfTwSZ2yM/2kkeaTzezyeFvjjb3NYvD2aCI67kwHnqDD7CCfApC7f8c\n", "7YSNKAnDCRJpcGCFBeZmyw008IJVaRSy6KUbcOxfbrjRIGT9a1Y8OtU8yh4tWZr5Yc+U+JbZYou7\n", "WusLkwILx4/b6211T4nt55+0L+huMrl8pTWtNcWvPjm7tuu71Z2N5WoxJopCxZKoc2ZD2axVz9fd\n", "UJtq3dYqs97mjzirw/kbI4F5pf6O+l+WzTIV15oC/mJ3qDo6x6Uj3w4bf8J7bPx2ZHnS99nAtklc\n", "mPVbMAxtIXwizJq7PTwlDmH6NU/TNW6Ji+IaJGv2Y+tEFPJwdE8UWWK3WyfjvmcJLdwXFKu/FGtI\n", "ERN4kseFc0zFBbvRK1KOajglizpMzuUysl2FsR0RIjZUmLQ4JmoHuG8xtm5jclSySHAKFDzqjoRe\n", "nvXc00LLdm5Ke4/l2vsctbdG2gb3/ZXWW3Df0ywKIlt0Wy+O9t7qFSZjJD4Ta9gcNXBl3FKxTXoq\n", "zPhl7Ck2A58ywmgqDWL2tYefwmxpD4wY2GQNG0eMqgeJdmOijNIZytPs5ERtOlEbSPgyUmM7TpZW\n", "NbKbhI2J7nSiOxAr7u8e6t7Qvbl7e/ee7kT3iW7dQGJeJrlnXmIea+GC7CULMAhB9iOBe9vy3cux\n", "aiyHLrac9frYcoUJLGZTfbHCBOJsJ67sNLGdJoUj1LOdeuwsZnyHzfr2xU3yeyQ725e0s6nqbA+0\n", "C8MJQzrRZBwxC3ipkTL2w16p3jhSzS7xLa7P4ig01i9GI3+NtOAP8XJx40gXO2NenG46L5AMzovR\n", "29Al0s/wIssYSb234P0FHy9g0/OPF8hxBCshDK+FeHkS5p4UyDHYHg47T8GqsgaK8CjIVgIdANkI\n", "w+MukKRfYQpkabyEnONPQW5E2MPeiPw48laEPexSG3jN1rZdbQfbjradaWMr+gEM4NMgx0BOImWY\n", "ErTXgrwOchIZxDtAXge5BMfnpR7IsEisPwxyeiHYCchlkAv9uAHIJ/3glk988gRmBb3jOiJ40STe\n", "cRQkCUYyCnISNpfDICmYHk4RwVvvxQu/BvIjvPArIEf8kwznBt77Q2RgX2q5juz21yI7Ivvw0p+w\n", "LpB+xt5ceh/kHaRav9a2ow35TziQxHt/D2Qv9QDIVuRVv8BePrll3k72AZPnu692s58LPdd62HXv\n", "4J3fw5tepdddiIzy/mv9MC89gQOM5AL6tFO4XmtraDKfGszO65vC8kKtSLnOogNRmjZ4o/DPpd7W\n", "qsqQ1/ILc6PXThxxpt/SZXKHXJUN1Y68Fu/aSOuQw/3sfLDEuq4nfOv5cm9twVOz/NWD0fDSYutA\n", "qGVJuIwvrIrUWqy1EVdYZ3LaiGXWzXTr9a6Z9Y58c3mRv6mxJdreBH4ZiDoNFZ5AmaEt6Kpp8dYF\n", "azqXN1U+lh9uIv5SnnS1BduYsB1En3JtSI5o29OWaBOnxF4JCeECV8Q5uW7x39hMTIQyieqMdALh\n", "BlyoGjPkc+gbH0FgYZNNzdT7Ivn4n8KTehNkKyOJkDExOyNtmM0PEN8JkYtdOuBgf6o2JqoysYKv\n", "V/1R1Z9U/XnV21XvVmmYOgIT0hcwZH0E8iuQIZAySxXu/yrsuztB1oK46Ghy1HUB0DVuuQ2RHG5N\n", "UD7wFnxJoyBd8l1OdmFpB5krH7iE+bMT5A6IZi6Tb2YzBpihyAGpn5GReewtO3sVNtbG+FObItt5\n", "2Y5X4VyU7UhKnLcNjUOwMzAJ0GNkV4DKk/AakTgtaSGFuelEKYomXwaZ2+bFgffRls9B1KxB0kvY\n", "+iHI34IUuefipDfR2VfR2W3GERO75V5k8JXJd3gOnfQyyA9B3kW82q/K/hmSimuumyKvMGlfRw8H\n", "uTIc6CojJeQueof6aR7dijFJsL/XoNYfJr8WwmbXaF+GYNUKNvG5DvhAujW6l3VsNpMW2Kuo4VNi\n", "v85QKBikl1UgFL30Y5A7iF19E7LLXZAtIF641ntBTsIhexiEhsANkJsQaXqRl3gdfPUF8NWDIGcU\n", "sSv5QuOrAIQ4CM5/BuQGyLFJKA4ssEdBDgPJYe8sjBSQwyDaTsjmRGJoCIhvDiM350KE3pLLzvgE\n", "zPIlCGcX8LZ3QLTogdFcfPTrIO9QNhfIfQrdgr92q3kXpLYvcu/bA3IKr/ox3vIlkI/wquTh78P7\n", "3iA5Di+9F6+6BmQU5BO89JrGl9lLp/Y1phpHG2F3x+uuIa8W3nTfLCxXs07NQqQBXs5PBC/XB+LH\n", "G37E3tBUKOa4oEiIaNi1dogmq3sKP8yF/MguDq01Ehp3N1UW2mpbKioC/ppiX9TfMLvYateXNvrs\n", "m3aveW7Gc/EZT8yucTTMdLlCZcGY190RKCtvaCv78997gn+m1O2bUVbZ7C41lnst/O66UFuwxFdd\n", "oc23u+rGt/zsheicspYFQV8sVFtU/VRTbUe9xVw7y+eONLgLDxyYKlvdyPG+vyXe94bEzYIsiE+7\n", "CSSI3RPoju2z9qA7NkHU2oNVI7hAJsMSB3ICu9uBRyO5OnCPDrAFtpUc67jdAdsZtrd37GHbybGe\n", "21h9uB54akBcPfhjzx4cDfbINnGunzcJ85m8qeFek3iOaVg87G5JlxCEyClmpN9C4ldxPHmrobwm\n", "A5pOjQBjmfQA2jAMudykCQHcSJ1JiGl2EbInYvq/Vv2dKqP6tUo1IH1GWZdTTW9DKi3lm93F2L2n\n", "YSthyEQ2l9bg1Y7jxzuE98aX8OvG34RsvIr7VJjDf53zcF8yZpcwZSD6mgAkIMfJILQNbfRkpB8r\n", "Yg/2fRkuoQ4kCjLQp0vSiRK2bRyxCQQj4RIonoIieVlDYvp3hJMCUtlUAzH9YfGUCO2NNX0nLA47\n", "DeTczbqHccYRy2nLJct1CzsD0W6xAoPH4anzzPTM96z2aIa5mP6ocEa4zEYBzj4qnhEvizdwP4AK\n", "JHcaDhhgxE+ZR80XzNfoju9YTlrOW67ijvdwxzwE09V62jxxj3oYwFLDvAzB5JPj4LS+DhGjPhsL\n", "FxHm5JVV+W1Gi8VRYg+XF1c6TNq6Rw/xcWNVWTGvyTcUVhVZ7Yba6bvobyc/xP93ysEchem7nqwY\n", "mVRQiAn9gjic3CBshuvtNtCP8mG2TCLXjc35TsMSw6BBHJZEA/A5krPEBQBjQAgY7qHKSFdkc6vU\n", "DKPCv2IY1WBrN7b+AWQudp8EKQHhyL6XT4vCZQ3l0cHoqu/XDengRGCd1a9DLl9GqkN+2wNwwdlQ\n", "sou0TtgDF+Lo0yC/wp+2g+ipddI/5DAeWmBauk1IHY/momkzSiLvElz8JghHaFNs4CfhgoGOlkaO\n", "oJCRzLDOU2bMN0Ei2P0cWypsQY3OWjt76c3oPtKPYQv9TyB4R2mZhr0RU+0MBJCSR9AZ+WRyO0wW\n", "cZhSj2hOayAtU4L9aZBjlJODPFRkKZ3ViAOpg4ajhjMGccAUsWqtWsRH+iLW1tCD75t/sDr4zDPB\n", "1T8wf79daG1oa9hY861v1WxkG9s4gatnMtjnTAZbyH1FvU5qqWMjoM6YmJuRtmHln5iLr5mRbisJ\n", "R9J2SGI8Ywu8/J3bM9LediazqJkaGGhhr7mHKRmJFuNIgZrMKQicaTEmXOmEKyBthwgwxMiIk52+\n", "kGtHhyxqJ5CIucaRFezgAB1MLhkaHGJfYfeQ8okC7BMFFCmIiaEjHkhBAWMinpHScdwW5HYcrQJ0\n", "HkLrY5lEND2iY5M/QAzkNvKauRJjiatEBHAiHNoTbLlLFZU7ywPlbCw7PQG0xRmQhqBntMfiaOGC\n", "eAxHmSr3JLtXzDiyWpDzUmDJuk8E1q7TcDQfLDpahLAXDLD7IKvgDF6NLQO2PsUW8gslHcVdg9zH\n", "7o9BzoKU4ZgVAdWfQ1DZh6X7ldLXSxEjXmotZQOdsA1PYhknk8wamGT2mVNY3DUIxgqDvKKYlpIn\n", "7efhpVbbzXYPvNRrEIW2z55CpOkrWP3fBDkJae5zkDUg+xxgg4DP8zrCDtVw8nXHmw5EFOKPZmQf\n", "7IO40IOtNrh1v4C97h1I7oCQk/oAqtVWG6+Fe35GfAY6BTG/KyE8XAfpAyEVdSZIaTObyWuaX4Zt\n", "6HVEmphb2V3fh2lhB8h+kPNQ3faDLO9At3S8jiXxNBbTPpDLIFEIk2dAbnYBjaK7rxtiDxOtkwd6\n", "jmBptGGZjPb0YfsLKK5tvbgDSLgPEg7IfkZS5+dfnf/5fCbajGKt7gXZD3JsCZq8DF6TZWghyCiI\n", "dSU79tkqtpUCWf4MlMtndjyDvn4Gr/4MlvYPMGpWYixcBzkKosf4oOFyFruUsRYFWZ0bHwbs7sLX\n", "95cyfeoPSr9Z+kYpa5wDKCkzQfJBCEnxMkgUI+Gb2PpTkHzs/ghf+3OQl0HWKvJuSmu32n0YID/K\n", "DYVuxJK+7HgNX55AFTXAGAmDrKWTMAa6MQZaMQa8IEcwBrq96GFfnw8KCYZCtLYPQyEyoxdD4SKG\n", "wnmIkOGGHmjr1zAEVoC8jG8P46C0Fls0FKwYCltgjftx+C1Y4z7AYDiIcfAByCoISRtB3uhQhsJZ\n", "EMKYO92lDIobIL1QtLrx1d8B2QdyB8QCCSrSg0b19vSyp/wMw6AV5Cq+eQ/IPpALIHdAjmIc3FwK\n", "Vo2vb8OIMGMI3MXX/whffAvIRpBdIKufgQAkapiIa5kas6pAmoSmgi9mY3mqvT6yhOYi3kNaXAWp\n", "me4hBNuWqtT5eY5wfXlwyfMtc762rLl52dfmLNjq77TNe3KgadGWNbNmrdmyqPtbA+FAd391ZY1K\n", "sM6cEVtc1bG81TPbyO5lqTDWdDTYW/1VbXU2wTt+raAsT5fvmb24LvqVed7WlV/v6Pj6ytZY1D+n\n", "wRZ9fsvixVuejzY8OTx3zgvzfeVOm/upuS3P9zfVNC42e8qKBH/nAndduD42Pycj/0VORv4lyciV\n", "EoevGoOicAKWyO2te1qxzAX7sr6B+MRnwizhM87ENfIVUlUjW5tkxCmkDDWwhYUtmg3GhDktJaBy\n", "UCBnJ8hgUAkuokTDwqnBXIoNkEI2NQ+r1eVkA4TOXAQHQDnpthdg/YfIBmsOzPT1XkR7JY/Vn0XE\n", "+E3E812ulwFydwkHmbwkQ1MNJHeJB/GzQ7sPyZ47dPuAQrUjfx9yPncU7EPOZ7S4Dzmfu4oPIvdm\n", "FcIWkH2a3FVyEEkbgH1KRip7EaCdco462akp9yiCriM1vTWImkYmruehXFE+VBySJUZzNtLI5za7\n", "+d/aG+f4/fOay8ub5/n9cxrt48u6BOOMYMgaebrL4+l6OmINBWcYha6bwLWtaJ7ny/4KTeN/bKu2\n", "GDxdq1tbV3d5DJZq22KyZasnfsN/lckPIvfThIgMZQgHE4hELeKdvDCc9fFPQGCBoZuwXB4DhaM4\n", "rZQMquQqbh2MGVsp7PUgd5Q7w13mbiDs9U3owW0CjvcJq4R1wkZhq6BmS69wlHV9zI6+XyWuEzeK\n", "W0V8AEUgz2eyEa9VR/nATOFvS7+sN6H9T0z8hvsBG2Mi15hQBRC5mG0tk1ynNFMZQgpAHYHyuJ9o\n", "bxc+e/AF7pM/8RxfLGS4AJ+XmBFIDs3YMEMgZKAZlOKXh42RCjZmS+hQgMm12wK7A4cCxwNMrrUF\n", "KjDQOpswbg0BIFtxBk8WzmUwi/+bJ1DQdoANTBtHcorHOFJDokhMr+ftvJ+P8iq2EBMkFfpHj2Rt\n", "vxAV2NF1kDa/aMBRQ4Ojoa5hZgOg5/SN9kZ/Y7QR1zViZUI4RUyv5a28j4/wOEUjWASvEMZNSIMj\n", "FJh1MAncpdvpG+wN/oYou510r5EO5O5pag63yoZMMw1P0trNlaKZBioOMkYHnOX86khJpc8caysx\n", "6wVzRaVeX1lhFvTmkraY2VdZEqnmO2a2Su5gRUF7ka2y8C9qmioKeIEvqGiq+YvCSltRe0FF0C21\n", "ziQf/W8nnuPu0bdwsHGVHBTXK+FebHzG9Ju57RyAAFQUsWPIwBNawkRPK1eCTq0gf0UNQZ3NSE/7\n", "JgEPQewE2DcJ8LLHUP4u7ANy0z6I9PlD3SjVCNmgniT6EwlsOLAWfblmsi+1DdYGX0OEPo260dzo\n", "aWzFp7mDTzPtI9/DnXSCDXfy404zQQjWZ60fd1I3mBs8Da34Krg13YLdv9Ha6GuM4NNUa8xynKgM\n", "cU32ldZGsVWOJG1V3HChe//upxH+o5+GzZM57Nt8xL6NlvNBXweuXBoquqB+wAGwRQU0FupZRP+i\n", "L03uYjZQikMfDQ399KfCvgefhcVX5XtVsXu9S/fyJzQBKYboPF5NKRhaWCc4ultg2t2sbNq2sn9V\n", "uNsaMT/8YAuNmatCjM8j3JgzEqdBLBN3HJgjJzRpGELkWwLcMMN9iw0qG7RQYBRldc8UfgJaMTuk\n", "UB+EqRUGpyGAaC8tQBFpmqb4Uf4Cf41nc34/RkjefuGwcEq4KHzCOFhMf0R1WnVJdV2lQoi6+oj6\n", "tPqS+rpaDd2PzgaLky0N08+WDqrIaJG9AAcYm+Vlf0IIRoNwhM9TPdHR8YRqhnam1ztTK7zX2d3d\n", "iYpoFEc9yQe1XE9CBzQmREFOaGSFSksgKxrg5EwJnlO4oobtaGTcP6wA7DR1Rv5wIuvqH7TjP/bi\n", "jeO1479i362PG+F/LpjYul4gGTixnpOK1GI9u2CayNMo9JUHYx5PLFiu/PK/P3WP/XJZ/PTf8n/P\n", "/xNXJXRLVUB/XW9nSrVdDrFZDzt/Ech2GbIyUZxOrXdvcm9zM8H5Fgydg25Em2BrCcimHEBlJXuv\n", "SkVgKGU7pWRtryyVOXPKxQW5GKB9Kml0AZ2wgDEDY2mlDGCQBFSoHCRwDMrzv4H8GmQ9wjAITe8Y\n", "yM0cgOBNzOuwugfpo/thJNmHKY3YMKkVSmYPyD6QA1ASjuW8IF8gveFD46eIaF4PNeFdRDRfKL4G\n", "6aK3eAUCm9+FBW0popuvYes6ZJljIF+AGBB8MB/e/LPWD6zsNn0Q8+/Dkn+s7Cws+QYI+kdhIL4M\n", "ch/EgMDv+SCE50+uuXdh5V+BPv8AW0Xo3/XoVUqJly4p2Soyig6GqnQAr0ngDfvwNgThj4wNKY53\n", "6StGwmDxTYhI+RCRKLxzJd7kJoSlG5b7EM7oXQ5DJblLuiladTiXSnYXiVInXedztQeeQgtPooVX\n", "QdTYvVglYwx6ZWEqwiaOVaPRamSB3GqxWPn/Xjzbx4Qnm40JU77ZxWH3ymD0mTnV1XOeiQZXuvk1\n", "jhq+vLm7tra7uZyvcfj9Pp5nolVrKxOxeN7nl+PIPhJa+AKyyW6SOJ6N2U0E2garCllnpVu0gA8K\n", "64VNwjZBNZADcVLxXM5OK40BnUbfrxnSbNBs1qjI3nYLEta3mNxiI0EMF04gRKVIdGId3IDgOhVP\n", "YY3qNKapj8l/oT39X+166qkuoWX7iy/K2Ow0p7r4L2Rs9hPQ2LYzAvGlIy1pazpkbE8Fpn0KQjsy\n", "pyoyWZx26U9hGHgLcuzRyjOVAgG0tzIhvtKY6GKthQd5cJ4y5Qh/XZlyXWyn6yH89a4s/nqXjL+e\n", "DDbEmP4ImIUgm4FdxpGZbAbO7iIY9tlsBs5eMptmYBLpOuz1oZ0mz1RfRjbjEfiMzzKSOuI77buE\n", "IhPIS05+2PApu2fyQOORHMb3LwD6HW7ugXViPzLDW6F39uTMEfvg5OwFOdKOMQ1yE+QXtDUb8xvk\n", "r0GuQkm92AFxi5Txk1MMMkcxFM+CTG0p4fOfAklRWhHIKZCPJ7HJ0czraObBxqONsLo0x9HaA1Cg\n", "D4SUhvagjfvJ742WXQXZBzIK8gmadxnN+5QR638EGRxzQvvojHE/+J2w4JFKR2NuvoQfnU26x+OB\n", "L1AZTFPmkf/ReUaYij7un9kMc3KdkraQaYy/Y1QCTsmZmcLm5WGWKMrAzF3Mlq//58uH1v/Ot+vw\n", "P775S2mdXTxxhP8XoZyr5PyCSVIVAU+Z8bqUHC/KBiBQO6UTIPoilQx8nUzrx4BWFtTH8LNdv4f9\n", "JHQkOumNCX86UUp2Yyuh2znSqPJRo3ogv5yVvZzV8FDYL4lEMjDciayZWpchGHJsMrXaCqBlUEsG\n", "tCwjnQPIs9U4UsmudNLj/GSmpqULgdvJ08IlqL6yGpb8QLwJbrMSgIr6I/mn8y/lX8+HB4V8kojE\n", "14OpXyq5ztTcJNAm2c8R02mUC7mHaDM9LKB3YYUs0DqsDp8j4uh1rHBohqVdWJI+LPu0DFeUn0ae\n", "80Ew+BvllEQF5RPuHWEgtUNA6hBCPrJJ2my9QNc+gLiUl68qV81QtasWAgcUGZPSDeBtH8s/m/8B\n", "ILiPUlMJKIM1NXWy5HzJVSBiUijOSbRRjTamsHUX5O9hEvstNVl0mBxuR8gx1/EUmoz6JMlLZdex\n", "iv4Ya9MBNHhyKT0LAi+zJyxPH7MbsjjJ5CGzPMN8WtlLauX7a9qKwq6lDcGmxeGKivDipmDDUle4\n", "qK0m6ArVmEw1IVeT4Lb5vbXC7E61f87SYHDpHL+6c7ZQ6/Xb3IKgcQU73O6OoEvz0Fr0HUmDWNhN\n", "kPo0kOUIZ48tMNwQt4HbDJWJqfe38Mk3o78ENcV0q8nfc4tk0EHVetUm1TbV5IolC8y0BkGIFCEd\n", "JovUTog4E7jLBrhHBFEtR4S7fVp3JMQXYDX6ar/Q8uKL29m8WTbxBfc3/GXC6fkWSehSP1ZMeCaS\n", "HGfkhOFYnqzXIVdGPZCSA28h42lkV0U+CbAlaekW2O16+yaw2wS2Y/Z+u5KrQxYjw8OhtPpMwmxk\n", "zCHYFCmV7XDgDcVTtv+m0marnPovaK6qMrN//FeyG1n95xvceW6QydmLCO43IwMr3wOmso638bW8\n", "OJys5dt4Nnrl2GJRTkwWmIiJuBAFCpejSOMMYbWxi62sz747d+4T3/+UUnw4+8RvRK2MHcctEH8i\n", "VZaK9alNpdtKd8Ne7CxlU+9c6RX4FJaUDiKLe0yG18Y3nyBvD0y5Y1i6E5Vy4RSm1hC8ZSmyqJND\n", "wQ1BBHcE2Z1OBNPYjrHtxMyM1I8qFRtmbp7JuFRtOjHTmJjFLoXzm5tlnCUMJ4LkYSLn0ixjYkFa\n", "GkLQVBBBU0sWDS5C5uCiQ4sQ1rdIkQumla1Sgngh7WAEpTCaAmoRQj/7SOTeS3FFxiJXETvmNibq\n", "mYgCK91EPVWESLRmkmOttxH3OKuVQvdmBRKtTKxhl3bg0g5jh6tDRMkt+Jcm4nhE3BkPxMVhaUF9\n", "K65YAE/yJIO5AMtIL8jnkLUARAsdn22ndohIV8Q5uTJVADOT4kDF26VF0iL742X4Gr+ARunQ1jGN\n", "MotZn0LZiKOIc6HCEV8g9MWgc+jqdKwpUbCrXfkH84+CXV1G3Md8pbRQalfBwYKjwE+8DA72BQ4Z\n", "ChwFdQXsQhXE58+hIJiLPUwzSO0o3lecKhazeeAREDWk6zBcZjtK9pWkwPgugPH1gqzMJUYuB+ci\n", "vAaC8V4OyeUayA0C44GJ/3TDJZj4VzLZJHWp8XrjPYSKUIzMq5BNVoFcBjkLchNkJeSVLSFcHLoU\n", "wpKAAxtBboCsQCjja5BnXmtD8kBY6IGbWoXOJdD9HiUCW4qgTyO6Xphe2wriiMYmHEBdDuaIcP90\n", "eN2Z2CKMvxUE5UdlnvAKZxou4xUowHpVLsTnPgiJhyvQ6FcYSZ5qvgip63shxCiF1oReDsF5hDbf\n", "wetcDH2C11mWa//rrP2mh+ArtA8pwp6pCOdsAXBPB0Ff1rT8a11dX1vepPy2t6/Zsmjh1jXsd+vC\n", "RVvWtAtzip/vDj0501UZfTJUE2uuVrPR1eJt91us9e2elh4dPzT368vY9S/Nm/uNZcGmZS919299\n", "Lhp99vUl2V99fKl79lNNTUvbq03eqLeurayxo8bd2VQxq57kmkpunVAoPM34TYTvl6xAUUNVMmkI\n", "JOaXgdAYH0sCw4J1QBqdnAAZAolZZenCoH7ASa5m5CWyDwBMMITkJpohITVvbt7ezJTtZjLOQ6SP\n", "lPaCg8muz2TE3IufsL0HjH2f4taSredZcTrq7oPtvM0bBzgBwIoUJ9Vb5K+sj8OifxS84gA0gbZA\n", "PACZJnAUNXxScFNEWnvhplAeHjb3wO96GO61I3hcFkblrcpjylOlg3h0mzs+5dGkehzAMyP1vXjm\n", "fjwuEujFc/ZNPkc63Pro+PBYLFqLBm5+2cJDYEgRbxgufzlUNGL9vfLmLq+nq6m8vKnL4+1iMvIr\n", "jnKeL3e0zmitWlRbu6iKbTxyhP99X3eosjLU7cv+DlctqquTzy0rk8+cto9vXzvxmVCW9dPEpdKq\n", "ST9NqXHELPtp2OrZkJaCOT8NXDTS8aDiCyAHzDTXzDSnjeKnyeFGPs5PE9Mfs5y1fGC5ibAa2UUT\n", "079Tf7L+fP3VehXpgD8S9kI2/ZG4F26ZsNhDThrGggWlPk8S7BSnFO+F4SRc3IOfH5XshTMGaDmS\n", "vpLPYuUMJ486zyAUW4+MdiBjJY+6zwCyTA+LRxQkDkyco4ikuw+ix24UBHE/kt4DpHhwaoUrzcQj\n", "Tjv5gchD35x3t7qnewatoeLQBnh0oAFBE4JHh//5f8yjM35r8cMOHf4PmXzin/iOIFLtgyffFtUa\n", "VT3Z9NJZN85tgc/aQsn4SQZB2cw6NcNQ4vJUsoWMrGIa0hb00BZgyAWSQ6g1xEf+7u+62P/5e+1f\n", "jgoz2/9OtuU1T3yH/4Iw8f8ze37h456vlquQEPyOgShb8lG4BhJeIex7HAyYOSgWapFJN9kiSaUj\n", "HBZVYEQr0OhUUdUaEUjsaGux0lb2jwniZDCW2/wu+6+LiKBqH0+1nzjRzs9vPyFjUYT4ffyAkCaZ\n", "KyWVVkJGZYJWVqpaIqcyQYwifMnJoo05SF51BsKKPZPFBiJ5k6ewnyTsvuAMWNZGQQgelyBOTiLx\n", "MwsPdxRj6CBWsTOA5coqY3IxkgO47DQICuAkDxecwhWHccVeKjNYwv+7oLN8g7HMYzZ7yozKb9BS\n", "C1iJWovyK8ya+mf8Tv0r+0VfTVwVlvJ5wjGS5weA/g+7cSZmkg1ZMoo+bO9jGj0TGzVGDeuOfETx\n", "JBHAw4R901DJhpLNJdtL9pQkSk6UpEvGSvRQNcwBG5R4kVgOBp2pJVtaF5xyyvbecqu1HP9OKBvC\n", "66VOZ+mUf0yOXsytEBYKWmpnGbdZ1jygFCWhEwmK7pGE2sH24FtinXoF1kzYzuWiD5se0kCwbSM7\n", "uZ0p4ECUGQLhMPe3V0CJtTsYE7UTkgpTPRwEV4bR4Pkd2oe1qrWK/6OHVZAz4wI//gNFDwlkN863\n", "s/eqn/gL/r5o4xq4MDdH+LZUDr1vDKhB6fIxaNQxiHSbQYZA3GoCOHEHpH7G5xgvT8xJY+aw8Vqd\n", "STSmYXxgU6g8G3w5YlITkIIvnfAFRmrZDuPYIRVFY7Yrpolp+PqEDwzz+pwCBMqjhOLEnKzH7jh3\n", "jrvC3YL6WUBzvgDw9KAmUBSqTcwhvKw6K1PUB63rrZusItMirIeYrJE1Zyf7rKusbBRVUYuryMXH\n", "aG0mubl2e61A1awa2Y0ayO4RxmPD58JXwrfC7LEWYyICppCS3criQGqddqN2KwT3F3I1UrWI3dHA\n", "Xr0flcJSxaPFFyBTixAtyWhAZve7sFifNX1gYm36uemvYPDYSYFekFgoGhuxV9LH0L1+BPI5bKcv\n", "V74GseJl52tYcQhw8TmAKb1WtwNgSheALPQKDhyuO4UDVyHDrGwCE0CbEX6EqU8JRRo0dC+s69Ra\n", "qt5Kgj8xg9+ikQRPdxVEi9ZTCdLLILty9Vr3o6n7qYoPWvkqIuZQ+lQ6yZqRerkOLYO1BC2j5q0F\n", "oaKWK5AM+A5SakYZMU1aOrCsab1ebXGlKPuK3a1ery9SKYYiWAvDXp+YNYKMV3dH3FXhbk+wpm2G\n", "u7DNHK/xxGfWOCPz64M96yvbjbW1PmPQ1Ogr4xdEg2UzXCWmqhl2Pm5wNnY11vc0V4g98wptTmPQ\n", "XcWPf15Q1dTdVNfdXCnO61J11tebXZY8Pr+yyROaW8KvEMzVDQ6Ht8KipzWqW/gK93NaI5slDcf0\n", "6t0cvIVsUMjcS1Q4VkrmYCL4kp7xJTEznR115zjPf1M4Du6/gtFd/PtslvYwJT+JSFxheERUP5A2\n", "w3gVU6Jok0PqDTCijKmnQVooYpSS7S1X8dnV1cVuSesU4nEe8GOcjvPwp6QaB2Y+hJMTIBwTTmCh\n", "RwWhfqTPOGQAf32aoLbZn+QZLg2ycQHwbyrB1Q+yHgbpbSBjICdyZbmcrCVOw8MynJOcZkx4Mstm\n", "Tuk24nM5PT9MMZtm40gh+3Ox2Yk/Fwek7cVyYhyVTqGQ2v1grqug5Mmw3yCEDt8Dsh+Low9bvYBD\n", "IOjF1cD9WWl8wcim0hbjTjjLVmIKbMRkiFiRGGs9DWYRsfUC4Odo+ZlyWBkrTgMtMQoGTcot3EQS\n", "ByzDJVTW9wChjuH5kVxLsDgnw/k9+ew+1nwf+5Hxdz9BQ1ZgCu4g5DWq8WiEmXSFca3xFePrRlW2\n", "LUetZ6ArUZoG+bEAfygdBtGiKRGgN16oulYFtHhZJdSyqSJb4KcFkZn5ZH/c1d5QJojlje3u1kWl\n", "obrnZ7asinlqYsubW5dGK/nCuU/Z68IVYXdHg6PJVdfaqMiG3s5lwUol1+EB5Xmty+bK/oSNJx8+\n", "/rC0HiNgCUgAuzQqOAQBbvBu9gq52ooP3+NpukclXZ4MeDu9rJe2g0+M1aFfb/uzWEXydcdy1z1H\n", "17XRc2L6Q97j3nPeK17WcRtywzEInRwYZuzvbcfbzrVdaUMIedu0PN6pbdlE93RI27M663ByzH/b\n", "jzXeb/QTcoDIhdk1d7Iy3iL+r6XYfDZ79qDUahEyWjZjawgkxghihaEGzTdS1bAYFpFEJDBSSsew\n", "0jQEpD0N/MBIJZtt7fNjlDIGP8wiefvsImUKTcPR7mY73Vgr3c3d8qpM2lA3IWhDP7bzD6RaNaVd\n", "tbuzdlVJi1D5FflrgSsMmOzkioK1kACBAp1cWfwCnKuwyUtnYRhaWfICVB6IkdILYOjrAhsDWwNY\n", "8KC/rW1hh9a0vtz6Wis7tBYpTadms8vOd1xFYsqKjrUIzD0FT9L5yfK0yfNdV7vY8ZcRh3keEeYf\n", "IOZ2Y5yd8UH8ZpydsXLBC6jI/AGSe1cufGEh2gDD4AcLby5EdCBhg+gx50/m8P2AhyydgplrBRYw\n", "WOvlNNIVIGuU9kqj8G6Nok0nFz4aNCc+tK+Vl6VctpFS9p3mVTjC/6XFF612t/ksFl+buzrqszhM\n", "1Y1lZY3VJuX3A6uv3OgKx2tr42GXsdxnbY97Zj/R0PDEbE+8/ZSzFZe2OrO//LqyxiqTqQqX0u+3\n", "dc665rK67qDDEeyuK2uuc+oE43M9jfNby8tb5zf2PGdk43F44gvxFW4Nyadu7qdwa5VAkobcZFXM\n", "9pN28THuNpenCK0AUMjHaflD+RvyN+dvz9+Tn8g/kZ/OH8u/nY/T8o2Ma0FpseE025Btg22zbbtt\n", "jy1hO2FL28Zst204zWZkvFIazNV6KGPjswwsvigNQbwMCZgJc5rE8akSrPp3bIuvKBLs+NuPbimG\n", "9Yf/cTK+1TnxOl/MesaJ+CKmmaqN2bJPfJqTBLjaxwSwAA8TmcXrD2zi9XNdnHIt/xldW04XBqZc\n", "yAvTLuQ/G8/nP6MLBaYjjAoL+Z0UO9MC1VNAFCT0VIEQoXg5bEarhBeSFisDJN6mcnC8uarVw/4J\n", "CyGws39Ce/uO9vbsWi1Ui3mcn5utegKJCeoisT65ybmNSYFsBU34MxLn9FOUKpSS+dxq4Nu8hu23\n", "uXehi3ydEKaK1FQYCba2X4P8HORDEJd8+acweD6NsIgPsFXhojwc4Acn91WkKuSnudPQABAvkwRG\n", "Kbu7Tz6PfNGvMQLfY50s57cwnrYEKWwBkEFIe50gm0A4ZAKOdWLE1AQACuAMTEbZKKJCrj6irxZC\n", "gPQynvIeyB+BVDhrcTSD9fAmGvpWxTEs05yPoikJnsxaipA96T16U/n4dbzfJibrIJQSJqqoHLL3\n", "PM6PIDBnK9Tlb0Pt7hGXQ3TeAZMyme+1YD+ElbEV5CbIUkhlpJQTasZbIK061kejuguAPqMkzR6q\n", "N4stNTKQWkEAW5SM5vXlAUcdjEyPgjbR/D7ICmdy3sczYGo5l6mMkEx8mVI79ZDP78D8eAfhLyhL\n", "kvym7Q0gR6+0s9tttG+FPfQgpPU/gIFyl+Mgwvmp/iZCfJJtFfEK9sCVkOJ3onPeAtkFEecuAqK0\n", "MGT5yJoFkoSY+DxVDgXpqUF9AW8PrJphLP1hiEURfKBaFB5ZhQzSd7GkvjljMt7/TcoAgRqwC+St\n", "JvREc18zLHDNB/HTFo4j0v8AIv13gRwFOQCb+S4KZEBeZQRepTdn7Z/FLnizfX87Voi1GPyvCltg\n", "+CBHC8GSrwShD0c1uI7hSxyjNGF0MWlnyxEAdZWcGkBrfBVgC6/at9izPSnFEQ91Jle7NF422Xe7\n", "siWAWetdBxFgdAC992MQB/rs39CP9dhaANIO8gxIIUgvDIJhyCzUgb205QNyv68Xtuk69OPT6MfT\n", "6Mc+JppIBpB9CPzYj67cj15shcSzn+I90FfRXK/Nz3XdAfRaFOQAkzP4SlE7zcJjsUYaRdmeDAha\n", "KxNDH7ZDDjXGmx28LToUD8smxvCMnhqh1OP1W/+w5kVHwNLuCFrX1I6P2BvmUJA5BZ3PabALP2z8\n", "yrMvzmr4yuImRbQsrxQ80WBdabSmzVZb5DH7za3ucddDpkriseT/JZ2riPvm2/mqAlU99H+q3xfT\n", "K0BLquH/yLqXvFJ8C8KOEwEI64s3Ybs/BwtYxJhO0SNYSvoMWyqne399TKvKeX1L4nFlXfpPgorL\n", "trmc+xv+GrX5/3u7QJXP2pxvlPPTkku4QSzBGjRX86jV67YmDwB2TI10aYKamKZfo/l32j1N96OX\n", "0MkRmdmmT1U8EQW7bErT+YTS9i8fZGuTMtIrcpydO/E2r1ap6pNAwEImKNzVHEDbTmSD1WDbJFc8\n", "2CAHwDa56CxFsWD9VGdAtXJZ8HSikH2w/sKhwg2FmwtVdAdbWupEaGGwbBpYneICoELOhoci8FHE\n", "mUdgbxqpvVpC5C+RGXlcQd/npOV6VGDK2pxlS5k26zwzh/jq9V3PPru8t7CiMD/fUVBWXaJZz+8c\n", "f4Hf2b55YIlKbBdVJVUz7K/Cn47++CXrD3xLP58HDKrb4BQcCjoUZlAAcVgpdw8Mv4dGn459TCMn\n", "x4tidGqGASdepH4ApxfMY8WPxNxUZpInKtPwIQXhgK+ltd6F8iXkykYZJipyJCXqp8ldSq/Vsp1a\n", "pddK2E4Jeq0M4yF1Tg+wNHEgltepX6If1K/Xb9KrEbABkbAgjYcVgo4UY4WkfSvkOKDdwI8St69E\n", "wITUaweW7RTBjU0J7e/s7l9WlpRU4l9RV9eeR7te2GIuKzOzf18+y7/f/rjPQHGJn/E3GR/w8F+X\n", "DCViPRpck2YyxAjPpI6arIiCmoTSEIJmgYQHTDyghVEFM4NxpIx+shXEEzmplbJK86dOIHSYx0gA\n", "z2pPEUW6BCRBTYWEPoKMYCKxSqkgDtkHpkhknLNL3HQiaw3G5HksOstz1nsqBnkY5B3Y4gFmwT70\n", "KIHgYFFCSZjkaP6FXA2YNSCjBMUFQeBrMMWdx6L/CQiViZ8JcgDLvB6r1UEsSVGs6fNBrhOQ7ztw\n", "hi/XrkGKM61+W3G3V1Ft4qL5Ezgy1VkgjAFpL26lwa3ewq1QA4av0mZBaB6BKafAOFMV/8vxf1RZ\n", "g7bmJ2dV1cRWhOa+WNFbGg9Uz6y3OxpjXu+Cai2/TvjOeb2uevZTTaFls6tjHc66JnvdzCpPR4PN\n", "XMKvJ96J+fa3ImZeBfceqiPfRt9wOsIGlYJUml5NBZLV7EeVAVqsPiPX7wQtYSfBzgrPgEAge+Vp\n", "aQNMlNtAEiDAoJbSTuX7E2cpnPr9H5s4lgt259OKG1JHhu88CryzZHmQgjvCJXsLVjA1uwrR8L9z\n", "avzt42fEZ+M/+x3zgJt4SdAIaa6O/w4bfkifyAIl2DLSEL4ex74jOAvTXGppjJLnqdRky+4wdcyM\n", "OgS0zzioMyON5TrFT9dwCT/yJ+itK9hbV2By+GW2qyXrHJg3Yw9+Yg8VxhE3vXwqwvfyK3hxCoht\n", "8hXhdXherYJPEIZTO40HjEeM4oBky+U/67F1D5YHXbENweorEVt3D4KWDkJqraPNgRojbDt1pOx0\n", "2aUydvlBAmcBISCotSBvgkRQGGqFB+Ch3hVeYZhL7TDuM6bwSAsedBeP1LKtpKbYgqdR3SSKNtQr\n", "0YaqYekd3HoU5BrIfpCLBAyEh6wDAfgW7xbhms1Nh4iJfeQIEvCUb6zVhvj9r8xVl7ojtZb6Ylde\n", "eYG10pQndr74SpmmtKbF21JfXVBRZHeVGkTLi/xXx/eUhWeU5RUENRpTpdfEPxne7myb4agI6vS2\n", "mlrjt2mOeBnREI5cIfc/UVViCfhcfkbajZm9HqQTJXsxOBi/E5HYNKJV0ZpJ6ieOMm5fEJDEAiXQ\n", "6vF1ebWFMlBpIAuHIPmziJIDKF+MW8txo6KCXnAeX/4aSA8Sk1ZQJVHYYslW0wZih92pr2BVgTDM\n", "OnCWQL7WqlY+xK8UPrsTX7MmPv6/+cpnhG+N/2HXgQNP8mcRq7hqYoxfInzM3llPpZpFxl3dvJXf\n", "z78bGu8QPnZ+WZa1cRsFKz/Gmbh2ISK1eFHVzyujIcGyvaSFbbcYR8rl6AQ2e5vT7G+J9nSinSm4\n", "UFivwE7UCXIcBGAs3CRgnMINyC5neMiHRTtRthPVyTUuwSTq5ViF0igCzpInS88j6i4FR8rHyPDf\n", "XrqHHUhEjSNWdlZFVb2i2ib/quIX0Go/BRMO1sM5lkoG3wu+HxQppgEhaOzPrRT1BELK6n5Eoe3U\n", "HgCj34klZmf+AcQ17Cw4AJtfK4b7PpBekDcx7xDmJWTju17DqkIwAmuxFceiEMdS0EaaDxShI1D+\n", "zoCchmYC6DUpDqUkCpJCsvaK8FqocKewfT5yNcKefzhyiv2kzrRfbr/RLiKMRkbwf1PcD0WbdLMd\n", "VBoZwzdO7myQH4N8A215H+R5kKsgrWgkmpsEwApeDS3sATmNxh0DSaFxp0BWQBO6BE3oDMgxkKNQ\n", "hy7B7HoG5AbIsfbJEAyfUlUou9hNQ6WkQIzWXOH7V8sCnZ6aOc1lvK2xy+/pDJTlVwxEm3vqTYLr\n", "mVBoVZe3pnNFizkQaCwVukyR31/S84cNtz1zmiocAXY6+61omjP+A1+gonmud2mwtqZzZSi0ssuj\n", "K3WXLR4PepfHg41Bjmo1fCZUsPWxhb8olcKodUiWxgmPEbGc0olsQGd+Gu71Usac2bj3cjAKJ7wB\n", "qdBbStZmQKdXyEcrAih0PwP1G1o3I/ZoSVgZ8xQ4XviQY2laCWHJp7XLIIgjXjaAi3yE5WWXwXe0\n", "lLaK0bpOtRGqwavwl6wDATZ48k3DfpTEewmLJvlDoiDkl+yGsiOnMUlhmD96cobdHghB78PoQZYP\n", "DdT3s9haicoA66o2It8DqRTJldUvVCvBWN8EOQuyEjUI5oNshAp9LYh6VU3Xmu4AJdUCzNQLzdea\n", "7zSjelWzpZmtIsm1qlfQ/OfR8lcoPQu6xsYCpcko7SWX8R1G4UTWfII0RKNGs0lRA8lk9XtozUto\n", "wxqqrIf4sO66ZXVCtilvMBJyF+esz5Qzmx1hrRY5FcHrbpXL4pEMsaPL3PREe21PqPIbM+bUlVZ3\n", "rmgtrCzMt+X3D744UBn2WeOh2nBVoeCa8USHx9bQVfdSnaCqifb6Wld0VInqqCg8s/Tppe0FFYHq\n", "9q7KxjYH47V3hBbuHVpfngOiCjDZHwd6LGZieZOIpOoBqUjkh2MFQTEm9otD4gZxs6hhmoZLVI6o\n", "hxOCkkbJZ+REccbKxJDVbXj6uVnCe9tlHXQxVycsZG3QcN+eNJ6qRQD6xIr+i/pP1T9X/5X6F+oP\n", "1Z+qtewBZrVH3aruVi9Tq4elz9Q5QH4ByQ2yBVdWV7MlalQZaQIqq5oXJhOqZINs8hR3EeEcp8VL\n", "jCuZ1GZ1q8ezmEyz/2P8KaHlN42/aT9zButMC+fk9/J/w6m5PH7R2xqVXlX/NqcSmb5MCv5Acok4\n", "mC2IkA1WhtyoZ9JihuCcmeZKyO2cpDOgZh2shLfA/4AuD0FWSKeMBpchaBCHUycMacMYyh4YUO0e\n", "kpZc4ZwN1+XQyO9T0rGcI9yHLGEDHaVMMjkRvA9Z3AYsxvcpWt+u8quiqj4VjiI74r6ajqr96qi6\n", "T42jajYN/Jqopg+h9Mvhd7lPle3tWr82qu3T4hw6SqXs7Tq/Lqrr0+EoXuU+gWnZDX5D1NBnwFHA\n", "EK4EhDUwc9if8vx5sIDiTwTT/jQcu0+zTY9V64tY1UT55q8Hvv/9wPhF+rmdqPrlL6sSRPENZrNv\n", "8JfZb9D6tl6lYd9AVHGqemkIdok9RLAoDskV66FBwIwBaCYq3uYEHLwTFtnjcHHrKcDtNgLc8tIc\n", "exGxPnVCl9aN6cSBlFHn0gV14rD8bWT8foK0BiJ77sNIdyhfV8NbeC8f5nt4NiRXKmUdpqXU36Hv\n", "oFFZVF5VGN/hjpquVFvUXjUSQdmVMCuzQ1qL1qsNa3u0uBn6/A71OYqme3Vh9Pkd6m6NwWLwGsLo\n", "7jt5dGWeJc+bF87ryUOdytVoxzLqZtxkGetrBI5qfR6iCepj3v+YrgZ2Mefk7lBf/+XbaqXeU3Ym\n", "AWl8UIuxzIsYy3gO5YrsRnaDzB7QgyJYgUiQcPcpvcTOyeMYg4DLjuOUPIxFZRAjkt4u+sWoiEO5\n", "AgGPHcYpefgy8UIuq7KaHYtgHGnv4KW+HqOXkmM52Njh6H0OvS1QvZiJbC2ULOwV+55ylor8ZiKP\n", "wUDcD6/Cu/gg2rgbw6sTrbolylEKd+jNLExID3M9eDPCYFfTGMDryQODXarGVXfwehbRK4bxemq8\n", "mTww5GHRw96MTQ3cAZUupOXsBAB9+SLd9EL8HvmNeC7OXuqy8Bln445I+TbIBUwZhK0MQFxsvG6S\n", "gdwAzyWloeAjAUaacEwD5SicKv4rwi0lkmGhF3RWSA4k3JOY/y7I25hbBdC9YTRCDyzHhDpFxecw\n", "SbYU4X02GrcadxkPGlVM9DusPwXEf/xB2gjwrF1FB4sYu82Cl1jMTFvOLm9md7xLyKuuC1hXL+8K\n", "96kbQ7VdTDv+kcllLRhcOX6RFxc/pauJx24jtjAptPDttG5puZ8CGWCTUqExCex9xo2FTHJMuC0D\n", "budAtqcib/8/ALfl9PaUXCeErsrWDWFXqTJydOyjNT/YcqfCckcORQ1b9DROakhaxutWs39HZj33\n", "9Pjbs54HcPf27exberlzvI/8kW74I3nCQlRnsl7MTsysTnT9FLekb3yC589la6OxscAdEI6QzXIX\n", "U+ySscL+QuHfMVMWTzVT4u86xVQpbUaK+VDxBohiu5VaOlKsGEKiPjBpNlFGjFJTJwljo5At7UBV\n", "HdZn2SwFRD1kPzwwxUo4zSRIMRuz2Dt9QTEbL7CRruHmUMTGblRWQwqlINdwSMbU/Wq51sPExMRH\n", "7MyCKdc8za4pTR5SHcfp/SqsOrfVcpzJxFV2Rh7FmcjnPsfObYkV7Vbh9HOqK6pbqgmVdiBZpHKq\n", "hGH2B8shy3HLOcsVyy3LhAV/sDgteDK71x127TtTnruJ7ZekOK1R69KKrI3afm22HoUw8U8Txuy3\n", "cnJ/kbCwb2Xpt0z9VnmT30U9/Lgvl7DQJJc2u/CVqjZA+N0NmTOGvPaxKszw7FealhNKlh2mp9KX\n", "UT7V+mzNvuxXgm3HKAvwPWXLy4QBLhUvW1n2Qpk4MO3zKbWai7P6kC/3Mf+XqDPpbBWFqi7BGmkp\n", "t+W+7IMUL6hKKqqLBe+X5wxNzV4D8WXwsY8YHzPwf87YUPKQ7rhOGBjRqqmuH1u/RbDBFkyBHhCC\n", "FLDRwgbyR9h9F+RrWOeZ2FjCZJ6UWwgJcwXGYJdBAgpj7swD+SlqygHpcruACZ0QTghpYQxJ9zoS\n", "294C/8cikPxAfRMRd3+MA7+vppov0tcgRH5BGaWiyqRyq0KqucgoHSIg1IdLv0gih+D4JArYCXJi\n", "anKt+Aq2qXLyXqwkP8RRVPlRshLJE66wZeLRyudTKuY9VNaHh2E6eZH7BCEAq7FwWECACM36joIB\n", "1uJJlBi7EYRKRB/Bg7O6OJV0NoNo5Auu51ArCa3BA6mpVINiIaZISKt2+xAx/8Y/PHuDF9b8tquL\n", "5//+wvidO+wjKjGNhC8SZ+2XtiFJF1VVBLLjUkxjEmWXhN8V1fiw8pmLapTvP6krfItgZMArJZ7K\n", "3MT0dfxMfj6/GhLxv+HBwNHB5P0u/0P+Z3ySf49/n/8Y2oxAPipoC2oV0xaoElwO/5KfUkhOQYli\n", "qoKsIyRPaS4yhs6r1WZPq0dYOP4U0xQEfpy/d+ZMO1MX5DZ+h+JE1FwDJvWUYBBFNdBmuCynl8vV\n", "3SZhwgOzWJWwsH28gx//zgft2dpb3E326nnceXavJByEcoxoLlkii1lDKRrSZlhTYrC67YauOoaU\n", "gaGCDQUYX3xASZeYNsqUOnWxoun1b5iqpYfUg2OsQ1EAK4mKWEjAPa47p7uiu6Wb0KkHUkU6lMti\n", "assm3TbdbiY7ZwvSsMFJGfi8XBRXowXucLY8VK4wlCli1rLlX9saYR/5iSe62P/5s0v7nhr/z/zs\n", "p/qe5NezPpjLcaLAj3Ez+PcTMwLS8Rn8wEi9msybMxByRFUBpW0gt0FcjBGOuFDJlyK/LewEKObb\n", "QG6DuCzsBDMbjojJkzYgsa+zkfXZOWwNgmwDKcKxTmy5sDXWqAxUPesyvTIxi9lOsWFqZyo7SsUJ\n", "Sa2XbYHq8xjwaojk/wTOUlhM1j91IZsU7xd+XIjg9DQqNRcbRxzCA8aTRzyyjEXpHCl83Esw5MRz\n", "iJKXc4iScdglKL6BylceRFTDLvtBRDXEYcq+BBIFiSPEVFc+WT38OkyOB5HXtKvmYA0iWWohA49O\n", "ZlRK5/HYHghvF4quAfmUguDDeGYvyBt45k7ImK1ZuNAB6QLIVTzsAuGqg2iB1XINz/svCJXYWcMP\n", "mFq8qGcqO5yyYAxTJcIpsqEo9Aq2ZXWm+lp3fumKAJMRm+d5mp2F7EdT3+jp4l90tDh6/XU6s7ey\n", "oYUExuLehRXB2VX3sZGVHGFf/hdhJTch/FfGp4yEy5Itr0KCCpuEE+P/yhcKK8OyfYIvZvN5EbKt\n", "p8tnFCwGDZN9Ipq5xAmK27GuTZTz/8hkmXLuH6R8DvI5R7khAK7KCed55BCWLpbIDnZHWkqjZxIg\n", "VBZpe+U0ed0w1VGumTr+lB3yDOtkr7la9tvkpaUSG029DAYHcHQkh40Y/bdhPf2vIH/moKrTjr9y\n", "/MLxoeNTB1WlTh7VndFRFWX7Eftp+yX7dbsahcHesh+zn7V/YL/JdpkQn4W3hG3UYs1mr/kgyEfi\n", "lS1eSxc+Gon03f4u/v3xL5cvsDXOrb89/ieOkGNhictWWPG5bAf6Lve8YOHvM+1eQ3UG5fJgV3Jl\n", "hQkWpx8LlVxXULok17cCE2Ta22QJP0MmoUtTSTxpiGwuiN5PQqQShlOIDXFxTC7LwjxzsNGgwt3E\n", "lOp1Mk9FATsNlw2rnQmB42mQXkgVVMQyDgVuFqnYIGQ2uQurTi+MIndhLlhO1o4VWI/bFCuNtBB3\n", "mIeLI7huFVbYz3Bdt2JMkeYzXYqfgvHML/pJ/e7d9T/ZXbd7dx2/enfdnt3Y372njvpuLvRBxiMr\n", "uNtSAbCxDtkpBX7ERksFlQ5ECk0h9EEl218u1rvd+Vi+RgvwwyNOUunhSExeUF2DUH0SnZCESaAQ\n", "xi4lMOM0mFs3lMGUQVELT2GrGwYh9IjkA9mZNQGzLWgYG0HeAHkL5LQZn+4U7jWKi7fgbArgJ9f4\n", "LpBRdo7JYjE/RpFkW77XBf5hbZKtJO+bPKZHFEr+q6aZjmzeBOvLBxT7PYP/O8lXwXpzM8LcYiB7\n", "EPzok71LnWyiQmRG0LfPmKjLSPY6trKUig+kg6V0GhAJBhG8sZuRkRliNiOKKnrkP7RMJKrZnGUL\n", "pa2+mny1TBq2HbcxabiIHTTbcDCJYu3CZNkgCnZbgbVhBUYPBUmvKFB6cSWm+laQI3AUIIIgqbVY\n", "mboh3QOnvo+ZfwZM+gzGwWkoFDdc9xHWdj8XFHgBfpWT8IBeALkKH9AoyH4Qqkl2EtV49vlTfnbh\n", "NThfLoKcnsErlX9WaZV2vYZ2LSfPEzEjeHYc8Oxcxrp8H8QO8z5hlFEjLzumtXQULT2PuMU7IARD\n", "9gntosWfocUX0eJRNPYayAEUJzvgP+IXHsl61PoeSp8o1WhFN5+01s10u2fWWZXfuFActTUumVlV\n", "3bG0uXlpR7XbcXwZ/3l1W63VWttWXd3mt1j8bX8u5OdXzewPNvXPdLlm9jfNWlk/fga6LM1NwsXd\n", "mcXFRf6BFdAbWfyN/llgEsFmpXaYwLkZ0ZNtw8l/F/HAKKmd7HcOISvsNrY5p9GJoO0MLRWI2s3P\n", "SBuwshSwQ+hsrrKAUM4J1+cWem83wH2M7DTMIr7MCCYqGKlKy0Z8qBdAxALA2kkqZ372aia1avMp\n", "MFcn/1CZcuTDMZETCT158uFC+cIiumHCCHglaYJ9cAQjOTJkfJJKih00uDOIJygNSGbalyyOYvzY\n", "5Z9yuWUV1P7H5BAqQE4SR08EeGonJHe5AYlCtlsoA6LdzpYpqGCbFWTkw56WRGcdZRHnUZahkbZL\n", "6LiZzrFQWXl7GlHxZbDehCJuLdz9+BfS0j+zm/658Zf//T3L955e84eWF1+qmF3xPfZv9bOWwbWV\n", "syu/VzmbL/npP7b/tP199h/7uXDhQi4/S6gi37WPf13OI3bJecTEXVzZmogGbMPXugSE0BYGQTpB\n", "xkA4v+K/oxRjw0Muu4RbFgbsOUAFGb1YioN9RKEKTgcwjmh7H8UxDhf0FEzCGcs4xsm2kjjwnGQQ\n", "YxkjYTiZsowCpS/nrEumrKPIb7qDQDoNJTyVnQFCEjAHJT3Ca+X8KxlpUA/JNFrRV8FuFXX2OZGe\n", "5TpDXAkTnSkl7EDVmSqFTemr8AjPqAePwIzXIB4k5R1FpPIdxNhqkJ8U9vX44NprE+OTpeSTkYJe\n", "+MnDCuLJw8kijyRGX1bCXJWw1ziy75UQWWTjP5yC70MErBIJy36VnCShimxGf5bNsRphY8IkDYJb\n", "7a49VAuTlZ8fnpJPNe38p+l8F50vLanlh1Mn6tP1Y/XigGSsJ0tX/dT8J3btsdy1z9G1FukQrnUh\n", "5vgQ8npcM3k59wl1AP+A6gBWcgvFvdKCWcDpQL2aACrXUCGbBCOJBbIbOm/WAky7vIB0Ow81H1QU\n", "azHLOGJmWwvYGphGyS+2OjblEZ84jRjmuXkI2E/GFvUDAOjKYkUGibFBG1NGcA/b6VF2wmwnrAi6\n", "jWynETs9MnSIs6cxW9EBzFFiXHOYSnzGyKCFMoVQqBpJoZLq5JPrAtIhpKA1hZGElbzSdKuJNWVx\n", "EzwJ1MRYGM1divyluXPZEErPHZs7ZfWVC9phDq3BAncKxAcRcA3442mwYAqAIXyxA1Cg+kDOgBwD\n", "oUo3vfBu78PU2A8dqg9z4ihIH3AsD5YfxcT4BSbGAegFbcgFPFpxBqEiJ3Oe5RQ8y5HqXvib12AR\n", "7IU2t7F2ay2CMGov196oZSNjJ5gFFXk6C/IhyK/RA/8AMgo5ZS8izVMgd0FsAbjxQM4gsUrbhoAQ\n", "gAreo4KCR6Kno5ei16P3ouqB5JHZp2cDwQfJV/rZ7MTTiKc5CnIfRI9om/tICrkDtP6VqNNwMf5J\n", "PFcgEEpuEv5GNuOPFJzGvDyYrWE+TF2XOlh4tPBMoZiF8jkAEkf3HQDZiz7sAdmLjiR1cz/IKZCT\n", "6DwkUlJfSRGQk0pPST/CtDtfexXTjqSbH6JvroKM5iSaS+ilX9Tjq8w4iuoGX1ChC2Cd3Ef9QXvA\n", "H2Cy1Sp01yl0132qWRBB76HP7Oi9Y9j6AsSA3XsoOniUkdTZ6AfRm1H2bnfQgZrZ4GEdo8iuu4Pe\n", "06D37uZ6bzmKG0S6ETMRvxafItpoH2ZgD5cdnAouMllrUKxVag3GLXUdtTWzZ9hsM2bX1HbUWeLT\n", "6g1Gf6+8tKmlxRJe0VFdE1vRHH2xquqpzulVBms880KVCgesDM0tnVZoMFxRa89X+GFTWygsVxjk\n", "ucoJH/crTsNZuVlvF6t1qvpYGaL2vMVAZ1levKb45eLXimUEq9HiAva9iq8Ww7AlBhDaZhULSFOb\n", "khIbCWWrL4QjvyoO2ktc9iKjw1UU9NRWlhaWGd4pNuVbnSazz+3M90QqzGV5eY/ltZuIXxopADvF\n", "1RvrXfWiUl8aFv9nCFPv/4e98xBB5vEADVeR9q3KSAHoeeeYkpSSEfNEUvbVaW4yzDR/qsWXfG8a\n", "2VhGPxT8xlNJuOT74sciqky9qdqvOqw6pVKxyQMsYdLCku+rPmZqWVKlKlWxgfg5Du1Q7YOmNqqi\n", "0t2AtOSfiW9qSMaEP9gQ/iFhyPkmxsQy4WPG7T2cX/gEUUNOF2P5Vpg3gE+b3GNNsAUc0erZ0Ak4\n", "zYrSiSKgwmK7Qg5lZ9JSgJTKhMuYcGdiBYNuGYJ5t/uQWzOQvOWecAv0x5q0VKTkDyMgz5eRzkG9\n", "upVTtIagaNVm8Ed/RtpU/9jw7VyIUlYMThVVOisDleIwfKAISJWWo/2jwgWUDNDDF98jLBdUwwpE\n", "0MfCZ4JsBCjJIFYDK1iKyzPmufLEYamwhJMFSlQRcmakGIJmKXK2ykNLWTX9MH0OJxAIhoyYmfDT\n", "J7uBxaEPFosD0JR3gXwKYkPaGCG/DUu1sG18Con8KtQ0NSq79GBrBchdEKr8c818x4yX0JgtZq85\n", "bFYNSyuoNhDkLC0UpjYIO69SgVSQdci13uU96MUa4L3sveFl3GUVen0+SBt6eQvIEZB1AKna5Tvo\n", "w9m+y74bgMldhRyv5WCIr9XCrZuqHa29UHutVjWAo8NSL/70Sk4dvAc2qqu11bLX6vYj1T3lH/Vf\n", "8F/z4wJkWvf6VyDT+hX/637w/ecxdK+il3rRS/up/DzIVaj9UVhDHCDzQerQUVcReXW19HNEVU72\n", "khadRslxFjOyn81rESJIMfNaqJc+kKu5EDL0VlVVayQ8CfU6Ge+u1YY88kwReSsvlo1/+PNSb6G5\n", "vKAqoGszLAqXN3utRkd18Xc++vJw+5MVL4WfpJjU6M9KAxX5lmJ9lVXf1FJYVldmq6txGV/6lP/q\n", "XO+qL8NKzKqKi7H5JlBsayFn5uz8Fyg9rkVYUJERBsVsgAlT55YgknZJvuzagh8iheLPAYGNbznQ\n", "V2t8TJAv4owIbZbQkqRDRih9wFBJ3jJNmNgQKhg0rTdtMm0z7TYdMmnoj6VpaT16ZjNIP+seQKFY\n", "2aTEenprOn4bU94sBGmzKZfHQ2APyqQkMxImZSF7g0L2BgEQrlCPGTMXippWX5gFlc6GlKTgZw2o\n", "2HtNDzGW0TglF4zNMZBiM2VllNAPqv+Zs6XiYfdj2pqd5l0bKrm8atkCNeQI3mgdDuyyHLRgcFtQ\n", "xRyDm+YMXutVkCMg65BWuct60IoTrZetN6w4EWmCyyFUvGajWWAbtV2wXbNhUOfSKF6xKSLcPZje\n", "dTYbkqVfQyZmyj4KM/w12DOWI7oW+TTSRSTVuLXZgGh3qymknhx2whvCljeAp3/i7b5xz5Rhxn/1\n", "cvgrX+ngC7Y8NK54LsxXcf8knGVr0atw9mQRPuVVKAl/tjDZz2wMZAFc4fLWZJekFAKRlqsZ5+vM\n", "VYKcXKAyKA3H+B+IQHZRyQUWK9I2rVIm+Q3+iRrMV1ETSdd18gd4j5DmCrgm7n2p1iTWJzEI4btG\n", "Ro0pFzYnpWvlLCgHY8YOOdbElC0sB4CkhrS0CSiLh0KPwGqx4WZzF8q2M9balBzbICKuIaHLpOC8\n", "Wq+TgULL2V/L+8uHqBicfI0zgPNkrIbGQgTKJj9ovAlgcMA/Qmu+WPkJ0rR2IJMoeb3yHnY+gA0H\n", "qQgmkrlkU7h2sq5zy1TmQtXuUeHpYkFdbYXH4nAa1c+UeitKSmrnNltiZTNKXI7ZLk9TRZ4ohEW+\n", "sJlNdX1pSWlJscNZ8LrB7DRbPY5CXdRY6LEbTWWu/K3FVQU1pZZs//4+698izs2NSUZgvfTDsHoC\n", "60p/lgMoHs7dsMSsl0FfAAg9AX3lEFTnTbksKcJykcHKUoiyGALsqpMAqvJYX+YN5q3Po9iu5AHh\n", "CIwJZwh7LOdhHoU1nYBb3sllQ1HU9yjs+e/AoLsPBKbd5NGCM5D2oSNlyx8ezd2NfNAH6XK6qFBB\n", "L1MKaz2ionuLyryWhra2Bou3rKjdVj+rxj2r/v+y9ybgbVVn/vA9V6styZKszZYX2ZYsyUss2Yol\n", "WzKxvMXOQhYSHCclk/wLZGEZyAwkAdqGYUqWzrSkLc3CAGHakm06g3yjOEthyMyQhbRT3CkJCbhN\n", "uiQkYWhoSymlwf6f33uvZDsLMDPf9z3P9zxTmp+vjq7OOfe9Z3vPed/fW8D/en38r5hw+Iotieqq\n", "uKXIZy9rBFdZ4xjOMpUQHPmVWMXeE4r4eiisekxSWVU1KasyuqJdLoJdfCuHpDnsTrpnuRe773c/\n", "6t7o1i3EVtt/QHs7y2HguaJU0aEi1UKZyEoSirClJkeGeBOgRVcyGLFflv6W4XkDl8E6LEBihm7D\n", "PAP4rEEwsxJwwgCLYsMruCfPRJtmr0OH/Dmg0G0iBv7CUU/mJgwxxfKND0MBegZAeuRBwIZi8OzL\n", "1uKV8m3kUbO9EtxglWexm+KXa/ak/7vYSlmJNcXjWFNI/n/lCekf+3/uJ5PX/jqeSZhuln4KFo5f\n", "AyhI9hYK1gVX5TWARYCzAKEhs2fl5C3NmVHys54oghOeKNJpiOnCqKz0TjrpbzL0GPoMywx8BL4A\n", "6ayHdAYMR7h0ZEN4KY/ulM5BPD8hGckZzoNcKDKiTCCKqcw9mHKHYFcD0nO9pb9KvCIVlxJdwlNQ\n", "wlcXry8e5SCvpG/S36p8HjL6JYQ2CPBX0fbnWkjoDf/bEBkFq9+OhL3+w0igEPZhOYOfht8Fm/JW\n", "SGhnWB5iGoUu8DpQVO8BjIZHsyRIH6AfTNZidaNdquU/jOG6z74M7KT77cewIKIwgB9g+omVdZfB\n", "3aJsBzbOTsAcfVP5duyZEa/RFuj6u6DKKjEbt0CV3QXH/dO1F3lCemK4M4ywY10Q+wcZyoQ0Qs/w\n", "2ykA0TFAD86u/oirZlz1YP+jGQCXl/Q8+1LU6yjWaORmgrlRairLOtCnN9fsAC3qZJQfIzd3wAVA\n", "F7hDYxxYhpFFoUDN+rC7dApBritjkTQxwN4u8mBLLjyztKOsvbgU23KhWWXtZRsndGLfrqLU2VSB\n", "jbsK9lXPnHpyTy/o9HSWzQnjuqiw0zM3AOW1s64i346LtnF7cN/L6oU/Jr2wSGqFmr+Iw4AlVhYL\n", "x1TYy28Z3cvvGT4rJmift441fXp8u1Y8NsW3G2VQLaNIdxNC17opjuMx/+T4diewEjoP2Av4VwAF\n", "tTsIqJWD3R2vfbNW/G+FuJOJTcG0nIly14QNmilXR7mTw9tJkz3Y4aAYd8QtIe3H9sp+6HkU606K\n", "0clVJvHa0HeOa0LfWf8Hoe+Y9Rqi1OFvZOIOPSYyruObhT+DY/AsdMmNZOE/lH6CbYO3/ExS+YkL\n", "sV8tUyIa+JeGbWTZpfCmZl3uiGsG1pbgRdPmkbmRlq+eNOQ3apWJhyIRkbV/ob3u5pjn4bve/ZLK\n", "eOV9dhAV/jzitkRHFgtXxLOCVbiA8w64pafDeUmYkOQOkY26bLLeiivYreMQuFlgZOSpkR0FDUPE\n", "oWoNpQy0aj4HW3bzSraWbWLbmRzCSqe4HDxPihpgE/GlcCVaJAruFaDg5t9jCQGHrvSA/giaxmR9\n", "L5Tb53PAEZizNmcT3NBzBnKO5JzMOZ+j5jfk9ObwG87T/G981Qh1cBW2T7qR33msErqh8L2OJziX\n", "mw0eD1dL8DJdKauvsFrLwp7GjqlTesR/jiy+/a5Jk5Yt/rOJwT+78PADlz5P707P5fQjktN/ZORE\n", "h0PSWcCjeXLc4ykY5MICxQ4h6QhQQaQpXILEEztE7knwEuCi4gKDS8YGtpXtYqqF6VfZaTSB+RDT\n", "aJQnihc9H8vj3coR6AppK4Q0H6rsbrLofyhnQ87WnF1cGgOv5pzOuZijIj4Dng2e/iIkM2A8At/w\n", "XhDGDFiOWCClt5H/BX6La5IK+ivcUXF0qR8nkS9dRyAawT/yc1WR+Eu+ynEJNUKrMEdsk7nNCipA\n", "5Y1QpzMBjwKSGKzvB7Cp5D+sWPRJScD9TBYeSIikXkgQc4US1uhRPHQKMAhYLNJ5XLpAFQRf/lS0\n", "m17AWhWZrUMPBK9EqsKCZfwIvRyZWS1Vy79CPKKpYOuURuDYNwuBWM/cmlmrzuQda2ZG+yQ7Vzom\n", "oPjQM+G+gRgKJbTJdH9mfymVM0REhEi38WyhhfB763lqvXzZxRVc7LLO7EL8An5LQrb4P4LnPa/M\n", "iHyKE5bC9nIzEt4AyL4OOYLs7aBeIT1E7YF8dg4wtJaLiAuHmFjpPnEZ1s50+LqVXEZGQ8zLJqJH\n", "AOdpPMxy3MBJgpegkv0k1CvS67Vb+IogvdawiY836XWWzeA9XGfdjCO6Dc6tTnwX2RTBn4mbJuK7\n", "5s3N+BTfFMctk7ZOAtX5Bu1WZLPBsPXabNY6NyGbr9Q9hZhDa5s30e8nbeI/dAWYy/Zp52af8v3p\n", "iVy77bR5qgsKqj22zN+WIjkGXFHm73DoU2/xFIlvF338VmG1x2r1VBdm/lYmQ0VFIdxCf9n8T7mB\n", "jx3ERUOca4v+65FIpMuwvbzPtAanpSnTIfxJmmaZxLHGrjLjzHi6mX+5mv+MxrFbmVr4F3Y/r0vP\n", "aF2SOZny1aOlp89oL+MtnjFdRpnjaiDNInMoGFeNN8jPFsrimVJ1QiEfK16jsQJaZUjoEGYKt4t7\n", "pFkLePnhOAfSM7fh8JAtiCsDBLkDnUGTNzMMn0PpoNCERe08SG+tkI18Njo6PCqPDtK0zIggPQG1\n", "tRVwH2CjosAqo8SAoLaoy9Rcd4cSC02M/0JRZ68JyhhGYFbpPR9+5rP4ynw8LU7GOiOgOzRXe6pD\n", "1TyrjbN4BrMsqU5+cydu7rR0lnXymxdYUlP5zVNx81TP1NBUlHsnyr0zMwAt4i9zUWYAauQfGkcH\n", "oEWZAajRkmodkja2wjCIlxFAGQFLoCyAyJGD+HoCL2YCipngmRCawJNNlOwYTLVaEIyJZ9XNf9mN\n", "X3Zbusu6+S087VY+4fOxMHUz//nN+PnNnptDN8uOV0sg9PEj1lVDlZSDoXs1Xtjy6w5UU/BCKYIf\n", "TunSiMMrXme0moK57pOHLENmyJqi0qwY2K09qD3OG+zA8/q9+sPwuXveuNd42MgvducdzDuehwv/\n", "Qf9xP74K7g0eDuKidm/t4Vp8VXew7ngdLiYfnHx8Mr7q2dtzuAcX0/dOPzwdX804OOP4DBWNUMSc\n", "mjkOumr00XzCd5/0uy9i1GILmqurm/EvWlDVVFbWVFWQ+Tt8z42/+u4Nv5JHsCPV8Xg1/pU1YaRr\n", "KvM0YbBq8twgnW24wReKj21YnC7W8fFjuqTC+DGi+Ehe14y8lYYJAd597yn3qYcUN1vi+JetJmX2\n", "fJk5vzHC7v75z1v4/9nNwJ8LCmciyo3QGLJEMiBSGxH5YzlKfrEGMtek5TCYFA2wy5FareQpa+Dl\n", "kw/USHbRkRRld1kNsb/o5AMb/Mo4BMwb5INpuaPcyuvjUOpG/rxUs5/f08KWPv10y+bNVLcg18uK\n", "FL1M8+nxLJI41yWVDPEsKAqSopc5QjcIbpH5kAlu8ZmCWRB19oAc0GIs9UMmjgXiDN0onIUcYiIT\n", "zgJnpWKW8GEKAlookSyaoXwpQSwQtSLd7JviE1dcG4zCek0wisb/fjCKj19jf3698OL8XYRGPmID\n", "4iBvnxPYc/IM99zoRCuHJzPI5G9PaLdpNTLt/sDL2te0Z/gYorDuG0MDZ4yXjSN8DEmbjR6juKLf\n", "pKbVvJ+PjdiHMfs9fp4KyxQ/toGlVmzwnCm+jA2eJ4q38T/9Raor0n2hzNhOZB/X54lDcylgV6Si\n", "cjKVKyItClQ3GW4bInMkCsdXYaEwH1Q379hGzyZwLCE9hXOHO7EttQlgB/PNEfdJ93k3NKal7lXu\n", "de7Nbt48tsOw8XEoxEuyLPAna87XQCcgthsHeBO0AKK5OUzRHlDw24BlKGw94CHAFpx0rC/cgs3C\n", "ZZhBTyF23Qb3VpBGPoyEHZgzl1Wvrl4PfvchFHeq5gIvrnIcOx5vGmqiJ9DqAlmNXO1gtZk1RUFP\n", "oa/aW9A2MdKRM03rbewMBCdHSgp81b6CLJfenKIJAV9VXWkk2VKfE5hU43TVtvPBrKYi0OBD+6gd\n", "sbA9xLE3gQ2TPTeZ/KUvCyNYfZuxNwV6dn6NOOpZhnZyB5UsWi5TmXJvTFtJ5mQ4cNUZDtwxzeW9\n", "DLP1mMYSRmN5tHgjGoscP4Eay8wQux45H7WcseR8snlmptEYy0cbjQNnWw4i6cdL25eNPEhBB4mw\n", "cjNe2uN4aUtcK2FOt2nMCwThp/QIgF7lesB+wFa81Ffdp/FSwakkXUIqfD2knWhOu3FsuwsGvHjR\n", "2INH0yJLlw2AS/Qxs1soXaTtmQLU1o3ankI7I6LSTajeOjTl11HCYcASwFrAAOA8YPP48unYeDus\n", "a17PNuztaGmrqtehOm8j4QSK3g7A0Die4NCRp1HmZld2pFI3Doy2PVZwo8Y3yoY4p7iWt75QybWt\n", "r75SHp+e4auhuxRf41tT6pC0EcYVZ9XvwbjifrWsCcvHbUNyOF716JHWYqjzZ3MyjYSchIzyAlGt\n", "xDCXp9IA/8fqWlq+3tIivvLOO+/IZS8aeYDtpFiCOuGv5WiC14sZSCzEcEwZSGkOaQY1/Es1RUnv\n", "1/E2+lxONpZglrGYQpUjCGEP68NKb1x0Qv6NpknTo+lDmPEPEX1PrynQBDWqFYhBiH/f7uiYfQfF\n", "IkRNeT25jHYqMtrCnzKNo0VoIurLathYDFHUdmISkV5QgbBKRQHbidmNJvMXdDxVy2ubhMSeu5HE\n", "tIrEeBVVMOfsU6GKcK3Xq7DDQJXXwcKzT4dvEIBPryvQBXWqFSyi42LWedmdSu0zgh5f/+e4qAZe\n", "Fl8Tz4iqhf9tgdNLp9c/hnpOPkv9n74E21UvgZ1W2gsTmthp4Yf0HLeDgRQRVfhAda3saRMzDbd2\n", "6KbkSS0JmsyxDJnWoK7i0CeK2saFuUGW47iyV/KnJb/1NCwWwMYqXsYq5gXxZcUh/3pxL1ElOfgl\n", "akL+oteI7hMlBrk8IsuDZDHygPBD6js9qM/LIrth0TPHRdu8cQkupYS/xfPewZ/3OXreEGQNV3ox\n", "OwZIT1Dvzzq4ZkVKbma8r99B/Rz1nMbhVr4WdQnbU65Qv1N2b3RZYMx/CPYcZzC4m2E8AM8e6dHC\n", "cRSq1/U/pIM1nKVpDXQWdh5T4U+0tF7utzCZvxBbkk1opR9gFNeCZJqMK5vpow2mxJNxT6OyIbsw\n", "3ZjfxZeTiteeQn5HWztW70wVaxN17sp6T7HDZCr0R33WdtbuSUbm2bzFVm2bpmTCxILhDwX1uLil\n", "E4V2VSNFLpUDlsqRSrNRTJUApv+1yKXtQ+nF7fcjBoGlnd+WaucVD7cn23kTf49fp9qG5LBDwUFE\n", "Gq8bkmbV8U/NPLWZ/61D6PPUpJA0axJbAa19BLENZrYuasX6opWntfC0Fn7nJEvqpiEpBnPXXtht\n", "ngWEYTG8uAM/6VzUCUaETixPOl/ozOz+/A/CnBZiGzS9JvpElDc0rwVPchYWocloG9YTyRCM5qKW\n", "VIT/EMEphYglUhZR8TVhs7yf2jKIIEqTiL4GvvE3DG6qUTlU8ib/1cFNodcrFvTXi2yaq3PfMLIp\n", "+IPSOfpCHA40URDTa4Ob3iCuaRpxTUUloKnG6rg2oClI7saHMU3H8ruh/NwwkOl5QB/Oby+SyxDO\n", "8jpgntsIOAfoBdyKXa5zgCigG9AFQrlzgCigN4HFEeSXYbuTHSmkGB68RzFl5rqWdcqo74QShhT1\n", "oTCk52JKsenupnlNXHxN8Z54X5w/zgUU2YSCLgCmJD5DQNHsl3zOozWTDgYoDu+nhxJlwanO6nKb\n", "tdhrXdjy7Iyp7eEvtK28ueVTA4guUeUVu51Feepooi0e1fzzgQM0txaINcIp8SJ4L9gjktGJ9bvs\n", "BUu80ljgbuQrSJzGa8EZZg0V0C6AtAjqTAjkcJetIzhUNON6m/UFfg1jC7g0pVuLZsKfJFnEe6Zq\n", "CLYaORRSj85fQKIj9eLUZX6GlCppiuV1583LW5q3Km9dnnYh/2zuNs8zLzWvMq8z43OTrcfWZ1tm\n", "W21bb6PP9h47ztpX29fb6XNBT0FfwbKC1QXrC+hzIbiSlxXC+oLyK+kumVeytGRVyboSfI6WTi7t\n", "LV1SivBeWt5K6LSoj2qGk6F5qNk8qllTXk9eX96yvNV566lmTeYec595mXm1ef11axYr7C6cV7i0\n", "cFXhuuuWjLCo80qXlq4qXcdLtn3CblbaW1joxT+fuchrs1cUmc1FFXabt8gsfqWwoqIQ/+xed16e\n", "22u3ewvN5kIvrTfKR95nf8PnrnqxWzIjIix5KyEYLLmwgEpWr+YLIjNFh5XN9aRFINQ2W/rLuHJl\n", "tqTqB1P1ISkJy5BWmHediVCQ8ch9kTWRJyJqZdgkr4/M9EYhJMhUpM6ueIHBPg2H6jhXNciphpBU\n", "YK9THCoRzkTE/NBfJF7BfpFvSHrfJx/r+LEN+n3olEPCf0KPBI9X0vAQkw/6DjCNfLKX/gF7i8GE\n", "1bQOWy0P5j2ex/8M5B3hf6RfocmewPi0z3oUrRXBFtOnnBeg7VPIhp8U/BIhG45kwtZK57L60UnA\n", "G3BM2AnoqcCRIa4uUlzZQA9iBFzCAVYTzCNexy7U24BGuKycphhw4I7hQ+Q+TJCrAafoCvXewnYi\n", "2vgxdopd4EsfaQNWKAcAYApL42g2+1jSqjw8Q95RPNSr2ILfn9X0aD+D/DUvEbjGWDjSE1CoOFR5\n", "a8UuOKRMwYO8OfoMaRgXw+kKT3EOD3AScAKxISrrG+vFFSwT+NgJw45rSKj9gUAmZo/TxZLmBp+V\n", "Ly/q6jrq2zyR9orowvJm+03V9qDHNrEyaawKFJfUTyqvn+tid5ZU6K1uW3mpwWLoaPDHvJaqhkCZ\n", "P8dWavd6csx86JpQ7otWWP11sPegdk1+AP9GvD7zFgqCXpDek900RWHSyIPsP8RBwS7MVXkkfye8\n", "pDp5G+/kDZC397OyaXt/Hr/OUcHGULLTH2wmzB1MzQ3RJmOnJTV9MDU9lH5i+rbpIrlPSVWdfuW+\n", "2sFUbSj9aO3GWhEZpyYOpiaG+hv572ot/TfxW7vpVukRxFd6B7ChGyvDenlLcjbvI7MRGHUbHJqS\n", "9bPlJUJ/DrsiVcyul23XpTX83fTb4WUsJzlCqdnkMCVVJclot1H+YWMoVW/pb+Lp3RXEKroOBT7Q\n", "LXcgcofaTFyfmO/ID35n1lP7EjYyDsIg+yAmvFdghQSzJGkTYB1gB+Aoeedga2AfIIo5cQlgAABi\n", "ivS64Gb46dA2AbZJRXlzYOD5ur11h+v4gnFLZCfOOk9FLuDPgcirCMW9C4ukJqwDd7bvx8JwPoJT\n", "3YUT3j9N5rAcJ94HAKdm4AqwG3B8Bjx+Zh6YyX9zeiZP2DULTXYOKgvQz+XNOzgXK+WlEMG3III7\n", "8PTk0v8t/ahBzEEIYT+EsB3PehJmWevKN8Ms6ygJBA9/hMNA1DfZ1+tDWEVfRgD7AFsyZvbSBsDz\n", "kMFAzRGKLE3RrEFXcgEj6G6EIT8eeRPP/ndI+D7gTkiBREGPPxXy2N1+EPJIIGEp5PEB5LEMorgI\n", "ODgVLhQzTs7gwtwxY98MGJRBDgOAHYDtkMg5COMI4A2ACmKxAyo52OCJUyq6MiYLgVidalwX1+qu\n", "39FlY4/R7v7zkgkOj8/SbnI7TNaiCmvzFo21yOfyVrv0oYo/r46FA36Pp7HT13F3Qbt1SrW9qsLh\n", "L9sQiCQm5BYVWErCrd6OBWb2VWOwzOFx5evKNPmuYrOz3G3Tuw/lOm0mZ2mpvrLK2uRsm1iXdLib\n", "aqpvqrI1JcpCwdyCQImnytJhaw03JO06W3GgKJAI2mMBrG/auJ55guuC4GB7ERxsijGOHLjENbpz\n", "/YJW3rO+rB3RGhbK/HCfKZoJDkhMXHM1HTIN8mVxvxEEN5Z+M9dcX8CEowQKuaxwtfExIC80ntWB\n", "r4zyLBQjBNqtqcnUY+ozQbvFcltvKjAFTVx/HkfTFoscz+ykTYZS/R1lx+zjF5W9hiiHN8n/aV9G\n", "3yclu5+pwFQvxTH9vAYAAYq0FYBIVZn9E67kqkPpVvVMdUY1IqKrqx2iyK6KgckCIw2ZR+oxX0eJ\n", "fnPUZInP0WBdlLRYXkG54V+Ka0VZw8GXGaJ66Q/QY/QqtoIxL8hb2JvDv5zNvMM72HfFxz7+kvhY\n", "+2gMTYpTXct+IJUEsG4dwwCRhFfho4DnruaCIBqIN2H4SNaP20cJIWaho24cRwhBHBCZhyZ2CDot\n", "GscGgWhsChuEndggpPPI+BW7PPz2UvQjsjDKMi0QycIxABGQn8J8/SGgAAvuHMAHhZmVx2GYLR+G\n", "9+x5wBuAw9CO3gD8AYDY59IpjEgfAo4DSG06DtiPEelVwMUsUzi2lgderTpddbEKZMvVfKFxtPaN\n", "WhxZ3Iq69mVDXRzNslWczPjppLVOJ9gqfl+oLCvSpzwXcHx1CpUhb3DyAP8I1TqdDb5+AZU5TUNm\n", "hp5C3mLeh33uN6rerhKvCbsec40NeCFH/rNFVn8mJojXFAKICoUQ4jpEECzG+4pm5NfsXvGkoBL+\n", "VfHPuIKGbBy1mhJEUmCkK9Cvjapirn5fvfs1jhqNJQvBOtorLBFWCmuFTcJ2YUA4IpwUzgtG3vQz\n", "rKS9oBI0gZ62ly1h6C1aPpKzfTBbewPdZQu2AYJik9gjqviaF9HE5XN93mWoXcEoI92tmscrlN6p\n", "2q+SjX5a4yzUnG8TT9jJPhYd5p9Ufyn62WOKT/sZ4QWhWXoBFtqHALPA+oKABWnEIUQjoO8WGaDe\n", "GUZg274ICa0G2XqWCXN5nlV8jeVhd+1hav1ofKKz2ahEENhZTLKz9Iv14kIlQohMqJiNE2Ifkhaj\n", "CyTt8s9KFfdLYk8yjt09g0ZRqgYPRao0JIceIoUCNhqMWCNKiVTJYVUrayWrpb9AJr5ZD7s14jm9\n", "BKqsw7YT8HA5j1n/DxTJBVU4AnDBYe0Cri5iOfAWYCfa/YNo5ofdJ3Bg83t0Sw1ObZwIjTHPvdQN\n", "ma1DKedRyjrAryhnwO8BGhwyHrGBidc+aD9r593OhsIoisz5bDlbAQc4DPS5l7lXu/ltFISjgJfE\n", "vNaIo7wxIscwkefdMUFMdu/8ePjWJYsX28O3TKqdXRqyN3nroiX6nWzm8LstLczWMi/c2xYoLou4\n", "iv3NycLZFGeKj6OTxD7BLZzewzQ2dc1ogKnMGx0TZwqmmJJFIJNLaHDb0Cjew9MJNvzAthhyPaR4\n", "DtkpIIqTXk/hoLQmE8xcID+gzG5bRm0kJhFMKYVyhBOTpV8nM2XZBrG55hykyEeWPgQNXg3VZzlg\n", "A2C+ha/yBqK5k3N7wdONm5ZZ+IITbLciAlDRqIKwvDSGkPwiXGLxdbn5hWarz6yqnGirqnDefnv7\n", "OrZl+D/d5fm6XP1N1tzicIAFWr78ZdlefKRYTIjvk13Ccq7zpl+oe7kO3HBD1zUaHzUVh13CGH+8\n", "64a1IbsE/WeyF1fMES7VsDH24LJt9hTALsB27Pptxq6fbBMubcKIvoM2u7JRHaZmQzvsgj68v+BY\n", "AXTm0iNwoSJKnyMYwrHiTx+rPoWDv4MZw2/pVTpz3IyZu4m8gshYklyDUPZTKHuLfiesIDabdkB5\n", "3YGSyHx8B4qDu55ifC4bO+yvPoYiTlcruZMB/LUG5tZPNDB313fVZAzMneHQBPunGD+I9cMbSgNO\n", "/TgL8x+hb/h533ibj3Ex8XapLKiqgX80he3p1/Ilxn0Kw8dC4uuAZxz5IWH9J8WCZRiDYiHJHaOr\n", "oKW/ii+syiz99WplaWHh79iSGeHIeRojHLNUyvZ6KYuFtEGjnGAMga8xyhNyo3zQoKiCbkY8GFWV\n", "YOVJVYWkxXweRcCsWvkM4QQcdrXYy3odqg8ZbDuxofU2rh5E34VXU3pr3i5sJ2hwxrAUb8fBO/PA\n", "EttK21qbSj5sSC+xr8Re/0+gI96KnQWdy+XiSwAKV+XikD5Rcq6Ev+rekiWgwDiBl7oSgJAL0o+z\n", "jBjnAVrsPCDqgrSK4i+gka0CXMDh/kVspbwFOAatSQ+Sx1dh6XMMmtIxMDh8OBFt7xQeUI8HfAMP\n", "eAGPdRrgxlOuxgNuwANuztuBB1ySOTpJr7Ktw0BVgCF5Nfxh9K4CPM18PN4QoADPlQMYgp31CSwl\n", "5wH6UOHVgOWA04AcPE4f6r8asBxwkQCPcyqQeaYjeBwdHucoHuc4Hof4Oz7iYItkwkmM93p2jYae\n", "GBvty/vDSk9zdWHXpAmdztay29uqpzaV28prC1SlDT67b9ItdTMeKJme350sjVa5ShvavB72ZJ6n\n", "wdvcGvSXNccKQl21JRMR0VhbHm4pr58+sahzmitSb6+c6AnGKszkD107clblVPyhk0KnyphqC0l6\n", "EABW1fPekPNprtCgLh4kJ0bM9Gqa77VDSB7jD01ESRZsTKaq5H3IikH47duG5InlBWyQtML0uz7j\n", "EFbIC8LKM1lfJW+bINg3V2eT9JHf1jCEfOI8hzhIEtpSbXyUbsPhk3QZyvRrgMWAJM6cOobwZeeQ\n", "tGZyZpzOhtsa6/t2td80+a0lyW9a/1n9pkvoUOs+NIQzAEsJ7YFaQgMzLYss92HSMls8Fq5WlhBD\n", "KihRpcK6EgrmgkEBp16tCN5baWlF+a9iPd0g59IQwglZ49CAudHTGGpUUSbtg6l2WnB1DqY6yail\n", "sYx378llvWVLynj39iPm8FyEQT1HvHIAJ0VFBZxEu+0F28DbuOoGucB56oY4fDkNuAQ4hvO1Juxf\n", "rAbsByxvw+DStqsNPtttp9sutsGPog3O3ZD9euxx7G8/hj2O5bje2r6rHbuQ7ReVbaAVUi9O7NZ2\n", "kHN3x5GOkx3nO+Dc3YHq4atVgB10Uyfd1Hmk82Tn+U7chLO97s55OOfb0YnhAk+a7i6bB8+7GK5P\n", "eS/A0K4ADzqfJIBnpEeeh0c+GRz7yANHmk42nW9SyQ873kO8UgkJM7bvakcjll/VdW1wJH921JH8\n", "4/6CqkSVp6TSHnInq4vClY6Qt67eVdVYGplmixhrq80lBeacgurykuh4X/P7KyoLKmxF5f4Sc3GV\n", "29toEPXNgZI6j6VqQmlpmdFWaDIWuczDJaO+6BWsiHXzOa2e3Su54VpyFotLC9ayKcVSmy+3bKGM\n", "Sbf0Aga41grZBYRWfRlTbqm+gjjj6kOSs56uKkAugiy4Mg2eqzTOCUT55OCq6GYe3gmwvjgDYHke\n", "edKTY9GsGJDDAKjg9gPzkzIcxeTKN+ViIkyFh2R3PCcLUyfAotnroU7oDcEd2s87gd/jD/llX+hK\n", "ayNOJWW6GpXC6HEyw+OR1tlddj78v42hfh4G/RMYX96G0noK49OlKrSfydjOCVhjsCA8RbOGvQA/\n", "+yPyIcIBygBRmdMnqs6BdpFIil6to9H9v9BAHrtxe7BPHNsexMLyiiLvp7YAmVv3pJhkbvF7Qolw\n", "STILfAQ3w6lHpuETvpCy42gPjzILuph76Npjb3s2bM6A2eAxhAw8TaPElMWXJXx8C9EulmySsgxG\n", "KQ+RU0yTukfdp16mVisu529TSBUcAs/LX5q/Kl/D74nZum3zbEttapDZ4qR2ngrM7PSVuls9T70U\n", "Pz+a+fkAwnufxwH26nwU0Zw/JX9+/vJ8NYpTDuPUC1XEQEpuqNFYRA4T6Kf3UK0yOT2u/Mr8/Aqz\n", "y6Gp4R/LnPyjtcLCP4pJm78kPy9Hb/bY7JUl+WZ9Tp7HJusBLKiCbUme4GTbUvkhSa0BFakSbZer\n", "SSFsgW0kWwjF8oyUqkfhm6iBFizNhNXGNkBZDtemFF9/RasyykTnTJknFaJwaQ2WLwiqKc0CMXH+\n", "KI+jmeLGclU6hNe3puAa9g/rEGzDNYOw53aQC52YC0164Lj4pngJJgbwdEo7xEp4D2qV77Rvai/B\n", "ccWhrdTy5IcheKP8Xdw41bjAqFqRThinwQ/uTzAWMBiLjDU8UXoYxgLfMcokEQ6q2Xt2mDzYLfYy\n", "O280FrKuMjyv2qs6rDqhOoeoVRQ2bx2gFxPoETW4bDFhoAm+qjmtuajBq0YUEdkfKmmQPRVQS/77\n", "+Ub0UURvTb9u/BUqhRRYSqu8FPgzYiMmD0QALVc91yL+TeBvxJaFf/VXCz7+zeMt69kUFmQLhrfT\n", "v6eHX2Et0eGn2JIo/Ex55/ktHzPL2FelQnAvLabVR8bcBwqrXk27ptbBlDVE72TAbPVYQ1bVin4L\n", "baj2e1RXpD956G6ZNEMYPSy9egMJ4WtBlPQ+0X7aidHjACTzvoqsaPpNXA+wUDpfOUil8h25sLt5\n", "GEvu7wOIAeMpAALLY95HjARpOdE2QIqIKsVf6ztI6KOlMxbMR7O7JG/mX4IdxDKswuiUaBVG2T8A\n", "KkG8shbrZOKOjOLjKlytxADYDObIquLmYvipH0b25wDbAUsBy1DafMBFApT7JuA4CgfttrQEBb5B\n", "myfOTNEoK73KtQ5GtmB1KS9vZPKxxTVMQeXst3yadFvK3BaHv6E4Ot0w3fyXt9TcnPAWBiNFZ9gD\n", "c5jH4gvWFpTUlVlbIvqZC1x1XXVVnS1R90+VebKc5slSdpfMt/UCOU7iGc+Ca+ezUW7NwuzWiv3Q\n", "+8oynZJCQSu2htdjx3o+G7QzhsCtMkUWefdKGqT+SpQ7/41JsTJEiOmt6l0wg72E934RGtIlizLj\n", "SYux4WSH5//vcaXB1eTMTlQaNFbiGBorhRAKnF2SX2Hv4jXJ8kPtHM8PVQijjrdR1nlo/KP0WR/g\n", "isJGUlkghkrm6BwuR8ARc6hXsE+gfmLdN+Z7YuU3InmSY5lwPR6c7x7hB1KRCe60RUR+2++WObhf\n", "GMPBncLLGgSMQG/dWD5u5ZLZrMkyKY3ttZKK2JOkl7An+wPVW4jhcUlFIVz67SIOhbj+gsXI1NwF\n", "ueKK9FTDAgMX8iraFIHxjOIPsg7tvw9dqo+vKYQ02PXQArBlsip/HW7B9km53y9zuvsp3IuybS6z\n", "vbOnxhBsG0vqKxWK7SzBNqsa/jjQUuUgiu3hb9ri7pERWU50rn5C2ScGH3Je+v6yR7FkTpYxiqtz\n", "zX2fo/sK0ovK7uP3Ddzve9S30YfgX4j6oHCdyr85mP3NHfSboPQCF/XAa2Vnyi5DFyHquRdgbGJu\n", "4DrKaw1nGi43qMbnMVruGspDJy2qyHA6IC7zX7P3R/ZynbUI7v2aEE3Jg5h2GbaWQ2Tj6Sh3lLP3\n", "h43TGmgPlMPrvH3omGaPoGbqGmXXPweNHCqt7EOHNj8gx43jwzosU9WMepxAi1S42w/IUfl4ZyS/\n", "ci3gvYzt9Gs4VwkD7sfETyT6tA54AhDCxxSuLDkZ29pxXgvZZqYWiGQf8cmko7B2364egDn3CfU5\n", "tagEXaStUqEPvPqyu7NqxWjEsz/A6gQRonkjRHQz/kenduEPFlniinKvKmLj/zHn1H+e+S3xW9PY\n", "68Mr2VcERVbiK1xWZvbkHr7s4bJS0SLSPCTdj8F7FlwQzprBusAfmeVRVbdj9UMcApsBJwC/Umzx\n", "+WJIoyZjhjcxdLwD0+etml0wfV6tWa/BuQFXzCG1RZnYjDDjRqcCAbNBRWulPAs8RGT+7EF0KMzB\n", "0hOKodpC6WVAK0zWnsOVBVdy4KxrKPUz+9ASM9G0+jqkNZ8tx1b4g7A3lqPW8Nb6CyaTWKsGJY18\n", "73fxCA/iEeZrloOPZS1tvAEoZNEvKMgMMVvzNZhRIHagJViyDBn/k2LN43qisdMo09lSeIJ5ZJIG\n", "EhcKOhiEGIib8BQmzzewiRLAhkSAi95mi8j/qWjVo7rtHvGLnV8U75nx5NQviF+Y+iR/k19mX6B/\n", "tezR4Uf5m2TUcX7BrwziT2UPHqxf008I22BtdQbL2FmCTLjAV7J78fLuA/wQQOGeLHAoFoeSprCY\n", "FGeJi0XEctKuSJoR0ek5MRPPScfnTkz/r+FZZsH15zktnH9UY8M7aIbS0Db4wLgAMYkOao6jDaiH\n", "MiSdK5KG0VBgmoWye2T6rO49GHQKENAcwJtYrCZ1oDrMBIJTLxxAyK/FOkTCGUqaERQHca3kkDm6\n", "hUlTq17mIkPAHO0KJRaO1JyjCFx2rpRm4rAMSpBk5lcDLxheNrxmUC3McG8tlG7DsdkJwzkDkX4k\n", "TRtzn8tN5crBQ7V8wpuVuzj3/txHER8SjkeSBTy6IcATeJm0LYZYQRnncATMGHPcmGmoFC0IDTUn\n", "FwFUpd9j8IgCenIQQybnIiKJxVB7J6ALX6lxpRLB8SzHlqoCgCw5jbU473URVQesi+VQHrIpgKRV\n", "5ZDujWM2tEsX2mUfbPJOCRfQSpqIjQgNwo8GgUhaA7IGp5KDmkpVcBt4A68f/EhSAQAOIFIVXteU\n", "bISOPjTvD2HP3pPTByISP8Q9GfAHyPzDXCxHTqLsVcI6lP02WigqI92KZ6HYCyexwF2lXQc+JkhD\n", "WpCDKJsRVywCS1ud9192L3jsC7d855UFz2ye+9GbL7zw5kf//u8Y3ywjFnaC94V8MYklHW/wa9Dn\n", "t7EX2Mvo84vwjPdm2UT4OEgDXNZ9u4/iZ+JqX9bD+wTgV4LiWGO2IEyUtAUrAzPGv/QTOdvwpkZo\n", "8Jcz7IMT1y4K4AP4KBtio4micljkEzmu/1EM8UuAKwAjBrZ1GWNHaRaH/nw+EDdhb/81rL7uA0Ab\n", "G7MazbQoohREKDpBm49aoM7S3vHPcSfgAcA3BHkhynVKraXfKF6RT+V+byFtY2C/cEw4hdC41Dam\n", "4BcXs27tH2JWpfmVGqEOAFd0ya7mTXev+jAmtL2aw5gGTmrOYyh1ogF9iCPWXbCBbLL04CCQgo9c\n", "yJ4GHgCcBvwRkANpLcBVDwRDUsjJh0XYL1CV1wGHAT2AQpwknNJkFstFxO6VJwudKy2AUwA9cp2S\n", "LWRB9jUdB3wfANrYGB+FZWrnGG0+xFSRD56YdcnRdpPZY9Y5SrxBc8WhObPZX38sRZOiJmmoDS5g\n", "b/J1DrVBWuf8TI6x+BBWOa02WuVkvz+Y/f4O/v1UPizaXra9Zjtju2zj2jDuTntsIRvvQUmoURww\n", "dFa+XPla5ZnKy5W4B5RynspQJe6pZATyQoqNDPN5vk58RShglj2W0Vi+g3K0JOg+96Evi/K4zVMK\n", "hmgelCknFVerxTQdk8gEixJ7IndI5gtczKE/h99kyKWgEltxUINIxOJCOURFyjQo5VlylZ/ZlOAP\n", "Y8KhG6+2N7baKa6ZNYRFvVFnV87NTEMgejDCN13SU2r6cf23cCQKPWXgsP6E/pxetTD9Hf0emCno\n", "yI/eSsTDdOYs7aMh5wRGp/McYo0Bb2NEhe0EFcJMZPzZG3+re/oL/37rv/3brT985Gndd77T850z\n", "NxujrHf4e2zu8O6o8eborl0wyxJcHL7Jx5gcdk4SsHV0H5rbZQB8nSQPb3jyglX6BgYZiqb4AOBO\n", "rEVgLSIq9lSIZ5u2Mx+WchHWwf9ItyDp71k/bIozgXIhO5nsAu9uUMoFRV2Rtobr/+kW7XRsAyxE\n", "0j9p/5mPmAOyHRzvus/gHd8D+FvAIxhVp2jnY1QFtRwqyVczulAaUxxoTPBm4eojhQGHAPcDzmDo\n", "fgJwnyEz9IyLbpt14NbLx/78DX4HY/yXhScxxr8P32G1YBd8fCUrD0m9gJWAc4BXAD8B3I57I0KH\n", "MAccoypLv8jz4++eokj+ADCELaUWzXTNbRrVijQimfNh5h3Nn/ifAYOmSFMDptWHcOcUjbx1gkUg\n", "8XDBso0vtSBjZQVdoA1CjD3aPojxdJZx75IWrcalgSUbVzcayZhtw/CvWTFffuUPX2F3sO8Ob2kJ\n", "s2UtvE9Tm6A+/4txNs25ik2zf+R9UUuxjwJsZcobklq9vP9o1FfgasQX33zeQMx3c9I8y7zYfL/5\n", "UbN2ITko9RdmDpzHbTVlQrVQUBN2heKZyKfG7ytPSZsQimXeOvI9QgdYB8BKIx3NmYxZ6yO81B4s\n", "Y5oBGwAfAXqydmMfkd8aBqGPyGsaOwwgy+ZS0zgdTv5nu3MAJEaaYkcxPhUPgM+RfG+W4MxVi/AA\n", "fdhLyQE/wq6yA2AozC1zl/G7d/kPgMGxEKpjLgKK9AWWwZg9J1CIuCKI7rWQIlpDi6MIYLK/nBRF\n", "LbuzVV0P/brXsQQE1X0oehmKno+QPr2BJTxHNsYIgWxlx5mlTRKZM95RkZNT0RHP/J3+ZxPz8yf+\n", "2XTlr/i1Sbctq65edtukzN/2yff8VSLxV/dMzvwlHculvOsw+/dUZUh6lI/K/bkqtOH0Ws0mLIdz\n", "SeeSuaUtg9JKDLFLER34pOU8ZsVbLdhYedzyLcvzlr0WNYwCQBpN21cbOZCBO6jTB9Pf8jzvEemG\n", "siF43fGLanJwDA+mwsomJdmmZFqOm39wk3vHBLfs3pGawJc07IqkkRO4zs1Vtvdg+SXoLfAnM8lf\n", "mELSIqxtKQQmIiEh5NF7FuxhWSyWMgvvrW5Lvw2GLu4J+IEzlD7kHHTKM4KH1KYKOkUOkEJfTaPz\n", "KujBWwAxLHmex7uksDHnAX/gT5s0wVgh4Iq5ul3zXHxhfw67lLfiwCZGERYBsKYZWBVeF94cxtbF\n", "Q8gwigw3WTN5YddF+hNlaHAVuWpcCdc01+eQYV8mr/TukoMwf4A/vHRnmCesDK8Fm+hmfk3eE7py\n", "XTn8fFwRnVc+lFACIwS8sQiMqmP8LwVbdLHfuLqqN/lYkXX4XRVj7+WfMs/pCXZaQ8W3R6Ozm336\n", "afZ6xlRd9ubCr/6f6nmF4l1W50CTL5hXlBeb9/nKooq6Wl/bgmgsr8Ts9zZ9aVWBRT4H+kD8UNir\n", "Wi+ohDvw9hjCZbON7Dkme9+eRSRW8khOGkYDb/P1gllFY4wqqZqlWqy6X/WoimszBgSTl1M0UAKF\n", "L/CxvAAUjHSWx0cvVcTlzf3cHQnV+o3yHk2Cl/8RlT8XtslmbHPCpZscdMdGAc+GBv+EcOBKgEiR\n", "lyd6RJQHT+OViTs+J34olzfyS/FDZuLlaYXHJC3mW8Qjh+IoDMkEJjkZE281HdZczhzWSKKGljca\n", "Yri6TAHhM/TcamLGQuhD+Yll4h5G5/xch8WZmSgHLZbux0JSVGkoDAaD9hGLMFP7nDnt984SP7zn\n", "no3j6riG4l5KazCVPcqyrFyXiddpkXifuEZ8QhwtfcwmFF+UQb/mj6OVaTbUFNkWCwteR4Y6MpnQ\n", "C3VNm1UebFHej7W3mpG2p6Fw6KQmPTfrXtSQC/Ee8Fr2igbhLTnu2R6Visn7Ppqh6/iAQ/xPNE/q\n", "Fg0HcObIb3ar7vvfM8fPcuaoUt3ozHHkHJejQbVcMPCVwkKsagWM/0mb/KI3auWdlEHtWW0OH3a1\n", "FjgvGLGGTQv5lnxxBb8z//78R/M35j+Xn8o/lD+YfzY/B83CwTuPGWt3HNTl4P2PofEIjLl+vtjl\n", "Ksa/Q5kLVdTu8djH/EP8VpVLGFHd/InxW1Wu6H811uvIOXGYP/9jgklwCnt0DBuPOoUkC/GkeAOQ\n", "Va2ILHRmUM+eNGm2ulYX9/vjOtVjrV1drQH+P9nn9VfCKdW3/9fn9f+XPq+qjhv7vIojx/g4Oovm\n", "Fp3w7ZQ2RGM9kQ2l4eMjwkwtfVZ8T6G6yEwwY2edT5hs5A3Kgfs0azRPaOhXmpmaRZr7NPxXaoWq\n", "jf9Kl9lyHNSd1dEUpcaUqHCkyL5FCHYuD5Ya/u+HfL4a3pO4E5PWRj4fCF3isPAPqjt4G22gPdkB\n", "kCi9LKhGGZSUXj4g93oVSsnJ9J4x3bYr21vrM71U5k52C3tHfnL98Zz2w/UKxQhoNZbz8fz8Afxu\n", "sThROCe+y39n38NUKvmsBDGXBZG4K/mq5nsY/N89IHPkmDl8XTzG79cK5WNCJl9z5K1BJ46wCF/Q\n", "lJtZ4VTmGf7+L9hR8djHTeLjHx/4fzYvJoR4Xv8o/lioF97YY9F41DV7nJpCjiGNwLFKo1XXpGFY\n", "IC5MFuVoC7U4LIfmu1z7kBbmB7u0B7Svak38W63FafFbopbJll7LEstKy1rLJst2CziBEQrLco6v\n", "x2GQ5BqETWKYMKLI2ccr7LsmZNJYipCUz9JvEK+kTxsuGlAVvaHAEDRkWPZXG9Ybthh2GvYbjhlM\n", "GK/g75AK8YU7b1rljZmzcVltcTlg9Z5x2FPOVR0RB5MmdIVcgc7bGhtv6wy4Ql0T/nQ4NCXijvQ9\n", "0Nb2l/Mi7oYp4cN79VWTZkyILmjzVbYtaKydOalatzd+iyk6pS/ccf/sCRNm398enj8larol/r+y\n", "/X9Vtv8bv/y/Hr+8bOQjMZ/LrFD4CsyHi2Bc3K/nMnIrhHMQmCwOM39O8zV7Ulk6H3wwW/pz4J4y\n", "iDWodVAOTtvvFK8kixDEOeCMObud85xLnauc65ybnTuc+5xHnby5nnSeB9lAgcpMekClNuOLIlsk\n", "Obz0wDGHmG8tyS8pN/P5ZzL79XRDkd1p0OfYyqtdrHp4KduaSAy/5izLzcQwGPkt28b7WrlQI/w8\n", "VRtCLIJaouHkarjsimIbgpemiz9vNl6PzdJfobmSfrPiUgV1worCiqqK5oopFfMrllc8VLGhAgwB\n", "ByperTCRpUtwUKrS2KyZmL/jPBdo7U9kRiL2cfuLSRDFruJAcay4u3he8dLiVcXrijcX7yjeV3y0\n", "GIIoPl9MKj1ifqZPV16spN5XWVAZrGyq7Knsq1xWubpyfeWWyp2V+yuPVZoWSlWUN4QGc4dGnTcQ\n", "s8r+T2RFqXj3RFwqeUXhiEbZtkR3rCcuunvt3lBReNK8uXlOt8k+wSUWTCt1ufxN8apYa9tfTKqc\n", "y1TVbRNcnS1Tn+3d5K6w6fPtXtHrDzW1/Kztr2UZ145cFutFl1AkVAgFUnEF12IqsPZUmFg9FTTz\n", "Oa4iu5MHgkAjdH7HM4ne1tv8XlcolgwkFnX6fJ2LEvFFnf4VrXPntjDV3kRzq8MXKTfXTLsjHr9z\n", "ak3VlDtv8n29peXriHtTJSwTX2RfEwJCTJgibE5NDaWmkQIw1SJHa0b/D+J9Bi8F6X0GC4NVwebg\n", "lOD84PIgoo1uDe4KHgi+GjSR+Vi7hr8jbbuz3d8ebZ/c3tu+pH1l+9r2Te3b2wfaj7RjbG0/1y4u\n", "FPY0iho+ZHvFGj7Ra8jOyauE80rVWFI3DaZuIv7kLj4mVma8ca4iJpV9dXRy/HddKf8Urcz6mKOH\n", "iy/afRPLSibW1dic1RMipWWRSrvNFykraQzV2O1VSJnotzdXVzmqAl6zxRuocvmrh4+bfVXVDlup\n", "3VAbtFcHvVc80aDL5vHb8v0euzPQ6IHjg6M8YLMFyx3OQLTCH7UVl5vySt2WhkqTp9hmLizL9zdY\n", "3R45DtbI+3yB8GMu42amTsVDqQRJOE6m+7kkYQck7LjkIAk7Ch1VjmbHFMd8x3LHQ44Njq2OXY4D\n", "jlcdXMJ8RMjnnc/SHyY5h51hfzganhzuDS8JYztoU3h7eCB8JAw5h8+FeV8gJRYKWHAwFQwJ/N+1\n", "FKfkf8072h4z3oaUryGaynLig0ifdl90Uy9yF7iD7iZ3j1v2Hlzv3uLe6d7vPuY2Ybe+v5F6Z6Or\n", "MdAYa+xunNe4tHFV47rGzY07Gvc1Hm1E72w830jGB+MW5E7XxKvsstQZx8OMW9ZRS3h+T2hqpMjd\n", "0FNX3+th1qquid6I21c2uSY8NVrpzO0qmhWuiHitVm+koibus7C7Y3+9YnrlpNm1NTPiFXV+k9tU\n", "veiWqNteU1zqiXbPmvMFX8xdG/eUttSXhnvm0Fh+50gN26TKFxoEB19b+NU1wp4y0cHbaJ2oV9eg\n", "2jSsomZOp8MqG1eT1zyNEdGJjXzk8Mttkm1yWPK4tq0z5ulUjInOhrAjYMsz8SStKU/DRJWhaILX\n", "UOgwiWetVqPZ5A7U1ZRphvVl829pdhbm5RvzjBOaI1oHu+xqaW0Jl2iMNuiqH45Usw94HfXYwdcJ\n", "GB00XpUuELPZIszX/t26gjuefan1JJvLCxxOq57EcxWOVIvt/DcGwUFcd/rQnhwRyyWNqMVzuRoZ\n", "a4TVEit3FLIpw4dF8/Bk1ji8n50+GWOH2IGmScM3D0++CXl187z+iuelE7w8H64VcK2ECPX0il8/\n", "DqCFPVqRIWeNtZzPQOVWsXV4arsYP6nafaVXdeFKQYbj8qfst+I7gkbIEUKSBpaQWpEmeT39kSOq\n", "CDBK4t8IavqG/tBD2yI2lcpmY92tu3a1/sPx9es3eNk6tm74IdY1/P3h77Mu+BlRQeKP+Ejn5f2v\n", "RmgYncf8gyl/qN+pvoKJrHKov1jFK65iPi6YShFrSrX8ELHGiCMQmBiLRmNYmY3a2dMEwf9zuPgj\n", "Mv7vZ02NoknntFrsueoJHs8EbYNuajQ6udDPJ+SXh+9gPxoWHuzoeNDaVGgqsZpdNmuOr742ou9p\n", "624pa/SW2+wT94vLP94sPv1xA68ytclbRi6IPaJGsAm9kk3N5aBTY7KEtqcflEzyBxv2rCRr9oOD\n", "r1ONoT1Wesm5oo4PsGRKhA0DPnvLQSN1GHL50MrbjhzivjzmUsLbs6rpEyd9a2/nH5n75omtTx3s\n", "Glm9sejBlsdavlm8iiNE2i3ME+eybwilwk3C7XvyNGZ1jRJKz2xJ1Q0Ke5pFCNIuGjhGxGqOboz3\n", "ROZHHPnXbLSlIrQR7wnxxbMckw8pLYOpFuzBjd3p8o7bA3Pc+CtxrspaWlNaNs1f2VVUEdRM4B9r\n", "S8unVPq7Snw+XQ19LJtWqXyrtpTgW3/l5BKvT1fLvuFu8LtceXnOeo+7IVDgzMtz1ZXt5pfZxKCS\n", "SM3sFkHL35Wfa5C5gl/S6Plcrs8YCIqEuYTGIWGPHm+Fz+yNlQ6NxqHh3e8W9sHwQvad4Vz2AQu2\n", "vdT2zN+1LUkkrs53gpSTzVcS9WQ6o6d3m0PvNmdc9rHGyspGjYNR9t8dvo0XwbO/p+3vnuEFDP8M\n", "2fMxZf7IWTaTfPFyBHiHIqijl7nYDnIIGvXv+f88HkWWX+BmmV+AjzrvCmfG8A48lk2/jHQuK2Ek\n", "IL4oviKU8f4+g8JEY36z8fnNlpnsyNr2upoI+TRgGqxgZkyDKhvFu6Q/fMjJBJnmA0E0FijXeVmE\n", "edH/5V0mVq4SX8yGnLYYjTOGN82YyyZOZhO95fl2Cj89bGeRraMxqC3GnIMHxVc+bikvLKZY1GwD\n", "e0CJO/ZrcYdqPX/rufR8b7Pm66ZfYN7rpl9khWPS78im/5aVU3ovF9Zeut8o3y+cJfmZkM7lZxHK\n", "2VekonJogTBWXlMus1iDAOWQYuKsVRG7rInMJ/LAjA67hnIKLLsIrn7bAIJ3XNC/zFso4x/KsKHC\n", "2BVowAZ2RTI5y+SzvH6LCC0Th3J2OogrVLEVclSyFdJTOJl4C/A9QFP2jO6AWjG0UVgoFQ9x6QCO\n", "ZclufJ9iwbZQ2gp4C/A9AMWBJTcrCtjqB+cqRQ1cB02zF8rteYAfp8XrcNULj4h9UHgPeck5BHWZ\n", "nA2A0YW6bAI0oXSKAjUVsDtLvjoVQFGfDqD0uSh9CnmJoWDyXO8GfI6XFBv134J9sZeP2Nasm7r3\n", "2b+dvWqm3z9z1ey/ZeLwcM+UKe+0P353e/vdj7e/014/e2kstnR2/W+44hKpnf943/wvz6+lNrCY\n", "v2svtQGT0gZ+MCb95mz6u8KxMemPZdMvC8fHpN+RTf+t8B80XizmfbGTt6VKYd6eAjVmiAIY22R7\n", "5Thdb1yvzJwD73EwJ/8ZV+fyGTEfFfA/hYNSpcpynS5Zbi130H/875h+KXaO6ZSG4TVs3/DX2bzh\n", "XewRS6ZbjumRhlzxlfbftA//rj3TJ7P96B9JVnal35WPSX8sm36ZVYxJvyOb/lsWUtLd4j+KJ7Pp\n", "v2OerAz/gvJ3yPlzKaI/UjqXITimHuQSgwWSRZlC+xlfu2BKH+pXqzNcJTm0E2yk67zBqziIx/Nq\n", "Z6zyMlLPGH3uUYkmPl8bGa16bQotCJZymEgW97DHenqGv9TDjg9/SXzl+ec/bmEzh/vZ12+5ZWRk\n", "5Jf8xQdU9/HncPL6a4V3TBRHceQKT8+lNiWnv2uQ4yvewv/sJznJ6b81yese20hAOMqfu0SI78lH\n", "2/kMrYbsDbFdUKI0D9e45uG18qcYbRZHx7YKdU/+DdrC6NhM9c0b+TX7E72nIuU9/Vp+f/y9Pkw2\n", "NsXyexX2Zd4r+y3dX0LP93aDMJpO95fQ/ZeEXZl8xqX/Tvj2de9fKnw8olHazW7Kv0yZJ9zZ9jQ2\n", "/SIzZ+u5m/IpU/L/ONNeVfn0firkPs+qx6Q/lk2/zIJj0tdn03/DEtly45ReK9dH2H/d9IvCP2Xr\n", "E6f61Cr1+QdKb+By/ojun6Dkc+i66ReEPdReGkYC7CPxpDBb+GXqllBqTih1i0KcmJpjSU0bktjE\n", "aZjMS+lPaqKlv1MFBbrT2envjHZO7uztXNK5snNt56bO7Z3w9IYC3XmukyvQ8rbWNEt/jYor6TWX\n", "akhJrymsqapprplSM79mec1DNRtqttbsqjlQ82oNV4Zp70Lues28TTbz1soX40a+pPAX8gmVFRLT\n", "Y6GlXy1ekUrlT82W/lbGle3Wi62kbLcWtAZbm1p7Wvtal7Wubl3fuqV1Z+v+1mOtJq5Aa1yK/gEV\n", "VDYBzWrQMb4UHuPxqx0l81FUajVXW6C3MIOotxpKQ47yKvvECZaKoDOozrWb85y5+fXNE+NVba5b\n", "moqiNcWeSFtXW8QTaLulpuXz1a2hBcXRGnd01qJZ0aqO6uKSFqZSB3yuCkdugS/fXqjOM+VoNdYO\n", "0VHYFAqErOVhT2V9udNZXNNWH5neUOAP13eZPfXl4caKoglTk+GbJ+blqATl3brxDrPv9nfCJrnP\n", "8bYTpnceUtrODqUvusUwtZ2Qcv/mG6cr/iVhiuk5Y4+oVvxLdETJb1JGShoCr95+3GOGIoVFjprU\n", "Gy1UqH49n4r4MGvC+kTeZ4000l6rIyKWvtXz1lvvihXvvsW+OXwv+2bLnvb2PVS3uXxeWEDjYz3V\n", "7R3egkfTb86mvyv8fEz6Y9n0y+PSv51Nf0/45Zj09dn03wh/pGefy+fiBfzZY8KzqaYQb5appow3\n", "fjMFSTTZArL2SBpxwNLv4yu9GCVmh95xVn5EK5P5YOQfjJlxmEy68MFo6S9h2BQqcZUESsYe2G4u\n", "2VGyr+RoCTaFSs7Dqimmsl8zpfOmjF1seKCpeXNW0yW13TGr7pdGx3FV54SGuKPHXl5V5c8zBaqq\n", "yu09jnjEH3WarhnbVaqC4rm317IXh6dHpjSUWDQaS0nDlAhLD3fW3j632K4pyM8M+4q+oUqRXGPK\n", "/P9/aF7js7Q4ndKblfFIbpsunu6g9BZl/Hp6TPod2fTfCk9m4gyzfxa/xtMn0Tzx5JeEMemvZNPn\n", "fEne0gjz8e4X7CzXvmcwdWpmKDUrlKobws67vEUo2eqIQ3CmJVU0iGOJOksqMpiKhLBw71Bj6Otw\n", "dvg7oh2TO3o7lnSs7FjbsaljeweYMDD0dZzrEImW4ebR9VoVf69VudebeRv4h4arz8D2lImT+JBn\n", "UxF1ShVvUdhM9F300fjmK/AFfU2+Hl+fb5lvtW+9b4tvp2+/75jPtFC6Sf4J1wp6aE+xx9UT6In1\n", "dPfM61nas6pnXc/mnh09+3qO9qD59JzvwZ7i+KWgFw6MmRQ+/kUaJ3ordAHZ6RMWcmMWAqqxtpeN\n", "7Bdj1wVMpRJLZjZ74hOKEvPvrC5ffctNwfYvV7TWFWtUpsyK4YuF07rqbWUBu6/RZx23fLAGbaEq\n", "bEk2t5XpjQ/FQp32qkk1Py5K2LIK30qNLeh1lTtyCqpinsza8XfsJ/TOe6mNtAl7rpv+OWWuvDp9\n", "ntIGr05fKnyH0oMj74s/Fd/n6YvltYcoUptC+mzxfT6jR1lBKhbCQCEOEfEYbe2lYhlv5AmZjfoJ\n", "meY1QXFLxmBahlESQeZ5I/M6vX5v1DvZ2+td4l3pXevd5N3uRQRoNDLvOW+GAdTDG40nQ15G40zu\n", "VaPw+CVqBYZkSZML3g7JTX8wQPPKVNB2Eh+gg9R2gq5gIBgLdgfnBZcGVwXBI7wjuC94NIi2Ezwf\n", "lKnBG9A0Gy42UNNsKGgINjQ19DT0NSxrWN2wvmFLw86G/Q3HGjD1YqxvvDZAWob17SqKSXF29Lph\n", "0o4ebY8Oe66OqSaGPx68JiL17okbNw6vvYpYLDs2XKH3u1x57/8wJv1r2fQnhb+/7v1zsu1kfPpS\n", "rEWVMeYKH2NiQlL4ZqotBK6ftsyxULsFHuZ59lJI3i5zupda+pv4HzpokGLyV2WWVHIwlQxlR5EM\n", "Md+eJtHDX2GeqhCvMEZ/sCZK4FUkLiboVSQKEsFEU6In0ZdYllidWJ/YktiZ2J84ljBd0+Vprsgc\n", "jTnK6TAo5ho/WdjkkyIHWzvayTWaCcHaZKUv2dvQOLe5dPhhVXFdi7fxZnukOuLxui1yH2+b1VPW\n", "MqFoTO/WqEWLTXlP/tZbw6XeSRPc9WXVja48TbFT6d1/1zGnsDpakhnLLaKL5PxFpf8OXDd9jnDw\n", "uulLhe+PSX83m/6+sF32YeYT/WkVYtU/ruT/93w+YtjhYad5vy4T+lPlIRBglVtSBYOpghCd3DIy\n", "yVYN4gVVYPuw38RTuapePCizDYyhrcr00HH+FeMmfxf/4JJHf/RQlbFE3qLst+K9Wi9a6b1aC6xB\n", "a5O1x9pnXWZdbV1v3WLdad1vPWY1kXkwH1zK0JnR3eR4M04HX2Ipb8/hzZIsTvuXrCt6dAo5ore0\n", "tP+LGNouu6IPv8FUM+aQI7oYaty4UdZFT3F5FIuQ0zKaU38sCpm5nAnUb+T0J5k81+q5LvqiuJ9r\n", "XlXCQ3tKVT7YmPgu0TyW4yv0VfkQSXG+b7nvId8G31bfLt8B36uYx8w+6gLmUH8+l6hPCYMgpAKh\n", "ccrsdafUMcps4NOVWdWYfdSxe5AGsT0vM02x0vz8UvwbN0Wx14drM5ORyuEoKsI/0sFHfj5iEbay\n", "1wWbMH2PUZMDHTw7BueO3T/VT5oPVYaPtmqXOqDOGLeuUq9Tb1bvUO9TH1VjtFWfV2Om1rkU5QSr\n", "OVJgnCq9TV9QkqduF12xicUF/8hEdX5JhVX0f/xabn2DP1d+P7w+XGfh/YF9jt7P54YFxXffzX5J\n", "89nXKP13C+X0efwhnKqdPP0JZR4tFn6lpM+k+5+g+y89IN/vHnEL28ak/+7SaD438f6TyWep8I2R\n", "HJ7eQf0K/XOLkv8/0v1Xp88TnpLTeT1Ps7PZ9N8JX6X0/HH38/q8mF37ieXUHp9WxvH+MemvZNPn\n", "3CB9rfAmpVOcKUo/RPm3zZDzt/P63Er1kdN/9ys5vfSq++cl5PRxsRGQz6rrp39ukbyHU87nD8QI\n", "uUW4CIV8Lqnisk4+15KaDp18Osw6atSfUa8mfzDo7l20tuhydvm7ol2Tu3q7lnSt7Frbtalre9dA\n", "15EurC26znXxqZ2WK1zpRzlZq4IxmnnuZ9PMkxi7kheTNHYlC5LBZFOyJ9mXXJZcnVyf3JLcmdyf\n", "PJbEnOT6zJr5uIAWuquCX5CS86Mb6ueN4aq6G8S7SIyPjFFuy7++gt6jsjpuEAcjcHXEDL1alN+z\n", "G+8z+55/N1dQ9O332YP0/n+o7GU9ldHDwf+rpPP7m4Qbp4/hC64Qntuj1WDjV0sewE4iZ3TSClOL\n", "5aWAQ8LsnDQu9GbuVec6e1SiWi3H+MWRAlnl8XHK4DIEDDFDt2GeYalhlWGdYbNhh2Gf4agB45Th\n", "PEip86we5aDVRY4XhYPKArNYmZa4pj+e+rdR3gLI0P/+5V+OJwCeMUOmAF7S+NBYDuC/bVwCEuAs\n", "B8n3ZA4SLscfg4Mkm/61bPqTinzHcZbQOPD0mPSL2fR/FbZm0sX8MfevFU4KModNgI3wcb5ZGFCs\n", "U2qGaMaSz2fjyhq/vxTKJdmR1OCMN1UXwkeK4pNd3Y3jHb6xwkhBfTIfMqaBXFUE+XC/l16RF1Gr\n", "Yt5u7zzvUu8q7zrvZu8O7z7vUWgOJ73nQa7YTPdfV/e7AXnN2OO6kXHz5PVJba5/QvAJVDfZzWJl\n", "3+oVkveQsh77jTDqY634YGO8VMbRcX6aGF8/f/30pcr8thh7PeIrgrx3rhOKhB8p79nC79/P09dT\n", "+leFd+g9+4XXWIBZYQsBbY4NUUjKIUGOt90KzySK5XBWhGNoJXxKA8MjjL3WLq+DAP/EyxOFXPYX\n", "e7RqDR82x3kxbcN5VyuM/VtxZcbVGbUc+AFG3FjoF4D/Y59wFJ63CE8vG7bL7BphBRZKg4CNYLfR\n", "g+pFJDrUi/BQ3s+OwUPZBb+CHL2okGgslHJyFG4HKVdFqX+Ab3AUoIXTQRm4ZFPwyHwNAKcMaRvA\n", "jC/uU9JWSGdxNQvwqDFjyEqnJFeHg8YRuOyjKIl0lf6++AMEuxwS/xOsWn8HUd4lypHU9Rg8Ml6w\n", "q+B+NR9UBb3w9V3GVuOJdoHaZYpmPuhJQGeWnqzthddvN4QC1utYuYrRkXOg/CUW2Tr8sXy2PHfG\n", "8KYr7IGPN+Ks4qDynlQPkT+VjU0FqaZAMdbNQ/15XJhfAJ/LixwGvpL3VN7uPNUKSZVngMRA+C8z\n", "JRyE31Yu4DwdZsKlC4R6IoWRBCGdmrLMGZJeUPiGFkpn4Lm7JueJLN+EGbwm2iHJJGd/0ARud0vK\n", "MpQ0g452jeUJyzbLC5aXLboVSVvcMtWywHKX5WHLVyxPWXZbDlpyFqbftFyCGXaORdnUegHMXmYH\n", "2AZmOhY57nOscTzh0Cy8Dq1/lsBEsOYqnqRW+RRRHBy4W3xE/BswE8bxjo4T/Zl8mybUr+X35BI/\n", "Nl6ZkT5RjHlm9aoq5dNF3jV0XnhesxHD71kPsw//J2sYXjt88tFb2b+z54bfZHr28PDaDThGPHJE\n", "fIU6ENhwKpIC0+wpEITc3AZBLYRGXuQYHfkRx9jInzg2jwxwjBMmCF8a2c3xrZFfcxwi/BnhGcKz\n", "QBZFPixG2ESYRG6sDTmwh+meRzhqqEQNlaihEjVUooZK1FCJGipRQyVqqEQNlaihEjVUooZK1FCJ\n", "GipRQyVqqEQNlaihErVUopZK1FKJWipRSyVqqUQtlailErVUopZK1FKJWipRSyVqqUQtlailErVU\n", "opZK1FKJOipRRyXqqEQdlaijEnVUoo5K1FGJOipRRyXqqEQdlaijEnVUoo5K1FGJOipRRyXqqEQ9\n", "lainEvVUop5K1FOJeipRTyXqqUQ9lainEvVUop5K1FOJeipRTyXqqUQ9lainEvVUok1Qj7zKUUOo\n", "JdQR6gkXjqzhmCI8jhRmIDQSmggf41jCa/5djlHCGKU0jzyLU1fCBOFLhD8beYvjGcKzQEa/4rUF\n", "NhEmkQOvLb+f1/MtoZrXc4CjhlBLqCPUEy4cWcoxRXgcKbyeQCOhifAxjrVCiLeDWiFKGBMsHJtH\n", "fscxTpgg/JlQwPEM4Vkgo/tZjLCJMInf8hry+9kj/J4Qr+GLHDWEWkIdoZ5w0sjXObYSJgnbCTsJ\n", "JxNOI+wl7CO8jXAh4XLCuwjvJryH8F7CdfwdhYT1I3/k+DSlPEP4LOE2wm8T7iZMER7i0g4J/0bX\n", "rxAeITxOdT5B354kfIPwFOFpwiG682eEZwjPArnk+W+55IEmQnpG1kVIT8q6CXsIpxBOJbyZcAbh\n", "TMJZhLMJF+Dp2BK6Xkq4jHA56sPuIrybkCTDSDLszwnvI3yAvn2QcCXhKsLVhA8RPkx3PkK4hkp8\n", "jD9FlHpKlHpKlHpKlHpKlHpKlL9fYCthkrCdsJNwMuE0wtt4O4xSz4ryd4qUuwjvJryH8F7CdYTw\n", "t47yd4rrZwifJdxG+G3C3YQpyvMQ7y9R/h5RynFKP0EpJwnfIDxFeJoQo0eURo8ojR5R6uNR6uNR\n", "6uNRRk/B3yCQnoW/KeAMwpmEswhnEy5AnfmbwvVSwmWEy1Eif1PAuwkfIHyQcCXhKsLVhA8RPkK1\n", "WkN5YrSJ8Xfxa44aQi2hjlBPOIn/KsbfBTBJ2E7YSTiZcBrhbXT/Qi6rGH8XuL6L8G7CewjvJVzP\n", "+3iMvwVcP0P4LOE2wm8T7iZMUW6H6PoI4XHCE4QnCd8gPEV4GshlDjQSmgiptlzmQKozlznSZxDO\n", "JJxFOJtwAWrIZY7rpYTLCOm5GD0Xo+fiMgc+SLiScBXhasKHCNdQbo/x62Yae5tp7G2msbeZxt5m\n", "GnububS/y7GVMEnYTthJOJlwGuFthAtHHue4nK7vIryb8B7CewnX8d7XTKNZM5c5Up4hfJZwG+G3\n", "CXcT/gPVJDXyDMe9lHKE8DilnyA8SfgG4SnC04Rv8RbVTPNFM80XzTRfNDOqP5c/kJ6Cyx84g3Am\n", "4SzC2YQYnZq5/HG9lHAZ4QOU24OEKwlXEa4mfIhwDf0WM1ScpB0nacdJ2nGSdpykHSdpx0nacZJ2\n", "nKQdJ2nHSdpxknacpB0nacdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpB0nacdJ2nGSdpyk\n", "HSdpx0nacZJ2nKQdJ2nHSdpxknacpB0nacdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpB0n\n", "acdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGkn\n", "SNoJknaCpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmSdoKknSBpJ0ja\n", "CZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmS\n", "doKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaa8UMNqsFF4S8oUXhRdHhvjVS4RYgbxEK5CXhB/y\n", "e16iGfwlmsFfohn8JZrBX2L307crCP+C4yG+XgL2ES7ktTqE/QyOywnvIryb8B7Cewm/SIgZ9pDw\n", "TV6fQ8IWwqcIn6ZvnyF8lnAb4bcJdxOmqKy9uObrGWAP4RTCqYTTCG8mnEE4k3AW4WzCWwjnEM4l\n", "vJXw86gJu53wDsI7CZfQt0sJMcIfJ63hOGkNx0lrOE5aw3HSGo6T1nCctIbjpDUcJ63hOM37x2ne\n", "P07z/nHSGo6T1nCctIbjpDUcJ63hOGkNx2kufotmzLdophvi169yTHH8Gcn/ZySZM3R9hq7P0vVZ\n", "XDMDasuR15Yjry1HXluOccIEIa8tR15bjkOEPyM8Q3gWiNpyjBE2ESaRG2rL8WG6h9eWGalEI5Vo\n", "pBKNVKKRSjRSiUYq0UglGqlEI5VopBKNVKKRSjRSiUYq0UglGqlEI5VopBJNVKKJSjRRiSYq0UQl\n", "mqhEE5VoohJNVKKJSjRRiSYq0UQlmqhEE5VoohJNVKKJSjRRiZXQvzhGCbn+xZHrXxzjhAnClwi5\n", "/sXxDOFZIKNfQf/i2ESYRA7Qvzhy/Yv5KX8/5e+n/P2Uv5/y91P+fsrfT/n7KX8/5e+n/P2Uv5/y\n", "91P+fsrfT/kHKP8A5R+g/AOUf4DyD1D+Aco/QPkHKP8A5R+g/AOUf4DyD1D+Aco/QPkHKf8g5R+k\n", "/IOUf5DyD1L+Qco/SPkHKf8g5R+k/IOUf5DyD1L+Qco/SPmHoPNxjBJyvZIj1ys5xgkThFyv5HiG\n", "8CyQ0f3QKzk2ESbxW+iVHLleycKUc5hyDlPOYco5TDmHKecw5RymnMOUc5hyDlPOYco5TDmHKecw\n", "5VxPOddTzvWUcz3lXE8511PO9ZRzPeVcTznXU871lHM95VxPOddTzvWUM3SlFxl0JaCWUEeoJ+S6\n", "MIOuBEwSthN2Ek4mnEbYS9hHeBvhQsLlhHcR3k14D+G9hFwX5shnWAa9CSnPED5LuI3w24S7CVOE\n", "XBfm+G90/cr/7e1MgOwo7jPerZV2Vxe3AWMsP+MDDEKWhGBmxGGt7gvd4pAlpKe3o92Zefve8o6V\n", "VoBlrxHIB5CkcscCh5CkApWEHChEoOC4HBIUJakk5iocQ27HSZzEOSqpOFH+329mtU+ywJWqVLx+\n", "3+s309PT/f96ju7+PgG+CB6nzi+z9xXwVfA18HXwa+T8Ovgm+JZQY2GvkZRwJkgbNRb2GkkJV4Ar\n", "wVXgavBWcB24HtwAbgS3qXUaC3uNsISDYKL6aCzsNcISEhlPZPQkNayDLfa2wRFwL7gPHAX3k/Me\n", "8ABntLGwD+A3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8A\n", "fgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4\n", "DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3\n", "gN8AfgP4DeA3gN8AfgP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8Q\n", "fkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4\n", "DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3\n", "hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4jeA3gt8IfiP4jeA3gt8IfiP4jeA3gt8IfiP4jeA3gt8I\n", "fiP4jeA3gt8IfiP4jeA3gl9G9z6C3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC\n", "3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4JfZAB/BbwS/EfxG8BvB\n", "bwS/EfxG8BvBbwS/EfxG8BvBbwS/EfxG8BvBbwS/zCH4CH4XaX7McArYDfaAveAt9saySPNjhovA\n", "xeBScDm4BtxOfnvbN0xIp2AGVsEh8JA99xdp3GR4GHwUfAx8HHwSfJrSvkT6RfA4+DL4Cvgq+Br4\n", "ulDzY4YzwJkgtdX8mCF11jjLcB24HtwAbgS3qYYaPRkOgIMg7fK0y9MuzY8ZtsERcC+4DxwFD1Da\n", "mKX7NIdgOAXsBnvAXvAWY6pPcwiGi8DF4FJwObgG3A7uOHnQMCGdghlYBYfAB43xPq6gPs0hGB4G\n", "HwUfAx8HnwSfoiZPnzxs+AxbXgSPs/1l8BXwVfA18HXwDXvX7dMcguEMcCZI/TWHYEgrNIdguA5c\n", "D24AN4K6Ivo0h2A4AA6CLUprgyPgXnAfOAoe4NgxS69xa12/YQscccsND5I+5LYZPgQ+zJZHwCPg\n", "s26+4VF3k+Fz4PPkPAa+AJ5wG/waf5vyW2+xLX4H6bvAneAusAwOk/9usAEesKN2Wg03GLbsLDut\n", "hlcZHmTLIfAh8GHwEfAIOZ91FxketXrutBoKn2f7MfAF8ISb5XdaDe0oq6FwB3gXuBPcBZbBYfLf\n", "DTbAA7Y90ZyJ4R2gjc0Nd5FOwBTMwCo4BN4HPmj9IdGcieGPgj8OfoG9h8FHwcfAx8Enwac51zNK\n", "a87EcCW4ClwNrgHXgreC68D14AZwI7gJ3AxuAbeCu1UfzZwY9oMxuIe9A6Cu/ZQ4pMQhJQ4pcUiJ\n", "Q0ocUuKQEoeUOKTEISUOKXFIiUNKHFLikBKHlDikxCElDilxSIlDShxS4pASh5Q4pMQhJQ4pcUiJ\n", "Q0ocUuKQEoeUOKTEISUOKXFIiUNKHFLikBKHlDikxCElDilxyIhDRhwy4pARh4w4ZMQhIw4ZcciI\n", "Q0YcMuKQEYeMOGTEISMOGXHIiENGHDLikBGHjDhkxCEjDhlxyIhDRhwy4pARh4w4ZMQhIw4ZcciI\n", "Q0YcMuKQEYeMOGTEISMOGXHIiENGHDLikBGHYbtyZxm2wIPgIfAh8GHwEfCI0K5E4TZwB3gXuBPc\n", "BZbBA4b7NVdm+LThPcT5HiIwxnzRGPNFY8wXjTFfNMZ80RjzRWPMF40xXzTGfNEY80VjzBeNMV80\n", "xnzRGPNFY8wXjTFfNMZ80RjzRWPM4Dl3ib8s/68qGU7PNSVos3rsV57uciV3QZGe3JFniuWZX6S7\n", "bXtUpKUnXFqkLyB/l/OTp9r3Z/XfWCHt3cXGRp6e5M7x+4p0l1vkHyjSkzvyTLE8Lxbpbtv+1SLd\n", "46/y3yzSve6yrguK9FQ3q2t2kZ7W/Uddq4v0dDdn2uVFeoZbPW18+3luxrQfLNLnu95pX+wbiWtJ\n", "o7S4Xs82xQPtarnRseXGUjhnbv918bwbS/Pnzpt/7dwF9v9iU57tWmUrjkiapXKp1Sj3x0PlRlaq\n", "7ymtjJP+uLo7bgzEjdLSRruSDZWblcGkFtdKfStml+J9lWq7mYzE1dFSNanEtWbcX2oNNurtgcHS\n", "2qRWb40Ox6UVQ7tXzi6Va/2lofJoaXdcasQDSbMVNyxzUitV4karbN9pu5E0+5NKK6nXmnPcEld3\n", "w27UNVziBtyg9fGfM37nu7lOs0ol6/mJq1meluUZdrFtWeGG3G630s229F7+5rjqGbnmuIr9GrLv\n", "krM3FPsrdZyhya/YvmP7HjHst5x9pGqWq2H7F9vxdZe5TbZtwLWthLJtP3ueGy0dWglzrZzrbP88\n", "tqgN8wyvte8FBZ6eq7O0a0+Vdvo5Empbtk/Lftvz3fYNUZfMttXdHsOVti1hT9UiozYNgCXr9w2r\n", "e8Xy6pimpQaJlMpXZFYQxdjtsz1Vy9m0vSOUM2rbFdUKeZvESHUYtBLrllOR/F7slG2fjtK5Vd5u\n", "cjSIqNrVopZ5yQk1qrClZfnz36mdqUHefurSMqxTnznvcO4+y62jypSxnBi0YD+Gw3faWyKOTX7X\n", "irqdyYiOm2f3l9D+8nbuKdpSsrrEsNM8xc6g/R7hqIEiJnkZ461XHMZLbbK/SSqmlnuIet7CPba3\n", "whHq16s44szydKbYrgldGwl8fTdLs6lVXJwvoY357z1w3zpVbt3iWSUW5VOxV33qZ8Qp76HVom+V\n", "icREW5LiqPwc4/046Sgxj9Qy27O7OHq87yyHnTbHzKYPtalfXoeynbNJSn0so/w2sRsvc/ys6uPD\n", "RUzFZYWt42dpEptq0SvV0/L25deC7lBDHNXq4HWiPXuLfSo5j3il2KJ6j8LWliL3Xju6cZZeNUTc\n", "8nhdaeWPtzq2X+MRXM7vGlfxRN0HC/abRZ3KRXzGa3d631Ht98JcicgNdcQqKUqZ6E3DnLF1FvY7\n", "eZnDvTDnpW15FMecizPZO9u9Le+ZJTtX3t783qOrMa9dC84q3FMTcg5yLytRVqPgq8w9vknuOmc/\n", "PR5lys63JNwR8+s1z9HZPwdhKHH7aW+r6GPj97OSu8K2X3Fa2ae3o0xbVLqupgrbKrRY99j4tDtj\n", "szhbi6jkd5v8Ph2TI+ZOMtF/8p5ds0iViz6cPx2Sjntotbi/7rZPlYiNdpxxoLjDn8lFuYhrw2Je\n", "Z2udK6mzrvmTIOGekF89w7S0DL/j19QeWqQrtV5cDS2uvtZppQ1yXP+pe0bnPS1/+i+gju98rx4v\n", "7czeXuL+0ijin9cn7+Nv/9TQ2TKOUizWcO/Tc6sMS4nLn1z59Zt1PA/PFsu8VhWOKNP+t8+9rojO\n", "ROTG823graNFjdtWyxJvS1WiP/EsnMM7Tctas9Bpve97vRP973J/lFrpOjj9uah+2dmO8beXQp/v\n", "3Mln3Hx3lv/5++0zyXJ1ud+2CP+8necX3Ifch638K91VVt7vuOPud93fuI+4q901drWccL/nft/9\n", "gb0hzbHa/BlvVXusbP0jwn9otflj9/3uF+2NaoG73t3g/sLeGv/enstfdS9bS1+xp/RCu3Pc5P7W\n", "Pedudn9lb0S6Nz1k7f2ivV1Mtdr3WYxnug9YW5e5j7md7i63y93iFrk33Dfcg9bn/tTa9XV3v40V\n", "3uvOdZ9zx6zHjLkvu0/buOtZqavdq9Z7honI3e497in3K+6Xjatv2ojhp6xHf8ld6n7T/Yy7xD3v\n", "VrvPGIfvt3fcJ91vuBesl71p7/prLbojxkLb3Wq9Yb17n3vC/bnb4LvcP7gfcf/oNrrLrYd027vo\n", "qLvH3et+yb1ld6eL3L+4f3X/5A67R91PuvvcZhsTTrdRRK873092L7pzbOy7xe5Uj9to5bfcr7pn\n", "bGz4a+4rbprbaiOfP3G3ub90D7hZ7jL3bhsXvWTjytvdt9zF7t/cP7vX3efdu9y33R3uE+6T7lPu\n", "gPF7p9vmPu62u79zR90Pux3ur92Fforv9j2+10/10/x0P8PP9Of4c/15/nx/gb/QX+Tf5S92j/lL\n", "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\n", "2UlrVKk0bv9hjY2seH4AHtCFLgplbmRzdHJlYW0KZW5kb2JqCjEzIDAgb2JqCjw8IC9DSURUb0dJ\n", "RE1hcCAxNSAwIFIgL0ZvbnREZXNjcmlwdG9yIDEyIDAgUiAvQmFzZUZvbnQgL0F2ZW5pci1Cb29r\n", "Ci9DSURTeXN0ZW1JbmZvIDw8IC9PcmRlcmluZyAoSWRlbnRpdHkpIC9TdXBwbGVtZW50IDAgL1Jl\n", "Z2lzdHJ5IChBZG9iZSkgPj4KL1N1YnR5cGUgL0NJREZvbnRUeXBlMiAvVyAxNyAwIFIgL1R5cGUg\n", "L0ZvbnQgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9FbmNvZGluZyAvSWRlbnRpdHktSCAvQmFzZUZv\n", "bnQgL0F2ZW5pci1Cb29rCi9EZXNjZW5kYW50Rm9udHMgWyAxMyAwIFIgXSAvU3VidHlwZSAvVHlw\n", "ZTAgL1RvVW5pY29kZSAxOCAwIFIgL1R5cGUgL0ZvbnQKPj4KZW5kb2JqCjEyIDAgb2JqCjw8IC9E\n", "ZXNjZW50IC0zNjYgL0ZvbnRCQm94IFsgLTE2NyAtMjg4IDEwMDAgOTQwIF0gL1N0ZW1WIDAgL0Zs\n", "YWdzIDMyCi9YSGVpZ2h0IDAgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Gb250RmlsZTIgMTYgMCBS\n", "IC9Gb250TmFtZSAvQXZlbmlyLUJvb2sKL01heFdpZHRoIDY4MiAvQ2FwSGVpZ2h0IDAgL0l0YWxp\n", "Y0FuZ2xlIDAgL0FzY2VudCAxMDAwID4+CmVuZG9iagoxNyAwIG9iagpbIDQ4ClsgNTY5LjMzMzMz\n", "MzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMKNTY5LjMz\n", "MzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgXQo1NiBbIDU2OS4zMzMzMzMz\n", "MzMzIF0gODcyMiBbIDY4MiBdIF0KZW5kb2JqCjMgMCBvYmoKPDwgL0YxIDE0IDAgUiA+PgplbmRv\n", "YmoKNCAwIG9iago8PCAvQTEgPDwgL0NBIDAgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMCA+PgovQTIg\n", "PDwgL0NBIDEgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMSA+PiA+PgplbmRvYmoKNSAwIG9iago8PCA+\n", "PgplbmRvYmoKNiAwIG9iago8PCA+PgplbmRvYmoKNyAwIG9iago8PCA+PgplbmRvYmoKMiAwIG9i\n", "ago8PCAvQ291bnQgMSAvS2lkcyBbIDEwIDAgUiBdIC9UeXBlIC9QYWdlcyA+PgplbmRvYmoKMjEg\n", "MCBvYmoKPDwgL0NyZWF0aW9uRGF0ZSAoRDoyMDE0MDIyMDE3NTMyNS0wNycwMCcpCi9Qcm9kdWNl\n", "ciAobWF0cGxvdGxpYiBwZGYgYmFja2VuZCkKL0NyZWF0b3IgKG1hdHBsb3RsaWIgMS4xLjEsIGh0\n", "dHA6Ly9tYXRwbG90bGliLnNmLm5ldCkgPj4KZW5kb2JqCnhyZWYKMCAyMgowMDAwMDAwMDAwIDY1\n", "NTM1IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDA3MzYzOCAwMDAwMCBuIAowMDAwMDczNDQ0\n", "IDAwMDAwIG4gCjAwMDAwNzM0NzYgMDAwMDAgbiAKMDAwMDA3MzU3NSAwMDAwMCBuIAowMDAwMDcz\n", "NTk2IDAwMDAwIG4gCjAwMDAwNzM2MTcgMDAwMDAgbiAKMDAwMDAwMDA2NSAwMDAwMCBuIAowMDAw\n", "MDAwMzg4IDAwMDAwIG4gCjAwMDAwMDAyMDggMDAwMDAgbiAKMDAwMDAwMTMzMyAwMDAwMCBuIAow\n", "MDAwMDczMDYwIDAwMDAwIG4gCjAwMDAwNzI3MTIgMDAwMDAgbiAKMDAwMDA3MjkxOSAwMDAwMCBu\n", "IAowMDAwMDcyMjM5IDAwMDAwIG4gCjAwMDAwMDEzNTMgMDAwMDAgbiAKMDAwMDA3MzI3NyAwMDAw\n", "MCBuIAowMDAwMDcyMzc4IDAwMDAwIG4gCjAwMDAwNzIyMTYgMDAwMDAgbiAKMDAwMDA3MjE5NCAw\n", "MDAwMCBuIAowMDAwMDczNjk4IDAwMDAwIG4gCnRyYWlsZXIKPDwgL0luZm8gMjEgMCBSIC9Sb290\n", "IDEgMCBSIC9TaXplIDIyID4+CnN0YXJ0eHJlZgo3Mzg0OQolJUVPRgo=\n" ], "image/png": [ "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\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.hist(evs.real)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "import math \n", "import numpy as np\n", "def matrix_calc(L=None):\n", " \"\"\"docstring\"\"\"\n", " if L is None:", " L = np.random.random(size=(1,1))", " raise Exception(\"message\")\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This string contains a ~~strikethrough~~, struckthrough. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This string contains a `'` single tick inside backticks, leading to a ``\\textquotesingle`` in latex." ] } ], "metadata": { "signature": "sha256:9fffd84e69e3d9b8aee7b4cde2099ca5d4158a45391698b191f94fabaf394b41" }, "nbformat": 4, "nbformat_minor": 0 } nbconvert-5.3.1/nbconvert/tests/files/notebook3_with_errors.ipynb000066400000000000000000000024461315361605600253750ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Notebook with errors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook contains a cell which deliberately throws an exception. This is to test if `nbconvert` stops conversion if the flag `--execute` is given without `--allow-errors`. In the cells before and after the one which raises the exception we compute a couple of numbers. If they exist in the output we know that the respective cells were executed." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "print(\"Hello world, my number is {}\".format(24 - 1))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "print(\"Some text before the error\")\n", "raise RuntimeError(\"This is a deliberate exception\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "print(\"The answer to the question about life, the universe and everything is: {}\".format(43 - 1))" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 } nbconvert-5.3.1/nbconvert/tests/files/notebook4_jpeg.ipynb000066400000000000000000000443271315361605600237600ustar00rootroot00000000000000{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "The latest trend in DevOps." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/jpeg": "/9j/4AAQSkZJRgABAQAAZABkAAD/4QCMRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUA\nAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABkAAAAAQAA\nAGQAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAfSgAwAEAAAAAQAAAXUAAAAA/+0AOFBob3Rv\nc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/AABEIAXUB\n9AMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQD\nBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygp\nKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJma\noqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/\nxAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQID\nEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RF\nRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqy\ns7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2wBDABwcHBwcHDAc\nHDBEMDAwRFxEREREXHRcXFxcXHSMdHR0dHR0jIyMjIyMjIyoqKioqKjExMTExNzc3Nzc3Nzc3Nz/\n2wBDASIkJDg0OGA0NGDmnICc5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm\n5ubm5ubm5ubm5ub/3QAEACD/2gAMAwEAAhEDEQA/AG470uKdinY4rjNhAKep7UKBS4piJMelOApF\nNSY9KZIgpCMcinU7FMBlFOIpMUhiYppXNSUuPSgCuRjrRipyAajK4qWikxmDRRiipKEo6UtGKGAU\n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\noAaSaMmkNFUB/9k=\n", "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import Image\n", "Image('containerized_deployments.jpeg', embed=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.0" } }, "nbformat": 4, "nbformat_minor": 0 } nbconvert-5.3.1/nbconvert/tests/files/notebook_jl.ipynb000066400000000000000000000007021315361605600233410ustar00rootroot00000000000000{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "function foobar(x)\n", " 100x\n", "end" ] } ], "metadata": { "kernelspec": { "display_name": "Julia 0.4.0-dev", "language": "julia", "name": "julia-0.4" }, "language_info": { "name": "julia", "version": "0.4.0" } }, "nbformat": 4, "nbformat_minor": 0 } nbconvert-5.3.1/nbconvert/tests/files/override.py000066400000000000000000000002711315361605600221630ustar00rootroot00000000000000c = get_config() #Export all the notebooks in the current directory to the sphinx_howto format. c.NbConvertApp.notebooks = ['notebook2.ipynb'] c.NbConvertApp.export_format = 'python' nbconvert-5.3.1/nbconvert/tests/files/testimage.png000066400000000000000000000036031315361605600224640ustar00rootroot00000000000000PNG  IHDRdG~u pHYsttfx5IDATxmSW jD#tұj1$&%2cmCXuRG2 <.pI5vEr9޽]!'dE2H$(*|J…Y,600L& `!'RآjRJD"r2"LB$ Dxee%oit{fVWW/_lz}ƲQVV6(#ʏ#ESfىчbyԩSt# .ߘ۠i#܆CZ]hGB4b H |mN% _.V:_Z>Zm<7P[U+pq_qKdB)Þ1tuOX/^D$~/Հ3 q3NFGGX^zM6c 7o10u5\^VVv (պSdۍ;wPr{5ٳg@`zz:Jz\׻HF#nsWWW~hd>[n4bdq sA$<#xO12H}}: %`d}ӧ#%łuܿNw 9"Ð)$twJ)`r7or`XQbMM!ݻP{X E"X++kJO,B06 14v.L0e6^oggdDׯ_!2?=aB^!+++!D"J>F,^J& 1ac2JeBӴlhhPTO[[x!{|>gdgE*655qF+j -whO]]|+u =LL }A 8˗Foe+ Z[gNcH,_ ryS9rq+шF]]Sabe*{ j@Y4BzVQ*aݻwHybbBR}t7+fln|j2T*Fs FQ0 asʱX,vB HX,*ۍ'Ohn+\}U4&Ѩ Bh2<sLf͵5Ǔdjkk3555`0d+H!MMM333;8{QRt:Bdjnn~Mn~㩭e5f6~ƁD"p8rfc  FQ XFVmiiZ;5=;łXp" Nb?dIENDB`nbconvert-5.3.1/nbconvert/tests/test_nbconvertapp.py000066400000000000000000000471121315361605600230070ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Test NbConvertApp""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import os import io from .base import TestsBase from ..postprocessors import PostProcessorBase from nbconvert import nbconvertapp from nbconvert.exporters import Exporter from traitlets.tests.utils import check_help_all_output from ipython_genutils.testing import decorators as dec from testpath import tempdir import pytest #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- class DummyPost(PostProcessorBase): def postprocess(self, filename): print("Dummy:%s" % filename) class TestNbConvertApp(TestsBase): """Collection of NbConvertApp tests""" def test_notebook_help(self): """Will help show if no notebooks are specified?""" with self.create_temp_cwd(): out, err = self.nbconvert('--log-level 0', ignore_return_code=True) self.assertIn("--help-all", out) def test_help_output(self): """ipython nbconvert --help-all works""" check_help_all_output('nbconvert') def test_glob(self): """ Do search patterns work for notebook names? """ with self.create_temp_cwd(['notebook*.ipynb']): self.nbconvert('--to python *.ipynb --log-level 0') assert os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') def test_glob_subdir(self): """ Do search patterns work for subdirectory notebook names? """ with self.create_temp_cwd(): self.copy_files_to(['notebook*.ipynb'], 'subdir/') self.nbconvert('--to python --log-level 0 ' + os.path.join('subdir', '*.ipynb')) assert os.path.isfile(os.path.join('subdir', 'notebook1.py')) assert os.path.isfile(os.path.join('subdir', 'notebook2.py')) def test_build_dir(self): """build_directory affects export location""" with self.create_temp_cwd(): self.copy_files_to(['notebook*.ipynb'], 'subdir/') self.nbconvert('--to python --log-level 0 --output-dir . ' + os.path.join('subdir', '*.ipynb')) assert os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') def test_convert_full_qualified_name(self): """ Test that nbconvert can convert file using a full qualified name for a package, import and use it. """ with self.create_temp_cwd(): self.copy_files_to(['notebook*.ipynb'], 'subdir') self.nbconvert('--to nbconvert.tests.fake_exporters.MyExporter --log-level 0 ' + os.path.join('subdir', '*.ipynb')) assert os.path.isfile(os.path.join('subdir', 'notebook1.test_ext')) assert os.path.isfile(os.path.join('subdir', 'notebook2.test_ext')) def test_explicit(self): """ Do explicit notebook names work? """ with self.create_temp_cwd(['notebook*.ipynb']): self.nbconvert('--log-level 0 --to python notebook2') assert not os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') def test_absolute_template_file(self): """--template '/path/to/template.tpl'""" with self.create_temp_cwd(['notebook*.ipynb']), tempdir.TemporaryDirectory() as td: template = os.path.join(td, 'mytemplate.tpl') test_output = 'success!' with open(template, 'w') as f: f.write(test_output) self.nbconvert('--log-level 0 notebook2 --template %s' % template) assert os.path.isfile('notebook2.html') with open('notebook2.html') as f: text = f.read() assert text == test_output def test_relative_template_file(self): """Test --template 'relative/path.tpl'""" with self.create_temp_cwd(['notebook*.ipynb']): os.mkdir('relative') template = os.path.join('relative', 'path.tpl') test_output = 'success!' with open(template, 'w') as f: f.write(test_output) self.nbconvert('--log-level 0 notebook2 --template %s' % template) assert os.path.isfile('notebook2.html') with open('notebook2.html') as f: text = f.read() assert text == test_output @dec.onlyif_cmds_exist('xelatex') @dec.onlyif_cmds_exist('pandoc') def test_filename_spaces(self): """ Generate PDFs with graphics if notebooks have spaces in the name? """ with self.create_temp_cwd(['notebook2.ipynb']): os.rename('notebook2.ipynb', 'notebook with spaces.ipynb') self.nbconvert('--log-level 0 --to pdf' ' "notebook with spaces"' ' --PDFExporter.latex_count=1' ' --PDFExporter.verbose=True' ) assert os.path.isfile('notebook with spaces.pdf') @dec.onlyif_cmds_exist('xelatex') @dec.onlyif_cmds_exist('pandoc') def test_pdf(self): """ Check to see if pdfs compile, even if strikethroughs are included. """ with self.create_temp_cwd(['notebook2.ipynb']): self.nbconvert('--log-level 0 --to pdf' ' "notebook2"' ' --PDFExporter.latex_count=1' ' --PDFExporter.verbose=True' ) assert os.path.isfile('notebook2.pdf') def test_post_processor(self): """Do post processors work?""" with self.create_temp_cwd(['notebook1.ipynb']): out, err = self.nbconvert('--log-level 0 --to python notebook1 ' '--post nbconvert.tests.test_nbconvertapp.DummyPost') self.assertIn('Dummy:notebook1.py', out) @dec.onlyif_cmds_exist('pandoc') def test_spurious_cr(self): """Check for extra CR characters""" with self.create_temp_cwd(['notebook2.ipynb']): self.nbconvert('--log-level 0 --to latex notebook2') assert os.path.isfile('notebook2.tex') with open('notebook2.tex') as f: tex = f.read() self.nbconvert('--log-level 0 --to html notebook2') assert os.path.isfile('notebook2.html') with open('notebook2.html') as f: html = f.read() self.assertEqual(tex.count('\r'), tex.count('\r\n')) self.assertEqual(html.count('\r'), html.count('\r\n')) @dec.onlyif_cmds_exist('pandoc') def test_png_base64_html_ok(self): """Is embedded png data well formed in HTML?""" with self.create_temp_cwd(['notebook2.ipynb']): self.nbconvert('--log-level 0 --to HTML ' 'notebook2.ipynb --template full') assert os.path.isfile('notebook2.html') with open('notebook2.html') as f: assert "data:image/png;base64,b'" not in f.read() @dec.onlyif_cmds_exist('pandoc') def test_template(self): """ Do export templates work? """ with self.create_temp_cwd(['notebook2.ipynb']): self.nbconvert('--log-level 0 --to slides ' 'notebook2.ipynb') assert os.path.isfile('notebook2.slides.html') with open('notebook2.slides.html') as f: assert '/reveal.css' in f.read() def test_output_ext(self): """test --output=outputfile[.ext]""" with self.create_temp_cwd(['notebook1.ipynb']): self.nbconvert('--log-level 0 --to python ' 'notebook1.ipynb --output nb.py') assert os.path.exists('nb.py') self.nbconvert('--log-level 0 --to python ' 'notebook1.ipynb --output nb2') assert os.path.exists('nb2.py') def test_glob_explicit(self): """ Can a search pattern be used along with matching explicit notebook names? """ with self.create_temp_cwd(['notebook*.ipynb']): self.nbconvert('--log-level 0 --to python ' '*.ipynb notebook1.ipynb notebook2.ipynb') assert os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') def test_explicit_glob(self): """ Can explicit notebook names be used and then a matching search pattern? """ with self.create_temp_cwd(['notebook*.ipynb']): self.nbconvert('--log-level 0 --to=python ' 'notebook1.ipynb notebook2.ipynb *.ipynb') assert os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') def test_default_config(self): """ Does the default config work? """ with self.create_temp_cwd(['notebook*.ipynb', 'jupyter_nbconvert_config.py']): self.nbconvert('--log-level 0') assert os.path.isfile('notebook1.py') assert not os.path.isfile('notebook2.py') def test_override_config(self): """ Can the default config be overriden? """ with self.create_temp_cwd(['notebook*.ipynb', 'jupyter_nbconvert_config.py', 'override.py']): self.nbconvert('--log-level 0 --config="override.py"') assert not os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') def test_accents_in_filename(self): """ Can notebook names include accents? """ with self.create_temp_cwd(): self.create_empty_notebook(u'nb1_análisis.ipynb') self.nbconvert('--log-level 0 --to Python nb1_*') assert os.path.isfile(u'nb1_análisis.py') @dec.onlyif_cmds_exist('xelatex', 'pandoc') def test_filename_accent_pdf(self): """ Generate PDFs if notebooks have an accent in their name? """ with self.create_temp_cwd(): self.create_empty_notebook(u'nb1_análisis.ipynb') self.nbconvert('--log-level 0 --to pdf "nb1_*"' ' --PDFExporter.latex_count=1' ' --PDFExporter.verbose=True') assert os.path.isfile(u'nb1_análisis.pdf') def test_cwd_plugin(self): """ Verify that an extension in the cwd can be imported. """ with self.create_temp_cwd(['hello.py']): self.create_empty_notebook(u'empty.ipynb') self.nbconvert('empty --to html --NbConvertApp.writer_class=\'hello.HelloWriter\'') assert os.path.isfile(u'hello.txt') def test_output_suffix(self): """ Verify that the output suffix is applied """ with self.create_temp_cwd(): self.create_empty_notebook('empty.ipynb') self.nbconvert('empty.ipynb --to notebook') assert os.path.isfile('empty.nbconvert.ipynb') def test_different_build_dir(self): """ Verify that the output suffix is not applied """ with self.create_temp_cwd(): self.create_empty_notebook('empty.ipynb') os.mkdir('output') self.nbconvert( 'empty.ipynb --to notebook ' '--FilesWriter.build_directory=output') assert os.path.isfile('output/empty.ipynb') def test_inplace(self): """ Verify that the notebook is converted in place """ with self.create_temp_cwd(): self.create_empty_notebook('empty.ipynb') self.nbconvert('empty.ipynb --inplace') assert os.path.isfile('empty.ipynb') assert not os.path.isfile('empty.nbconvert.ipynb') assert not os.path.isfile('empty.html') def test_no_prompt(self): """ Verify that the notebook is converted in place """ with self.create_temp_cwd(["notebook1.ipynb"]): self.nbconvert('notebook1.ipynb --log-level 0 --no-prompt --to html') assert os.path.isfile('notebook1.html') with open("notebook1.html",'r') as f: text = f.read() assert "In [" not in text assert "Out[" not in text self.nbconvert('notebook1.ipynb --log-level 0 --to html') assert os.path.isfile('notebook1.html') with open("notebook1.html",'r') as f: text2 = f.read() print(text2) assert "In [" in text2 assert "Out[" in text2 def test_allow_errors(self): """ Verify that conversion is aborted with '--execute' if an error is encountered, but that conversion continues if '--allow-errors' is used in addition. """ with self.create_temp_cwd(['notebook3*.ipynb']): # Convert notebook containing a cell that raises an error, # both without and with cell execution enabled. output1, _ = self.nbconvert('--to markdown --stdout notebook3*.ipynb') # no cell execution output2, _ = self.nbconvert('--to markdown --allow-errors --stdout notebook3*.ipynb') # no cell execution; --allow-errors should have no effect output3, _ = self.nbconvert('--execute --allow-errors --to markdown --stdout notebook3*.ipynb') # with cell execution; errors are allowed # Un-executed outputs should not contain either # of the two numbers computed in the notebook. assert '23' not in output1 assert '42' not in output1 assert '23' not in output2 assert '42' not in output2 # Executed output should contain both numbers. assert '23' in output3 assert '42' in output3 # Executing the notebook should raise an exception if --allow-errors is not specified with pytest.raises(OSError): self.nbconvert('--execute --to markdown --stdout notebook3*.ipynb') def test_errors_print_traceback(self): """ Verify that the stderr output contains the traceback of the cell execution exception. """ with self.create_temp_cwd(['notebook3_with_errors.ipynb']): _, error_output = self.nbconvert('--execute --to markdown --stdout notebook3_with_errors.ipynb', ignore_return_code=True) assert 'print("Some text before the error")' in error_output assert 'raise RuntimeError("This is a deliberate exception")' in error_output assert 'RuntimeError: This is a deliberate exception' in error_output def test_fenced_code_blocks_markdown(self): """ Verify that input cells use fenced code blocks with the language name in nb.metadata.kernelspec.language, if that exists """ with self.create_temp_cwd(["notebook1*.ipynb"]): # this notebook doesn't have nb.metadata.kernelspec, so it should # just do a fenced code block, with no language output1, _ = self.nbconvert('--to markdown --stdout notebook1.ipynb') assert '```python' not in output1 # shouldn't have language assert "```" in output1 # but should have fenced blocks with self.create_temp_cwd(["notebook_jl*.ipynb"]): output2, _ = self.nbconvert('--to markdown --stdout notebook_jl.ipynb') assert '```julia' in output2 # shouldn't have language assert "```" in output2 # but should also plain ``` to close cell def test_convert_from_stdin_to_stdout(self): """ Verify that conversion can be done via stdin to stdout """ with self.create_temp_cwd(["notebook1.ipynb"]): with io.open('notebook1.ipynb') as f: notebook = f.read().encode() output1, _ = self.nbconvert('--to markdown --stdin --stdout', stdin=notebook) assert '```python' not in output1 # shouldn't have language assert "```" in output1 # but should have fenced blocks def test_convert_from_stdin(self): """ Verify that conversion can be done via stdin. """ with self.create_temp_cwd(["notebook1.ipynb"]): with io.open('notebook1.ipynb') as f: notebook = f.read().encode() self.nbconvert('--to markdown --stdin', stdin=notebook) assert os.path.isfile("notebook.md") # default name for stdin input with io.open('notebook.md') as f: output1 = f.read() assert '```python' not in output1 # shouldn't have language assert "```" in output1 # but should have fenced blocks @dec.onlyif_cmds_exist('xelatex') @dec.onlyif_cmds_exist('pandoc') def test_linked_images(self): """ Generate PDFs with an image linked in a markdown cell """ with self.create_temp_cwd(['latex-linked-image.ipynb', 'testimage.png']): self.nbconvert('--to pdf latex-linked-image.ipynb') assert os.path.isfile('latex-linked-image.pdf') @dec.onlyif_cmds_exist('pandoc') def test_embedded_jpeg(self): """ Verify that latex conversion succeeds with a notebook with an embedded .jpeg """ with self.create_temp_cwd(['notebook4_jpeg.ipynb', 'containerized_deployments.jpeg']): self.nbconvert('--to latex notebook4_jpeg.ipynb') assert os.path.isfile('notebook4_jpeg.tex') @dec.onlyif_cmds_exist('pandoc') def test_markdown_display_priority(self): """ Check to see if markdown conversion embedds PNGs, even if an (unsupported) PDF is present. """ with self.create_temp_cwd(['markdown_display_priority.ipynb']): self.nbconvert('--log-level 0 --to markdown ' '"markdown_display_priority.ipynb"') assert os.path.isfile('markdown_display_priority.md') with io.open('markdown_display_priority.md') as f: markdown_output = f.read() assert ("markdown_display_priority_files/" "markdown_display_priority_0_1.png") in markdown_output @dec.onlyif_cmds_exist('pandoc') def test_write_figures_to_custom_path(self): """ Check if figure files are copied to configured path. """ def fig_exists(path): return (len(os.listdir(path)) > 0) # check absolute path with self.create_temp_cwd(['notebook4_jpeg.ipynb', 'containerized_deployments.jpeg']): output_dir = tempdir.TemporaryDirectory() path = os.path.join(output_dir.name, 'files') self.nbconvert( '--log-level 0 notebook4_jpeg.ipynb --to rst ' '--NbConvertApp.output_files_dir={}' .format(path)) assert fig_exists(path) output_dir.cleanup() # check relative path with self.create_temp_cwd(['notebook4_jpeg.ipynb', 'containerized_deployments.jpeg']): self.nbconvert( '--log-level 0 notebook4_jpeg.ipynb --to rst ' '--NbConvertApp.output_files_dir=output') assert fig_exists('output') # check default path with notebook name with self.create_temp_cwd(['notebook4_jpeg.ipynb', 'containerized_deployments.jpeg']): self.nbconvert( '--log-level 0 notebook4_jpeg.ipynb --to rst') assert fig_exists('notebook4_jpeg_files') nbconvert-5.3.1/nbconvert/utils/000077500000000000000000000000001315361605600166665ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/utils/__init__.py000066400000000000000000000000001315361605600207650ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/utils/base.py000066400000000000000000000020471315361605600201550ustar00rootroot00000000000000"""Global configuration class.""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from traitlets import List from traitlets.config.configurable import LoggingConfigurable from traitlets import Unicode class NbConvertBase(LoggingConfigurable): """Global configurable class for shared config Useful for display data priority that might be used by many transformers """ display_data_priority = List(['text/html', 'application/pdf', 'text/latex', 'image/svg+xml', 'image/png', 'image/jpeg', 'text/markdown', 'text/plain'], help= """ An ordered list of preferred output type, the first encountered will usually be used when converting discarding the others. """ ).tag(config=True) default_language = Unicode('ipython', help='Deprecated default highlight language as of 5.0, please use language_info metadata instead' ).tag(config=True) def __init__(self, **kw): super(NbConvertBase, self).__init__(**kw) nbconvert-5.3.1/nbconvert/utils/exceptions.py000066400000000000000000000012441315361605600214220ustar00rootroot00000000000000"""NbConvert specific exceptions""" #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- class ConversionException(Exception): """An exception raised by the conversion process.""" pass nbconvert-5.3.1/nbconvert/utils/io.py000066400000000000000000000024561315361605600176560ustar00rootroot00000000000000# coding: utf-8 """io-related utilities""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import codecs import sys from ipython_genutils.py3compat import PY3 def unicode_std_stream(stream='stdout'): u"""Get a wrapper to write unicode to stdout/stderr as UTF-8. This ignores environment variables and default encodings, to reliably write unicode to stdout or stderr. :: unicode_std_stream().write(u'ł@e¶ŧ←') """ assert stream in ('stdout', 'stderr') stream = getattr(sys, stream) if PY3: try: stream_b = stream.buffer except AttributeError: # sys.stdout has been replaced - use it directly return stream else: stream_b = stream return codecs.getwriter('utf-8')(stream_b) def unicode_stdin_stream(): u"""Get a wrapper to read unicode from stdin as UTF-8. This ignores environment variables and default encodings, to reliably read unicode from stdin. :: totreat = unicode_stdin_stream().read() """ stream = sys.stdin if PY3: try: stream_b = stream.buffer except AttributeError: return stream else: stream_b = stream return codecs.getreader('utf-8')(stream_b) nbconvert-5.3.1/nbconvert/utils/lexers.py000066400000000000000000000003201315361605600205350ustar00rootroot00000000000000"""Deprecated as of 5.0; import from IPython.lib.lexers instead.""" from warnings import warn warn("nbconvert.utils.lexers is deprecated as of 5.0. Use IPython.lib.lexers") from IPython.lib.lexers import * nbconvert-5.3.1/nbconvert/utils/pandoc.py000066400000000000000000000101021315361605600204760ustar00rootroot00000000000000"""Utility for calling pandoc""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function, absolute_import import subprocess import warnings import re from io import TextIOWrapper, BytesIO from nbconvert.utils.version import check_version from ipython_genutils.py3compat import cast_bytes, which from .exceptions import ConversionException _minimal_version = "1.12.1" def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'): """Convert an input string using pandoc. Pandoc converts an input string `from` a format `to` a target format. Parameters ---------- source : string Input string, assumed to be valid format `from`. fmt : string The name of the input format (markdown, etc.) to : string The name of the output format (html, etc.) Returns ------- out : unicode Output as returned by pandoc. Raises ------ PandocMissing If pandoc is not installed. Any error messages generated by pandoc are printed to stderr. """ cmd = ['pandoc', '-f', fmt, '-t', to] if extra_args: cmd.extend(extra_args) # this will raise an exception that will pop us out of here check_pandoc_version() # we can safely continue p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) out, _ = p.communicate(cast_bytes(source, encoding)) out = TextIOWrapper(BytesIO(out), encoding, 'replace').read() return out.rstrip('\n') def get_pandoc_version(): """Gets the Pandoc version if Pandoc is installed. If the minimal version is not met, it will probe Pandoc for its version, cache it and return that value. If the minimal version is met, it will return the cached version and stop probing Pandoc (unless :func:`clean_cache()` is called). Raises ------ PandocMissing If pandoc is unavailable. """ global __version if __version is None: if not which('pandoc'): raise PandocMissing() out = subprocess.check_output(['pandoc', '-v']) out_lines = out.splitlines() version_pattern = re.compile(r"^\d+(\.\d+){1,}$") for tok in out_lines[0].decode('ascii', 'replace').split(): if version_pattern.match(tok): __version = tok break return __version def check_pandoc_version(): """Returns True if pandoc's version meets at least minimal version. Raises ------ PandocMissing If pandoc is unavailable. """ v = get_pandoc_version() if v is None: warnings.warn("Sorry, we cannot determine the version of pandoc.\n" "Please consider reporting this issue and include the" "output of pandoc --version.\nContinuing...", RuntimeWarning, stacklevel=2) return False ok = check_version(v , _minimal_version ) if not ok: warnings.warn( "You are using an old version of pandoc (%s)\n" % v + "Recommended version is %s.\nTry updating." % _minimal_version + "http://pandoc.org/installing.html.\nContinuing with doubts...", RuntimeWarning, stacklevel=2) return ok #----------------------------------------------------------------------------- # Exception handling #----------------------------------------------------------------------------- class PandocMissing(ConversionException): """Exception raised when Pandoc is missing.""" def __init__(self, *args, **kwargs): super(PandocMissing, self).__init__( "Pandoc wasn't found.\n" + "Please check that pandoc is installed:\n" + "http://pandoc.org/installing.html" ) #----------------------------------------------------------------------------- # Internal state management #----------------------------------------------------------------------------- def clean_cache(): global __version __version = None __version = None nbconvert-5.3.1/nbconvert/utils/tests/000077500000000000000000000000001315361605600200305ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/utils/tests/__init__.py000066400000000000000000000000001315361605600221270ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/utils/tests/test_io.py000066400000000000000000000024151315361605600220520ustar00rootroot00000000000000# encoding: utf-8 """Tests for utils.io""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import io as stdlib_io import sys from ipython_genutils.testing.decorators import skipif from ..io import unicode_std_stream from ipython_genutils.py3compat import PY3 if PY3: from io import StringIO else: from StringIO import StringIO def test_UnicodeStdStream(): # Test wrapping a bytes-level stdout if PY3: stdoutb = stdlib_io.BytesIO() stdout = stdlib_io.TextIOWrapper(stdoutb, encoding='ascii') else: stdout = stdoutb = stdlib_io.BytesIO() orig_stdout = sys.stdout sys.stdout = stdout try: sample = u"@łe¶ŧ←" unicode_std_stream().write(sample) output = stdoutb.getvalue().decode('utf-8') assert output == sample assert not stdout.closed finally: sys.stdout = orig_stdout @skipif(not PY3, "Not applicable on Python 2") def test_UnicodeStdStream_nowrap(): # If we replace stdout with a StringIO, it shouldn't get wrapped. orig_stdout = sys.stdout sys.stdout = StringIO() try: assert unicode_std_stream() is sys.stdout assert not sys.stdout.closed finally: sys.stdout = orig_stdout nbconvert-5.3.1/nbconvert/utils/tests/test_pandoc.py000066400000000000000000000047631315361605600227170ustar00rootroot00000000000000"""Test Pandoc module""" #----------------------------------------------------------------------------- # Copyright (C) 2014 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import os import warnings from ipython_genutils.testing import decorators as dec from nbconvert.tests.base import TestsBase from .. import pandoc #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- class TestPandoc(TestsBase): """Collection of Pandoc tests""" def __init__(self, *args, **kwargs): super(TestPandoc, self).__init__(*args, **kwargs) self.original_env = os.environ.copy() @dec.onlyif_cmds_exist('pandoc') def test_pandoc_available(self): """ Test behaviour that pandoc functions raise PandocMissing as documented """ pandoc.clean_cache() os.environ["PATH"] = "" with self.assertRaises(pandoc.PandocMissing): pandoc.get_pandoc_version() with self.assertRaises(pandoc.PandocMissing): pandoc.check_pandoc_version() with self.assertRaises(pandoc.PandocMissing): pandoc.pandoc("", "markdown", "html") # original_env["PATH"] should contain pandoc os.environ["PATH"] = self.original_env["PATH"] with warnings.catch_warnings(record=True) as w: pandoc.get_pandoc_version() pandoc.check_pandoc_version() pandoc.pandoc("", "markdown", "html") self.assertEqual(w, []) @dec.onlyif_cmds_exist('pandoc') def test_minimal_version(self): original_minversion = pandoc._minimal_version pandoc._minimal_version = "120.0" with warnings.catch_warnings(record=True) as w: assert not pandoc.check_pandoc_version() self.assertEqual(len(w), 1) pandoc._minimal_version = pandoc.get_pandoc_version() assert pandoc.check_pandoc_version() def pandoc_function_raised_missing(f, *args, **kwargs): try: f(*args, **kwargs) except pandoc.PandocMissing: return True else: return False nbconvert-5.3.1/nbconvert/utils/version.py000066400000000000000000000014521315361605600207270ustar00rootroot00000000000000# encoding: utf-8 """ Utilities for version comparison It is a bit ridiculous that we need these. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from distutils.version import LooseVersion def check_version(v, check): """check version string v >= check Parameters ---------- v : str version of the package check : str minimal version required Note: If dev/prerelease tags result in TypeError for string-number comparison, it is assumed that the check passes and the version dependency is satisfied. Users on dev branches are responsible for keeping their own packages up to date. """ try: return LooseVersion(v) >= LooseVersion(check) except TypeError: return True nbconvert-5.3.1/nbconvert/writers/000077500000000000000000000000001315361605600172255ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/writers/__init__.py000066400000000000000000000001741315361605600213400ustar00rootroot00000000000000from .debug import DebugWriter from .files import FilesWriter from .stdout import StdoutWriter from .base import WriterBase nbconvert-5.3.1/nbconvert/writers/base.py000066400000000000000000000022311315361605600205070ustar00rootroot00000000000000""" Contains writer base class. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from traitlets import List from ..utils.base import NbConvertBase class WriterBase(NbConvertBase): """Consumes output from nbconvert export...() methods and writes to a useful location. """ files = List([], help=""" List of the files that the notebook references. Files will be included with written output.""").tag(config=True) def __init__(self, config=None, **kw): """ Constructor """ super(WriterBase, self).__init__(config=config, **kw) def write(self, output, resources, **kw): """ Consume and write Jinja output. Parameters ---------- output : string Conversion results. This string contains the file contents of the converted file. resources : dict Resources created and filled by the nbconvert conversion process. Includes output from preprocessors, such as the extract figure preprocessor. """ raise NotImplementedError() nbconvert-5.3.1/nbconvert/writers/debug.py000066400000000000000000000030131315361605600206620ustar00rootroot00000000000000""" Contains debug writer. """ from __future__ import print_function #----------------------------------------------------------------------------- #Copyright (c) 2013, the IPython Development Team. # #Distributed under the terms of the Modified BSD License. # #The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from .base import WriterBase from pprint import pprint #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- class DebugWriter(WriterBase): """Consumes output from nbconvert export...() methods and writes usefull debugging information to the stdout. The information includes a list of resources that were extracted from the notebook(s) during export.""" def write(self, output, resources, notebook_name='notebook', **kw): """ Consume and write Jinja output. See base for more... """ if isinstance(resources['outputs'], dict): print("outputs extracted from %s" % notebook_name) print('-' * 80) pprint(resources['outputs'], indent=2, width=70) else: print("no outputs extracted from %s" % notebook_name) print('=' * 80) nbconvert-5.3.1/nbconvert/writers/files.py000066400000000000000000000122701315361605600207030ustar00rootroot00000000000000"""Contains writer for writing nbconvert output to filesystem.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import io import os import glob from traitlets import Unicode, observe from ipython_genutils.path import link_or_copy, ensure_dir_exists from ipython_genutils.py3compat import unicode_type from .base import WriterBase class FilesWriter(WriterBase): """Consumes nbconvert output and produces files.""" build_directory = Unicode("", help="""Directory to write output(s) to. Defaults to output to the directory of each notebook. To recover previous default behaviour (outputting to the current working directory) use . as the flag value.""" ).tag(config=True) relpath = Unicode( help="""When copying files that the notebook depends on, copy them in relation to this path, such that the destination filename will be os.path.relpath(filename, relpath). If FilesWriter is operating on a notebook that already exists elsewhere on disk, then the default will be the directory containing that notebook.""" ).tag(config=True) # Make sure that the output directory exists. @observe('build_directory') def _build_directory_changed(self, change): new = change['new'] if new: ensure_dir_exists(new) def __init__(self, **kw): super(FilesWriter, self).__init__(**kw) self._build_directory_changed({'new': self.build_directory}) def _makedir(self, path): """Make a directory if it doesn't already exist""" if path: self.log.info("Making directory %s", path) ensure_dir_exists(path) def write(self, output, resources, notebook_name=None, **kw): """ Consume and write Jinja output to the file system. Output directory is set via the 'build_directory' variable of this instance (a configurable). See base for more... """ # Verify that a notebook name is provided. if notebook_name is None: raise TypeError('notebook_name') # Pull the extension and subdir from the resources dict. output_extension = resources.get('output_extension', None) # Get the relative path for copying files resource_path = resources.get('metadata', {}).get('path', '') relpath = self.relpath or resource_path build_directory = self.build_directory or resource_path # Write all of the extracted resources to the destination directory. # NOTE: WE WRITE EVERYTHING AS-IF IT'S BINARY. THE EXTRACT FIG # PREPROCESSOR SHOULD HANDLE UNIX/WINDOWS LINE ENDINGS... items = resources.get('outputs', {}).items() if items: self.log.info("Support files will be in %s", os.path.join(resources.get('output_files_dir',''), '')) for filename, data in items: # Determine where to write the file to dest = os.path.join(build_directory, filename) path = os.path.dirname(dest) self._makedir(path) # Write file self.log.debug("Writing %i bytes to support file %s", len(data), dest) with io.open(dest, 'wb') as f: f.write(data) # Copy referenced files to output directory if build_directory: for filename in self.files: # Copy files that match search pattern for matching_filename in glob.glob(filename): # compute the relative path for the filename if relpath != '': dest_filename = os.path.relpath(matching_filename, relpath) else: dest_filename = matching_filename # Make sure folder exists. dest = os.path.join(build_directory, dest_filename) path = os.path.dirname(dest) self._makedir(path) # Copy if destination is different. if not os.path.normpath(dest) == os.path.normpath(matching_filename): self.log.info("Copying %s -> %s", matching_filename, dest) link_or_copy(matching_filename, dest) # Determine where to write conversion results. if output_extension is not None: dest = notebook_name + output_extension else: dest = notebook_name dest = os.path.join(build_directory, dest) # Write conversion results. self.log.info("Writing %i bytes to %s", len(output), dest) if isinstance(output, unicode_type): with io.open(dest, 'w', encoding='utf-8') as f: f.write(output) else: with io.open(dest, 'wb') as f: f.write(output) return dest nbconvert-5.3.1/nbconvert/writers/stdout.py000066400000000000000000000010031315361605600211130ustar00rootroot00000000000000""" Contains Stdout writer """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from nbconvert.utils import io from .base import WriterBase class StdoutWriter(WriterBase): """Consumes output from nbconvert export...() methods and writes to the stdout stream.""" def write(self, output, resources, **kw): """ Consume and write Jinja output. See base for more... """ io.unicode_std_stream().write(output) nbconvert-5.3.1/nbconvert/writers/tests/000077500000000000000000000000001315361605600203675ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/writers/tests/__init__.py000066400000000000000000000000001315361605600224660ustar00rootroot00000000000000nbconvert-5.3.1/nbconvert/writers/tests/test_debug.py000066400000000000000000000031321315361605600230650ustar00rootroot00000000000000""" Module with tests for debug """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import sys from ...tests.base import TestsBase from ..debug import DebugWriter from ipython_genutils.py3compat import PY3 if PY3: from io import StringIO else: from StringIO import StringIO #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- class TestDebug(TestsBase): """Contains test functions for debug.py""" def test_output(self): """Test debug writer output.""" # Capture the stdout. Remember original. stdout = sys.stdout stream = StringIO() sys.stdout = stream # Create stdout writer, get output writer = DebugWriter() writer.write('aaa', {'outputs': {'bbb': 'ccc'}}) output = stream.getvalue() # Check output. Make sure resources dictionary is dumped, but nothing # else. assert 'aaa' not in output assert 'bbb' in output assert 'ccc' in output # Revert stdout sys.stdout = stdoutnbconvert-5.3.1/nbconvert/writers/tests/test_files.py000066400000000000000000000242331315361605600231060ustar00rootroot00000000000000""" Module with tests for files """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import os from ...tests.base import TestsBase from ..files import FilesWriter class Testfiles(TestsBase): """Contains test functions for files.py""" def test_basic_output(self): """Is FilesWriter basic output correct?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create the resoruces dictionary res = {} # Create files writer, test output writer = FilesWriter() writer.write(u'y', res, notebook_name="z") # Check the output of the file with open('z', 'r') as f: output = f.read() self.assertEqual(output, u'y') def test_ext(self): """Does the FilesWriter add the correct extension to the output?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create the resoruces dictionary res = {'output_extension': '.txt'} # Create files writer, test output writer = FilesWriter() writer.write(u'y', res, notebook_name="z") # Check the output of the file assert os.path.isfile('z.txt') with open('z.txt', 'r') as f: output = f.read() self.assertEqual(output, u'y') def test_extract(self): """Can FilesWriter write extracted figures correctly?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create the resoruces dictionary res = {'outputs': {os.path.join('z_files', 'a'): b'b'}} # Create files writer, test output writer = FilesWriter() writer.write(u'y', res, notebook_name="z") # Check the output of the file with open('z', 'r') as f: output = f.read() self.assertEqual(output, u'y') # Check the output of the extracted file extracted_file_dest = os.path.join('z_files', 'a') assert os.path.isfile(extracted_file_dest) with open(extracted_file_dest, 'r') as f: output = f.read() self.assertEqual(output, 'b') def test_build_dir(self): """Can FilesWriter write to a build dir correctly?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create the resoruces dictionary res = {'outputs': {os.path.join('z_files', 'a'): b'b'}} # Create files writer, test output writer = FilesWriter() writer.build_directory = u'build' writer.write(u'y', res, notebook_name="z") # Check the output of the file assert os.path.isdir(writer.build_directory) dest = os.path.join(writer.build_directory, 'z') with open(dest, 'r') as f: output = f.read() self.assertEqual(output, u'y') # Check the output of the extracted file extracted_file_dest = os.path.join(writer.build_directory, 'z_files', 'a') assert os.path.isfile(extracted_file_dest) with open(extracted_file_dest, 'r') as f: output = f.read() self.assertEqual(output, 'b') def test_build_dir_default(self): """FilesWriter defaults to input path""" with self.create_temp_cwd(): os.mkdir('sub') resources = { 'metadata': {'path': 'sub'} } writer = FilesWriter() writer.write(u'content', resources, notebook_name="out") dest = os.path.join('sub', 'out') assert os.path.isfile(dest) with open(dest) as f: self.assertEqual(f.read().strip(), 'content') def test_links(self): """Can the FilesWriter handle linked files correctly?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create test file os.mkdir('sub') with open(os.path.join('sub', 'c'), 'w') as f: f.write('d') # Create the resoruces dictionary res = {} # Create files writer, test output writer = FilesWriter() writer.files = [os.path.join('sub', 'c')] writer.build_directory = u'build' writer.write(u'y', res, notebook_name="z") # Check the output of the file assert os.path.isdir(writer.build_directory) dest = os.path.join(writer.build_directory, 'z') with open(dest, 'r') as f: output = f.read() self.assertEqual(output, u'y') # Check to make sure the linked file was copied path = os.path.join(writer.build_directory, 'sub') assert os.path.isdir(path) dest = os.path.join(path, 'c') assert os.path.isfile(dest) with open(dest, 'r') as f: output = f.read() self.assertEqual(output, 'd') def test_glob(self): """Can the FilesWriter handle globbed files correctly?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create test files os.mkdir('sub') with open(os.path.join('sub', 'c'), 'w') as f: f.write('e') with open(os.path.join('sub', 'd'), 'w') as f: f.write('e') # Create the resoruces dictionary res = {} # Create files writer, test output writer = FilesWriter() writer.files = ['sub/*'] writer.build_directory = u'build' writer.write(u'y', res, notebook_name="z") # Check the output of the file assert os.path.isdir(writer.build_directory) dest = os.path.join(writer.build_directory, 'z') with open(dest, 'r') as f: output = f.read() self.assertEqual(output, u'y') # Check to make sure the globbed files were copied path = os.path.join(writer.build_directory, 'sub') assert os.path.isdir(path) for filename in ['c', 'd']: dest = os.path.join(path, filename) assert os.path.isfile(dest) with open(dest, 'r') as f: output = f.read() self.assertEqual(output, 'e') def test_relpath(self): """Can the FilesWriter handle relative paths for linked files correctly?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create test file os.mkdir('sub') with open(os.path.join('sub', 'c'), 'w') as f: f.write('d') # Create the resoruces dictionary res = {} # Create files writer, test output writer = FilesWriter() writer.files = [os.path.join('sub', 'c')] writer.build_directory = u'build' writer.relpath = 'sub' writer.write(u'y', res, notebook_name="z") # Check the output of the file assert os.path.isdir(writer.build_directory) dest = os.path.join(writer.build_directory, 'z') with open(dest, 'r') as f: output = f.read() self.assertEqual(output, u'y') # Check to make sure the linked file was copied dest = os.path.join(writer.build_directory, 'c') assert os.path.isfile(dest) with open(dest, 'r') as f: output = f.read() self.assertEqual(output, 'd') def test_relpath_default(self): """Is the FilesWriter default relative path correct?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create test file os.mkdir('sub') with open(os.path.join('sub', 'c'), 'w') as f: f.write('d') # Create the resoruces dictionary res = dict(metadata=dict(path="sub")) # Create files writer, test output writer = FilesWriter() writer.files = [os.path.join('sub', 'c')] writer.build_directory = u'build' writer.write(u'y', res, notebook_name="z") # Check the output of the file assert os.path.isdir(writer.build_directory) dest = os.path.join(writer.build_directory, 'z') with open(dest, 'r') as f: output = f.read() self.assertEqual(output, u'y') # Check to make sure the linked file was copied dest = os.path.join(writer.build_directory, 'c') assert os.path.isfile(dest) with open(dest, 'r') as f: output = f.read() self.assertEqual(output, 'd') def test_relpath_precedence(self): """Does the FilesWriter relpath option take precedence over the path?""" # Work in a temporary directory. with self.create_temp_cwd(): # Create test file os.mkdir('sub') with open(os.path.join('sub', 'c'), 'w') as f: f.write('d') # Create the resoruces dictionary res = dict(metadata=dict(path="other_sub")) # Create files writer, test output writer = FilesWriter() writer.files = [os.path.join('sub', 'c')] writer.build_directory = u'build' writer.relpath = 'sub' writer.write(u'y', res, notebook_name="z") # Check the output of the file assert os.path.isdir(writer.build_directory) dest = os.path.join(writer.build_directory, 'z') with open(dest, 'r') as f: output = f.read() self.assertEqual(output, u'y') # Check to make sure the linked file was copied dest = os.path.join(writer.build_directory, 'c') assert os.path.isfile(dest) with open(dest, 'r') as f: output = f.read() self.assertEqual(output, 'd') nbconvert-5.3.1/nbconvert/writers/tests/test_stdout.py000066400000000000000000000030141315361605600233200ustar00rootroot00000000000000# coding: utf-8 """ Module with tests for stdout """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import sys from ...tests.base import TestsBase from ..stdout import StdoutWriter from ipython_genutils.py3compat import PY3 if PY3: from io import StringIO else: from StringIO import StringIO #----------------------------------------------------------------------------- # Class #----------------------------------------------------------------------------- class TestStdout(TestsBase): """Contains test functions for stdout.py""" def test_output(self): """Test stdout writer output.""" # Capture the stdout. Remember original. stdout = sys.stdout stream = StringIO() sys.stdout = stream # Create stdout writer, test output writer = StdoutWriter() writer.write(u'a×', {'b': 'c'}) output = stream.getvalue() if not PY3: output = output.decode('utf-8') self.fuzzy_compare(output, u'a×') # Revert stdout sys.stdout = stdoutnbconvert-5.3.1/readthedocs.yml000066400000000000000000000001251315361605600165340ustar00rootroot00000000000000conda: file: docs/environment.yml python: version: 3.5 pip_install: true nbconvert-5.3.1/scripts/000077500000000000000000000000001315361605600152155ustar00rootroot00000000000000nbconvert-5.3.1/scripts/jupyter-nbconvert000077500000000000000000000001461315361605600206440ustar00rootroot00000000000000#!/usr/bin/env python from nbconvert.nbconvertapp import main if __name__ == '__main__': main() nbconvert-5.3.1/setup.cfg000066400000000000000000000000321315361605600153420ustar00rootroot00000000000000[bdist_wheel] universal=1 nbconvert-5.3.1/setup.py000066400000000000000000000165441315361605600152520ustar00rootroot00000000000000#!/usr/bin/env python # coding: utf-8 # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function # the name of the package name = 'nbconvert' #----------------------------------------------------------------------------- # Minimal Python version sanity check #----------------------------------------------------------------------------- import sys v = sys.version_info if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)): error = "ERROR: %s requires Python version 2.7 or 3.3 or above." % name print(error, file=sys.stderr) sys.exit(1) PY3 = (sys.version_info[0] >= 3) #----------------------------------------------------------------------------- # get on with it #----------------------------------------------------------------------------- import os import setuptools from setuptools.command.bdist_egg import bdist_egg from glob import glob from io import BytesIO try: from urllib.request import urlopen except ImportError: from urllib import urlopen from distutils.core import setup from distutils.cmd import Command from distutils.command.build import build from distutils.command.sdist import sdist pjoin = os.path.join here = os.path.abspath(os.path.dirname(__file__)) pkg_root = pjoin(here, name) packages = [] for d, _, _ in os.walk(pjoin(here, name)): if os.path.exists(pjoin(d, '__init__.py')): packages.append(d[len(here)+1:].replace(os.path.sep, '.')) package_data = { 'nbconvert.filters' : ['marked.js'], 'nbconvert.resources' : ['style.min.css'], 'nbconvert' : [ 'tests/files/*.*', 'tests/exporter_entrypoint/*.py', 'tests/exporter_entrypoint/*/*.*', 'exporters/tests/files/*.*', 'preprocessors/tests/files/*.*', ], } notebook_css_version = '4.3.0' css_url = "https://cdn.jupyter.org/notebook/%s/style/style.min.css" % notebook_css_version class FetchCSS(Command): description = "Fetch Notebook CSS from Jupyter CDN" user_options = [] def initialize_options(self): pass def finalize_options(self): pass def _download(self): try: return urlopen(css_url).read() except Exception as e: if 'ssl' in str(e).lower(): try: import pycurl except ImportError: print("Failed, try again after installing PycURL with `pip install pycurl` to avoid outdated SSL.", file=sys.stderr) raise e else: print("Failed, trying again with PycURL to avoid outdated SSL.", file=sys.stderr) return self._download_pycurl() raise e def _download_pycurl(self): """Download CSS with pycurl, in case of old SSL (e.g. Python < 2.7.9).""" import pycurl c = pycurl.Curl() c.setopt(c.URL, css_url) buf = BytesIO() c.setopt(c.WRITEDATA, buf) c.perform() return buf.getvalue() def run(self): dest = os.path.join('nbconvert', 'resources', 'style.min.css') if not os.path.exists('.git') and os.path.exists(dest): # not running from git, nothing to do return print("Downloading CSS: %s" % css_url) try: css = self._download() except Exception as e: msg = "Failed to download css from %s: %s" % (css_url, e) print(msg, file=sys.stderr) if os.path.exists(dest): print("Already have CSS: %s, moving on." % dest) else: raise OSError("Need Notebook CSS to proceed: %s" % dest) return with open(dest, 'wb') as f: f.write(css) print("Downloaded Notebook CSS to %s" % dest) cmdclass = {'css': FetchCSS} class bdist_egg_disabled(bdist_egg): """Disabled version of bdist_egg Prevents setup.py install performing setuptools' default easy_install, which it should never ever do. """ def run(self): sys.exit("Aborting implicit building of eggs. Use `pip install .` to install from source.") def css_first(command): class CSSFirst(command): def run(self): self.distribution.run_command('css') return command.run(self) return CSSFirst cmdclass['build'] = css_first(build) cmdclass['sdist'] = css_first(sdist) cmdclass['bdist_egg'] = bdist_egg if 'bdist_egg' in sys.argv else bdist_egg_disabled for d, _, _ in os.walk(pjoin(pkg_root, 'templates')): g = pjoin(d[len(pkg_root)+1:], '*.*') package_data['nbconvert'].append(g) version_ns = {} with open(pjoin(here, name, '_version.py')) as f: exec(f.read(), {}, version_ns) setup_args = dict( name = name, description = "Converting Jupyter Notebooks", version = version_ns['__version__'], scripts = glob(pjoin('scripts', '*')), packages = packages, package_data = package_data, cmdclass = cmdclass, author = 'Jupyter Development Team', author_email = 'jupyter@googlegroups.com', url = 'http://jupyter.org', license = 'BSD', platforms = "Linux, Mac OS X, Windows", keywords = ['Interactive', 'Interpreter', 'Shell', 'Web'], classifiers = [ 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', ], ) setuptools_args = {} install_requires = setuptools_args['install_requires'] = [ 'mistune>=0.7.4', 'jinja2', 'pygments', 'traitlets>=4.2', 'jupyter_core', 'nbformat>=4.4', 'entrypoints>=0.2.2', 'bleach', 'pandocfilters>=1.4.1', 'testpath', ] extra_requirements = { 'test': ['pytest', 'pytest-cov', 'ipykernel', 'jupyter_client>=4.2'], 'serve': ['tornado>=4.0'], 'execute': ['jupyter_client>=4.2'], } extra_requirements['all'] = sum(extra_requirements.values(), []) setuptools_args['extras_require'] = extra_requirements if 'setuptools' in sys.modules: from setuptools.command.develop import develop cmdclass['develop'] = css_first(develop) # force entrypoints with setuptools (needed for Windows, unconditional because of wheels) setup_args['entry_points'] = { 'console_scripts': [ 'jupyter-nbconvert = nbconvert.nbconvertapp:main', ], "nbconvert.exporters" : [ 'custom=nbconvert.exporters:TemplateExporter', 'html=nbconvert.exporters:HTMLExporter', 'slides=nbconvert.exporters:SlidesExporter', 'latex=nbconvert.exporters:LatexExporter', 'pdf=nbconvert.exporters:PDFExporter', 'markdown=nbconvert.exporters:MarkdownExporter', 'python=nbconvert.exporters:PythonExporter', 'rst=nbconvert.exporters:RSTExporter', 'notebook=nbconvert.exporters:NotebookExporter', 'asciidoc=nbconvert.exporters:ASCIIDocExporter', 'script=nbconvert.exporters:ScriptExporter'] } setup_args.pop('scripts', None) setup_args.update(setuptools_args) if __name__ == '__main__': setup(**setup_args)