[med-svn] [python-biom-format] 02/05: Imported Upstream version 2.1.4+dfsg

Andreas Tille tille at debian.org
Tue Oct 27 17:58:59 UTC 2015


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository python-biom-format.

commit 4838a061cfab1e86e40f3edcfc70c460ba39c3ab
Author: Andreas Tille <tille at debian.org>
Date:   Tue Oct 27 18:31:46 2015 +0100

    Imported Upstream version 2.1.4+dfsg
---
 .coveragerc                                        |   17 +
 .travis.yml                                        |   35 +
 ChangeLog.md                                       |   33 +-
 INSTALL                                            |   24 +
 MANIFEST.in                                        |    1 +
 PKG-INFO                                           |   30 -
 README.md                                          |    3 +-
 biom/__init__.py                                   |    5 +-
 biom/cli/__init__.py                               |   31 -
 biom/cli/installation_informer.py                  |  121 ---
 biom/cli/metadata_adder.py                         |  186 ----
 biom/cli/table_converter.py                        |  209 ----
 biom/cli/table_head.py                             |   46 -
 biom/cli/table_normalizer.py                       |   74 --
 biom/cli/table_subsetter.py                        |  139 ---
 biom/cli/table_summarizer.py                       |  136 ---
 biom/cli/uc_processor.py                           |   85 --
 biom/cli/util.py                                   |   35 -
 biom/commands/__init__.py                          |    0
 biom/commands/installation_informer.py             |  123 +++
 biom/commands/metadata_adder.py                    |  165 +++
 biom/commands/table_converter.py                   |  221 ++++
 biom/commands/table_normalizer.py                  |   91 ++
 biom/commands/table_subsetter.py                   |  122 +++
 biom/commands/table_summarizer.py                  |  168 +++
 biom/{cli => commands}/table_validator.py          |  107 +-
 biom/interfaces/__init__.py                        |    0
 biom/interfaces/html/__init__.py                   |    0
 biom/interfaces/html/config/__init__.py            |    0
 biom/interfaces/html/config/add_metadata.py        |   99 ++
 biom/interfaces/html/config/convert.py             |   74 ++
 biom/interfaces/html/config/normalize_table.py     |   56 +
 biom/interfaces/html/config/show_install_info.py   |   36 +
 biom/interfaces/html/config/summarize_table.py     |   53 +
 biom/interfaces/html/config/validate_table.py      |   55 +
 biom/interfaces/html/input_handler.py              |   56 +
 .../interfaces/html/output_handler.py              |    4 +-
 biom/interfaces/optparse/__init__.py               |    0
 biom/interfaces/optparse/config/__init__.py        |    0
 biom/interfaces/optparse/config/add_metadata.py    |  114 ++
 biom/interfaces/optparse/config/convert.py         |   81 ++
 biom/interfaces/optparse/config/normalize_table.py |   84 ++
 .../optparse/config/show_install_info.py           |   39 +
 biom/interfaces/optparse/config/subset_table.py    |   77 ++
 biom/interfaces/optparse/config/summarize_table.py |   64 ++
 biom/interfaces/optparse/config/validate_table.py  |   65 ++
 biom/interfaces/optparse/input_handler.py          |   79 ++
 biom/interfaces/optparse/output_handler.py         |   80 ++
 biom/parse.py                                      |  114 +-
 biom/table.py                                      |  261 ++---
 biom/util.py                                       |   26 +-
 doc/conf.py                                        |    4 +-
 doc/index.rst                                      |   88 +-
 images/biom-logos.ai                               | 1124 ++++++++++++++++++++
 licenses/numpydoc.txt                              |    1 +
 licenses/scikit-learn.txt                          |   35 +
 licenses/scipy.txt                                 |   31 +
 scripts/biom                                       |   22 +
 scripts/serve-biom                                 |   11 +
 setup.cfg                                          |    5 -
 setup.py                                           |   40 +-
 tests/bench_tables/10000x10000x0.001_bench.biom.gz |  Bin 0 -> 229557 bytes
 .../10000x10000x0.001_bench_hdf5.biom.gz           |  Bin 0 -> 642038 bytes
 tests/bench_tables/10000x10000x0.010_bench.biom.gz |  Bin 0 -> 2345285 bytes
 .../10000x10000x0.010_bench_hdf5.biom.gz           |  Bin 0 -> 814036 bytes
 tests/bench_tables/10000x10000x0.100_bench.biom.gz |  Bin 0 -> 23248570 bytes
 .../10000x10000x0.100_bench_hdf5.biom.gz           |  Bin 0 -> 4671830 bytes
 tests/bench_tables/10000x1000x0.001_bench.biom.gz  |  Bin 0 -> 69230 bytes
 .../10000x1000x0.001_bench_hdf5.biom.gz            |  Bin 0 -> 362557 bytes
 tests/bench_tables/10000x1000x0.010_bench.biom.gz  |  Bin 0 -> 320640 bytes
 .../10000x1000x0.010_bench_hdf5.biom.gz            |  Bin 0 -> 485677 bytes
 tests/bench_tables/10000x1000x0.100_bench.biom.gz  |  Bin 0 -> 2659788 bytes
 .../10000x1000x0.100_bench_hdf5.biom.gz            |  Bin 0 -> 1873395 bytes
 tests/bench_tables/10000x100x0.001_bench.biom.gz   |  Bin 0 -> 27854 bytes
 .../10000x100x0.001_bench_hdf5.biom.gz             |  Bin 0 -> 313875 bytes
 tests/bench_tables/10000x100x0.010_bench.biom.gz   |  Bin 0 -> 64621 bytes
 .../10000x100x0.010_bench_hdf5.biom.gz             |  Bin 0 -> 345814 bytes
 tests/bench_tables/10000x100x0.100_bench.biom.gz   |  Bin 0 -> 241263 bytes
 .../10000x100x0.100_bench_hdf5.biom.gz             |  Bin 0 -> 433017 bytes
 tests/bench_tables/10000x10x0.001_bench.biom.gz    |  Bin 0 -> 24427 bytes
 .../bench_tables/10000x10x0.001_bench_hdf5.biom.gz |  Bin 0 -> 311609 bytes
 tests/bench_tables/10000x10x0.010_bench.biom.gz    |  Bin 0 -> 26800 bytes
 .../bench_tables/10000x10x0.010_bench_hdf5.biom.gz |  Bin 0 -> 313657 bytes
 tests/bench_tables/10000x10x0.100_bench.biom.gz    |  Bin 0 -> 50797 bytes
 .../bench_tables/10000x10x0.100_bench_hdf5.biom.gz |  Bin 0 -> 340159 bytes
 tests/bench_tables/1000x10000x0.001_bench.biom.gz  |  Bin 0 -> 62599 bytes
 .../1000x10000x0.001_bench_hdf5.biom.gz            |  Bin 0 -> 362607 bytes
 tests/bench_tables/1000x10000x0.010_bench.biom.gz  |  Bin 0 -> 319000 bytes
 .../1000x10000x0.010_bench_hdf5.biom.gz            |  Bin 0 -> 530288 bytes
 tests/bench_tables/1000x10000x0.100_bench.biom.gz  |  Bin 0 -> 2588217 bytes
 .../1000x10000x0.100_bench_hdf5.biom.gz            |  Bin 0 -> 2485734 bytes
 tests/bench_tables/1000x1000x0.001_bench.biom.gz   |  Bin 0 -> 8166 bytes
 .../1000x1000x0.001_bench_hdf5.biom.gz             |  Bin 0 -> 90203 bytes
 tests/bench_tables/1000x1000x0.010_bench.biom.gz   |  Bin 0 -> 22915 bytes
 .../1000x1000x0.010_bench_hdf5.biom.gz             |  Bin 0 -> 92248 bytes
 tests/bench_tables/1000x1000x0.100_bench.biom.gz   |  Bin 0 -> 234452 bytes
 .../1000x1000x0.100_bench_hdf5.biom.gz             |  Bin 0 -> 113800 bytes
 tests/bench_tables/1000x100x0.001_bench.biom.gz    |  Bin 0 -> 3266 bytes
 .../bench_tables/1000x100x0.001_bench_hdf5.biom.gz |  Bin 0 -> 65803 bytes
 tests/bench_tables/1000x100x0.010_bench.biom.gz    |  Bin 0 -> 6512 bytes
 .../bench_tables/1000x100x0.010_bench_hdf5.biom.gz |  Bin 0 -> 68066 bytes
 tests/bench_tables/1000x100x0.100_bench.biom.gz    |  Bin 0 -> 29839 bytes
 .../bench_tables/1000x100x0.100_bench_hdf5.biom.gz |  Bin 0 -> 80553 bytes
 tests/bench_tables/1000x10x0.001_bench.biom.gz     |  Bin 0 -> 2795 bytes
 .../bench_tables/1000x10x0.001_bench_hdf5.biom.gz  |  Bin 0 -> 65803 bytes
 tests/bench_tables/1000x10x0.010_bench.biom.gz     |  Bin 0 -> 3083 bytes
 .../bench_tables/1000x10x0.010_bench_hdf5.biom.gz  |  Bin 0 -> 65803 bytes
 tests/bench_tables/1000x10x0.100_bench.biom.gz     |  Bin 0 -> 5583 bytes
 .../bench_tables/1000x10x0.100_bench_hdf5.biom.gz  |  Bin 0 -> 67851 bytes
 tests/bench_tables/100x10000x0.001_bench.biom.gz   |  Bin 0 -> 28147 bytes
 .../100x10000x0.001_bench_hdf5.biom.gz             |  Bin 0 -> 315597 bytes
 tests/bench_tables/100x10000x0.010_bench.biom.gz   |  Bin 0 -> 59244 bytes
 .../100x10000x0.010_bench_hdf5.biom.gz             |  Bin 0 -> 345664 bytes
 tests/bench_tables/100x10000x0.100_bench.biom.gz   |  Bin 0 -> 264503 bytes
 .../100x10000x0.100_bench_hdf5.biom.gz             |  Bin 0 -> 521065 bytes
 tests/bench_tables/100x1000x0.001_bench.biom.gz    |  Bin 0 -> 3236 bytes
 .../bench_tables/100x1000x0.001_bench_hdf5.biom.gz |  Bin 0 -> 65695 bytes
 tests/bench_tables/100x1000x0.010_bench.biom.gz    |  Bin 0 -> 6257 bytes
 .../bench_tables/100x1000x0.010_bench_hdf5.biom.gz |  Bin 0 -> 67743 bytes
 tests/bench_tables/100x1000x0.100_bench.biom.gz    |  Bin 0 -> 27986 bytes
 .../bench_tables/100x1000x0.100_bench_hdf5.biom.gz |  Bin 0 -> 87589 bytes
 tests/bench_tables/100x100x0.001_bench.biom.gz     |  Bin 0 -> 590 bytes
 .../bench_tables/100x100x0.001_bench_hdf5.biom.gz  |  Bin 0 -> 35080 bytes
 tests/bench_tables/100x100x0.010_bench.biom.gz     |  Bin 0 -> 952 bytes
 .../bench_tables/100x100x0.010_bench_hdf5.biom.gz  |  Bin 0 -> 35080 bytes
 tests/bench_tables/100x100x0.100_bench.biom.gz     |  Bin 0 -> 2395 bytes
 .../bench_tables/100x100x0.100_bench_hdf5.biom.gz  |  Bin 0 -> 35080 bytes
 tests/bench_tables/100x10x0.001_bench.biom.gz      |  Bin 0 -> 527 bytes
 tests/bench_tables/100x10x0.001_bench_hdf5.biom.gz |  Bin 0 -> 30984 bytes
 tests/bench_tables/100x10x0.010_bench.biom.gz      |  Bin 0 -> 562 bytes
 tests/bench_tables/100x10x0.010_bench_hdf5.biom.gz |  Bin 0 -> 30984 bytes
 tests/bench_tables/100x10x0.100_bench.biom.gz      |  Bin 0 -> 808 bytes
 tests/bench_tables/100x10x0.100_bench_hdf5.biom.gz |  Bin 0 -> 30984 bytes
 tests/bench_tables/10x10000x0.001_bench.biom.gz    |  Bin 0 -> 24370 bytes
 .../bench_tables/10x10000x0.001_bench_hdf5.biom.gz |  Bin 0 -> 311616 bytes
 tests/bench_tables/10x10000x0.010_bench.biom.gz    |  Bin 0 -> 26450 bytes
 .../bench_tables/10x10000x0.010_bench_hdf5.biom.gz |  Bin 0 -> 313659 bytes
 tests/bench_tables/10x10000x0.100_bench.biom.gz    |  Bin 0 -> 49427 bytes
 .../bench_tables/10x10000x0.100_bench_hdf5.biom.gz |  Bin 0 -> 340204 bytes
 tests/bench_tables/10x1000x0.001_bench.biom.gz     |  Bin 0 -> 2795 bytes
 .../bench_tables/10x1000x0.001_bench_hdf5.biom.gz  |  Bin 0 -> 65792 bytes
 tests/bench_tables/10x1000x0.010_bench.biom.gz     |  Bin 0 -> 3046 bytes
 .../bench_tables/10x1000x0.010_bench_hdf5.biom.gz  |  Bin 0 -> 65792 bytes
 tests/bench_tables/10x1000x0.100_bench.biom.gz     |  Bin 0 -> 5308 bytes
 .../bench_tables/10x1000x0.100_bench_hdf5.biom.gz  |  Bin 0 -> 67839 bytes
 tests/bench_tables/10x100x0.001_bench.biom.gz      |  Bin 0 -> 527 bytes
 tests/bench_tables/10x100x0.001_bench_hdf5.biom.gz |  Bin 0 -> 30984 bytes
 tests/bench_tables/10x100x0.010_bench.biom.gz      |  Bin 0 -> 561 bytes
 tests/bench_tables/10x100x0.010_bench_hdf5.biom.gz |  Bin 0 -> 30984 bytes
 tests/bench_tables/10x100x0.100_bench.biom.gz      |  Bin 0 -> 770 bytes
 tests/bench_tables/10x100x0.100_bench_hdf5.biom.gz |  Bin 0 -> 30984 bytes
 tests/bench_tables/10x10x0.001_bench.biom.gz       |  Bin 0 -> 299 bytes
 tests/bench_tables/10x10x0.001_bench_hdf5.biom.gz  |  Bin 0 -> 30984 bytes
 tests/bench_tables/10x10x0.010_bench.biom.gz       |  Bin 0 -> 301 bytes
 tests/bench_tables/10x10x0.010_bench_hdf5.biom.gz  |  Bin 0 -> 30984 bytes
 tests/bench_tables/10x10x0.100_bench.biom.gz       |  Bin 0 -> 334 bytes
 tests/bench_tables/10x10x0.100_bench_hdf5.biom.gz  |  Bin 0 -> 30984 bytes
 tests/test_cli/test_show_install_info.py           |   24 -
 tests/test_cli/test_summarize_table.py             |  122 ---
 tests/test_cli/test_table_normalizer.py            |   50 -
 tests/test_cli/test_uc_processor.py                |  109 --
 tests/test_commands/__init__.py                    |    0
 .../test_data/json_obs_collapsed.biom              |    1 +
 .../test_data/json_sample_collapsed.biom           |    1 +
 tests/test_commands/test_data/test.biom            |  Bin 0 -> 46952 bytes
 tests/test_commands/test_installation_informer.py  |   40 +
 .../test_metadata_adder.py}                        |   47 +-
 .../test_table_converter.py                        |  256 +++--
 tests/test_commands/test_table_normalizer.py       |   56 +
 .../test_table_subsetter.py}                       |   82 +-
 tests/test_commands/test_table_summarizer.py       |  132 +++
 .../test_table_validator.py}                       |    2 +-
 tests/test_data/empty.biom                         |  Bin 0 -> 21224 bytes
 tests/test_data/no-contents.biom                   |    0
 tests/test_data/test.biom                          |  Bin 0 -> 46952 bytes
 tests/test_data/test.json                          |    1 +
 tests/test_data/test.json.gz                       |  Bin 0 -> 678 bytes
 tests/test_interfaces/__init__.py                  |    0
 tests/test_interfaces/test_optparse/__init__.py    |    0
 .../test_optparse/test_input_handler.py            |  118 ++
 tests/test_parse.py                                |  143 +--
 tests/test_table.py                                |  152 +--
 tests/test_util.py                                 |    2 +-
 183 files changed, 4180 insertions(+), 2243 deletions(-)

diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 0000000..de07e8a
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,17 @@
+[run]
+omit =
+    */tests*
+    */__init__.py
+source = biom
+branch = True
+include = */biom/*
+
+[report]
+exclude_lines =
+    pragma: no cover
+    def __repr__
+    raise NotImplementedError
+    if __name__ == .__main__.:
+omit =
+    */tests*
+    */__init__.py
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..3e59cb5
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,35 @@
+# Modified from https://github.com/biocore/scikit-bio/
+language: python
+python:
+  - "2.7"
+env:
+  - NUMPY_VERSION=1.7
+  - NUMPY_VERSION=1.8
+  - NUMPY_VERSION=1.8 USE_H5PY=True
+  - NUMPY_VERSION=1.8 USE_CYTHON=True
+  - NUMPY_VERSION=1.7 USE_H5PY=True
+before_install:
+  - wget http://repo.continuum.io/miniconda/Miniconda3-3.7.3-Linux-x86_64.sh -O miniconda.sh
+  - chmod +x miniconda.sh
+  - ./miniconda.sh -b
+  - export PATH=/home/travis/miniconda3/bin:$PATH
+  # Update conda itself
+  - conda update --yes conda
+install:
+  - conda create --yes -n env_name python=$TRAVIS_PYTHON_VERSION pip numpy=$NUMPY_VERSION scipy nose pep8 Sphinx coverage
+  - if [ ${USE_CYTHON} ]; then conda install --yes -n env_name cython; fi
+  - if [ ${USE_H5PY} ]; then conda install --yes -n env_name h5py>=2.2.0; fi
+  - source activate env_name
+  - pip install coveralls pyqi
+  - pip install -e . --no-deps
+script:
+  - nosetests --with-doctest --with-coverage
+  - pep8 biom setup.py
+  - biom show-install-info
+  - make -C doc html
+  # we can only validate the tables if we have H5PY
+  - if [ ${USE_H5PY} ]; then for table in examples/*hdf5.biom; do echo ${table}; biom validate-table -i ${table}; done; fi
+  # validate JSON formatted tables
+  - for table in examples/*table.biom; do echo ${table}; biom validate-table -i ${table}; done;
+after_success:
+  - coveralls
diff --git a/ChangeLog.md b/ChangeLog.md
index 0eeec8e..eebf2fe 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,37 +1,6 @@
 BIOM-Format ChangeLog
 =====================
 
-biom 2.1.5
-----------
-
-New features and bug fixes, released on 21 October 2015.
-
-Changes:
-
-* Codebase is now Python 2/3 compatible. It is currently tested with Python
-  versions 2.7, 3.4 and 3.5.
-* `biom-serve` and the accompanying html interface has been removed.
-
-New Features:
-
-* `Table.head` has been added to retrieve the first few rows and or columns
-  from a table. This can be accessed through the new ``biom head`` command.
-  See [issue #639](https://github.com/biocore/biom-format/issues/639).
-* ``biom.parse.from_uc`` has been added to support creation of ``biom.Table``
-  objects from vsearch/uclust/usearch ``.uc`` files. This can be accessed
-  through the new ``biom from-uc`` command. See
-  [issue #648](https://github.com/biocore/biom-format/issues/648).
-* Codebase now uses [click](http://click.pocoo.org) instead of
-  [pyqi](https://github.com/biocore/pyqi) for its command line interface.
-  See [issue #631](https://github.com/biocore/biom-format/issues/631).
-
-Bug fixes:
-
-* `Table.update_ids` strict check was too aggressive. See
- [issue #633](https://github.com/biocore/biom-format/issues/633).
-* `biom --version` now prints the software version (previously the individual
-  commands did this, but not the base command).
-
 biom 2.1.4
 ----------
 
@@ -41,7 +10,7 @@ Changes:
 
 * Codebase updated to reflect pep8 1.6.x
 
-New features:
+Changes:
 
 * `Table.to_hdf5` and `Table.from_hdf5` now support custom parsers and
     formatters, see issue #608
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..08c4af0
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,24 @@
+INSTALL
+=======
+
+More details can be found at http://biom-format.org
+
+To build, simply run:
+
+$ python setup.py build
+
+To install into your home directory:
+
+$ python setup.py install --prefix=$HOME
+
+To install system-wide:
+
+$ python setup.py install
+
+If you have Sphinx installed, you can build the documentation locally with:
+
+$ cd doc; make html
+
+If you have nose installed, you can run the unit tests with:
+
+$ nosetests
diff --git a/MANIFEST.in b/MANIFEST.in
index 7f908c9..5e27d9a 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -5,6 +5,7 @@ include ChangeLog.md
 graft biom
 graft support_files
 graft examples
+graft scripts
 graft doc
 
 prune docs/_build
diff --git a/PKG-INFO b/PKG-INFO
deleted file mode 100644
index 6bcbffe..0000000
--- a/PKG-INFO
+++ /dev/null
@@ -1,30 +0,0 @@
-Metadata-Version: 1.1
-Name: biom-format
-Version: 2.1.5
-Summary: Biological Observation Matrix (BIOM) format
-Home-page: http://www.biom-format.org
-Author: Daniel McDonald
-Author-email: mcdonadt at colorado.edu
-License: BSD
-Description: BIOM: Biological Observation Matrix
-        http://www.biom-format.org
-        
-        The Biological Observation Matrix (BIOM) format or: how I learned to stop
-        worrying and love the ome-ome
-        Daniel McDonald, Jose C Clemente, Justin Kuczynski, Jai Ram Rideout,
-        Jesse Stombaugh, Doug Wendel, Andreas Wilke, Susan Huse, John Hufnagle,
-        Folker Meyer, Rob Knight, J Gregory Caporaso
-        GigaScience 2012, 1:7.
-        
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
-Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Operating System :: OS Independent
-Classifier: Operating System :: POSIX :: Linux
-Classifier: Operating System :: MacOS :: MacOS X
diff --git a/README.md b/README.md
index 6aba07f..0c347fc 100644
--- a/README.md
+++ b/README.md
@@ -12,4 +12,5 @@ Further details can be found at http://biom-format.org.
 Getting help
 ------------
 
-To get help with biom, you should use the [biom](http://stackoverflow.com/questions/tagged/biom) tag on StackOverflow (SO), or post the the [QIIME Forum](http://forum.qiime.org). Before posting a question, check out SO's guide on how to [ask a question](http://stackoverflow.com/questions/how-to-ask). The biom-format developers regularly monitor the `biom` SO tag.
+To get help with biom, you should use the [biom](http://stackoverflow.com/questions/tagged/biom) tag on StackOverflow (SO). Before posting a question, check out SO's guide on how to [ask a question](http://stackoverflow.com/questions/how-to-ask). The biom-format developers regularly monitor the `biom` SO tag.
+
diff --git a/biom/__init__.py b/biom/__init__.py
index 388709c..4266584 100755
--- a/biom/__init__.py
+++ b/biom/__init__.py
@@ -41,7 +41,7 @@ either in TSV, HDF5, JSON, gzip'd JSON or gzip'd TSV and parse accordingly:
 
 """
 # ----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
 #
 # Distributed under the terms of the Modified BSD License.
 #
@@ -73,5 +73,4 @@ example_table = Table([[0, 1, 2], [3, 4, 5]], ['O1', 'O2'],
                        {'environment': 'A'}], input_is_dense=True)
 
 
-__all__ = ['Table', 'example_table', 'parse_table', 'load_table',
-           '__format_version__', '__version__']
+__all__ = ['Table', 'example_table', 'parse_table', 'load_table']
diff --git a/biom/cli/__init__.py b/biom/cli/__init__.py
deleted file mode 100644
index 1cbc08c..0000000
--- a/biom/cli/__init__.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# ----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# ----------------------------------------------------------------------------
-
-from __future__ import division
-
-from importlib import import_module
-
-import click
-import biom
-
-
- at click.group()
- at click.version_option(version=biom.__version__)
-def cli():
-    pass
-
-
-import_module('biom.cli.table_summarizer')
-import_module('biom.cli.metadata_adder')
-import_module('biom.cli.table_converter')
-import_module('biom.cli.installation_informer')
-import_module('biom.cli.table_subsetter')
-import_module('biom.cli.table_normalizer')
-import_module('biom.cli.table_head')
-import_module('biom.cli.table_validator')
-import_module('biom.cli.uc_processor')
diff --git a/biom/cli/installation_informer.py b/biom/cli/installation_informer.py
deleted file mode 100644
index 9e3a999..0000000
--- a/biom/cli/installation_informer.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-from __future__ import division
-
-import sys
-
-import click
-
-from biom.cli import cli
-
-
- at cli.command(name='show-install-info')
-def show_install_info():
-    """Provide information about the biom-format installation.
-
-    Provide information about the biom-format installation, including settings
-    pulled from the configuration file. For more details, see
-    http://biom-format.org
-
-    Example usage:
-
-    Display biom-format installation information:
-
-    $ biom show-install-info
-
-    """
-    click.echo(_show_install_info())
-
-
-def _show_install_info():
-    lines = []
-    lines.extend(_get_formatted_system_info())
-    lines.extend(_get_formatted_dependency_version_info())
-    lines.extend(_get_formatted_package_info())
-    lines.append('')
-    return '\n'.join(lines)
-
-
-def _get_formatted_system_info():
-    return _format_info(_get_system_info(), 'System information')
-
-
-def _get_formatted_dependency_version_info():
-    return _format_info(_get_dependency_version_info(), 'Dependency versions')
-
-
-def _get_formatted_package_info():
-    return _format_info(_get_package_info(), 'biom-format package information')
-
-
-def _get_system_info():
-    return (("Platform", sys.platform),
-            ("Python version", sys.version.replace('\n', ' ')),
-            ("Python executable", sys.executable))
-
-
-def _get_dependency_version_info():
-    not_installed_msg = "Not installed"
-
-    try:
-        from click import __version__ as click_lib_version
-    except ImportError:
-        click_lib_version = not_installed_msg
-
-    try:
-        from numpy import __version__ as numpy_lib_version
-    except ImportError:
-        numpy_lib_version = ("ERROR: Not installed - this is required! "
-                             "(This will also cause the BIOM library to "
-                             "not be importable.)")
-
-    try:
-        from scipy import __version__ as scipy_lib_version
-    except ImportError:
-        scipy_lib_version = not_installed_msg
-
-    try:
-        from h5py import __version__ as h5py_lib_version
-    except ImportError:
-        h5py_lib_version = ("WARNING: Not installed - this is an optional "
-                            "dependency. It is strongly recommended for "
-                            "large datasets.")
-
-    return (("click version", click_lib_version),
-            ("NumPy version", numpy_lib_version),
-            ("SciPy version", scipy_lib_version),
-            ("h5py version", h5py_lib_version))
-
-
-def _get_package_info():
-    import_error_msg = ("ERROR: Can't find the BIOM library code (or "
-                        "numpy) - is it installed and in your "
-                        "$PYTHONPATH?")
-    try:
-        from biom import __version__ as biom_lib_version
-    except ImportError:
-        biom_lib_version = import_error_msg
-
-    return (("biom-format version", biom_lib_version),)
-
-
-def _format_info(info, title):
-    max_len = _get_max_length(info)
-
-    lines = ['']
-    lines.append(title)
-    lines.append('=' * len(title))
-    for e in info:
-        lines.append("%*s:\t%s" % (max_len, e[0], e[1]))
-
-    return lines
-
-
-def _get_max_length(info):
-    return max([len(e[0]) for e in info])
diff --git a/biom/cli/metadata_adder.py b/biom/cli/metadata_adder.py
deleted file mode 100644
index 96e2660..0000000
--- a/biom/cli/metadata_adder.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-from __future__ import division
-
-import click
-
-from biom import load_table
-from biom.cli import cli
-from biom.cli.util import write_biom_table
-from biom.parse import MetadataMap
-from biom.util import HAVE_H5PY
-
-
- at cli.command(name='add-metadata')
- at click.option('-i', '--input-fp', required=True,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The input BIOM table')
- at click.option('-o', '--output-fp', required=True,
-              type=click.Path(exists=False, dir_okay=False),
-              help='The output BIOM table')
- at click.option('-m', '--sample-metadata-fp', required=False,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The sample metadata mapping file (will add sample '
-                   'metadata to the input BIOM table, if provided).')
- at click.option('--observation-metadata-fp', required=False,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The observation metadata mapping file (will add '
-                   'observation metadata to the input BIOM table, if '
-                   'provided).')
- at click.option('--sc-separated', required=False, type=click.STRING,
-              help='Comma-separated list of the metadata fields to split '
-                   'on semicolons. This is useful for hierarchical data such '
-                   'as taxonomy or functional categories.')
- at click.option('--sc-pipe-separated', required=False, type=click.STRING,
-              help='Comma-separated list of the metadata fields to split '
-                   'on semicolons and pipes ("|"). This is useful for '
-                   'hierarchical data such as functional categories with '
-                   'one-to-many mappings (e.g. x;y;z|x;y;w)).')
- at click.option('--int-fields', required=False, type=click.STRING,
-              help='Comma-separated list of the metadata fields to cast '
-                   'to integers. This is useful for integer data such as '
-                   '"DaysSinceStart".')
- at click.option('--float-fields', required=False, type=click.STRING,
-              help='Comma-separated list of the metadata fields to cast '
-                   'to floating point numbers. This is useful for real number '
-                   'data such as "pH".')
- at click.option('--sample-header', required=False, type=click.STRING,
-              help='Comma-separated list of the sample metadata field '
-                   'names. This is useful if a header line is not provided '
-                   'with the metadata, if you want to rename the fields, or '
-                   'if you want to include only the first n fields where n is '
-                   'the number of entries provided here.')
- at click.option('--observation-header', required=False, type=click.STRING,
-              help='Comma-separated list of the observation metadata '
-                   'field names. This is useful if a header line is not '
-                   'provided with the metadata, if you want to rename the '
-                   'fields, or if you want to include only the first n fields '
-                   'where n is the number of entries provided here.')
- at click.option('--output-as-json', default=not HAVE_H5PY, is_flag=True,
-              help='Write the output file in JSON format.')
-def add_metadata(input_fp, output_fp, sample_metadata_fp,
-                 observation_metadata_fp, sc_separated, sc_pipe_separated,
-                 int_fields, float_fields, sample_header, observation_header,
-                 output_as_json):
-    """Add metadata to a BIOM table.
-
-    Add sample and/or observation metadata to BIOM-formatted files. See
-    examples here: http://biom-format.org/documentation/adding_metadata.html
-
-    Example usage:
-
-    Add sample metadata to a BIOM table:
-
-    $ biom add-metadata -i otu_table.biom -o table_with_sample_metadata.biom
-      -m sample_metadata.txt
-    """
-    table = load_table(input_fp)
-    if sample_metadata_fp is not None:
-        sample_metadata_f = open(sample_metadata_fp, 'U')
-    else:
-        sample_metadata_f = None
-    if observation_metadata_fp is not None:
-        observation_metadata_f = open(observation_metadata_fp, 'U')
-    else:
-        observation_metadata_f = None
-    if sc_separated is not None:
-        sc_separated = sc_separated.split(',')
-    if sc_pipe_separated is not None:
-        sc_pipe_separated = sc_pipe_separated.split(',')
-    if int_fields is not None:
-        int_fields = int_fields.split(',')
-    if float_fields is not None:
-        float_fields = float_fields.split(',')
-    if sample_header is not None:
-        sample_header = sample_header.split(',')
-    if observation_header is not None:
-        observation_header = observation_header.split(',')
-
-    result = _add_metadata(table, sample_metadata_f, observation_metadata_f,
-                           sc_separated, sc_pipe_separated, int_fields,
-                           float_fields, sample_header, observation_header)
-
-    if output_as_json:
-        fmt = 'json'
-    else:
-        fmt = 'hdf5'
-
-    write_biom_table(result, fmt, output_fp)
-
-
-def _split_on_semicolons(x):
-    return [e.strip() for e in x.split(';')]
-
-
-def _split_on_semicolons_and_pipes(x):
-    return [[e.strip() for e in y.split(';')] for y in x.split('|')]
-
-
-def _int(x):
-    try:
-        return int(x)
-    except ValueError:
-        return x
-
-
-def _float(x):
-    try:
-        return float(x)
-    except ValueError:
-        return x
-
-
-def _add_metadata(table, sample_metadata=None, observation_metadata=None,
-                  sc_separated=None, sc_pipe_separated=None, int_fields=None,
-                  float_fields=None, sample_header=None,
-                  observation_header=None):
-
-    if sample_metadata is None and observation_metadata is None:
-        raise ValueError('Must specify sample_metadata and/or '
-                         'observation_metadata.')
-
-    # define metadata processing functions, if any
-    process_fns = {}
-    if sc_separated is not None:
-        process_fns.update(dict.fromkeys(sc_separated,
-                                         _split_on_semicolons))
-
-    if sc_pipe_separated is not None:
-        process_fns.update(dict.fromkeys(sc_pipe_separated,
-                           _split_on_semicolons_and_pipes))
-
-    if int_fields is not None:
-        process_fns.update(dict.fromkeys(int_fields, _int))
-
-    if float_fields is not None:
-        process_fns.update(dict.fromkeys(float_fields, _float))
-
-    # parse mapping files
-    if sample_metadata is not None:
-        sample_metadata = MetadataMap.from_file(sample_metadata,
-                                                process_fns=process_fns,
-                                                header=sample_header)
-
-    if observation_metadata is not None:
-        observation_metadata = MetadataMap.from_file(
-            observation_metadata,
-            process_fns=process_fns,
-            header=observation_header)
-
-    # NAUGHTY: this is modifying the input table IN PLACE!!! And then
-    # RETURNING IT! MetadataAdder is angry!
-
-    # add metadata as necessary
-    if sample_metadata:
-        table.add_metadata(sample_metadata, axis='sample')
-
-    if observation_metadata:
-        table.add_metadata(observation_metadata, axis='observation')
-
-    return table
diff --git a/biom/cli/table_converter.py b/biom/cli/table_converter.py
deleted file mode 100644
index 2506e0d..0000000
--- a/biom/cli/table_converter.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-from __future__ import division
-
-import click
-
-from biom import load_table
-from biom.cli import cli
-from biom.cli.util import write_biom_table
-from biom.parse import MetadataMap
-
-
-table_types = ["OTU table",
-               "Pathway table",
-               "Function table",
-               "Ortholog table",
-               "Gene table",
-               "Metabolite table",
-               "Taxon table",
-               "Table"]
-
-observation_metadata_types = {
-    'sc_separated': lambda x: [e.strip() for e in x.split(';')],
-    'naive': lambda x: x
-}
-observation_metadata_types['taxonomy'] = \
-    observation_metadata_types['sc_separated']
-
-observation_metadata_formatters = {
-    'sc_separated': lambda x: '; '.join(x),
-    'naive': lambda x: x
-}
-
-
- at cli.command(name='convert')
- at click.option('-i', '--input-fp', required=True,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The input BIOM table')
- at click.option('-o', '--output-fp', required=True,
-              type=click.Path(exists=False, dir_okay=False),
-              help='The output BIOM table')
- at click.option('-m', '--sample-metadata-fp', required=False,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The sample metadata mapping file (will add sample '
-                   'metadata to the input BIOM table, if provided).')
- at click.option('--observation-metadata-fp', required=False,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The observation metadata mapping file (will add '
-                   'observation metadata to the input BIOM table, if '
-                   'provided).')
- at click.option('--to-json', default=False, is_flag=True,
-              help='Output as JSON-formatted table.')
- at click.option('--to-hdf5', default=False, is_flag=True,
-              help='Output as HDF5-formatted table.')
- at click.option('--to-tsv', default=False, is_flag=True,
-              help='Output as TSV-formatted (classic) table.')
- at click.option('--collapsed-samples', default=False, is_flag=True,
-              help='If --to_hdf5 is passed and the original table is a '
-                   'BIOM table with collapsed samples, this will '
-                   'update the sample metadata of the table to '
-                   'the supported HDF5 collapsed format.')
- at click.option('--collapsed-observations', default=False, is_flag=True,
-              help='If --to_hdf5 is passed and the original table is a '
-                   'BIOM table with collapsed observations, this will '
-                   'update the observation metadata of the table '
-                   'to the supported HDF5 collapsed format.')
- at click.option('--header-key', required=False, type=click.STRING,
-              help='The observation metadata to include from the input '
-                   'BIOM table file when creating a tsv table file. '
-                   'By default no observation metadata will be included.')
- at click.option('--output-metadata-id', required=False, type=click.STRING,
-              help='The name to be given to the observation metadata '
-                   'column when creating a tsv table file if the column '
-                   'should be renamed.')
- at click.option('--table-type', required=False,
-              type=click.Choice(table_types),
-              help='The type of the table.')
- at click.option('--process-obs-metadata', required=False,
-              type=click.Choice(
-                observation_metadata_types),
-              help='Process metadata associated with observations when '
-              'converting from a classic table.')
- at click.option('--tsv-metadata-formatter', required=False,
-              default='sc_separated',
-              type=click.Choice(
-                observation_metadata_formatters),
-              help='Method for formatting the observation metadata.')
-def convert(input_fp, output_fp, sample_metadata_fp, observation_metadata_fp,
-            to_json, to_hdf5, to_tsv, collapsed_samples,
-            collapsed_observations, header_key, output_metadata_id, table_type,
-            process_obs_metadata, tsv_metadata_formatter):
-    """Convert to/from the BIOM table format.
-
-    Convert between BIOM table formats. See examples here:
-    http://biom-format.org/documentation/biom_conversion.html
-
-    Example usage:
-
-    Convert a "classic" BIOM file (tab-separated text) to an HDF5 BIOM
-    formatted OTU table:
-
-    $ biom convert -i table.txt -o table.biom --to-hdf5
-    """
-    if sum([to_tsv, to_hdf5, to_json]) > 1:
-        raise ValueError("--to-tsv, --to-json, and --to-hdf5 are mutually "
-                         "exclusive. You can only pass one of these options.")
-
-    table = load_table(input_fp)
-    if sample_metadata_fp is not None:
-        with open(sample_metadata_fp, 'U') as f:
-            sample_metadata_f = MetadataMap.from_file(f)
-    else:
-        sample_metadata_f = None
-    if observation_metadata_fp is not None:
-        with open(observation_metadata_fp, 'U') as f:
-            observation_metadata_f = MetadataMap.from_file(f)
-    else:
-        observation_metadata_f = None
-
-    _convert(table, output_fp, sample_metadata_f, observation_metadata_f,
-             to_json, to_hdf5, to_tsv, collapsed_samples,
-             collapsed_observations, header_key, output_metadata_id,
-             table_type, process_obs_metadata, tsv_metadata_formatter)
-
-
-def _convert(table, output_filepath, sample_metadata=None,
-             observation_metadata=None, to_json=False, to_hdf5=False,
-             to_tsv=False, collapsed_samples=False,
-             collapsed_observations=False, header_key=None,
-             output_metadata_id=None, table_type=None,
-             process_obs_metadata=None, tsv_metadata_formatter='sc_separated'):
-
-    if sum([to_tsv, to_hdf5, to_json]) == 0:
-        raise ValueError("Must specify an output format")
-    elif sum([to_tsv, to_hdf5, to_json]) > 1:
-        raise ValueError("Can only specify a single output format")
-
-    if table_type is None:
-        if table.type in [None, "None"]:
-            table.type = "Table"
-        else:
-            pass
-    else:
-        table.type = table_type
-
-    if tsv_metadata_formatter is not None:
-        obs_md_fmt_f = observation_metadata_formatters[tsv_metadata_formatter]
-
-    if sample_metadata is not None:
-        table.add_metadata(sample_metadata)
-
-    # if the user does not specify a name for the output metadata column,
-    # set it to the same as the header key
-    output_metadata_id = output_metadata_id or header_key
-
-    if process_obs_metadata is not None and not to_tsv:
-        if table.metadata(axis='observation') is None:
-            raise ValueError("Observation metadata processing requested "
-                             "but it doesn't appear that there is any "
-                             "metadata to operate on!")
-
-        # and if this came in as TSV, then we expect only a single type of
-        # metadata
-        md_key = list(table.metadata(axis='observation')[0].keys())[0]
-
-        process_f = observation_metadata_types[process_obs_metadata]
-        it = zip(table.ids(axis='observation'),
-                 table.metadata(axis='observation'))
-        new_md = {id_: {md_key: process_f(md[md_key])} for id_, md in it}
-
-        if observation_metadata:
-            for k, v in observation_metadata.items():
-                new_md[k].update(v)
-        table.add_metadata(new_md, 'observation')
-
-    if to_tsv:
-        result = table.to_tsv(header_key=header_key,
-                              header_value=output_metadata_id,
-                              metadata_formatter=obs_md_fmt_f)
-        with open(output_filepath, 'w') as f:
-            f.write(result)
-        return
-    elif to_json:
-        fmt = 'json'
-        result = table
-    elif to_hdf5:
-        fmt = 'hdf5'
-        result = table
-        if collapsed_observations:
-            metadata = [{'collapsed_ids': sorted(md.keys())}
-                        for md in result.metadata(axis='observation')]
-            result._observation_metadata = metadata
-        if collapsed_samples:
-            metadata = [{'collapsed_ids': sorted(md.keys())}
-                        for md in result.metadata()]
-            result._sample_metadata = metadata
-        if collapsed_observations or collapsed_samples:
-            # We have changed the metadata, it is safer to make sure that
-            # it is correct
-            result._cast_metadata()
-    write_biom_table(result, fmt, output_filepath)
-
-    return
diff --git a/biom/cli/table_head.py b/biom/cli/table_head.py
deleted file mode 100644
index 9d924c7..0000000
--- a/biom/cli/table_head.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# ----------------------------------------------------------------------------
-# Copyright (c) 2011-2013, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# ----------------------------------------------------------------------------
-
-from __future__ import division
-
-import click
-
-from biom import load_table
-from biom.cli import cli
-
-
- at cli.command()
- at click.option('-i', '--input-fp', required=True,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The input BIOM table')
- at click.option('-o', '--output-fp', default=None,
-              type=click.Path(writable=True),
-              help='An output file-path', required=False)
- at click.option('-n', '--n-obs', default=5, type=int,
-              help="The number of observations to show",
-              required=False)
- at click.option('-m', '--n-samp', default=5, type=int,
-              help="The number of samples to show",
-              required=False)
-def head(input_fp, output_fp, n_obs, n_samp):
-    """Dump the first bit of a table.
-
-    Example usage:
-
-    Print out the upper left corner of a BIOM table to standard out:
-
-    $ biom head -i table.biom
-
-    """
-    table = load_table(input_fp).head(n=n_obs, m=n_samp)
-
-    if output_fp is None:
-        click.echo(str(table))
-    else:
-        with open(output_fp, 'w') as fp:
-            fp.write(str(table))
diff --git a/biom/cli/table_normalizer.py b/biom/cli/table_normalizer.py
deleted file mode 100755
index cad6ebf..0000000
--- a/biom/cli/table_normalizer.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python
-
-# ----------------------------------------------------------------------------
-# Copyright (c) 2011-2013, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# ----------------------------------------------------------------------------
-
-from __future__ import division
-
-import click
-
-from biom import load_table
-from biom.cli import cli
-from biom.cli.util import write_biom_table
-from biom.util import HAVE_H5PY
-
-
- at cli.command(name='normalize-table')
- at click.option('-i', '--input-fp', required=True,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The input BIOM table')
- at click.option('-o', '--output-fp', default=None,
-              type=click.Path(writable=True),
-              help='An output file-path')
- at click.option('-r', '--relative-abund', default=False, is_flag=True,
-              help='convert table to relative abundance',
-              required=False)
- at click.option('-p', '--presence-absence', default=False, is_flag=True,
-              help='convert table to presence/absence',
-              required=False)
- at click.option('-a', '--axis', default='sample',
-              type=click.Choice(['sample', 'observation']),
-              help='The axis to normalize over')
-def normalize_table(input_fp, output_fp, relative_abund, presence_absence,
-                    axis):
-    """Normalize a BIOM table.
-
-    Normalize the values of a BIOM table through various methods. Relative
-    abundance will take the relative abundance of each observation in terms of
-    samples or observations.  Presence absensece will convert observations to
-    1's and 0's based on presence of the observation.
-
-    Example usage:
-
-    Normalizing a BIOM table to relative abundnace:
-
-    $ biom normalize-table -i table.biom -r -o normalized_table.biom
-
-    Converting a BIOM table to a presence/absence table:
-
-    $ biom normalize-table -i table.biom -p -o converted_table.biom
-    """
-    table = load_table(input_fp)
-    result = _normalize_table(table, relative_abund, presence_absence, axis)
-
-    write_biom_table(result, 'hdf5' if HAVE_H5PY else 'json', output_fp)
-
-
-def _normalize_table(table, relative_abund=False, presence_absence=False,
-                     axis='sample'):
-    if relative_abund is False and presence_absence is False:
-        raise ValueError("Must specifiy a normalization type")
-    elif relative_abund is True and presence_absence is True:
-        raise ValueError("Must specify only one normalization type")
-
-    if relative_abund:
-        table.norm(axis=axis)
-    else:
-        table.pa()
-
-    return table
diff --git a/biom/cli/table_subsetter.py b/biom/cli/table_subsetter.py
deleted file mode 100644
index fa056f2..0000000
--- a/biom/cli/table_subsetter.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-from __future__ import division
-
-import click
-
-from biom.cli import cli
-from biom.parse import (get_axis_indices, direct_slice_data, direct_parse_key,
-                        generatedby)
-from biom.table import Table
-from biom.util import biom_open, HAVE_H5PY
-
-
- at cli.command(name='subset-table')
- at click.option('-i', '--input-hdf5-fp', default=None,
-              type=click.Path(exists=True, dir_okay=False),
-              help='the input hdf5 BIOM table filepath to subset')
- at click.option('-j', '--input-json-fp', default=None,
-              type=click.Path(exists=True, dir_okay=False),
-              help='the input json BIOM table filepath to subset')
- at click.option('-a', '--axis', required=True,
-              type=click.Choice(['sample', 'observation']),
-              help='the axis to subset over, either sample or observation')
- at click.option('-s', '--ids', required=True,
-              type=click.Path(exists=True, dir_okay=False),
-              help='a file containing a single column of IDs to retain '
-                   '(either sample IDs or observation IDs, depending on the '
-                   'axis)')
- at click.option('-o', '--output-fp', required=True,
-              type=click.Path(writable=True, dir_okay=False),
-              help='the output BIOM table filepath')
-def subset_table(input_hdf5_fp, input_json_fp, axis, ids, output_fp):
-    """Subset a BIOM table.
-
-    Subset a BIOM table, over either observations or samples, without fully
-    parsing it. This command is intended to assist in working with very large
-    tables when tight on memory, or as a lightweight way to subset a full
-    table. Currently, it is possible to produce tables with rows or columns
-    (observations or samples) that are fully zeroed.
-
-    Example usage:
-
-    Choose a subset of the observations in table.biom (JSON) and write them to
-    subset.biom:
-
-    $ biom subset-table -j table.biom -a observations -s observation_ids.txt \
-           -o subset.biom
-
-    Choose a subset of the observations in table.biom (HDF5) and write them to
-    subset.biom:
-
-    $ biom subset-table -i table.biom -a observations -s observation_ids.txt \
-           -o subset.biom
-
-    """
-    if input_json_fp is not None:
-        with open(input_json_fp, 'U') as f:
-            input_json_fp = f.read()
-
-    with open(ids, 'U') as f:
-        ids = [line.strip() for line in f]
-
-    table, format_ = _subset_table(input_hdf5_fp, input_json_fp, axis, ids)
-
-    if format_ == 'json':
-        with open(output_fp, 'w') as f:
-            for line in table:
-                f.write(line)
-                f.write('\n')
-    else:
-        if HAVE_H5PY:
-            import h5py
-        else:
-            # This should never be raised here
-            raise ImportError("h5py is not available, cannot write HDF5!")
-
-        with h5py.File(output_fp, 'w') as f:
-            table.to_hdf5(f, generatedby())
-
-
-def _subset_table(hdf5_biom, json_table_str, axis, ids):
-    if axis not in ['sample', 'observation']:
-        raise ValueError("Invalid axis '%s'. Must be either 'sample' or "
-                         "'observation'." % axis)
-
-    if hdf5_biom is None and json_table_str is None:
-        raise ValueError("Must specify an input table")
-    elif hdf5_biom is not None and json_table_str is not None:
-        raise ValueError("Can only specify one input table")
-
-    if json_table_str is not None:
-        idxs, new_axis_md = get_axis_indices(json_table_str, ids, axis)
-        new_data = direct_slice_data(json_table_str, idxs, axis)
-
-        # multiple walks over the string. bad form, but easy right now
-        # ...should add a yield_and_ignore parser or something.
-        def subset_generator():
-            yield "{"
-            yield direct_parse_key(json_table_str, "id")
-            yield ","
-            yield direct_parse_key(json_table_str, "format")
-            yield ","
-            yield direct_parse_key(json_table_str, "format_url")
-            yield ","
-            yield direct_parse_key(json_table_str, "type")
-            yield ","
-            yield direct_parse_key(json_table_str, "generated_by")
-            yield ","
-            yield direct_parse_key(json_table_str, "date")
-            yield ","
-            yield direct_parse_key(json_table_str, "matrix_type")
-            yield ","
-            yield direct_parse_key(json_table_str, "matrix_element_type")
-            yield ","
-            yield new_data
-            yield ","
-            yield new_axis_md
-            yield ","
-
-            if axis == "observation":
-                yield direct_parse_key(json_table_str, "columns")
-            else:
-                yield direct_parse_key(json_table_str, "rows")
-            yield "}"
-
-        format_ = 'json'
-        table = subset_generator()
-    else:
-        with biom_open(hdf5_biom) as f:
-            table = Table.from_hdf5(f, ids=ids, axis=axis)
-        format_ = 'hdf5'
-
-    return table, format_
diff --git a/biom/cli/table_summarizer.py b/biom/cli/table_summarizer.py
deleted file mode 100644
index 77a0778..0000000
--- a/biom/cli/table_summarizer.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-from __future__ import division
-
-from operator import itemgetter
-
-import click
-from numpy import std
-
-from biom import load_table
-from biom.cli import cli
-from biom.util import compute_counts_per_sample_stats
-
-
- at cli.command(name='summarize-table')
- at click.option('-i', '--input-fp', required=True,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The input BIOM table')
- at click.option('-o', '--output-fp', default=None,
-              type=click.Path(writable=True, dir_okay=False),
-              help='An output file-path')
- at click.option('--qualitative', default=False, is_flag=True,
-              help="Present counts as number of unique observation ids per"
-                   " sample, rather than counts of observations per sample.")
- at click.option('--observations', default=False, is_flag=True,
-              help="Summarize over observations")
-def summarize_table(input_fp, output_fp, qualitative, observations):
-    """Summarize sample or observation data in a BIOM table.
-
-    Provides details on the observation counts per sample, including summary
-    statistics, as well as metadata categories associated with samples and
-    observations.
-
-    Example usage:
-
-    Write a summary of table.biom to table_summary.txt:
-
-    $ biom summarize-table -i table.biom -o table_summary.txt
-
-    """
-    table = load_table(input_fp)
-    result = _summarize_table(table, qualitative, observations)
-    if output_fp:
-        with open(output_fp, 'w') as fh:
-            fh.write(result)
-    else:
-        click.echo(result)
-
-
-def _summarize_table(table, qualitative=False, observations=False):
-    lines = []
-
-    if observations:
-        table = table.transpose()
-
-    min_counts, max_counts, median_counts, mean_counts, counts_per_samp =\
-        compute_counts_per_sample_stats(table, qualitative)
-    num_observations = len(table.ids(axis='observation'))
-
-    counts_per_sample_values = list(counts_per_samp.values())
-
-    if table.metadata() is None:
-        sample_md_keys = ["None provided"]
-    else:
-        sample_md_keys = table.metadata()[0].keys()
-
-    if table.metadata(axis='observation') is None:
-        observation_md_keys = ["None provided"]
-    else:
-        observation_md_keys = table.metadata(axis='observation')[0].keys()
-
-    num_samples = len(table.ids())
-
-    if observations:
-        # as this is a transpose of the original table...
-        lines.append('Num samples: %d' % num_observations)
-        lines.append('Num observations: %d' % num_samples)
-    else:
-        lines.append('Num samples: %d' % num_samples)
-        lines.append('Num observations: %d' % num_observations)
-
-    if not qualitative:
-        total_count = sum(counts_per_sample_values)
-        lines.append('Total count: %d' % total_count)
-        lines.append('Table density (fraction of non-zero values): %1.3f' %
-                     table.get_table_density())
-
-    lines.append('')
-
-    if qualitative:
-        if observations:
-            lines.append('Sample/observations summary:')
-        else:
-            lines.append('Observations/sample summary:')
-    else:
-        lines.append('Counts/sample summary:')
-
-    lines.append(' Min: %r' % min_counts)
-    lines.append(' Max: %r' % max_counts)
-    lines.append(' Median: %1.3f' % median_counts)
-    lines.append(' Mean: %1.3f' % mean_counts)
-    lines.append(' Std. dev.: %1.3f' % std(counts_per_sample_values))
-
-    if observations:
-        # since this is a transpose...
-        lines.append(
-            ' Sample Metadata Categories: %s' %
-            '; '.join(observation_md_keys))
-        lines.append(
-            ' Observation Metadata Categories: %s' %
-            '; '.join(sample_md_keys))
-        lines.append('')
-    else:
-        lines.append(
-            ' Sample Metadata Categories: %s' %
-            '; '.join(sample_md_keys))
-        lines.append(
-            ' Observation Metadata Categories: %s' %
-            '; '.join(observation_md_keys))
-        lines.append('')
-
-    if qualitative:
-        lines.append('Observations/sample detail:')
-    else:
-        lines.append('Counts/sample detail:')
-
-    for k, v in sorted(counts_per_samp.items(), key=itemgetter(1)):
-        lines.append('%s: %r' % (k, v))
-
-    return "\n".join(lines)
diff --git a/biom/cli/uc_processor.py b/biom/cli/uc_processor.py
deleted file mode 100644
index 9534d73..0000000
--- a/biom/cli/uc_processor.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# ----------------------------------------------------------------------------
-# Copyright (c) 2011-2013, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# ----------------------------------------------------------------------------
-
-from __future__ import division
-
-import click
-
-from biom.cli import cli
-from biom.cli.util import write_biom_table
-from biom.parse import parse_uc
-from biom.exception import TableException
-
-
- at cli.command('from-uc')
- at click.option('-i', '--input-fp', required=True,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The input uc filepath.')
- at click.option('-o', '--output-fp', default=None,
-              type=click.Path(writable=True),
-              help='The output BIOM filepath', required=False)
- at click.option('--rep-set-fp', type=click.Path(exists=True, dir_okay=False),
-              help="Fasta file containing representative sequences with "
-                   "where sequences are labeled with OTU identifiers, and "
-                   "description fields contain original sequence identifiers. "
-                   "This output is created, for example, by vsearch with the "
-                   "--relabel_sha1 --relabel_keep options.",
-              required=False)
-def from_uc(input_fp, output_fp, rep_set_fp):
-    """Create a BIOM table from a vsearch/uclust/usearch BIOM file.
-
-    Example usage:
-
-    Simple BIOM creation:
-
-    $ biom from-uc -i in.uc -o out.biom
-
-    BIOM creation with OTU re-naming:
-
-    $ biom from-uc -i in.uc -o out.biom --rep-set-fp rep-set.fna
-
-    """
-    input_f = open(input_fp, 'U')
-    if rep_set_fp is not None:
-        rep_set_f = open(rep_set_fp, 'U')
-    else:
-        rep_set_f = None
-    table = _from_uc(input_f, rep_set_f)
-    write_biom_table(table, 'hdf5', output_fp)
-
-
-def _id_map_from_fasta(fasta_lines):
-    result = {}
-    for line in fasta_lines:
-        if line.startswith('>'):
-            try:
-                obs_id, seq_id = line.split()[:2]
-            except ValueError:
-                raise ValueError('Sequence identifiers in fasta file '
-                                 'must contain at least two space-'
-                                 'separated fields.')
-            result[seq_id] = obs_id[1:]
-        else:
-            pass
-    return result
-
-
-def _from_uc(input_f, rep_set_f=None):
-    table = parse_uc(input_f)
-
-    if rep_set_f is not None:
-        obs_id_map = _id_map_from_fasta(rep_set_f)
-        try:
-            table.update_ids(obs_id_map, axis='observation', strict=True,
-                             inplace=True)
-        except TableException:
-            raise ValueError('Not all sequence identifiers in the input BIOM '
-                             'file are present in description fields in the '
-                             'representative sequence fasta file.')
-
-    return table
diff --git a/biom/cli/util.py b/biom/cli/util.py
deleted file mode 100644
index 8b5c972..0000000
--- a/biom/cli/util.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# ----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# ----------------------------------------------------------------------------
-
-from __future__ import division
-
-import biom.util
-import biom.parse
-
-
-def write_biom_table(table, fmt, filepath):
-    """Write table in specified format to filepath"""
-
-    if fmt not in ['hdf5', 'json', 'tsv']:
-        raise ValueError("Unknown file format")
-
-    if fmt == 'hdf5' and not biom.util.HAVE_H5PY:
-        fmt = 'json'
-
-    if fmt == 'json':
-        with open(filepath, 'w') as f:
-            f.write(table.to_json(biom.parse.generatedby()))
-    elif fmt == 'tsv':
-        with open(filepath, 'w') as f:
-            f.write(table)
-            f.write('\n')
-    else:
-        import h5py
-
-        with h5py.File(filepath, 'w') as f:
-            table.to_hdf5(f, biom.parse.generatedby())
diff --git a/biom/commands/__init__.py b/biom/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/biom/commands/installation_informer.py b/biom/commands/installation_informer.py
new file mode 100644
index 0000000..11b126f
--- /dev/null
+++ b/biom/commands/installation_informer.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from __future__ import division
+from sys import platform, version as python_version, executable
+from pyqi.core.command import Command, CommandOut, ParameterCollection
+
+__author__ = "Greg Caporaso"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Daniel McDonald", "Jose Clemente", "Greg Caporaso",
+               "Jai Ram Rideout", "Justin Kuczynski", "Andreas Wilke",
+               "Tobias Paczian", "Rob Knight", "Folker Meyer", "Sue Huse"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+
+class InstallationInformer(Command):
+    BriefDescription = ("Provide information about the biom-format "
+                        "installation")
+    LongDescription = ("Provide information about the biom-format "
+                       "installation, including settings pulled from the "
+                       "configuration file. For more details, see "
+                       "http://biom-format.org")
+    CommandIns = ParameterCollection([])
+    CommandOuts = ParameterCollection([
+        CommandOut(Name='install_info_lines',
+                   DataType='str',
+                   Description='Installation info')
+    ])
+
+    def run(self, **kwargs):
+        lines = []
+
+        lines.extend(self.get_formatted_system_info())
+        lines.extend(self.get_formatted_dependency_version_info())
+        lines.extend(self.get_formatted_package_info())
+        lines.append('')
+
+        return {'install_info_lines': lines}
+
+    def get_formatted_system_info(self):
+        return self._format_info(self.get_system_info(), 'System information')
+
+    def get_formatted_dependency_version_info(self):
+        return self._format_info(self.get_dependency_version_info(),
+                                 'Dependency versions')
+
+    def get_formatted_package_info(self):
+        return self._format_info(self.get_package_info(),
+                                 'biom-format package information')
+
+    def get_system_info(self):
+        return (("Platform", platform),
+                ("Python/GCC version", python_version.replace('\n', ' ')),
+                ("Python executable", executable))
+
+    def get_dependency_version_info(self):
+        not_installed_msg = "Not installed"
+
+        try:
+            from pyqi import __version__ as pyqi_lib_version
+        except ImportError:
+            pyqi_lib_version = not_installed_msg
+
+        try:
+            from numpy import __version__ as numpy_lib_version
+        except ImportError:
+            numpy_lib_version = ("ERROR: Not installed - this is required! "
+                                 "(This will also cause the BIOM library to "
+                                 "not be importable.)")
+
+        try:
+            from scipy import __version__ as scipy_lib_version
+        except ImportError:
+            scipy_lib_version = not_installed_msg
+
+        try:
+            from h5py import __version__ as h5py_lib_version
+        except ImportError:
+            h5py_lib_version = ("WARNING: Not installed - this is an optional "
+                                "dependency. It is strongly recommended for "
+                                "large datasets.")
+
+        return (("pyqi version", pyqi_lib_version),
+                ("NumPy version", numpy_lib_version),
+                ("SciPy version", scipy_lib_version),
+                ("h5py version", h5py_lib_version))
+
+    def get_package_info(self):
+        import_error_msg = ("ERROR: Can't find the BIOM library code (or "
+                            "numpy) - is it installed and in your "
+                            "$PYTHONPATH?")
+        try:
+            from biom import __version__ as biom_lib_version
+        except ImportError:
+            biom_lib_version = import_error_msg
+
+        return (("biom-format version", biom_lib_version),)
+
+    def _format_info(self, info, title):
+        max_len = self._get_max_length(info)
+
+        lines = ['']
+        lines.append(title)
+        lines.append('=' * len(title))
+        for e in info:
+            lines.append("%*s:\t%s" % (max_len, e[0], e[1]))
+
+        return lines
+
+    def _get_max_length(self, info):
+        return max([len(e[0]) for e in info])
+
+CommandConstructor = InstallationInformer
diff --git a/biom/commands/metadata_adder.py b/biom/commands/metadata_adder.py
new file mode 100644
index 0000000..cdab17f
--- /dev/null
+++ b/biom/commands/metadata_adder.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from __future__ import division
+from pyqi.core.command import (Command, CommandIn, CommandOut,
+                               ParameterCollection)
+from pyqi.core.exception import CommandError
+from biom.parse import MetadataMap
+from biom.table import Table
+
+__author__ = "Greg Caporaso"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Greg Caporaso", "Morgan Langille", "Jai Ram Rideout",
+               "Daniel McDonald"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+
+class MetadataAdder(Command):
+    BriefDescription = "Add metadata to a BIOM table"
+    LongDescription = ("Add sample and/or observation metadata to "
+                       "BIOM-formatted files. Detailed usage examples can be "
+                       "found here: http://biom-format.org/documentation/add"
+                       "ing_metadata.html")
+
+    CommandIns = ParameterCollection([
+        CommandIn(Name='table', DataType=Table,
+                  Description='the input BIOM table', Required=True),
+        # sample_metadata and observation_metadata are currently files (or
+        # file-like) because of the existing metadata map / processing function
+        # support. Ideally, these two parameters should be MetadataMap
+        # instances.
+        CommandIn(Name='sample_metadata', DataType=file,
+                  Description='the sample metadata map (will add sample '
+                  'metadata to the input BIOM table, if provided)'),
+        CommandIn(Name='observation_metadata', DataType=file,
+                  Description='the observation metadata map (will add '
+                  'observation metadata to the input BIOM table, if '
+                  'provided)'),
+        CommandIn(Name='sc_separated', DataType=list,
+                  Description='list of the metadata fields to split on '
+                  'semicolons. This is useful for hierarchical data such as '
+                  'taxonomy or functional categories'),
+        CommandIn(Name='sc_pipe_separated', DataType=list,
+                  Description='list of the metadata fields to split on '
+                  'semicolons and pipes ("|"). This is useful for '
+                  'hierarchical data such as functional categories with '
+                  'one-to-many mappings (e.g. x;y;z|x;y;w)'),
+        CommandIn(Name='int_fields', DataType=list,
+                  Description='list of the metadata fields to cast to '
+                  'integers. This is useful for integer data such as '
+                  '"DaysSinceStart"'),
+        CommandIn(Name='float_fields', DataType=list,
+                  Description='list of the metadata fields to cast to '
+                  'floating point numbers. This is useful for real number '
+                  'data such as "pH"'),
+        CommandIn(Name='sample_header', DataType=list,
+                  Description='list of the sample metadata field names. This '
+                  'is useful if a header line is not provided with the '
+                  'metadata, if you want to rename the fields, or if you want '
+                  'to include only the first n fields where n is the number '
+                  'of entries provided here',
+                  DefaultDescription='use header from sample metadata map'),
+        CommandIn(Name='observation_header', DataType=list,
+                  Description='list of the observation metadata field names. '
+                  'This is useful if a header line is not provided with the '
+                  'metadata, if you want to rename the fields, or if you want '
+                  'to include only the first n fields where n is the number '
+                  'of entries provided here',
+                  DefaultDescription='use header from observation metadata '
+                  'map'),
+        CommandIn(Name='output_as_json', DataType=bool,
+                  Description='Output as JSON', Default=False)
+    ])
+
+    CommandOuts = ParameterCollection([
+        CommandOut(Name='table', DataType=tuple,
+                   Description='Table with added metadata, and the output '
+                               'format')
+    ])
+
+    def run(self, **kwargs):
+        table = kwargs['table']
+        sample_metadata = kwargs['sample_metadata']
+        observation_metadata = kwargs['observation_metadata']
+        sc_separated = kwargs['sc_separated']
+        sc_pipe_separated = kwargs['sc_pipe_separated']
+        int_fields = kwargs['int_fields']
+        float_fields = kwargs['float_fields']
+        sample_header = kwargs['sample_header']
+        observation_header = kwargs['observation_header']
+        output_as = 'json' if kwargs['output_as_json'] else 'hdf5'
+
+        # define metadata processing functions, if any
+        process_fns = {}
+        if sc_separated is not None:
+            process_fns.update(dict.fromkeys(sc_separated,
+                                             self._split_on_semicolons))
+
+        if sc_pipe_separated is not None:
+            process_fns.update(dict.fromkeys(sc_pipe_separated,
+                               self._split_on_semicolons_and_pipes))
+
+        if int_fields is not None:
+            process_fns.update(dict.fromkeys(int_fields, self._int))
+
+        if float_fields is not None:
+            process_fns.update(dict.fromkeys(float_fields, self._float))
+
+        # parse mapping files
+        if sample_metadata is not None:
+            sample_metadata = MetadataMap.from_file(sample_metadata,
+                                                    process_fns=process_fns,
+                                                    header=sample_header)
+
+        if observation_metadata is not None:
+            observation_metadata = MetadataMap.from_file(
+                observation_metadata,
+                process_fns=process_fns,
+                header=observation_header)
+
+        if sample_metadata is None and observation_metadata is None:
+            raise CommandError('Must specify sample_metadata and/or '
+                               'observation_metadata.')
+
+        # NAUGHTY: this is modifying the input table IN PLACE!!! And then
+        # RETURNING IT! MetadataAdder is angry!
+
+        # add metadata as necessary
+        if sample_metadata:
+            table.add_metadata(sample_metadata, axis='sample')
+
+        if observation_metadata:
+            table.add_metadata(observation_metadata, axis='observation')
+
+        return {'table': (table, output_as)}
+
+    def _split_on_semicolons(self, x):
+        return [e.strip() for e in x.split(';')]
+
+    def _split_on_semicolons_and_pipes(self, x):
+        return [[e.strip() for e in y.split(';')] for y in x.split('|')]
+
+    def _int(self, x):
+        try:
+            return int(x)
+        except ValueError:
+            return x
+
+    def _float(self, x):
+        try:
+            return float(x)
+        except ValueError:
+            return x
+
+CommandConstructor = MetadataAdder
diff --git a/biom/commands/table_converter.py b/biom/commands/table_converter.py
new file mode 100644
index 0000000..e0829c4
--- /dev/null
+++ b/biom/commands/table_converter.py
@@ -0,0 +1,221 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from __future__ import division
+from pyqi.core.command import (Command, CommandIn, CommandOut,
+                               ParameterCollection)
+from pyqi.core.exception import CommandError
+from biom.table import Table
+from biom.parse import MetadataMap
+
+__author__ = "Greg Caporaso"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Greg Caporaso", "Daniel McDonald",
+               "Jose Carlos Clemente Litran", "Jai Ram Rideout",
+               "Jose Antonio Navas Molina", "Jorge Cañardo Alastuey"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+
+class TableConverter(Command):
+    TableTypes = ["OTU table",
+                  "Pathway table",
+                  "Function table",
+                  "Ortholog table",
+                  "Gene table",
+                  "Metabolite table",
+                  "Taxon table"]
+
+    ObservationMetadataTypes = {
+        'sc_separated': lambda x: [e.strip() for e in x.split(';')],
+        'naive': lambda x: x
+    }
+
+    ObservationMetadataFormatters = {
+        'sc_separated': lambda x: '; '.join(x),
+        'naive': lambda x: x
+    }
+
+    ObservationMetadataTypes['taxonomy'] = \
+        ObservationMetadataTypes['sc_separated']
+
+    BriefDescription = "Convert to/from the BIOM table format"
+    LongDescription = ("Convert between BIOM and 'classic' (tab-delimited) "
+                       "table formats. Detailed usage examples can be found "
+                       "here: http://biom-format.org/documentation/biom_conver"
+                       "sion.html")
+
+    CommandIns = ParameterCollection([
+        # This is not an ideal usage of the pyqi framework because we are
+        # expecting a file-like object here, and a lot of the parameters deal
+        # with I/O-ish things, like converting between file formats. Even
+        # though no I/O is forced here, it would be better to have rich objects
+        # as input and output, instead of lines of data. However, this will
+        # likely require a refactoring/redesign of our interface for table
+        # conversions because the primary input here can be either a BIOM table
+        # or a classic table. One possible solution is to split out different
+        # types of conversions into their own (smaller and simpler) commands,
+        # which would allow us to avoid some of this I/O-ish stuff.
+        CommandIn(Name='table', DataType=Table,
+                  Description='the input table (file-like object), either in '
+                  'BIOM or classic format', Required=True),
+        CommandIn(Name='to_json', DataType=bool,
+                  Description='Output as a JSON table', Default=False),
+        CommandIn(Name='to_hdf5', DataType=bool,
+                  Description='Output as a HDF5 table', Default=False),
+        CommandIn(Name='to_tsv', DataType=bool,
+                  Description='Output as a TSV table', Default=False),
+        CommandIn(Name='collapsed_samples', DataType=bool,
+                  Description='If to_hdf5 and the original table is a '
+                              'collapsed by samples biom table, this will '
+                              'update the sample metadata of the table to '
+                              'the supported HDF5 collapsed format'),
+        CommandIn(Name='collapsed_observations', DataType=bool,
+                  Description='If to_hdf5 and the original table is a '
+                              'collapsed by observations biom table, this will'
+                              ' update the observation metadata of the table '
+                              'to the supported HDF5 collapsed format'),
+        CommandIn(Name='sample_metadata', DataType=MetadataMap,
+                  Description='the sample metadata map (will add sample '
+                  'metadata to the BIOM table, if provided). Only applies '
+                  'when converting from classic table file to BIOM table '
+                  'file'),
+        CommandIn(Name='observation_metadata', DataType=MetadataMap,
+                  Description='the observation metadata map (will add '
+                  'observation metadata to the BIOM table, if provided). Only '
+                  'applies when converting from classic table file to BIOM '
+                  'table file'),
+        CommandIn(Name='header_key', DataType=str,
+                  Description='pull this key from observation metadata within '
+                  'a BIOM table file when creating a classic table file',
+                  DefaultDescription='no observation metadata will be '
+                  'included'),
+        CommandIn(Name='output_metadata_id', DataType=str,
+                  Description='the name to be given to the observation '
+                  'metadata column when creating a classic table from a BIOM-'
+                  'formatted table', DefaultDescription='same name as in the '
+                  'BIOM-formatted table'),
+        CommandIn(Name='table_type', DataType=str,
+                  Description='the type of the table, must be one of: %s' %
+                  ', '.join(TableTypes), Required=False),
+        CommandIn(Name='process_obs_metadata', DataType=str,
+                  Description='process metadata associated with observations '
+                  'when converting from a classic table. Must be one of: %s' %
+                  ', '.join(ObservationMetadataTypes), Default=None),
+        CommandIn(Name='tsv_metadata_formatter', DataType=str,
+                  Description='Method for formatting the observation '
+                  'metadata, must be one of: %s' %
+                  ', '.join(ObservationMetadataFormatters),
+                  Default='sc_separated')
+    ])
+
+    CommandOuts = ParameterCollection([
+        CommandOut(Name='table', DataType=tuple,
+                   Description='The resulting table and format')
+    ])
+
+    def run(self, **kwargs):
+        table = kwargs['table']
+        sample_metadata = kwargs['sample_metadata']
+        observation_metadata = kwargs['observation_metadata']
+        header_key = kwargs['header_key']
+        output_metadata_id = kwargs['output_metadata_id']
+        process_obs_metadata = kwargs['process_obs_metadata']
+        obs_md_fmt = kwargs['tsv_metadata_formatter']
+        table_type = kwargs['table_type']
+        to_tsv = kwargs['to_tsv']
+        to_hdf5 = kwargs['to_hdf5']
+        to_json = kwargs['to_json']
+        collapsed_observations = kwargs['collapsed_observations']
+        collapsed_samples = kwargs['collapsed_samples']
+
+        if sum([to_tsv, to_hdf5, to_json]) == 0:
+            raise CommandError("Must specify an output format")
+        elif sum([to_tsv, to_hdf5, to_json]) > 1:
+            raise CommandError("Can only specify a single output format")
+
+        # if we don't have a table type, then one is required to be specified
+        if table.type in [None, "None"]:
+            if table_type is None:
+                raise CommandError("Must specify --table-type!")
+            else:
+                if table_type not in self.TableTypes:
+                    raise CommandError("Unknown table type: %s" % table_type)
+
+                table.type = table_type
+
+        if obs_md_fmt not in self.ObservationMetadataFormatters:
+            raise CommandError("Unknown tsv_metadata_formatter: %s" %
+                               obs_md_fmt)
+        else:
+            obs_md_fmt_f = self.ObservationMetadataFormatters[obs_md_fmt]
+
+        if sample_metadata is not None:
+            table.add_metadata(sample_metadata)
+
+        # if the user does not specify a name for the output metadata column,
+        # set it to the same as the header key
+        output_metadata_id = output_metadata_id or header_key
+
+        if process_obs_metadata is not None and not to_tsv:
+            if process_obs_metadata not in self.ObservationMetadataTypes:
+                raise CommandError(
+                    "Unknown observation metadata processing method, must be "
+                    "one of: %s" %
+                    ', '.join(self.ObservationMetadataTypes.keys()))
+
+            if table.metadata(axis='observation') is None:
+                raise CommandError("Observation metadata processing requested "
+                                   "but it doesn't appear that there is any "
+                                   "metadata to operate on!")
+
+            # and if this came in as TSV, then we expect only a single type of
+            # metadata
+            md_key = table.metadata(axis='observation')[0].keys()[0]
+
+            process_f = self.ObservationMetadataTypes[process_obs_metadata]
+            it = zip(table.ids(axis='observation'),
+                     table.metadata(axis='observation'))
+            new_md = {id_: {md_key: process_f(md[md_key])} for id_, md in it}
+
+            if observation_metadata:
+                for k, v in observation_metadata.items():
+                    new_md[k].update(v)
+            table.add_metadata(new_md, 'observation')
+
+        if to_tsv:
+            result = table.to_tsv(header_key=header_key,
+                                  header_value=output_metadata_id,
+                                  metadata_formatter=obs_md_fmt_f)
+            fmt = 'tsv'
+        elif to_json:
+            result = table
+            fmt = 'json'
+        elif to_hdf5:
+            result = table
+            if collapsed_observations:
+                metadata = [{'collapsed_ids': md.keys()}
+                            for md in result.metadata(axis='observation')]
+                result._observation_metadata = metadata
+            if collapsed_samples:
+                metadata = [{'collapsed_ids': md.keys()}
+                            for md in result.metadata()]
+                result._sample_metadata = metadata
+            if collapsed_observations or collapsed_samples:
+                # We have changed the metadata, it is safer to make sure that
+                # it is correct
+                result._cast_metadata()
+            fmt = 'hdf5'
+
+        return {'table': (result, fmt)}
+
+CommandConstructor = TableConverter
diff --git a/biom/commands/table_normalizer.py b/biom/commands/table_normalizer.py
new file mode 100755
index 0000000..95b370a
--- /dev/null
+++ b/biom/commands/table_normalizer.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from __future__ import division
+from pyqi.core.command import (Command, CommandIn, CommandOut,
+                               ParameterCollection)
+from pyqi.core.exception import CommandError
+from biom.table import Table
+from biom.util import HAVE_H5PY
+from biom import load_table
+
+__author__ = "Michael Shaffer"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Michael Shaffer"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__author__ = "Michael Shaffer"
+__email__ = "michael.shaffer at ucdenver.edu"
+
+
+class TableNormalizer(Command):
+    Axes = ['sample', 'observation']
+
+    BriefDescription = "Normalize a BIOM table"
+    LongDescription = ("Normalize the values of a BIOM table through various "
+                       "methods. Relative abundance will take the relative "
+                       "abundance of each observation in terms of samples or "
+                       "observations.  Presence absensece will convert "
+                       "observations to 1's and 0's based on presence of the "
+                       "observation"
+                       )
+
+    CommandIns = ParameterCollection([
+        CommandIn(Name='biom_table', DataType=str,
+                  Description='the input BIOM table'),
+        CommandIn(Name='axis', DataType=str,
+                  Description='the axis to subset over, either ' +
+                  ' or '.join(Axes),
+                  Required=False),
+        CommandIn(Name='relative_abund', DataType=bool,
+                  Description='normalize the table by relative abundance',
+                  Required=False),
+        CommandIn(Name='presence_absence', DataType=bool,
+                  Description='convert table to presence/absence values',
+                  Required=False)
+    ])
+
+    CommandOuts = ParameterCollection([
+        CommandOut(Name='table', DataType=tuple,
+                   Description='The resulting table and format')
+    ])
+
+    def run(self, **kwargs):
+        biom_table = kwargs['biom_table']
+        axis = kwargs['axis']
+        relative_abund = kwargs['relative_abund']
+        p_a = kwargs['presence_absence']
+
+        if axis not in self.Axes:
+            raise CommandError("Invalid axis '%s'. Must be either %s." % (
+                axis,
+                ' or '.join(map(lambda e: "'%s'" % e, self.Axes))))
+
+        if biom_table is None:
+            raise CommandError("Must specify an input table")
+
+        if relative_abund is False and p_a is False:
+            raise CommandError("Must specifiy a normalization type")
+        elif relative_abund is True and p_a is True:
+            raise CommandError("Must specify only one normalization type")
+
+        table = load_table(biom_table)
+
+        if relative_abund is True:
+            table.norm(axis=axis)
+        else:
+            table.pa()
+
+        if HAVE_H5PY:
+            return {'table': (table, 'hdf5')}
+        else:
+            return {'table': (table, 'json')}
+
+CommandConstructor = TableNormalizer
diff --git a/biom/commands/table_subsetter.py b/biom/commands/table_subsetter.py
new file mode 100644
index 0000000..4ae26e9
--- /dev/null
+++ b/biom/commands/table_subsetter.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from __future__ import division
+from pyqi.core.command import (Command, CommandIn, CommandOut,
+                               ParameterCollection)
+from pyqi.core.exception import CommandError
+from biom.parse import get_axis_indices, direct_slice_data, direct_parse_key
+from biom.table import Table
+from biom.util import biom_open
+
+__author__ = "Daniel McDonald"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Daniel McDonald", "Jai Ram Rideout",
+               "Jose Antonio Navas Molina"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__author__ = "Daniel McDonald"
+__email__ = "daniel.mcdonald at colorado.edu"
+
+
+class TableSubsetter(Command):
+    Axes = ['sample', 'observation']
+
+    BriefDescription = "Subset a BIOM table"
+    LongDescription = ("Subset a BIOM table, over either observations or "
+                       "samples, without fully parsing it. This command is "
+                       "intended to assist in working with very large tables "
+                       "when tight on memory, or as a lightweight way to "
+                       "subset a full table. Currently, it is possible to "
+                       "produce tables with rows or columns (observations or "
+                       "samples) that are fully zeroed.")
+
+    CommandIns = ParameterCollection([
+        CommandIn(Name='json_table_str', DataType=str,
+                  Description='the input BIOM table as an unparsed json '
+                              'string',
+                  Required=False),
+        CommandIn(Name='hdf5_table', DataType=str,
+                  Description='the fp to the input BIOM table',
+                  Required=False),
+        CommandIn(Name='axis', DataType=str,
+                  Description='the axis to subset over, either ' +
+                  ' or '.join(Axes), Required=True),
+        CommandIn(Name='ids', DataType=list,
+                  Description='the IDs to retain (either sample IDs or '
+                  'observation IDs, depending on the axis)', Required=True)
+    ])
+
+    CommandOuts = ParameterCollection([
+        CommandOut(Name='subsetted_table', DataType=tuple,
+                   Description='The subset generator')
+    ])
+
+    def run(self, **kwargs):
+        json_table_str = kwargs['json_table_str']
+        hdf5_biom = kwargs['hdf5_table']
+        axis = kwargs['axis']
+        ids = kwargs['ids']
+
+        if axis not in self.Axes:
+            raise CommandError("Invalid axis '%s'. Must be either %s." % (
+                axis,
+                ' or '.join(map(lambda e: "'%s'" % e, self.Axes))))
+
+        if hdf5_biom is None and json_table_str is None:
+            raise CommandError("Must specify an input table")
+        elif hdf5_biom is not None and json_table_str is not None:
+            raise CommandError("Can only specify one input table")
+
+        if json_table_str is not None:
+            idxs, new_axis_md = get_axis_indices(json_table_str, ids, axis)
+            new_data = direct_slice_data(json_table_str, idxs, axis)
+
+            # multiple walks over the string. bad form, but easy right now
+            # ...should add a yield_and_ignore parser or something.
+            def subset_generator():
+                yield "{"
+                yield direct_parse_key(json_table_str, "id")
+                yield ","
+                yield direct_parse_key(json_table_str, "format")
+                yield ","
+                yield direct_parse_key(json_table_str, "format_url")
+                yield ","
+                yield direct_parse_key(json_table_str, "type")
+                yield ","
+                yield direct_parse_key(json_table_str, "generated_by")
+                yield ","
+                yield direct_parse_key(json_table_str, "date")
+                yield ","
+                yield direct_parse_key(json_table_str, "matrix_type")
+                yield ","
+                yield direct_parse_key(json_table_str, "matrix_element_type")
+                yield ","
+                yield new_data
+                yield ","
+                yield new_axis_md
+                yield ","
+
+                if axis == "observation":
+                    yield direct_parse_key(json_table_str, "columns")
+                else:
+                    yield direct_parse_key(json_table_str, "rows")
+                yield "}"
+
+            format_ = 'json'
+            table = subset_generator()
+        else:
+            with biom_open(hdf5_biom) as f:
+                table = Table.from_hdf5(f, ids=ids, axis=axis)
+            format_ = 'hdf5'
+
+        return {'subsetted_table': (table, format_)}
+
+CommandConstructor = TableSubsetter
diff --git a/biom/commands/table_summarizer.py b/biom/commands/table_summarizer.py
new file mode 100644
index 0000000..0d6442e
--- /dev/null
+++ b/biom/commands/table_summarizer.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+from __future__ import division
+from signal import signal, SIGPIPE, SIG_DFL
+from operator import itemgetter
+
+from pyqi.core.command import (Command, CommandIn, CommandOut,
+                               ParameterCollection)
+
+from numpy import std
+from biom.util import compute_counts_per_sample_stats
+
+# Ignore SIG_PIPE and don't throw exceptions on it. This allows the user to
+# pipe the output from summarize table to other commands.
+# http://newbebweb.blogspot.com/2012/02/python-head-ioerror-errno-32-broken.html
+# http://docs.python.org/library/signal.html
+signal(SIGPIPE, SIG_DFL)
+
+
+__author__ = "Greg Caporaso"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Greg Caporaso", "Daniel McDonald", "Jose Antonio Navas Molina"]
+__license__ = "BSD"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+
+class TableSummarizer(Command):
+
+    """
+     Example usage:
+      from biom.commands.table_summarizer import TableSummarizer
+      from biom.parse import parse_biom_table
+      c = TableSummarizer()
+      table_f = open("table.biom")
+      t = parse_biom_table(table_f)
+      table_f.seek(0)
+      result = c(table=(t,None))
+      result = c(table=(t,None),qualitative=True)
+      result = c(table=(t,table_f),qualitative=True)
+      table_f.close()
+    """
+    BriefDescription = "Summarize sample or observation data in a BIOM table"
+    LongDescription = ("Provides details on the observation counts per sample,"
+                       " including summary statistics, as well as metadata "
+                       "categories associated with samples and observations.")
+
+    CommandIns = ParameterCollection([
+        CommandIn(Name='table',
+                  DataType=tuple,
+                  Description='the input BIOM table',
+                  Required=True),
+        CommandIn(Name='qualitative',
+                  DataType=bool,
+                  Description=('Present counts as number of unique '
+                               'observation ids per sample, rather than '
+                               'counts of observations per sample.'),
+                  Required=False,
+                  Default=False),
+        CommandIn(Name='observations',
+                  DataType=bool,
+                  Default=False,
+                  Description=('Summarize over observations'))
+    ])
+
+    CommandOuts = ParameterCollection([
+        CommandOut(Name='biom_summary',
+                   DataType=list,
+                   Description='The table summary')
+    ])
+
+    def run(self, **kwargs):
+        result = {}
+        qualitative = kwargs['qualitative']
+        by_observations = kwargs['observations']
+        table, table_lines = kwargs['table']
+
+        if by_observations:
+            table = table.transpose()
+
+        min_counts, max_counts, median_counts, mean_counts, counts_per_samp =\
+            compute_counts_per_sample_stats(table, qualitative)
+        num_observations = len(table.ids(axis='observation'))
+
+        counts_per_sample_values = counts_per_samp.values()
+
+        if table.metadata() is None:
+            sample_md_keys = ["None provided"]
+        else:
+            sample_md_keys = table.metadata()[0].keys()
+
+        if table.metadata(axis='observation') is None:
+            observation_md_keys = ["None provided"]
+        else:
+            observation_md_keys = table.metadata(axis='observation')[0].keys()
+
+        lines = []
+
+        num_samples = len(table.ids())
+
+        if by_observations:
+            # as this is a transpose of the original table...
+            lines.append('Num samples: %d' % num_observations)
+            lines.append('Num observations: %d' % num_samples)
+        else:
+            lines.append('Num samples: %d' % num_samples)
+            lines.append('Num observations: %d' % num_observations)
+
+        if not qualitative:
+            total_count = sum(counts_per_sample_values)
+            lines.append('Total count: %d' % total_count)
+            lines.append('Table density (fraction of non-zero values): %1.3f' %
+                         table.get_table_density())
+
+        lines.append('')
+
+        if qualitative:
+            if by_observations:
+                lines.append('Sample/observations summary:')
+            else:
+                lines.append('Observations/sample summary:')
+        else:
+            lines.append('Counts/sample summary:')
+
+        lines.append(' Min: %r' % min_counts)
+        lines.append(' Max: %r' % max_counts)
+        lines.append(' Median: %1.3f' % median_counts)
+        lines.append(' Mean: %1.3f' % mean_counts)
+        lines.append(' Std. dev.: %1.3f' % std(counts_per_sample_values))
+
+        if by_observations:
+            # since this is a transpose...
+            lines.append(
+                ' Sample Metadata Categories: %s' %
+                '; '.join(observation_md_keys))
+            lines.append(
+                ' Observation Metadata Categories: %s' %
+                '; '.join(sample_md_keys))
+            lines.append('')
+        else:
+            lines.append(
+                ' Sample Metadata Categories: %s' %
+                '; '.join(sample_md_keys))
+            lines.append(
+                ' Observation Metadata Categories: %s' %
+                '; '.join(observation_md_keys))
+            lines.append('')
+
+        if qualitative:
+            lines.append('Observations/sample detail:')
+        else:
+            lines.append('Counts/sample detail:')
+
+        for k, v in sorted(counts_per_samp.items(), key=itemgetter(1)):
+            lines.append(' %s: %r' % (k, v))
+
+        result['biom_summary'] = lines
+        return result
+
+CommandConstructor = TableSummarizer
diff --git a/biom/cli/table_validator.py b/biom/commands/table_validator.py
similarity index 89%
rename from biom/cli/table_validator.py
rename to biom/commands/table_validator.py
index ee90005..0e39628 100644
--- a/biom/cli/table_validator.py
+++ b/biom/commands/table_validator.py
@@ -15,63 +15,58 @@ from datetime import datetime
 from operator import and_
 from functools import reduce
 
-import click
 import numpy as np
+from pyqi.core.command import (Command, CommandIn, CommandOut,
+                               ParameterCollection)
 
-from biom.cli import cli
 from biom.util import HAVE_H5PY, biom_open, is_hdf5_file
 
 
- at cli.command(name='validate-table')
- at click.option('-i', '--input-fp', required=True,
-              type=click.Path(exists=True, dir_okay=False),
-              help='The input filpath to validate against the BIOM format'
-                   ' specification')
- at click.option('-f', '--format-version', default=None,
-              help='The specific format version to validate against')
- at click.option('--detailed-report', is_flag=True, default=False,
-              help='Include more details in the output report')
-def validate_table(input_fp, format_version, detailed_report):
-    """Validate a BIOM-formatted file.
-
-    Test a file for adherence to the Biological Observation Matrix (BIOM)
-    format specification. This specification is defined at
-    http://biom-format.org
-
-    Example usage:
-
-    Validate the contents of table.biom for adherence to the BIOM format
-    specification
-
-    $ biom validate-table -i table.biom
-
-    """
-    valid, report = _validate_table(input_fp, format_version, detailed_report)
-    click.echo("\n".join(report))
-    if valid:
-        # apparently silence is too quiet to be golden.
-        click.echo("The input file is a valid BIOM-formatted file.")
-        sys.exit(0)
-    else:
-        click.echo("The input file is not a valid BIOM-formatted file.")
-        sys.exit(1)
-
-
-def _validate_table(input_fp, format_version=None, detailed_report=False):
-    result = TableValidator()(table=input_fp, format_version=format_version,
-                              detailed_report=detailed_report)
-    return result['valid_table'], result['report_lines']
-
-
-# Refactor in the future. Also need to address #664
-class TableValidator(object):
+__author__ = "Daniel McDonald"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Daniel McDonald", "Jose Clemente", "Greg Caporaso",
+               "Jai Ram Rideout", "Justin Kuczynski", "Andreas Wilke",
+               "Tobias Paczian", "Rob Knight", "Folker Meyer", "Sue Huse",
+               "Jorge Cañardo Alastuey"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__author__ = "Daniel McDonald"
+__email__ = "daniel.mcdonald at colorado.edu"
+
+
+class TableValidator(Command):
+    BriefDescription = "Validate a BIOM-formatted file"
+    LongDescription = ("Test a file for adherence to the Biological "
+                       "Observation Matrix (BIOM) format specification. This "
+                       "specification is defined at http://biom-format.org")
+
+    CommandIns = ParameterCollection([
+        CommandIn(Name='table', DataType=object,
+                  Description='the input BIOM JSON object (e.g., the output '
+                  'of json.load)', Required=True),
+        CommandIn(Name='format_version', DataType=str,
+                  Description='the specific format version to validate '
+                  'against', Required=False, Default=None),
+        CommandIn(Name='detailed_report', DataType=bool,
+                  Description='include more details in the output report',
+                  Required=False, Default=False)
+    ])
+
+    CommandOuts = ParameterCollection([
+        CommandOut(Name='valid_table',
+                   Description='Is the table valid?',
+                   DataType=bool),
+        CommandOut(Name='report_lines',
+                   Description='Detailed report',
+                   DataType=list)
+    ])
 
     FormatURL = "http://biom-format.org"
     TableTypes = set(['otu table', 'pathway table', 'function table',
                       'ortholog table', 'gene table', 'metabolite table',
                       'taxon table'])
     MatrixTypes = set(['sparse', 'dense'])
-    ElementTypes = {'int': int, 'str': str, 'float': float, 'unicode': str}
+    ElementTypes = {'int': int, 'str': str, 'float': float, 'unicode': unicode}
     HDF5FormatVersions = set([(2, 0), (2, 0, 0), (2, 1), (2, 1, 0)])
 
     def run(self, **kwargs):
@@ -91,6 +86,8 @@ class TableValidator(object):
                 raise ValueError("Unrecognized format version: %s" %
                                  kwargs['format_version'])
 
+        # this is not pyqi-appriopriate, but how we parse this thing is
+        # dependent on runtime options :(
         with biom_open(kwargs['table']) as f:
             if is_json:
                 kwargs['table'] = json.load(f)
@@ -108,10 +105,6 @@ class TableValidator(object):
                 raise IOError("h5py is not installed, can only validate JSON "
                               "tables")
 
-    def __call__(self, table, format_version=None, detailed_report=False):
-        return self.run(table=table, format_version=format_version,
-                        detailed_report=detailed_report)
-
     def _validate_hdf5(self, **kwargs):
         table = kwargs['table']
 
@@ -329,10 +322,7 @@ class TableValidator(object):
 
     def _json_or_hdf5_get(self, table, key):
         if hasattr(table, 'attrs'):
-            item = table.attrs.get(key, None)
-            if item is not None and isinstance(item, bytes):
-                item = item.decode('utf8')
-            return item
+            return table.attrs.get(key, None)
         else:
             return table.get(key, None)
 
@@ -344,11 +334,11 @@ class TableValidator(object):
 
     def _is_int(self, x):
         """Return True if x is an int"""
-        return isinstance(x, (int, np.int64))
+        return isinstance(x, int)
 
     def _valid_nnz(self, table):
         """Check if nnz seems correct"""
-        if not self._is_int(table.attrs['nnz']):
+        if not isinstance(table.attrs['nnz'], int):
             return "nnz is not an integer!"
         if table.attrs['nnz'] < 0:
             return "nnz is negative!"
@@ -392,9 +382,6 @@ class TableValidator(object):
                        "%Y-%m-%dT%H:%M",
                        "%Y-%m-%dT%H:%M:%S",
                        "%Y-%m-%dT%H:%M:%S.%f"]
-        if isinstance(val, bytes):
-            val = val.decode('utf8')
-
         valid_time = False
         for fmt in valid_times:
             try:
@@ -573,3 +560,5 @@ class TableValidator(object):
             return self._valid_dense_data(table_json)
         else:
             return "Unknown matrix type"
+
+CommandConstructor = TableValidator
diff --git a/biom/interfaces/__init__.py b/biom/interfaces/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/biom/interfaces/html/__init__.py b/biom/interfaces/html/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/biom/interfaces/html/config/__init__.py b/biom/interfaces/html/config/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/biom/interfaces/html/config/add_metadata.py b/biom/interfaces/html/config/add_metadata.py
new file mode 100644
index 0000000..d400236
--- /dev/null
+++ b/biom/interfaces/html/config/add_metadata.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.html import (HTMLInputOption, HTMLDownload)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from pyqi.core.interfaces.html.output_handler import newline_list_of_strings
+from pyqi.core.interfaces.optparse.input_handler import string_list_handler
+
+from biom.interfaces.html.input_handler import load_biom_table
+from biom.commands.metadata_adder import CommandConstructor
+
+__author__ = "Evan Bolyen"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = [
+    "Evan Bolyen", "Jai Ram Rideout", "Greg Caporaso", "Morgan Langille",
+    "Daniel McDonald"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Evan Bolyen"
+__email__ = "ebolyen at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+
+inputs = [
+    HTMLInputOption(Parameter=cmd_in_lookup('table'),
+                    Type='upload_file',
+                    Handler=load_biom_table,
+                    Name='input-fp'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('sample_metadata'),
+                    Type='upload_file',
+                    Name='sample-metadata-fp'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('observation_metadata'),
+                    Type='upload_file',
+                    Name='observation-metadata-fp'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('sc_separated'),
+                    Handler=string_list_handler,
+                    Help='comma-separated list of the metadata fields to '
+                    'split on semicolons. This is useful for hierarchical '
+                    'data such as taxonomy or functional categories'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('sc_pipe_separated'),
+                    Handler=string_list_handler,
+                    Help='comma-separated list of the metadata fields to split'
+                    ' on semicolons and pipes ("|"). This is useful for '
+                    'hierarchical data such as functional categories with '
+                    'one-to-many mappings (e.g. x;y;z|x;y;w)'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('int_fields'),
+                    Handler=string_list_handler,
+                    Help='comma-separated list of the metadata fields to cast '
+                    'to integers. This is useful for integer data such as '
+                    '"DaysSinceStart"'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('float_fields'),
+                    Handler=string_list_handler,
+                    Help='comma-separated list of the metadata fields to cast '
+                    'to floating point numbers. This is useful for real number'
+                    ' data such as "pH"'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('sample_header'),
+                    Handler=string_list_handler,
+                    Help='comma-separated list of the sample metadata field '
+                    'names. This is useful if a header line is not provided '
+                    'with the metadata, if you want to rename the fields, or '
+                    'if you want to include only the first n fields where n is'
+                    ' the number of entries provided here'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('observation_header'),
+                    Handler=string_list_handler,
+                    Help='comma-separated list of the observation metadata '
+                    'field names. This is useful if a header line is not '
+                    'provided with the metadata, if you want to rename the '
+                    'fields, or if you want to include only the first n fields'
+                    ' where n is the number of entries provided here'),
+    HTMLInputOption(Parameter=None,
+                    Name='download-file',
+                    Required=True,
+                    Help='the download file')
+]
+
+outputs = [
+    HTMLDownload(Parameter=cmd_out_lookup('table'),
+                 Handler=newline_list_of_strings,
+                 FilenameLookup='download-file',
+                 FileExtension='.biom')
+]
diff --git a/biom/interfaces/html/config/convert.py b/biom/interfaces/html/config/convert.py
new file mode 100644
index 0000000..bfdfa11
--- /dev/null
+++ b/biom/interfaces/html/config/convert.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.html import (HTMLInputOption, HTMLDownload)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from pyqi.core.interfaces.html.output_handler import newline_list_of_strings
+
+from biom.interfaces.html.input_handler import load_metadata
+from biom.commands.table_converter import CommandConstructor
+
+__author__ = "Evan Bolyen"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = [
+    "Evan Bolyen",
+    "Jai Ram Rideout",
+    "Greg Caporaso",
+    "Daniel McDonald"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Evan Bolyen"
+__email__ = "ebolyen at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+
+inputs = [
+    HTMLInputOption(Parameter=cmd_in_lookup('table'),
+                    Type='upload_file',
+                    Help='the input table filepath, either in BIOM or classic '
+                    'format'),
+    HTMLInputOption(Parameter=cmd_in_lookup('to_tsv'),
+                    Type=bool),
+    HTMLInputOption(Parameter=cmd_in_lookup('to_json'),
+                    Type=bool),
+    HTMLInputOption(Parameter=cmd_in_lookup('to_hdf5'),
+                    Type=bool),
+    HTMLInputOption(Parameter=cmd_in_lookup('sample_metadata'),
+                    Type='upload_file',
+                    Handler=load_metadata),
+    HTMLInputOption(Parameter=cmd_in_lookup('observation_metadata'),
+                    Type='upload_file',
+                    Handler=load_metadata),
+    HTMLInputOption(Parameter=cmd_in_lookup('header_key')),
+    HTMLInputOption(Parameter=cmd_in_lookup('output_metadata_id')),
+    HTMLInputOption(Parameter=cmd_in_lookup('process_obs_metadata'),
+                    Type='multiple_choice',
+                    Choices=['taxonomy', 'naive', 'sc_separated'],
+                    Help='Process metadata associated with observations when '
+                    'converting from a classic table'),
+    HTMLInputOption(Parameter=cmd_in_lookup('tsv_metadata_formatter'),
+                    Type='multiple_choice',
+                    Choices=['naive', 'sc_separated'],
+                    Help='Format the metadata for TSV output'),
+    HTMLInputOption(Parameter=None,
+                    Name='download-file',
+                    Required=True,
+                    Help='the download file')
+]
+
+outputs = [
+    HTMLDownload(Parameter=cmd_out_lookup('table'),
+                 Handler=newline_list_of_strings,
+                 FilenameLookup='download-file',
+                 FileExtension='.biom')
+]
diff --git a/biom/interfaces/html/config/normalize_table.py b/biom/interfaces/html/config/normalize_table.py
new file mode 100755
index 0000000..5151717
--- /dev/null
+++ b/biom/interfaces/html/config/normalize_table.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.html import (HTMLInputOption, HTMLDownload)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from pyqi.core.interfaces.html.output_handler import newline_list_of_strings
+
+from biom.commands.table_converter import CommandConstructor
+
+__author__ = "Michael Shaffer"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Michael Shaffer"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Michael Shaffer"
+__email__ = "michael.shaffer at ucdenver.edu"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+
+inputs = [
+    HTMLInputOption(Parameter=cmd_in_lookup('biom_table'),
+                    Type='upload_file',
+                    Required=True,
+                    Help='the input table filepath'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('relative_abund'),
+                    Type=bool),
+    HTMLInputOption(Parameter=cmd_in_lookup('presence_absence'),
+                    Type=bool),
+    HTMLInputOption(Parameter=cmd_in_lookup('axis'),
+                    Type='multiple_choice',
+                    Choices=['observation', 'sample'],
+                    Help='axis by which to normalize the table'),
+
+    HTMLInputOption(Parameter=None,
+                    Name='download-file',
+                    Required=True,
+                    Help='the download file')
+]
+
+outputs = [
+    HTMLDownload(Parameter=cmd_out_lookup('table'),
+                 Handler=newline_list_of_strings,
+                 FilenameLookup='download-file',
+                 FileExtension='.biom')
+]
diff --git a/biom/interfaces/html/config/show_install_info.py b/biom/interfaces/html/config/show_install_info.py
new file mode 100644
index 0000000..da8772e
--- /dev/null
+++ b/biom/interfaces/html/config/show_install_info.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.html import HTMLPage
+from pyqi.core.command import make_command_out_collection_lookup_f
+from pyqi.core.interfaces.html.output_handler import html_list_of_strings
+from biom.commands.installation_informer import CommandConstructor
+
+__author__ = "Evan Bolyen"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = [
+    "Evan Bolyen",
+    "Jai Ram Rideout",
+    "Greg Caporaso",
+    "Daniel McDonald"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Evan Bolyen"
+__email__ = "ebolyen at gmail.com"
+
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+
+inputs = []
+
+outputs = [
+    HTMLPage(Parameter=cmd_out_lookup('install_info_lines'),
+             Handler=html_list_of_strings)
+]
diff --git a/biom/interfaces/html/config/summarize_table.py b/biom/interfaces/html/config/summarize_table.py
new file mode 100644
index 0000000..ec976e7
--- /dev/null
+++ b/biom/interfaces/html/config/summarize_table.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from pyqi.core.interfaces.html.output_handler import newline_list_of_strings
+from pyqi.core.interfaces.html import (HTMLInputOption, HTMLDownload)
+from biom.commands.table_summarizer import CommandConstructor
+from biom.interfaces.html.input_handler import (
+    load_biom_table_with_file_contents
+    )
+
+__author__ = "Evan Bolyen"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = [
+    "Evan Bolyen",
+    "Greg Caporaso",
+    "Jai Ram Rideout",
+    "Daniel McDonald"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Evan Bolyen"
+__email__ = "ebolyen at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+inputs = [
+    HTMLInputOption(Parameter=cmd_in_lookup('table'),
+                    Type="upload_file",
+                    Handler=load_biom_table_with_file_contents,
+                    Name='input-fp'),
+    HTMLInputOption(Parameter=cmd_in_lookup('qualitative'),
+                    Type=bool),
+    HTMLInputOption(Parameter=None,
+                    Name='download-file',
+                    Required=True,
+                    Help='the download file')
+]
+
+outputs = [
+    HTMLDownload(Parameter=cmd_out_lookup('biom_summary'),
+                 Handler=newline_list_of_strings,
+                 FilenameLookup='download-file',
+                 FileExtension='.biom.summary.txt')
+]
diff --git a/biom/interfaces/html/config/validate_table.py b/biom/interfaces/html/config/validate_table.py
new file mode 100644
index 0000000..50ddf40
--- /dev/null
+++ b/biom/interfaces/html/config/validate_table.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.html import (HTMLInputOption, HTMLPage)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from biom.commands.table_validator import CommandConstructor
+from biom.interfaces.html.input_handler import load_json_document
+
+__author__ = "Evan Bolyen"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Evan Bolyen", "Jai Ram Rideout", "Daniel McDonald",
+               "Jorge Cañardo Alastuey"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Evan Bolyen"
+__email__ = "ebolyen at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+
+def display_table_validity(result_key, data, option_value=None):
+    if data is None:
+        return "The input file is a valid BIOM-formatted file."
+    else:
+        to_join = ["The input file is not a valid BIOM-formatted file."]
+        to_join += data
+        return "<br/>".join(to_join)
+
+
+inputs = [
+    HTMLInputOption(Parameter=cmd_in_lookup('table'),
+                    Type='upload_file',
+                    Handler=load_json_document,
+                    Name='input-fp',
+                    Help='the input file to validate against the BIOM '
+                    'format specification'),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('format_version')),
+
+    HTMLInputOption(Parameter=cmd_in_lookup('detailed_report'), Type=bool),
+]
+
+outputs = [
+    HTMLPage(Parameter=cmd_out_lookup('report_lines'),
+             Handler=display_table_validity)
+]
diff --git a/biom/interfaces/html/input_handler.py b/biom/interfaces/html/input_handler.py
new file mode 100644
index 0000000..a230dd2
--- /dev/null
+++ b/biom/interfaces/html/input_handler.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+import json
+from biom.parse import MetadataMap, parse_biom_table
+
+__author__ = "Evan Bolyen"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Evan Bolyen", "Greg Caporaso", "Jai Ram Rideout"]
+__license__ = "BSD"
+__maintainer__ = "Evan Bolyen"
+__email__ = "ebolyen at gmail.com"
+
+
+def load_biom_table(table_f):
+    """Return a parsed BIOM table."""
+    return parse_biom_table(table_f)
+
+
+def load_biom_table_with_file_contents(biom_f):
+    """Return a BIOM table and the original open filehandle as a tuple.
+
+    Useful when additional computation needs to be performed on the file
+    contents, such as an MD5 sum.
+
+    WARNING: this function does not close the open filehandle that it returns.
+    Users of this function are responsible for closing the filehandle when done
+    using it!
+    """
+    table = parse_biom_table(biom_f)
+    if hasattr(biom_f, 'seek'):
+        biom_f.seek(0)
+    return table, biom_f
+
+
+def load_json_document(f):
+    """Return a parsed JSON object."""
+    return json.load(f)
+
+
+def load_metadata(lines):
+    """Parse a sample/observation metadata file, return a ``MetadataMap``.
+
+    If ``lines`` is ``None``, this function will return ``None``.
+    """
+    if lines is not None:
+        return MetadataMap.from_file(lines)
+
+    return None
diff --git a/tests/test_cli/__init__.py b/biom/interfaces/html/output_handler.py
similarity index 78%
rename from tests/test_cli/__init__.py
rename to biom/interfaces/html/output_handler.py
index 1e84e01..63ce058 100644
--- a/tests/test_cli/__init__.py
+++ b/biom/interfaces/html/output_handler.py
@@ -1,5 +1,7 @@
+#!/usr/bin/env python
+
 # ----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
 #
 # Distributed under the terms of the Modified BSD License.
 #
diff --git a/biom/interfaces/optparse/__init__.py b/biom/interfaces/optparse/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/biom/interfaces/optparse/config/__init__.py b/biom/interfaces/optparse/config/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/biom/interfaces/optparse/config/add_metadata.py b/biom/interfaces/optparse/config/add_metadata.py
new file mode 100644
index 0000000..47cb2d7
--- /dev/null
+++ b/biom/interfaces/optparse/config/add_metadata.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.optparse import (OptparseOption,
+                                           OptparseUsageExample,
+                                           OptparseResult)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from pyqi.core.interfaces.optparse.input_handler import (file_reading_handler,
+                                                         string_list_handler)
+from biom.commands.metadata_adder import CommandConstructor
+from biom.interfaces.optparse.input_handler import load_biom_table
+from biom.interfaces.optparse.output_handler import write_biom_table
+from biom.util import HAVE_H5PY
+
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout", "Greg Caporaso", "Morgan Langille",
+               "Daniel McDonald"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+usage_examples = [
+    OptparseUsageExample(ShortDesc="Adding sample metadata",
+                         LongDesc="Add sample metadata to a BIOM table",
+                         Ex="%prog -i otu_table.biom -o "
+                            "table_with_sample_metadata.biom -m "
+                            "sample_metadata.txt")
+]
+
+inputs = [
+    OptparseOption(Parameter=cmd_in_lookup('table'),
+                   Type='existing_filepath',
+                   Handler=load_biom_table, ShortName='i',
+                   Name='input-fp'),
+
+    OptparseOption(Parameter=cmd_in_lookup('sample_metadata'),
+                   Type='existing_filepath',
+                   Handler=file_reading_handler, ShortName='m',
+                   Name='sample-metadata-fp'),
+
+    OptparseOption(Parameter=cmd_in_lookup('observation_metadata'),
+                   Type='existing_filepath',
+                   Handler=file_reading_handler,
+                   Name='observation-metadata-fp'),
+
+    OptparseOption(Parameter=cmd_in_lookup('sc_separated'),
+                   Handler=string_list_handler,
+                   Help='comma-separated list of the metadata fields to split '
+                   'on semicolons. This is useful for hierarchical data such '
+                   'as taxonomy or functional categories'),
+
+    OptparseOption(Parameter=cmd_in_lookup('sc_pipe_separated'),
+                   Handler=string_list_handler,
+                   Help='comma-separated list of the metadata fields to split '
+                   'on semicolons and pipes ("|"). This is useful for '
+                   'hierarchical data such as functional categories with '
+                   'one-to-many mappings (e.g. x;y;z|x;y;w)'),
+
+    OptparseOption(Parameter=cmd_in_lookup('int_fields'),
+                   Handler=string_list_handler,
+                   Help='comma-separated list of the metadata fields to cast '
+                   'to integers. This is useful for integer data such as '
+                   '"DaysSinceStart"'),
+
+    OptparseOption(Parameter=cmd_in_lookup('float_fields'),
+                   Handler=string_list_handler,
+                   Help='comma-separated list of the metadata fields to cast '
+                   'to floating point numbers. This is useful for real number '
+                   'data such as "pH"'),
+
+    OptparseOption(Parameter=cmd_in_lookup('sample_header'),
+                   Handler=string_list_handler,
+                   Help='comma-separated list of the sample metadata field '
+                   'names. This is useful if a header line is not provided '
+                   'with the metadata, if you want to rename the fields, or '
+                   'if you want to include only the first n fields where n is '
+                   'the number of entries provided here'),
+
+    OptparseOption(Parameter=cmd_in_lookup('observation_header'),
+                   Handler=string_list_handler,
+                   Help='comma-separated list of the observation metadata '
+                   'field names. This is useful if a header line is not '
+                   'provided with the metadata, if you want to rename the '
+                   'fields, or if you want to include only the first n fields '
+                   'where n is the number of entries provided here'),
+
+    OptparseOption(Parameter=cmd_in_lookup('output_as_json'),
+                   Type=None,
+                   Default=not HAVE_H5PY,
+                   Action='store_true'),
+
+    OptparseOption(Parameter=None, Type='new_filepath', ShortName='o',
+                   Name='output-fp', Required=True,
+                   Help='the output BIOM table')
+]
+
+outputs = [
+    OptparseResult(Parameter=cmd_out_lookup('table'),
+                   Handler=write_biom_table,
+                   InputName='output-fp')
+]
diff --git a/biom/interfaces/optparse/config/convert.py b/biom/interfaces/optparse/config/convert.py
new file mode 100644
index 0000000..ab33097
--- /dev/null
+++ b/biom/interfaces/optparse/config/convert.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.optparse import (OptparseUsageExample,
+                                           OptparseOption, OptparseResult)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from biom.interfaces.optparse.input_handler import (load_biom_table,
+                                                    load_metadata)
+from biom.interfaces.optparse.output_handler import write_biom_table
+from biom.commands.table_converter import CommandConstructor
+
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout", "Greg Caporaso", "Daniel McDonald"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+usage_examples = [
+    OptparseUsageExample(ShortDesc="Converting from classic to BIOM format",
+                         LongDesc="Convert the classic file table.txt to a "
+                                  "HDF5 BIOM format OTU table",
+                         Ex='%prog -i table.txt -o table.biom '
+                            '--table-type "OTU table" --to-hdf5')
+]
+
+inputs = [
+    OptparseOption(Parameter=cmd_in_lookup('table'),
+                   Type='existing_filepath',
+                   Handler=load_biom_table,
+                   ShortName='i', Name='input-fp',
+                   Help='the input table filepath, either in BIOM or classic '
+                   'format'),
+    OptparseOption(Parameter=cmd_in_lookup('sample_metadata'),
+                   Type='existing_filepath',
+                   Handler=load_metadata,
+                   ShortName='m',
+                   Name='sample-metadata-fp'),
+    OptparseOption(Parameter=cmd_in_lookup('observation_metadata'),
+                   Type='existing_filepath',
+                   Handler=load_metadata, Name='observation-metadata-fp'),
+    OptparseOption(Parameter=cmd_in_lookup('header_key')),
+    OptparseOption(Parameter=cmd_in_lookup('output_metadata_id')),
+    OptparseOption(Parameter=cmd_in_lookup('process_obs_metadata')),
+    OptparseOption(Parameter=cmd_in_lookup('table_type')),
+    OptparseOption(Parameter=cmd_in_lookup('tsv_metadata_formatter')),
+    OptparseOption(Parameter=cmd_in_lookup('to_json'),
+                   Action='store_true'),
+    OptparseOption(Parameter=cmd_in_lookup('to_tsv'),
+                   Action='store_true'),
+    OptparseOption(Parameter=cmd_in_lookup('to_hdf5'),
+                   Action='store_true'),
+    OptparseOption(Parameter=cmd_in_lookup('collapsed_samples'),
+                   Action='store_true'),
+    OptparseOption(Parameter=cmd_in_lookup('collapsed_observations'),
+                   Action='store_true'),
+    OptparseOption(Parameter=None,
+                   Type='new_filepath',
+                   ShortName='o',
+                   Name='output-fp',
+                   Required=True,
+                   Help='the output filepath')
+]
+
+outputs = [
+    OptparseResult(Parameter=cmd_out_lookup('table'),
+                   Handler=write_biom_table,
+                   InputName='output-fp')
+]
diff --git a/biom/interfaces/optparse/config/normalize_table.py b/biom/interfaces/optparse/config/normalize_table.py
new file mode 100755
index 0000000..2aec86d
--- /dev/null
+++ b/biom/interfaces/optparse/config/normalize_table.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.optparse import (OptparseOption,
+                                           OptparseUsageExample,
+                                           OptparseResult)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from biom.interfaces.optparse.output_handler import write_biom_table
+from biom.commands.table_normalizer import CommandConstructor
+
+__author__ = "Michael Shaffer"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Michael Shaffer"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Michael Shaffer"
+__email__ = "michael.shaffer at ucdenver.edu"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+
+usage_examples = [
+    OptparseUsageExample(ShortDesc="Normalizing a BIOM table to relative"
+                                   "abundnace",
+                         LongDesc="Take a BIOM table and replace all values "
+                                  "with their relative abundance in relation "
+                                  "to the sample",
+                         Ex="%prog -i table.biom -r -o "
+                            "normalized_table.biom"),
+    OptparseUsageExample(ShortDesc="Converting a BIOM table to a "
+                                   "presence/absence table",
+                         LongDesc="Take a BIOM table and convert the values "
+                                  "to 0's and 1's based on presensce or "
+                                  "absence of observations",
+                         Ex="%prog -i table.biom -p -o converted_table.biom")
+]
+
+inputs = [
+    # table input
+    OptparseOption(Parameter=cmd_in_lookup('biom_table'),
+                   Type='existing_filepath',
+                   Handler=None, ShortName='i',
+                   Name='input-fp', Required=True,
+                   Help='the input BIOM table filepath to subset'),
+
+    # normalization to relative_abundance
+    OptparseOption(Parameter=cmd_in_lookup('relative_abund'),
+                   ShortName='r',
+                   Action='store_true',
+                   Help='convert table to relative abundance'),
+
+    # conversion to presensce/absence
+    OptparseOption(Parameter=cmd_in_lookup('presence_absence'),
+                   ShortName='p',
+                   Action='store_true',
+                   Help='convert table to presence/absence'),
+
+    # if relative abundance then normalize by sample or by observation
+    OptparseOption(Parameter=cmd_in_lookup('axis'),
+                   ShortName='a',
+                   Default='sample'),
+
+    OptparseOption(Parameter=None,
+                   Type='new_filepath',
+                   ShortName='o',
+                   Name='output-fp',
+                   Required=True,
+                   Help='the output filepath')
+]
+
+outputs = [
+    OptparseResult(Parameter=cmd_out_lookup('table'),
+                   Handler=write_biom_table,
+                   InputName='output-fp')
+]
diff --git a/biom/interfaces/optparse/config/show_install_info.py b/biom/interfaces/optparse/config/show_install_info.py
new file mode 100644
index 0000000..88bbaa7
--- /dev/null
+++ b/biom/interfaces/optparse/config/show_install_info.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.optparse import (OptparseUsageExample,
+                                           OptparseResult)
+from pyqi.core.command import make_command_out_collection_lookup_f
+from pyqi.core.interfaces.optparse.output_handler import print_list_of_strings
+from biom.commands.installation_informer import CommandConstructor
+
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout", "Greg Caporaso", "Daniel McDonald"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+usage_examples = [
+    OptparseUsageExample(ShortDesc="Displaying installation info",
+                         LongDesc="Display biom-format installation "
+                                  "information",
+                         Ex="%prog")
+]
+
+inputs = []
+
+outputs = [
+    OptparseResult(Parameter=cmd_out_lookup('install_info_lines'),
+                   Handler=print_list_of_strings)
+]
diff --git a/biom/interfaces/optparse/config/subset_table.py b/biom/interfaces/optparse/config/subset_table.py
new file mode 100644
index 0000000..bd2e94a
--- /dev/null
+++ b/biom/interfaces/optparse/config/subset_table.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from pyqi.core.interfaces.optparse import (OptparseOption,
+                                           OptparseUsageExample,
+                                           OptparseResult)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from pyqi.core.interfaces.optparse.input_handler import load_file_lines
+from biom.interfaces.optparse.input_handler import biom_load_file_contents
+from biom.interfaces.optparse.output_handler import write_subsetted_biom_table
+from biom.commands.table_subsetter import CommandConstructor
+
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout", "Daniel McDonald",
+               "Jose Antonio Navas Molina"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+
+usage_examples = [
+    OptparseUsageExample(ShortDesc="Subsetting a json BIOM table",
+                         LongDesc="Choose a subset of the observations in "
+                                  "table.biom and write them to subset.biom",
+                         Ex="%prog -j table.biom -a observations -s "
+                            "observation_ids.txt -o subset.biom"),
+    OptparseUsageExample(ShortDesc="Subsetting a hdf5 BIOM table",
+                         LongDesc="Choose a subset of the observations in "
+                                  "table.biom and write them to subset.biom",
+                         Ex="%prog -i table.biom -a observations -s "
+                            "observation_ids.txt -o subset.biom")
+]
+
+inputs = [
+    OptparseOption(Parameter=cmd_in_lookup('hdf5_table'),
+                   Type='existing_filepath',
+                   Handler=None, ShortName='i',
+                   Name='input-hdf5-fp',
+                   Help='the input hdf5 BIOM table filepath to subset'),
+
+    OptparseOption(Parameter=cmd_in_lookup('json_table_str'),
+                   Type='existing_filepath',
+                   Handler=biom_load_file_contents, ShortName='j',
+                   Name='input-json-fp',
+                   Help='the input json BIOM table filepath to subset'),
+
+    OptparseOption(Parameter=cmd_in_lookup('axis'), ShortName='a'),
+
+    OptparseOption(Parameter=cmd_in_lookup('ids'),
+                   Type='existing_filepath', Handler=load_file_lines,
+                   ShortName='s', Help='a file containing a single column of '
+                   'IDs to retain (either sample IDs or observation IDs, '
+                   'depending on the axis)'),
+
+    OptparseOption(Parameter=None, Type='new_filepath', ShortName='o',
+                   Name='output-fp', Required=True,
+                   Help='the output BIOM table filepath'),
+]
+
+outputs = [
+    OptparseResult(Parameter=cmd_out_lookup('subsetted_table'),
+                   Handler=write_subsetted_biom_table,
+                   InputName='output-fp')
+]
diff --git a/biom/interfaces/optparse/config/summarize_table.py b/biom/interfaces/optparse/config/summarize_table.py
new file mode 100644
index 0000000..f3538b5
--- /dev/null
+++ b/biom/interfaces/optparse/config/summarize_table.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from pyqi.core.interfaces.optparse import (OptparseOption,
+                                           OptparseUsageExample,
+                                           OptparseResult)
+from pyqi.core.interfaces.optparse.output_handler import (
+    write_or_print_list_of_strings)
+from biom.commands.table_summarizer import CommandConstructor
+from biom.interfaces.optparse.input_handler import (
+    load_biom_table_with_file_contents)
+
+__author__ = "Greg Caporaso"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Greg Caporaso", "Jai Ram Rideout", "Daniel McDonald"]
+__license__ = "BSD"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+usage_examples = [
+    OptparseUsageExample(ShortDesc="Basic script usage",
+                         LongDesc="Write a summary of table.biom to "
+                                  "table_summary.txt",
+                         Ex="%prog -i table.biom -o table_summary.txt")
+]
+
+inputs = [
+    OptparseOption(Parameter=cmd_in_lookup('table'),
+                   Type="existing_filepath",
+                   Handler=load_biom_table_with_file_contents,
+                   ShortName='i',
+                   Name='input-fp'),
+    OptparseOption(Parameter=cmd_in_lookup('qualitative'),
+                   Type=None,
+                   Action="store_true"),
+    OptparseOption(Parameter=cmd_in_lookup('observations'),
+                   Type=None,
+                   Action='store_true'),
+    OptparseOption(Parameter=None,
+                   Type='new_filepath',
+                   ShortName='o',
+                   Name='output-fp',
+                   Required=False,
+                   Default=None,
+                   Help='the output filepath')
+]
+
+outputs = [
+    OptparseResult(Parameter=cmd_out_lookup('biom_summary'),
+                   Handler=write_or_print_list_of_strings,
+                   InputName='output-fp')
+]
diff --git a/biom/interfaces/optparse/config/validate_table.py b/biom/interfaces/optparse/config/validate_table.py
new file mode 100644
index 0000000..170f2f3
--- /dev/null
+++ b/biom/interfaces/optparse/config/validate_table.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+import sys
+from pyqi.core.interfaces.optparse import (OptparseOption,
+                                           OptparseUsageExample,
+                                           OptparseResult)
+from pyqi.core.command import (make_command_in_collection_lookup_f,
+                               make_command_out_collection_lookup_f)
+from pyqi.core.interfaces.optparse.output_handler import print_list_of_strings
+from biom.commands.table_validator import CommandConstructor
+
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout", "Daniel McDonald", "Jorge Cañardo Alastuey"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
+cmd_in_lookup = make_command_in_collection_lookup_f(CommandConstructor)
+cmd_out_lookup = make_command_out_collection_lookup_f(CommandConstructor)
+
+
+def report_table_validity(result_key, data, option_value=None):
+    if data:
+        print "The input file is a valid BIOM-formatted file."
+        sys.exit(0)
+    else:
+        print "The input file is not a valid BIOM-formatted file."
+        sys.exit(1)
+
+usage_examples = [
+    OptparseUsageExample(ShortDesc="Validating a BIOM file",
+                         LongDesc="Validate the contents of table.biom for "
+                                  "adherence to the BIOM format specification",
+                         Ex="%prog -i table.biom")
+]
+
+inputs = [
+    OptparseOption(Parameter=cmd_in_lookup('table'),
+                   Type='existing_filepath',
+                   Handler=None, ShortName='i',
+                   Name='input-fp',
+                   Help='the input filepath to validate against the BIOM '
+                   'format specification'),
+    OptparseOption(Parameter=cmd_in_lookup('format_version'), ShortName='f'),
+
+    OptparseOption(Parameter=cmd_in_lookup('detailed_report'), Type=None,
+                   Action='store_true')
+]
+
+outputs = [
+    OptparseResult(Parameter=cmd_out_lookup('report_lines'),
+                   Handler=print_list_of_strings),
+    OptparseResult(Parameter=cmd_out_lookup('valid_table'),
+                   Handler=report_table_validity)
+]
diff --git a/biom/interfaces/optparse/input_handler.py b/biom/interfaces/optparse/input_handler.py
new file mode 100644
index 0000000..0945a71
--- /dev/null
+++ b/biom/interfaces/optparse/input_handler.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+import json
+from biom.util import biom_open
+from biom.parse import MetadataMap, parse_biom_table
+from pyqi.core.interfaces.optparse.input_handler import load_file_contents
+
+__author__ = "Greg Caporaso"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Greg Caporaso", "Jai Ram Rideout"]
+__license__ = "BSD"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+
+def biom_load_file_contents(fp):
+    if fp is None:
+        return fp
+    return load_file_contents(fp)
+
+
+def load_hdf5_or_json(fp):
+    """Return a parsed JSON object or an HDF5 object"""
+    with biom_open(fp) as f:
+        if hasattr(f, 'seek'):
+            return json.load(f)
+        else:
+            return f
+
+
+def load_biom_table(biom_fp):
+    """Return a parsed BIOM table."""
+    with biom_open(biom_fp, 'U') as table_f:
+        return parse_biom_table(table_f)
+
+
+def load_biom_table_with_file_contents(biom_fp):
+    """Return a BIOM table and the original open filehandle as a tuple.
+
+    Useful when additional computation needs to be performed on the file
+    contents, such as an MD5 sum.
+
+    WARNING: this function does not close the open filehandle that it returns.
+    Users of this function are responsible for closing the filehandle when done
+    using it!
+    """
+    with biom_open(biom_fp, 'U') as biom_f:
+        table = parse_biom_table(biom_f)
+
+        if hasattr(biom_f, 'seek'):
+            biom_f.seek(0)
+
+        return table, biom_f
+
+
+def load_json_document(fp):
+    """Return a parsed JSON object."""
+    with biom_open(fp, 'U') as f:
+        return json.load(f)
+
+
+def load_metadata(fp):
+    """Parse a sample/observation metadata file, return a ``MetadataMap``.
+
+    If ``fp`` is ``None``, this function will return ``None``.
+    """
+    if fp is None:
+        return None
+    else:
+        with open(fp, 'U') as f:
+            return MetadataMap.from_file(f)
diff --git a/biom/interfaces/optparse/output_handler.py b/biom/interfaces/optparse/output_handler.py
new file mode 100644
index 0000000..3d1370d
--- /dev/null
+++ b/biom/interfaces/optparse/output_handler.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+# ----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# ----------------------------------------------------------------------------
+
+from os.path import exists
+from pyqi.core.exception import IncompetentDeveloperError
+from pyqi.core.interfaces.optparse.output_handler import write_list_of_strings
+from biom.parse import generatedby
+from biom.util import HAVE_H5PY
+
+__author__ = "Greg Caporaso"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Greg Caporaso", "Jai Ram Rideout"]
+__license__ = "BSD"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+
+def write_subsetted_biom_table(result_key, data, option_value=None):
+    """Write a string to a file"""
+    if option_value is None:
+        raise IncompetentDeveloperError("Cannot write output without a "
+                                        "filepath.")
+
+    if exists(option_value):
+        raise IOError("Output path '%s' already exists." % option_value)
+
+    table, fmt = data
+
+    if fmt not in ['hdf5', 'json']:
+        raise IncompetentDeveloperError("Unknown file format")
+
+    if fmt == 'json':
+        write_list_of_strings(result_key, table, option_value)
+    else:
+        if HAVE_H5PY:
+            import h5py
+        else:
+            # This should never be raised here
+            raise ImportError("h5py is not available, cannot write HDF5!")
+
+        with h5py.File(option_value, 'w') as f:
+            table.to_hdf5(f, generatedby())
+
+
+def write_biom_table(result_key, data, option_value=None):
+    """Write a string to a file"""
+    if option_value is None:
+        raise IncompetentDeveloperError("Cannot write output without a "
+                                        "filepath.")
+
+    if exists(option_value):
+        raise IOError("Output path '%s' already exists." % option_value)
+
+    table, fmt = data
+
+    if fmt not in ['hdf5', 'json', 'tsv']:
+        raise IncompetentDeveloperError("Unknown file format")
+
+    if fmt == 'hdf5' and not HAVE_H5PY:
+        fmt = 'json'
+
+    if fmt == 'json':
+        with open(option_value, 'w') as f:
+            f.write(table.to_json(generatedby()))
+    elif fmt == 'tsv':
+        with open(option_value, 'w') as f:
+            f.write(table)
+            f.write('\n')
+    else:
+        import h5py
+
+        with h5py.File(option_value, 'w') as f:
+            table.to_hdf5(f, generatedby())
diff --git a/biom/parse.py b/biom/parse.py
index 7cbb243..9a732b0 100644
--- a/biom/parse.py
+++ b/biom/parse.py
@@ -9,15 +9,12 @@
 # ----------------------------------------------------------------------------
 
 from __future__ import division
-
+from string import maketrans
 import numpy as np
-from future.utils import string_types
-
 from biom.exception import BiomParseException, UnknownAxisError
 from biom.table import Table
 from biom.util import biom_open, __version__
 import json
-import collections
 
 __author__ = "Justin Kuczynski"
 __copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
@@ -29,8 +26,8 @@ __url__ = "http://biom-format.org"
 __maintainer__ = "Daniel McDonald"
 __email__ = "daniel.mcdonald at colorado.edu"
 
-MATRIX_ELEMENT_TYPE = {'int': int, 'float': float, 'unicode': str,
-                       u'int': int, u'float': float, u'unicode': str}
+MATRIX_ELEMENT_TYPE = {'int': int, 'float': float, 'unicode': unicode,
+                       u'int': int, u'float': float, u'unicode': unicode}
 
 QUOTE = '"'
 JSON_OPEN = set(["[", "{"])
@@ -127,7 +124,7 @@ def direct_slice_data(biom_str, to_keep, axis):
 
     # determine shape
     raw_shape = shape_kv_pair.split(':')[-1].replace("[", "").replace("]", "")
-    n_rows, n_cols = list(map(int, raw_shape.split(",")))
+    n_rows, n_cols = map(int, raw_shape.split(","))
 
     # slice to just data
     data_start = data_fields.find('[') + 1
@@ -166,13 +163,13 @@ def strip_f(x):
 
 def _remap_axis_sparse_obs(rcv, lookup):
     """Remap a sparse observation axis"""
-    row, col, value = list(map(strip_f, rcv.split(',')))
+    row, col, value = map(strip_f, rcv.split(','))
     return "%s,%s,%s" % (lookup[row], col, value)
 
 
 def _remap_axis_sparse_samp(rcv, lookup):
     """Remap a sparse sample axis"""
-    row, col, value = list(map(strip_f, rcv.split(',')))
+    row, col, value = map(strip_f, rcv.split(','))
     return "%s,%s,%s" % (row, lookup[col], value)
 
 
@@ -248,98 +245,6 @@ def get_axis_indices(biom_str, to_keep, axis):
     return idxs, json.dumps(subset)[1:-1]  # trim off { and }
 
 
-def parse_uc(fh):
-    """ Create a Table object from a uclust/usearch/vsearch uc file.
-
-        Parameters
-        ----------
-        fh : file handle
-            The ``.uc`` file to be parsed.
-
-        Returns
-        -------
-        biom.Table : The resulting BIOM table.
-
-        Raises
-        ------
-        ValueError
-            If a sequence identifier is encountered that doesn't have at least
-            one underscore in it (see Notes).
-
-        Notes
-        -----
-        This function assumes sequence identifiers in this file are in QIIME's
-        "post-split-libraries" format, where the identifiers are of the form
-        ``<sample-id>_<sequence-id>``. Everything before the first underscore
-        will be used as the sample identifier in the resulting ``Table``.
-        The information after the first underscore is not used directly, though
-        the full identifiers of seeds will be used as the observation
-        identifier in the resulting ``Table``.
-
-    """
-    data = collections.defaultdict(int)
-    sample_idxs = {}
-    sample_ids = []
-    observation_idxs = {}
-    observation_ids = []
-    # The types of hit lines we need here are hit (H), seed (S) and
-    # library seed (L). Store these in a set for quick reference.
-    line_types = set('HSL')
-    for line in fh:
-        # determine if the current line is one that we need
-        line = line.strip()
-        if not line:
-            continue
-        fields = line.split('\t')
-
-        line_type = fields[0]
-        if line_type not in line_types:
-            continue
-
-        # grab the fields we care about
-        observation_id = fields[9].split()[0]
-        query_id = fields[8].split()[0]
-
-        if observation_id == '*':
-            # S and L lines don't have a separate observation id
-            observation_id = query_id
-
-        # get the index of the current observation id, or create it if it's
-        # the first time we're seeing this id
-        if observation_id in observation_idxs:
-            observation_idx = observation_idxs[observation_id]
-        else:
-            observation_idx = len(observation_ids)
-            observation_ids.append(observation_id)
-            observation_idxs[observation_id] = observation_idx
-
-        if line_type == 'H' or line_type == 'S':
-            # get the sample id
-            try:
-                underscore_index = query_id.index('_')
-            except ValueError:
-                raise ValueError(
-                 "A query sequence was encountered that does not have an "
-                 "underscore. An underscore is required in all query "
-                 "sequence identifiers to indicate the sample identifier.")
-            # get the sample id and its index, creating the index if it is the
-            # first time we're seeing this id
-            sample_id = query_id[:underscore_index]
-            if sample_id in sample_idxs:
-                sample_idx = sample_idxs[sample_id]
-            else:
-                sample_idx = len(sample_ids)
-                sample_idxs[sample_id] = sample_idx
-                sample_ids.append(sample_id)
-            # increment the count of the current observation in the current
-            # sample by one.
-            data[(observation_idx, sample_idx)] += 1
-        else:
-            # nothing else needs to be done for 'L' records
-            pass
-    return Table(data, observation_ids=observation_ids, sample_ids=sample_ids)
-
-
 def parse_biom_table(fp, ids=None, axis='sample', input_is_dense=False):
     r"""Parses the biom table stored in the filepath `fp`
 
@@ -518,7 +423,7 @@ class MetadataMap(dict):
                     comments.append(line)
             else:
                 # Will add empty string to empty fields
-                tmp_line = list(map(strip_f, line.split('\t')))
+                tmp_line = map(strip_f, line.split('\t'))
                 if len(tmp_line) < len(header):
                     tmp_line.extend([''] * (len(header) - len(tmp_line)))
                 mapping_data.append(tmp_line)
@@ -582,10 +487,11 @@ def biom_meta_to_string(metadata, replace_str=':'):
     # Note that since ';' and '|' are used as seperators we must replace them
     # if they exist
 
-    if isinstance(metadata, string_types):
+    # metadata is just a string (not a list)
+    if isinstance(metadata, str) or isinstance(metadata, unicode):
         return metadata.replace(';', replace_str)
     elif isinstance(metadata, list):
-        transtab = bytes.maketrans(';|', ''.join([replace_str, replace_str]))
+        transtab = maketrans(';|', ''.join([replace_str, replace_str]))
         # metadata is list of lists
         if isinstance(metadata[0], list):
             new_metadata = []
diff --git a/biom/table.py b/biom/table.py
index 8caac29..04b0946 100644
--- a/biom/table.py
+++ b/biom/table.py
@@ -179,18 +179,16 @@ from datetime import datetime
 from json import dumps
 from functools import reduce
 from operator import itemgetter, add
-from future.builtins import zip
-from future.utils import viewitems
+from itertools import izip
 from collections import defaultdict, Hashable, Iterable
 from numpy import ndarray, asarray, zeros, newaxis
 from scipy.sparse import coo_matrix, csc_matrix, csr_matrix, isspmatrix, vstack
 
-from future.utils import string_types
 from biom.exception import TableException, UnknownAxisError, UnknownIDError
 from biom.util import (get_biom_format_version_string,
                        get_biom_format_url_string, flatten, natsort,
                        prefer_self, index_list, H5PY_VLEN_STR, HAVE_H5PY,
-                       __format_version__)
+                       H5PY_VLEN_UNICODE, __format_version__)
 from biom.err import errcheck
 from ._filter import _filter
 from ._transform import _transform
@@ -209,8 +207,8 @@ __maintainer__ = "Daniel McDonald"
 __email__ = "daniel.mcdonald at colorado.edu"
 
 
-MATRIX_ELEMENT_TYPE = {'int': int, 'float': float, 'unicode': str,
-                       u'int': int, u'float': float, u'unicode': str}
+MATRIX_ELEMENT_TYPE = {'int': int, 'float': float, 'unicode': unicode,
+                       u'int': int, u'float': float, u'unicode': unicode}
 
 
 def general_parser(x):
@@ -219,13 +217,7 @@ def general_parser(x):
 
 def vlen_list_of_str_parser(value):
     """Parses the taxonomy value"""
-    new_value = []
-    for v in value:
-        if v:
-            if isinstance(v, bytes):
-                v = v.decode('utf8')
-            new_value.append(v)
-
+    new_value = [v for v in value if v]
     return new_value if new_value else None
 
 
@@ -234,10 +226,15 @@ def general_formatter(grp, header, md, compression):
     test_val = md[0][header]
     shape = (len(md),)
     name = 'metadata/%s' % header
-    if isinstance(test_val, string_types):
+    if isinstance(test_val, unicode):
+        grp.create_dataset(name, shape=shape,
+                           dtype=H5PY_VLEN_UNICODE,
+                           compression=compression)
+        grp[name][:] = [m[header] for m in md]
+    elif isinstance(test_val, str):
         grp.create_dataset(name, shape=shape,
                            dtype=H5PY_VLEN_STR,
-                           data=[m[header].encode('utf8') for m in md],
+                           data=[m[header] for m in md],
                            compression=compression)
     else:
         grp.create_dataset(
@@ -274,7 +271,7 @@ def vlen_list_of_str_formatter(grp, header, md, compression):
         if m[header] is None:
             continue
         value = np.asarray(m[header])
-        data[i, :len(value)] = [v.encode('utf8') for v in value]
+        data[i, :len(value)] = value
     # Change the None entries on data to empty strings ""
     data = np.where(data == np.array(None), "", data)
     grp.create_dataset(
@@ -584,7 +581,7 @@ class Table(object):
         """
         metadata = self.metadata(axis=axis)
         if metadata is not None:
-            for id_, md_entry in viewitems(md):
+            for id_, md_entry in md.iteritems():
                 if self.exists(id_, axis=axis):
                     idx = self.index(id_, axis=axis)
                     metadata[idx].update(md_entry)
@@ -838,65 +835,6 @@ class Table(object):
                               self.ids()[:], self.ids(axis='observation')[:],
                               sample_md_copy, obs_md_copy, self.table_id)
 
-    def head(self, n=5, m=5):
-        """Get the first n rows and m columns from self
-
-        Parameters
-        ----------
-        n : int, optional
-            The number of rows (observations) to get. This number must be
-            greater than 0. If not specified, 5 rows will be retrieved.
-
-        m : int, optional
-            The number of columns (samples) to get. This number must be
-            greater than 0. If not specified, 5 columns will be
-            retrieved.
-
-        Notes
-        -----
-        Like `head` for Linux like systems, requesting more rows (or columns)
-        than exists will silently work.
-
-        Raises
-        ------
-        IndexError
-            If `n` or `m` are <= 0.
-
-        Returns
-        -------
-        Table
-            The subset table.
-
-        Examples
-        --------
-        >>> import numpy as np
-        >>> from biom.table import Table
-        >>> data = np.arange(100).reshape(5, 20)
-        >>> obs_ids = ['O%d' % i for i in range(1, 6)]
-        >>> samp_ids = ['S%d' % i for i in range(1, 21)]
-        >>> table = Table(data, obs_ids, samp_ids)
-        >>> print table.head()  # doctest: +NORMALIZE_WHITESPACE
-        # Constructed from biom file
-        #OTU ID S1  S2  S3  S4  S5
-        O1  0.0 1.0 2.0 3.0 4.0
-        O2  20.0 21.0 22.0 23.0 24.0
-        O3  40.0 41.0 42.0 43.0 44.0
-        O4  60.0 61.0 62.0 63.0 64.0
-        O5  80.0 81.0 82.0 83.0 84.0
-
-        """
-        if n <= 0:
-            raise IndexError("n cannot be <= 0.")
-
-        if m <= 0:
-            raise IndexError("m cannot be <= 0.")
-
-        row_ids = self.ids(axis='observation')[:n]
-        col_ids = self.ids(axis='sample')[:m]
-
-        table = self.filter(row_ids, axis='observation', inplace=False)
-        return table.filter(col_ids, axis='sample')
-
     def group_metadata(self, axis='sample'):
         """Return the group metadata of the given axis
 
@@ -1046,13 +984,13 @@ class Table(object):
         """
         updated_ids = zeros(self.ids(axis=axis).size, dtype=object)
         for idx, old_id in enumerate(self.ids(axis=axis)):
-            if strict and old_id not in id_map:
+            new_id = id_map.get(old_id, old_id)
+            if strict and new_id is old_id:  # same object, not just equality
                 raise TableException(
                     "Mapping not provided for %s identifier: %s. If this "
                     "identifier should not be updated, pass strict=False."
                     % (axis, old_id))
-
-            updated_ids[idx] = id_map.get(old_id, old_id)
+            updated_ids[idx] = new_id
 
         # prepare the result object and update the ids along the specified
         # axis
@@ -1300,9 +1238,9 @@ class Table(object):
         """
         return id in self._index(axis=axis)
 
-    def delimited_self(self, delim=u'\t', header_key=None, header_value=None,
+    def delimited_self(self, delim='\t', header_key=None, header_value=None,
                        metadata_formatter=str,
-                       observation_column_name=u'#OTU ID'):
+                       observation_column_name='#OTU ID'):
         """Return self as a string in a delimited form
 
         Default str output for the Table is just row/col ids and table data
@@ -1326,16 +1264,11 @@ class Table(object):
             OTU1\t10\t2
             OTU2\t4\t8
         """
-        def to_utf8(i):
-            if isinstance(i, bytes):
-                return i.decode('utf8')
-            else:
-                return str(i)
-
         if self.is_empty():
             raise TableException("Cannot delimit self if I don't have data...")
 
-        samp_ids = delim.join([to_utf8(i) for i in self.ids()])
+        samp_ids = delim.join(map(str, self.ids()))
+
         # 17 hrs of straight programming later...
         if header_key is not None:
             if header_value is None:
@@ -1348,25 +1281,26 @@ class Table(object):
                     "You need to specify both header_key and header_value")
 
         if header_value:
-            output = [u'# Constructed from biom file',
-                      u'%s%s%s\t%s' % (observation_column_name, delim,
-                                       samp_ids, header_value)]
+            output = ['# Constructed from biom file',
+                      '%s%s%s\t%s' % (observation_column_name, delim, samp_ids,
+                                      header_value)]
         else:
             output = ['# Constructed from biom file',
                       '%s%s%s' % (observation_column_name, delim, samp_ids)]
+
         obs_metadata = self.metadata(axis='observation')
         for obs_id, obs_values in zip(self.ids(axis='observation'),
                                       self._iter_obs()):
             str_obs_vals = delim.join(map(str, self._to_dense(obs_values)))
-            obs_id = to_utf8(obs_id)
+
             if header_key and obs_metadata is not None:
                 md = obs_metadata[self._obs_index[obs_id]]
                 md_out = metadata_formatter(md.get(header_key, None))
                 output.append(
-                    u'%s%s%s\t%s' %
+                    '%s%s%s\t%s' %
                     (obs_id, delim, str_obs_vals, md_out))
             else:
-                output.append(u'%s%s%s' % (obs_id, delim, str_obs_vals))
+                output.append('%s%s%s' % (obs_id, delim, str_obs_vals))
 
         return '\n'.join(output)
 
@@ -1654,7 +1588,7 @@ class Table(object):
 
         iter_ = self.iter_data(axis=axis, dense=dense)
 
-        return zip(iter_, ids, metadata)
+        return izip(iter_, ids, metadata)
 
     def iter_pairwise(self, dense=True, axis='sample', tri=True, diag=False):
         """Pairwise iteration over self
@@ -2077,7 +2011,7 @@ class Table(object):
 
         md = self.metadata(axis=self._invert_axis(axis))
 
-        for part, (ids, values, metadata) in viewitems(partitions):
+        for part, (ids, values, metadata) in partitions.iteritems():
             if axis == 'sample':
                 data = self._conv_to_self_type(values, transpose=True)
                 samp_ids = ids
@@ -2279,12 +2213,12 @@ class Table(object):
             new_md = {}
             md_count = {}
 
-            for id_, md in zip(*axis_ids_md(self)):
+            for id_, md in izip(*axis_ids_md(self)):
                 md_iter = f(id_, md)
                 num_md = 0
                 while True:
                     try:
-                        pathway, partition = next(md_iter)
+                        pathway, partition = md_iter.next()
                     except IndexError:
                         # if a pathway is incomplete
                         if strict:
@@ -2321,7 +2255,7 @@ class Table(object):
 
                 while True:
                     try:
-                        pathway, part = next(md_iter)
+                        pathway, part = md_iter.next()
                     except IndexError:
                         # if a pathway is incomplete
                         if strict:
@@ -2342,11 +2276,11 @@ class Table(object):
 
             if include_collapsed_metadata:
                 # reassociate pathway information
-                for k, i in sorted(viewitems(idx_lookup), key=itemgetter(1)):
+                for k, i in sorted(idx_lookup.iteritems(), key=itemgetter(1)):
                     collapsed_md.append({one_to_many_md_key: new_md[k]})
 
             # get the new sample IDs
-            collapsed_ids = [k for k, i in sorted(viewitems(idx_lookup),
+            collapsed_ids = [k for k, i in sorted(idx_lookup.iteritems(),
                                                   key=itemgetter(1))]
 
             # convert back to self type
@@ -3271,9 +3205,6 @@ html
             # fetch all of the IDs
             ids = grp['ids'][:]
 
-            if ids.size > 0 and isinstance(ids[0], bytes):
-                ids = np.array([i.decode('utf8') for i in ids])
-
             parser = defaultdict(lambda: general_parser)
             parser['taxonomy'] = vlen_list_of_str_parser
             parser['KEGG_Pathways'] = vlen_list_of_str_parser
@@ -3282,10 +3213,10 @@ html
 
             # fetch ID specific metadata
             md = [{} for i in range(len(ids))]
-            for category, dset in viewitems(grp['metadata']):
+            for category, dset in grp['metadata'].iteritems():
                 parse_f = parser[category]
                 data = dset[:]
-                for md_dict, data_row in zip(md, data):
+                for md_dict, data_row in izip(md, data):
                     md_dict[category] = parse_f(data_row)
 
             # If there was no metadata on the axis, set it up as none
@@ -3322,7 +3253,6 @@ html
                     # Retrieve only the ids that we are interested on
                     ids = source_ids[idx]
                     # Check that all desired ids have been found on source ids
-
                     if ids.shape != desired_ids.shape:
                         raise ValueError("The following ids could not be "
                                          "found in the biom table: %s" %
@@ -3554,7 +3484,7 @@ html
                 # is cleaner, as is the parse
                 grp.create_dataset('ids', shape=(len_ids,),
                                    dtype=H5PY_VLEN_STR,
-                                   data=[i.encode('utf8') for i in ids],
+                                   data=[str(i) for i in ids],
                                    compression=compression)
             else:
                 # Empty H5PY_VLEN_STR datasets are not supported.
@@ -3711,28 +3641,29 @@ html
         str
             A JSON-formatted string representing the biom table
         """
-        if not isinstance(generated_by, string_types):
+        if (not isinstance(generated_by, str) and
+                not isinstance(generated_by, unicode)):
             raise TableException("Must specify a generated_by string")
 
         # Fill in top-level metadata.
         if direct_io:
-            direct_io.write(u'{')
-            direct_io.write(u'"id": "%s",' % str(self.table_id))
+            direct_io.write('{')
+            direct_io.write('"id": "%s",' % str(self.table_id))
             direct_io.write(
-                u'"format": "%s",' %
+                '"format": "%s",' %
                 get_biom_format_version_string((1, 0)))  # JSON table -> 1.0.0
             direct_io.write(
-                u'"format_url": "%s",' %
+                '"format_url": "%s",' %
                 get_biom_format_url_string())
-            direct_io.write(u'"generated_by": "%s",' % generated_by)
-            direct_io.write(u'"date": "%s",' % datetime.now().isoformat())
+            direct_io.write('"generated_by": "%s",' % generated_by)
+            direct_io.write('"date": "%s",' % datetime.now().isoformat())
         else:
-            id_ = u'"id": "%s",' % str(self.table_id)
-            format_ = u'"format": "%s",' % get_biom_format_version_string(
+            id_ = '"id": "%s",' % str(self.table_id)
+            format_ = '"format": "%s",' % get_biom_format_version_string(
                 (1, 0))  # JSON table -> 1.0.0
-            format_url = u'"format_url": "%s",' % get_biom_format_url_string()
-            generated_by = u'"generated_by": "%s",' % generated_by
-            date = u'"date": "%s",' % datetime.now().isoformat()
+            format_url = '"format_url": "%s",' % get_biom_format_url_string()
+            generated_by = '"generated_by": "%s",' % generated_by
+            date = '"date": "%s",' % datetime.now().isoformat()
 
         # Determine if we have any data in the matrix, and what the shape of
         # the matrix is.
@@ -3750,30 +3681,30 @@ html
 
         # Determine the type of elements the matrix is storing.
         if isinstance(test_element, int):
-            matrix_element_type = u"int"
+            matrix_element_type = "int"
         elif isinstance(test_element, float):
-            matrix_element_type = u"float"
-        elif isinstance(test_element, string_types):
-            matrix_element_type = u"str"
+            matrix_element_type = "float"
+        elif isinstance(test_element, unicode):
+            matrix_element_type = "unicode"
         else:
             raise TableException("Unsupported matrix data type.")
 
         # Fill in details about the matrix.
         if direct_io:
             direct_io.write(
-                u'"matrix_element_type": "%s",' %
+                '"matrix_element_type": "%s",' %
                 matrix_element_type)
-            direct_io.write(u'"shape": [%d, %d],' % (num_rows, num_cols))
+            direct_io.write('"shape": [%d, %d],' % (num_rows, num_cols))
         else:
-            matrix_element_type = u'"matrix_element_type": "%s",' % \
+            matrix_element_type = '"matrix_element_type": "%s",' % \
                 matrix_element_type
-            shape = u'"shape": [%d, %d],' % (num_rows, num_cols)
+            shape = '"shape": [%d, %d],' % (num_rows, num_cols)
 
         # Fill in the table type
         if self.type is None:
-            type_ = u'"type": null,'
+            type_ = '"type": null,'
         else:
-            type_ = u'"type": "%s",' % self.type
+            type_ = '"type": "%s",' % self.type
 
         if direct_io:
             direct_io.write(type_)
@@ -3781,24 +3712,24 @@ html
         # Fill in details about the rows in the table and fill in the matrix's
         # data. BIOM 2.0+ is now only sparse
         if direct_io:
-            direct_io.write(u'"matrix_type": "sparse",')
-            direct_io.write(u'"data": [')
+            direct_io.write('"matrix_type": "sparse",')
+            direct_io.write('"data": [')
         else:
-            matrix_type = u'"matrix_type": "sparse",'
-            data = [u'"data": [']
+            matrix_type = '"matrix_type": "sparse",'
+            data = ['"data": [']
 
         max_row_idx = len(self.ids(axis='observation')) - 1
         max_col_idx = len(self.ids()) - 1
-        rows = [u'"rows": [']
+        rows = ['"rows": [']
         have_written = False
         for obs_index, obs in enumerate(self.iter(axis='observation')):
             # i'm crying on the inside
             if obs_index != max_row_idx:
-                rows.append(u'{"id": %s, "metadata": %s},' % (dumps(obs[1]),
-                                                              dumps(obs[2])))
+                rows.append('{"id": %s, "metadata": %s},' % (dumps(obs[1]),
+                                                             dumps(obs[2])))
             else:
-                rows.append(u'{"id": %s, "metadata": %s}],' % (dumps(obs[1]),
-                                                               dumps(obs[2])))
+                rows.append('{"id": %s, "metadata": %s}],' % (dumps(obs[1]),
+                                                              dumps(obs[2])))
 
             # turns out its a pain to figure out when to place commas. the
             # simple work around, at the expense of a little memory
@@ -3807,55 +3738,55 @@ html
             built_row = []
             for col_index, val in enumerate(obs[0]):
                 if float(val) != 0.0:
-                    built_row.append(u"[%d,%d,%r]" % (obs_index, col_index,
-                                                      val))
+                    built_row.append("[%d,%d,%r]" % (obs_index, col_index,
+                                                     val))
             if built_row:
                 # if we have written a row already, its safe to add a comma
                 if have_written:
                     if direct_io:
-                        direct_io.write(u',')
+                        direct_io.write(',')
                     else:
-                        data.append(u',')
+                        data.append(',')
                 if direct_io:
-                    direct_io.write(u','.join(built_row))
+                    direct_io.write(','.join(built_row))
                 else:
-                    data.append(u','.join(built_row))
+                    data.append(','.join(built_row))
 
                 have_written = True
 
         # finalize the data block
         if direct_io:
-            direct_io.write(u"],")
+            direct_io.write("],")
         else:
-            data.append(u"],")
+            data.append("],")
 
         # Fill in details about the columns in the table.
-        columns = [u'"columns": [']
+        columns = ['"columns": [']
         for samp_index, samp in enumerate(self.iter()):
             if samp_index != max_col_idx:
-                columns.append(u'{"id": %s, "metadata": %s},' % (
+                columns.append('{"id": %s, "metadata": %s},' % (
                     dumps(samp[1]), dumps(samp[2])))
             else:
-                columns.append(u'{"id": %s, "metadata": %s}]' % (
+                columns.append('{"id": %s, "metadata": %s}]' % (
                     dumps(samp[1]), dumps(samp[2])))
 
-        if rows[0] == u'"rows": [' and len(rows) == 1:
+        if rows[0] == '"rows": [' and len(rows) == 1:
             # empty table case
-            rows = [u'"rows": [],']
-            columns = [u'"columns": []']
+            rows = ['"rows": [],']
+            columns = ['"columns": []']
 
-        rows = u''.join(rows)
-        columns = u''.join(columns)
+        rows = ''.join(rows)
+        columns = ''.join(columns)
 
         if direct_io:
             direct_io.write(rows)
             direct_io.write(columns)
-            direct_io.write(u'}')
+            direct_io.write('}')
         else:
-            return u"{%s}" % ''.join([id_, format_, format_url, matrix_type,
-                                      generated_by, date, type_,
-                                      matrix_element_type, shape,
-                                      u''.join(data), rows, columns])
+            return "{%s}" % ''.join([id_, format_, format_url, matrix_type,
+                                     generated_by, date, type_,
+                                     matrix_element_type, shape,
+                                     ''.join(data), rows, columns])
 
     @staticmethod
     def from_tsv(lines, obs_mapping, sample_mapping,
@@ -4033,9 +3964,9 @@ html
             obs_ids.append(fields[0])
 
             if last_column_is_numeric:
-                values = list(map(dtype, fields[1:]))
+                values = map(dtype, fields[1:])
             else:
-                values = list(map(dtype, fields[1:-1]))
+                values = map(dtype, fields[1:-1])
 
                 if md_parse is not None:
                     metadata.append(md_parse(fields[-1]))
@@ -4091,7 +4022,7 @@ html
         O1	0.0	0.0	1.0
         O2	1.0	3.0	42.0
         """
-        return self.delimited_self(u'\t', header_key, header_value,
+        return self.delimited_self('\t', header_key, header_value,
                                    metadata_formatter,
                                    observation_column_name)
 
@@ -4147,7 +4078,7 @@ def list_list_to_sparse(data, dtype=float, shape=None):
     scipy.csr_matrix
         The newly generated matrix
     """
-    rows, cols, values = zip(*data)
+    rows, cols, values = izip(*data)
 
     if shape is None:
         n_rows = max(rows) + 1
@@ -4341,7 +4272,7 @@ def dict_to_sparse(data, dtype=float, shape=None):
     rows = []
     cols = []
     vals = []
-    for (r, c), v in viewitems(data):
+    for (r, c), v in data.iteritems():
         rows.append(r)
         cols.append(c)
         vals.append(v)
diff --git a/biom/util.py b/biom/util.py
index 7ecf6df..8e73583 100644
--- a/biom/util.py
+++ b/biom/util.py
@@ -9,7 +9,6 @@
 # ----------------------------------------------------------------------------
 
 import os
-import sys
 import inspect
 from contextlib import contextmanager
 
@@ -23,13 +22,8 @@ from gzip import open as gzip_open
 try:
     import h5py
     HAVE_H5PY = True
-
-    if sys.version_info.major == 2:
-        H5PY_VLEN_STR = h5py.special_dtype(vlen=unicode)  # noqa
-        H5PY_VLEN_UNICODE = h5py.special_dtype(vlen=unicode)  # noqa
-    else:
-        H5PY_VLEN_STR = h5py.special_dtype(vlen=str)
-        H5PY_VLEN_UNICODE = h5py.special_dtype(vlen=str)
+    H5PY_VLEN_STR = h5py.special_dtype(vlen=str)
+    H5PY_VLEN_UNICODE = h5py.special_dtype(vlen=unicode)
 
 except ImportError:
     HAVE_H5PY = False
@@ -47,7 +41,7 @@ __url__ = "http://biom-format.org"
 __maintainer__ = "Daniel McDonald"
 __email__ = "daniel.mcdonald at colorado.edu"
 __format_version__ = (2, 1)
-__version__ = "2.1.5"
+__version__ = "2.1.4"
 
 
 def generate_subsamples(table, n, axis='sample', by_id=False):
@@ -132,7 +126,7 @@ def unzip(items):
     BSD license).
     """
     if items:
-        return list(map(list, zip(*list(items))))
+        return map(list, zip(*items))
     else:
         return []
 
@@ -327,7 +321,7 @@ def compute_counts_per_sample_stats(table, binary_counts=False):
             sample_counts[sample_id] = (count_vector != 0).sum()
         else:
             sample_counts[sample_id] = float(count_vector.sum())
-    counts = list(sample_counts.values())
+    counts = sample_counts.values()
 
     if len(counts) == 0:
         return (0, 0, 0, 0, sample_counts)
@@ -355,7 +349,7 @@ def safe_md5(open_file, block_size=2 ** 20):
 
     # While a little hackish, this allows this code to
     # safely work either with a file object or a list of lines.
-    if hasattr(open_file, 'read'):
+    if isinstance(open_file, file):
         data_getter = open_file.read
         data_getter_i = block_size
     elif isinstance(open_file, list):
@@ -373,7 +367,7 @@ def safe_md5(open_file, block_size=2 ** 20):
     while data:
         data = data_getter(data_getter_i)
         if data:
-            result.update(data.encode('utf-8'))
+            result.update(data)
     return result.hexdigest()
 
 
@@ -387,7 +381,7 @@ def is_gzip(fp):
     project, but we obtained permission from the authors of this function to
     port it to the BIOM Format project (and keep it under BIOM's BSD license).
     """
-    return open(fp, 'rb').read(2) == b'\x1f\x8b'
+    return open(fp, 'rb').read(2) == '\x1f\x8b'
 
 
 @contextmanager
@@ -510,6 +504,6 @@ def is_hdf5_file(fp):
     bool
         Whether the file is an HDF5 file
     """
-    with open(fp, 'rb') as f:
+    with open(fp) as f:
         # from the HDF5 documentation about format signature
-        return f.read(8) == b'\x89HDF\r\n\x1a\n'
+        return f.read(8) == '\x89HDF\r\n\x1a\n'
diff --git a/doc/conf.py b/doc/conf.py
index b8f3658..f26f743 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -66,8 +66,8 @@ copyright = u'2011-2015, The BIOM Format Development Team'
 # built documents.
 #
 # The full version, including alpha/beta/rc tags.
-version = "2.1.5"
-release = "2.1.5"
+version = "2.1.4"
+release = "2.1.4"
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/doc/index.rst b/doc/index.rst
index 92308ed..704c2ac 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -9,13 +9,9 @@ The `BIOM file format <http://www.biom-format.org>`_ (canonically pronounced `bi
 
 The `BIOM format <http://www.biom-format.org>`_ is designed for general use in broad areas of comparative -omics. For example, in marker-gene surveys, the primary use of this format is to represent OTU tables: the observations in this case are OTUs and the matrix contains counts corresponding to the number of times each OTU is observed in each sample. With respect to metagenome data, this format would be used to represent metagenome tables: the observations in this case might correspond  [...]
 
-The BIOM project consists of the following components:
+There are two components to the BIOM project: first is the `definition of the BIOM format <./documentation/biom_format.html>`_, and second is `development of support objects <./documentation/table_objects.html>`_ in multiple programming languages to support the use of BIOM in diverse bioinformatics applications. The version of the BIOM file format is independent of the version of the `biom-format` software.
 
-* `definition of the BIOM file format <./documentation/biom_format.html>`_;
-* command line interface (CLI) for working with BIOM files, including `converting between file formats <./documentation/biom_conversion.html>`_, `adding metadata to BIOM files <./documentation/adding_metadata.html>`_, and `summarizing BIOM files <./documentation/summarizing_biom_tables.html>`_ (run ``biom`` to see the full list of commands);
-* application programming interface (API) for working with BIOM files in multiple programming languages (including Python and R).
-
-The ``biom-format`` package provides a command line interface and Python API for working with BIOM files. The rest of this site contains details about the BIOM file format (which is independent of the API) and the Python ``biom-format`` package. For more details about the R API, please see the `CRAN biom package <http://cran.r-project.org/web/packages/biom/index.html>`_.
+There are official implementations of BIOM format support objects (APIs) in the Python and R programming languages. The rest of this site contains details about the BIOM file format (which is independent of the API) and the Python ``biom-format`` API. For more details about the R API, please see the `CRAN biom package <http://cran.r-project.org/web/packages/biom/index.html>`_.
 
 Projects using the BIOM format
 ==============================
@@ -29,7 +25,6 @@ Projects using the BIOM format
 * `VAMPS <http://vamps.mbl.edu/>`_
 * `metagenomeSeq <http://www.bioconductor.org/packages/release/bioc/html/metagenomeSeq.html>`_
 * `Phinch <http://phinch.org>`_
-* `RDP Classifier <https://github.com/rdpstaff/classifier>`_
 
 If you are using BIOM in your project, and would like your project to be listed, please submit a `pull request <https://github.com/biocore/biom-format/pulls>`_ to the BIOM project. More information on `submitting pull requests can be found here <https://help.github.com/articles/using-pull-requests>`_.
 
@@ -47,30 +42,77 @@ BIOM version
 
 The latest official version of the biom-format project is |release| and of the BIOM file format is 2.0. Details on the `file format can be found here <./documentation/biom_format.html>`_.
 
-Installing the ``biom-format`` Python package
-=============================================
+Installing the biom-format project
+==================================
+
+To install the ``biom-format`` project, you can download the `latest version here <https://pypi.python.org/pypi/biom-format/>`_, or work with the development version. Generally we recommend working with the release version as it will be more stable, but if you want access to the latest features (and can tolerate some instability) you should work with the development version.
+
+The biom-format project has the following dependencies:
+
+	*  `Python <http://www.python.org/>`_ >= 2.7 and < 3.0
+	* `numpy <http://www.numpy.org/>`_ >= 1.7.0
+	* `pyqi <http://pyqi.readthedocs.org>`_ 0.3.2
+	* `scipy <http://www.scipy.org/>`_ >= 0.13.0 
+	* `h5py <http://www.h5py.org/>`_ >= 2.20.0 (optional; must be installed if creating or reading HDF5 formatted files)
+
+The easiest way to install the latest version of the biom-format project and its required dependencies is via pip::
+
+	pip install numpy
+	pip install biom-format
+
+That's it!
+
+If you decided not to install biom-format using pip, it is also possible to manually install the latest release. We'll illustrate the install process in the ``$HOME/code`` directory. You can either work in this directory on your system (creating it, if necessary, by running ``mkdir $HOME/code``) or replace all occurrences of ``$HOME/code`` in the following instructions with your working directory. Please note that ``numpy`` must be in your installed prior to installing ``biom-format``. C [...]
+
+	cd $HOME/code
+
+Download the `latest release, which can be found here <https://pypi.python.org/pypi/biom-format>`_. After downloading, unpack and install (note: x.y.z refers to the downloaded version)::
 
-To install the latest release of the ``biom-format`` Python package::
+	tar xzf biom-format-x.y.z.tar.gz
+	cd $HOME/code/biom-format-x.y.z
 
-    pip install numpy
-    pip install biom-format
+Alternatively, to install the development version, pull it from GitHub, and change to the resulting directory::
 
-To work with BIOM 2.0+ files::
+	git clone git://github.com/biocore/biom-format.git
+	cd $HOME/code/biom-format
 
-    pip install h5py
+To install (either the development or release version), follow these steps::
 
-To see a list of all ``biom`` commands, run::
+	sudo python setup.py install
 
-    biom
+If you do not have sudo access on your system (or don't want to install the ``biom-format`` project in the default location) you'll need to install the library code and scripts in specified directories, and then tell your system where to look for those files. You can do this as follows::
 
-To enable Bash tab completion of ``biom`` commands, add the following line to ``$HOME/.bashrc`` (if on Linux) or ``$HOME/.bash_profile`` (if on Mac OS X)::
+	echo "export PATH=$HOME/bin/:$PATH" >> $HOME/.bashrc
+	echo "export PYTHONPATH=$HOME/lib/:$PYTHONPATH" >> $HOME/.bashrc
+	mkdir -p $HOME/bin $HOME/lib/
+	source $HOME/.bashrc
+	python setup.py install --install-scripts=$HOME/bin/ --install-purelib=$HOME/lib/ --install-lib=$HOME/lib/
 
-    eval "$(_BIOM_COMPLETE=source biom)"
+You should then have access to the biom-format project. You can test this by running the following command::
+	
+	python -c "from biom import __version__; print __version__"
 
-Installing the ``biom`` R package
-=================================
+You should see the current version of the biom-format project.
+
+Next you can run::
+
+	which biom
+
+You should get a file path ending with ``biom`` printed to your screen if it is installed correctly. Finally, to see a list of all ``biom`` commands, run::
+
+	biom
+
+Enabling tab completion of biom commands
+----------------------------------------
+
+The ``biom`` command referenced in the previous section is a driver for commands in biom-format, powered by `the pyqi project <http://biocore.github.io/pyqi>`_. You can enable tab completion of biom command names and command options (meaning that when you begin typing the name of a command or option you can auto-complete it by hitting the *tab* key) by following a few simple steps from the pyqi documentation. While this step is optional, tab completion is very convenient so it's worth enabling.
+
+To enable tab completion, follow the steps outlined under `Configuring bash completion <http://biocore.github.io/pyqi/doc/tutorials/defining_your_command_driver.html#configuring-bash-completion>`_ in the pyqi install documentation, substituting ``biom`` for ``my-project`` and ``my_project`` in all commands. After completing those steps and closing and re-opening your terminal, auto-completion should be enabled.
+
+BIOM format in R
+================
 
-There is also a BIOM format package for R called ``biom``. This package includes basic tools for reading biom-format files, accessing and subsetting data tables from a biom object, as well as limited support for writing a biom-object back to a biom-format file. The design of this API is intended to match the python API and other tools included with the biom-format project, but with a decidedly "R flavor" that should be familiar to R users. This includes S4 classes and methods, as well as [...]
+There is also a BIOM format package for R, called ``biom``. This package includes basic tools for reading biom-format files, accessing and subsetting data tables from a biom object, as well as limited support for writing a biom-object back to a biom-format file. The design of this API is intended to match the python API and other tools included with the biom-format project, but with a decidedly "R flavor" that should be familiar to R users. This includes S4 classes and methods, as well a [...]
 
 To install the latest stable release of the ``biom`` package enter the following command from within an R session::
 
@@ -86,7 +128,7 @@ Please post any support or feature requests and bugs to `the biom issue tracker
 
 See `the biom project on GitHub <https://github.com/joey711/biom/>`_ for further details, or if you would like to contribute.
 
-Note that the licenses between the ``biom`` R package (GPL-2) and the ``biom-format`` Python package (Modified BSD) are different.
+Note that the licenses between the ``biom`` R package (GPL-2) and the other biom-format software (Modified BSD) are different.
 
 Citing the BIOM project
 =======================
@@ -100,4 +142,4 @@ You can cite the BIOM format as follows (`link <http://www.gigasciencejournal.co
 Development team
 ================
 
-The biom-format project was conceived of and developed by the `QIIME <http://www.qiime.org>`_, `MG-RAST <http://metagenomics.anl.gov>`_, and `VAMPS <http://vamps.mbl.edu/>`_ development groups to support interoperability of our software packages. If you have questions about the biom-format project please post them on the `QIIME Forum <http://forum.qiime.org>`_.
+The biom-format project was conceived of and developed by the `QIIME <http://www.qiime.org>`_, `MG-RAST <http://metagenomics.anl.gov>`_, and `VAMPS <http://vamps.mbl.edu/>`_ development groups to support interoperability of our software packages. If you have questions about the biom-format project you can contact gregcaporaso at gmail.com.
diff --git a/images/biom-logos.ai b/images/biom-logos.ai
new file mode 100644
index 0000000..66bdade
--- /dev/null
+++ b/images/biom-logos.ai
@@ -0,0 +1,1124 @@
+%PDF-1.5
%����
+1 0 obj
<</Metadata 2 0 R/OCProperties<</D<</ON[7 0 R 32 0 R 55 0 R 79 0 R 103 0 R 127 0 R]/Order 128 0 R/RBGroups[]>>/OCGs[7 0 R 32 0 R 55 0 R 79 0 R 103 0 R 127 0 R]>>/Pages 3 0 R/Type/Catalog>>
endobj
2 0 obj
<</Length 68064/Subtype/XML/Type/Metadata>>stream
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.0-c060 61.134777, 2010/02/12-17:32:00        ">
+   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+      <rdf:Description rdf:about=""
+            xmlns:dc="http://purl.org/dc/elements/1.1/">
+         <dc:format>application/pdf</dc:format>
+         <dc:title>
+            <rdf:Alt>
+               <rdf:li xml:lang="x-default">Web</rdf:li>
+            </rdf:Alt>
+         </dc:title>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
+            xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/">
+         <xmp:CreatorTool>Adobe Illustrator CS5</xmp:CreatorTool>
+         <xmp:CreateDate>2012-03-01T10:24:19-07:00</xmp:CreateDate>
+         <xmp:ModifyDate>2012-03-01T14:54:15-07:00</xmp:ModifyDate>
+         <xmp:MetadataDate>2012-03-01T14:54:15-07:00</xmp:MetadataDate>
+         <xmp:Thumbnails>
+            <rdf:Alt>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpGImg:width>256</xmpGImg:width>
+                  <xmpGImg:height>216</xmpGImg:height>
+                  <xmpGImg:format>JPEG</xmpGImg:format>
+                  <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgA2AEAAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQV [...]
+               </rdf:li>
+            </rdf:Alt>
+         </xmp:Thumbnails>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
+            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
+            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#">
+         <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
+         <xmpMM:OriginalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</xmpMM:OriginalDocumentID>
+         <xmpMM:DocumentID>xmp.did:F87F1174072068118C14A5E429A68D60</xmpMM:DocumentID>
+         <xmpMM:InstanceID>uuid:4125f840-c2b0-c348-84e2-49d0e8db7b08</xmpMM:InstanceID>
+         <xmpMM:DerivedFrom rdf:parseType="Resource">
+            <stRef:instanceID>uuid:52d3fbd8-d8d7-2543-8e0c-81d9ea137ecb</stRef:instanceID>
+            <stRef:documentID>xmp.did:8CF5709C0E20681188C6A12CE4B46A4D</stRef:documentID>
+            <stRef:originalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</stRef:originalDocumentID>
+            <stRef:renditionClass>proof:pdf</stRef:renditionClass>
+         </xmpMM:DerivedFrom>
+         <xmpMM:History>
+            <rdf:Seq>
+               <rdf:li rdf:parseType="Resource">
+                  <stEvt:action>saved</stEvt:action>
+                  <stEvt:instanceID>xmp.iid:F87F1174072068118C14A5E429A68D60</stEvt:instanceID>
+                  <stEvt:when>2012-03-01T10:24:22-07:00</stEvt:when>
+                  <stEvt:softwareAgent>Adobe Illustrator CS5</stEvt:softwareAgent>
+                  <stEvt:changed>/</stEvt:changed>
+               </rdf:li>
+            </rdf:Seq>
+         </xmpMM:History>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/">
+         <illustrator:StartupProfile>Web</illustrator:StartupProfile>
+         <illustrator:Type>Document</illustrator:Type>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+            xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+            xmlns:stFnt="http://ns.adobe.com/xap/1.0/sType/Font#"
+            xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/">
+         <xmpTPg:NPages>1</xmpTPg:NPages>
+         <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
+         <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
+         <xmpTPg:MaxPageSize rdf:parseType="Resource">
+            <stDim:w>822.000000</stDim:w>
+            <stDim:h>588.000000</stDim:h>
+            <stDim:unit>Pixels</stDim:unit>
+         </xmpTPg:MaxPageSize>
+         <xmpTPg:Fonts>
+            <rdf:Bag>
+               <rdf:li rdf:parseType="Resource">
+                  <stFnt:fontName>EurostileRegular</stFnt:fontName>
+                  <stFnt:fontFamily>Eurostile</stFnt:fontFamily>
+                  <stFnt:fontFace>Regular</stFnt:fontFace>
+                  <stFnt:fontType>Open Type</stFnt:fontType>
+                  <stFnt:versionString>Version 1.51</stFnt:versionString>
+                  <stFnt:composite>False</stFnt:composite>
+                  <stFnt:fontFileName>Eurostile</stFnt:fontFileName>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <stFnt:fontName>Impact</stFnt:fontName>
+                  <stFnt:fontFamily>Impact</stFnt:fontFamily>
+                  <stFnt:fontFace>Regular</stFnt:fontFace>
+                  <stFnt:fontType>Open Type</stFnt:fontType>
+                  <stFnt:versionString>Version 5.00x</stFnt:versionString>
+                  <stFnt:composite>False</stFnt:composite>
+                  <stFnt:fontFileName>Impact.ttf</stFnt:fontFileName>
+               </rdf:li>
+            </rdf:Bag>
+         </xmpTPg:Fonts>
+         <xmpTPg:PlateNames>
+            <rdf:Seq>
+               <rdf:li>Cyan</rdf:li>
+               <rdf:li>Magenta</rdf:li>
+               <rdf:li>Yellow</rdf:li>
+               <rdf:li>Black</rdf:li>
+            </rdf:Seq>
+         </xmpTPg:PlateNames>
+         <xmpTPg:SwatchGroups>
+            <rdf:Seq>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Default Swatch Group</xmpG:groupName>
+                  <xmpG:groupType>0</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>White</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>255</xmpG:green>
+                           <xmpG:blue>255</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>Black</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Red</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Yellow</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>255</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Green</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>255</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Cyan</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>255</xmpG:green>
+                           <xmpG:blue>255</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Blue</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>255</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>RGB Magenta</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>255</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=193 G=39 B=45</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>193</xmpG:red>
+                           <xmpG:green>39</xmpG:green>
+                           <xmpG:blue>45</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=237 G=28 B=36</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>237</xmpG:red>
+                           <xmpG:green>28</xmpG:green>
+                           <xmpG:blue>36</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=241 G=90 B=36</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>241</xmpG:red>
+                           <xmpG:green>90</xmpG:green>
+                           <xmpG:blue>36</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=247 G=147 B=30</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>247</xmpG:red>
+                           <xmpG:green>147</xmpG:green>
+                           <xmpG:blue>30</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=251 G=176 B=59</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>251</xmpG:red>
+                           <xmpG:green>176</xmpG:green>
+                           <xmpG:blue>59</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=252 G=238 B=33</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>252</xmpG:red>
+                           <xmpG:green>238</xmpG:green>
+                           <xmpG:blue>33</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=217 G=224 B=33</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>217</xmpG:red>
+                           <xmpG:green>224</xmpG:green>
+                           <xmpG:blue>33</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=140 G=198 B=63</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>140</xmpG:red>
+                           <xmpG:green>198</xmpG:green>
+                           <xmpG:blue>63</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=57 G=181 B=74</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>57</xmpG:red>
+                           <xmpG:green>181</xmpG:green>
+                           <xmpG:blue>74</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=146 B=69</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>146</xmpG:green>
+                           <xmpG:blue>69</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=104 B=55</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>104</xmpG:green>
+                           <xmpG:blue>55</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=34 G=181 B=115</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>34</xmpG:red>
+                           <xmpG:green>181</xmpG:green>
+                           <xmpG:blue>115</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=169 B=157</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>169</xmpG:green>
+                           <xmpG:blue>157</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=41 G=171 B=226</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>41</xmpG:red>
+                           <xmpG:green>171</xmpG:green>
+                           <xmpG:blue>226</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=113 B=188</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>113</xmpG:green>
+                           <xmpG:blue>188</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=46 G=49 B=146</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>46</xmpG:red>
+                           <xmpG:green>49</xmpG:green>
+                           <xmpG:blue>146</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=27 G=20 B=100</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>27</xmpG:red>
+                           <xmpG:green>20</xmpG:green>
+                           <xmpG:blue>100</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=102 G=45 B=145</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>102</xmpG:red>
+                           <xmpG:green>45</xmpG:green>
+                           <xmpG:blue>145</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=147 G=39 B=143</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>147</xmpG:red>
+                           <xmpG:green>39</xmpG:green>
+                           <xmpG:blue>143</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=158 G=0 B=93</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>158</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>93</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=212 G=20 B=90</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>212</xmpG:red>
+                           <xmpG:green>20</xmpG:green>
+                           <xmpG:blue>90</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=237 G=30 B=121</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>237</xmpG:red>
+                           <xmpG:green>30</xmpG:green>
+                           <xmpG:blue>121</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=199 G=178 B=153</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>199</xmpG:red>
+                           <xmpG:green>178</xmpG:green>
+                           <xmpG:blue>153</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=153 G=134 B=117</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>153</xmpG:red>
+                           <xmpG:green>134</xmpG:green>
+                           <xmpG:blue>117</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=115 G=99 B=87</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>115</xmpG:red>
+                           <xmpG:green>99</xmpG:green>
+                           <xmpG:blue>87</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=83 G=71 B=65</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>83</xmpG:red>
+                           <xmpG:green>71</xmpG:green>
+                           <xmpG:blue>65</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=198 G=156 B=109</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>198</xmpG:red>
+                           <xmpG:green>156</xmpG:green>
+                           <xmpG:blue>109</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=166 G=124 B=82</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>166</xmpG:red>
+                           <xmpG:green>124</xmpG:green>
+                           <xmpG:blue>82</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=140 G=98 B=57</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>140</xmpG:red>
+                           <xmpG:green>98</xmpG:green>
+                           <xmpG:blue>57</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=117 G=76 B=36</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>117</xmpG:red>
+                           <xmpG:green>76</xmpG:green>
+                           <xmpG:blue>36</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=96 G=56 B=19</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>96</xmpG:red>
+                           <xmpG:green>56</xmpG:green>
+                           <xmpG:blue>19</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=66 G=33 B=11</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>66</xmpG:red>
+                           <xmpG:green>33</xmpG:green>
+                           <xmpG:blue>11</xmpG:blue>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Grays</xmpG:groupName>
+                  <xmpG:groupType>1</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=0 G=0 B=0</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>0</xmpG:red>
+                           <xmpG:green>0</xmpG:green>
+                           <xmpG:blue>0</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=26 G=26 B=26</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>26</xmpG:red>
+                           <xmpG:green>26</xmpG:green>
+                           <xmpG:blue>26</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=51 G=51 B=51</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>51</xmpG:red>
+                           <xmpG:green>51</xmpG:green>
+                           <xmpG:blue>51</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=77 G=77 B=77</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>77</xmpG:red>
+                           <xmpG:green>77</xmpG:green>
+                           <xmpG:blue>77</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=102 G=102 B=102</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>102</xmpG:red>
+                           <xmpG:green>102</xmpG:green>
+                           <xmpG:blue>102</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=128 G=128 B=128</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>128</xmpG:red>
+                           <xmpG:green>128</xmpG:green>
+                           <xmpG:blue>128</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=153 G=153 B=153</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>153</xmpG:red>
+                           <xmpG:green>153</xmpG:green>
+                           <xmpG:blue>153</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=179 G=179 B=179</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>179</xmpG:red>
+                           <xmpG:green>179</xmpG:green>
+                           <xmpG:blue>179</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=204 G=204 B=204</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>204</xmpG:red>
+                           <xmpG:green>204</xmpG:green>
+                           <xmpG:blue>204</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=230 G=230 B=230</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>230</xmpG:red>
+                           <xmpG:green>230</xmpG:green>
+                           <xmpG:blue>230</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=242 G=242 B=242</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>242</xmpG:red>
+                           <xmpG:green>242</xmpG:green>
+                           <xmpG:blue>242</xmpG:blue>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Web Color Group</xmpG:groupName>
+                  <xmpG:groupType>1</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=63 G=169 B=245</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>63</xmpG:red>
+                           <xmpG:green>169</xmpG:green>
+                           <xmpG:blue>245</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=122 G=201 B=67</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>122</xmpG:red>
+                           <xmpG:green>201</xmpG:green>
+                           <xmpG:blue>67</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=255 G=147 B=30</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>147</xmpG:green>
+                           <xmpG:blue>30</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=255 G=29 B=37</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>29</xmpG:green>
+                           <xmpG:blue>37</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=255 G=123 B=172</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>255</xmpG:red>
+                           <xmpG:green>123</xmpG:green>
+                           <xmpG:blue>172</xmpG:blue>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>R=189 G=204 B=212</xmpG:swatchName>
+                           <xmpG:mode>RGB</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:red>189</xmpG:red>
+                           <xmpG:green>204</xmpG:green>
+                           <xmpG:blue>212</xmpG:blue>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+            </rdf:Seq>
+         </xmpTPg:SwatchGroups>
+      </rdf:Description>
+      <rdf:Description rdf:about=""
+            xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+         <pdf:Producer>Adobe PDF library 9.90</pdf:Producer>
+      </rdf:Description>
+   </rdf:RDF>
+</x:xmpmeta>
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                           
+<?xpacket end="w"?>
endstream
endobj
3 0 obj
<</Count 1/Kids[9 0 R]/Type/Pages>>
endobj
9 0 obj
<</ArtBox[30.5 13.5176 677.048 556.405]/BleedBox[0.0 0.0 822.0 588.0]/Contents 129 0 R/LastModified(D:20120301145415-07'00')/MediaBox[0.0 0.0 822.0 588.0]/Parent 3 0 R/PieceInfo<</Illustrator 130 0 R>>/Resources<</ColorSpace<</CS0 131 0 R>>/ExtGState<</GS0 132 0 R>>/Font<</TT0 125 0 R/TT1 126 0 R>>/ProcSet[/PDF/Text]/Properties<</MC0 127 0 R>>>>/Thumb 133 0 R/TrimBox[0.0 0.0 822.0 588.0]/Type/Page>>
endobj
129 0 obj
<</Filter/FlateDecode/Length 1200>>stream
+H��WMo
7
��W�.�Z����v��
�� =98�8u�؈
���}�4;�3��)r+��r���HivWzwya���
����������ښ�k��P����v�`��ír��CZ������/E��\�˳��zP���Κ��Vn�ޫ_����j�
��YcCz�Q�V��ِMzˆ�����Ű�y��d�K��^m�3Ε�&LhA�a�k��(�C`�	�tSΦD�G�.®��
+ض�|�9�����V]�כ�Dg��ΙD�L��"� ]2>Utr�֖L�*�1�br�����)
�5�`���"�9zu��[�����̡O��7�}:*
���p��HdD^9 �ޤ������>
T��M�<YQr�����$�2O��5������0�At�{�]a����"�9��3�%�r
�	
E�)�]�?&W�$
�k����pu���<!W`��+n8�^KO;�E��ap�A5�
������M�-�"g�k��\ܜ��|9&��V�:
\��r��)1
}J|Ч䥿f�C��@���R�6��+M��u�F�T
�+��t-MC!�I������$C� ��Q3L��#l��q�d�05�&�Î�k��ޒ�-
	ʮ��

w�6��KWD.q��I'	���M3�%���^�`�0��&DGG�*X>W/��[�#Ҹ�]t������A#�
���l��h��^[�x�%
5̧���8�
~��a
aԴ\J��fB����b2�d�o��k^��j�,s�\u��NbKW���^�O�/���.�F_�/�OC���W���&0l���]o�:L ��4�h����J��A��v���~N
!+S�[<�?~����7��z�yw�6���Ј�?o>�=>��
~V�js�����L�!mƈ
+�G�&j���ߟ��6Үѿi�r��i,�8��|���������[�.���%������N׮�l
�2b"/���e/���&
����ım�=
���Ը�a5t��^	��%9�VH�||�oO�o��V qs��Ԟ<b$
�"N��
�j�
rdf��ٖ��q%�$���L��
�GE��d&�h�Or5Tj7�a�h�����Ž�wL[p]�
�v�u�G��d9�`����D�~
��o_�M������^}�L}����Yv��y��
+���	w��o��� ����
endstream
endobj
133 0 obj
<</BitsPerComponent 8/ColorSpace 134 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 73/Length 1083/Width 102>>stream
+8;Z\7gQCP>$mYohN5(m4%SGp2'4D!_Zh@@(m8=<3*Zn,BJ_Gp0m0aA6KU5PZTYA*u
+Oo_MrMup4\Ihr9VacEB:+FX(r6^=6Rh+m!2/a_^Xb9,=U?+Gon2UpucWMQ"Q4(FfR
+A`:LQU])E4QRGuR.4[HiXARP(lcY^?F[TBjZGBj:b(7tu+(UADf&qo7j!PV3F4'0j
+V9,(Ibl\b:b,-4H&-1ZUScF0DbsQI(rI0\S9'2=q-UNcW-XDX9(f%_0QBrIHcLu3m
+m5;ldKqlfa7iNh?SB$EnFLX/3VZddV"gYf'M<0]aW?/*F at Z1JTFFc3*1!,]J0Bi(?
+0uD-R36mlc%fHp0+Y[%aWTP7A62+:8id&:l;S<\5`FncR`dGTs\ZDQ*#(#:XSP6,h
+`Y^UX1+lf`+#V<B^\01If$9UZ^8]0Db:$DLDE!A302I=KX?O7UU,SLsNhd`t#C6gW
+h:j?T\U5t;H[6+,"/IV'PT$\PkZ-&G86:iqf,lO=;.QbL0eY at g)Ejtn'$@qgN,'+e
+E.PgdTZ:#:I_t1X at hrE74kAc=Sap69%,=5J[&_7>qe!Sr/h;uH(MLAK2pBBQQ\P+%
+E"D2V*Bf/B.JobD!d:aCjtV&+A"#&:p;K:aU<N2iTZ9`+O*;Q5k].R)0bdqQ^L,4U
+5p9%s(k;">om324'[;3SSUB!uXNA[6CKtbdOuq1Lo.Rq-V,j>Pe&rTn`I<:F`GWA,
+Igh#9a at X^]F*a43ji`sYp8h$Lit_iU3rMo/q=AFh0pfR-Tl)88:39[Ijs4tn>kn5V
+`?njV#-2*th;4[&UqH_nA54i/Bm*ZEE<a$orCaKIq"/o@@.r%1^s"[eXhrgKN[;eu
+(d![C*nb at R0XTi=!D9T1<d8u2qrrLh!_GKV&38hq(K\^biOutHr]CD2d(e at D>=ILZ
+QnKLR#B)FI\OBB(ko>aO'_;aAhVd5#QC(DT.$[*1g$lVNE\VJ8/tslB>V+cn;)R>G
+El,J?[O1T_kc2Ns5e+o6dX#B`rQ<(0+^`$3g^(n8)eEU%Q*n2Cp^Ks4+l]`?`*?HY
+amM+&I:ft at F2dDDDZ9n@j0d_k~>
endstream
endobj
134 0 obj
[/Indexed/DeviceRGB 255 135 0 R]
endobj
135 0 obj
<</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>
endstream
endobj
127 0 obj
<</Intent 136 0 R/Name(Layer 1)/Type/OCG/Usage 137 0 R>>
endobj
136 0 obj
[/View/Design]
endobj
137 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>>
endobj
125 0 obj
<</BaseFont/MHJYDM+Impact/Encoding/WinAnsiEncoding/FirstChar 32/FontDescriptor 138 0 R/LastChar 120/Subtype/TrueType/Type/Font/Widths[176 0 0 0 0 0 0 0 0 0 0 0 0 0 185 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 552 0 0 0 0 0 0 0 0 0 0 717 0 546 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 504 520 495 0 511 0 519 0 274 0 0 274 0 523 511 0 0 358 471 305 0 437 0 434]>>
endobj
126 0 obj
<</BaseFont/MHJYDM+EurostileRegular/Encoding/WinAnsiEncoding/FirstChar 46/FontDescriptor 139 0 R/LastChar 120/Subtype/TrueType/Type/Font/Widths[195 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 617 0 0 0 0 0 0 204 0 0 0 858 0 613 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 510 511 485 0 502 0 510 0 188 0 0 188 0 516 506 0 0 398 474 326 0 402 0 404]>>
endobj
139 0 obj
<</Ascent 867/CapHeight 667/Descent -250/Flags 32/FontBBox[-185 -250 1123 867]/FontFamily(Eurostile)/FontFile2 140 0 R/FontName/MHJYDM+EurostileRegular/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 68/Type/FontDescriptor/XHeight 467>>
endobj
140 0 obj
<</Filter/FlateDecode/Length 4509/Length1 7158>>stream
+H�dV	XG��{`��98���И0�p���(��E�Bp
����D4�oc�J��;2��Q0��3�hL<"�lvs�ͺf�o�4�z�3����{��U�z�{�{�` ��:x��
o��8���f>�'+�$�\����� �k��J�o�O��{/(<�30����zFA��E]~�PG�4���
+��8bFI���G��t^��^\��W;i��0�Ē���l*��
+i�X�WR�)tݿh����+/���8\�>#��g�gM+�7�]4 �G�(��O��
�������*N�Tp
�����2�M��gN�)2��'vH$�=b����]�cA�~3޽������ʹc��V�|e��IE
+G

�1��a�G���޹�6w�R�����x��j����`4���*^Q���KDdTt�>��}��kl\�-!1)�_J����/9�#����g�_�r��'-��>����7�����;wo}��j�W>o��m�ӶnYT��������5�����
�s����M{�q;��<Q�p����ǜ)�_[�V��7�T0��?��z��7���;~�TÇ�?:���
Z�~sͪ�7lZ�NH����«� ��bql<�c���"w�k�D�$��b�+���ã̜Ye֚uf�9�����<Ԝk.���3��%����I�5��u] ]�I�� ���[W���
+|�k:�bn]��%�ߣ���K���'?�gvK���'m�۲�V���6���6���r�lW�k�k��k� ��0�bfC�=������n`M���k�
��]�1���1X�RT`&^�l��$a
+1
+�1�ɻ�1#��l��B�K.搿UP���w
�|�� 
��O<5�eD ������%؇X
"�(D�7���ųx1�"q��
	HD��)��S�؏%8�a,F3_�Ǐ(�JlA��
Y��
�⯨�a,�F�K�2��w�ypPT�‰#8�0�q�s�q�Ѐq�h�G8�s8��!
�p�y��xv�q���%�` ����:>�M|�/p_�K��m��W��H�
�h�=�o�N�z�q�5X��؄�؀�x����)x	嘅m(�td�
�k�|�TH��N	^�̤ȩaI�*�)�<���*5��~�.?O;6]�.��tΜ.��_�+Z
�hU�
�ɇ"$��f�7��F�	�V{�&,�����P+9����$��9C���B�Ђ4
3L�������w��jw�j���b�Vh�;=��0�_JJ\,�o4���N������Ą(K�.<��W��<~�ȝ�7;;��ey{�A,cu]I�#�B����k;� ��N
י�s���Gؔ�'�SN��K����h0���1&X�]
!��e:���l�]A��;U9ԋ@�#0�,�
�4
���T�
sw��� DZP��
.��
+
	��	Z_o������t~��J�8y!�"��O���L>�
S���4_�T�'u��6��L�P��[�[�J���9��z��MOLe�J˘�YYT�%�h6��q��T�T9�Sx{�A�u��T+��4��h�"Ġ
�f�������i��*rRE�>2j��e�5�222l��|%����PqJ�O,	F�Q�o��8x�����i��Ɵ ����]���ԫ|!��bѨT�b�.1YHR�*�`
�t��	Q�
���)i�4������JKY:\ʶ)�;$��M����	�j��RvM
ۛ��c!Y������P=�F��CM3<�r���
�������H2Y�)����d��ӣ'�i?r���K�f
�N�IRS�[|B�27KB��X��$G�,�N
��e���ɬ2�6���g��{�W����"m�u�I<?y�$u����������V��й���e����Y������+��5J���zb�@���i(<e����,lvj}9&���Ih����Co�ɓi}�����)�7T�i�֩���t6�)�Ґc1G�M� F�;U���F�����j������eef�~�]�C���7�\>k�
�s���������(A���lP�I11ē�à�].Cq�RUpz�'Y����q��$���.��^��h|�]ͤRIz���T���1���6�e'H-��!WW6�
�~�SU�د����3��{�ݻ
�˂O����Q$���[�2|�qPXpu]�bk%>b����&b����&��JeRgc�Fk:�i;揘�i���8㣑������h'�3�_�3�=�y�;����
+�	-^�ixa&��e��%٭1U�葞vH�g��'X��
��8
�hB�^�-�(*��ؙ)��O
VQM���>0�
>����9�u��ͪZZ�,3��O�f�,�w��3��vt9�y����]hYf�W�����3�mO�g�6��d���{�d��
�<g����p�6��uq��6֫g����S�uG���B��)}���ʂu���ɽ�a-�Yaۧ
Ԣ��!��'n�u��{�ת����z�c���
���]�T=u�����^e�dN����l}�3
׷6~�i��p=�V���
�-1j>�5�`h<#\'�ň:��X4I�p
+��l=h�ެ�7I=%�����#��1��HuN�As��^���$;�k6�����S��EŔ�{v‘gS�ے��[U��$�5�0hׄ�
yzz�2�%O�`ٍ�9g��#�h��v@=դ��~�s�Rޯq�y���
x���*
Sf��=�T�6ɴ�Z�=N�t��ZA�]�N�o�yۼ�o��RR��oJJ�����B{;Ά��W�B�����ԋ���)����R$��bIx���)���a_�qNJr�xI�dt]����Fbk�zv��΂1��9�eV�cU��X�V�lޘ�}@�.���3�l��@�O�ī�#�!m��
zfة)�L�>���$q�{$�~1��I_�G\� �:l)��|p��T�O��w����Î ��ʶ�\��<}����Z���<�.ݢ'��V��
�Ȣ�	��y[,�
�
+}�4�8���ls��	������TE���
+(����!h��T7�Wa
+��:��B8d��0I�S{�]W�-zǃ	T��.��ɩy�H2
o����s*+��OofJ3o�
6���Γ�m�?ռґ�<�rE��V�W*����3"����'"���"y���GGXU&T�kCp��@DR�8�B��s��-�=z�����:p;�
*.~����`4�������b�x�5��	���ʿ�C�íJdq%;�e�X^/��1ϳ�G;ͣl�y�ŷ/!�
kZX��Cv��n
b�Q
q"��f
�2b�=���b�Đ
E��������7Ί�����L�~a�E)�0D�U��ɖ�֍�/�<]���J���q�[I�)�ߠ&~�fj��I�G3�k(ߤ`�&v 2�|��ާ&�;Ԥ�D�U��!��\~�54�g��������-��T~$t���B�zm��w�a�T�O��N��s1w��k�X�K���xjd��n�+�7Q����tC�y*����7y�Ҍ5�kD�VJ�::tW�
���YP���H��|(��yգ�(!־F��:�<
+l�Q�r�-ܐK���h;��Nȓ�v��=��T�jh����V*d�:h?p���J��2!
mphk�Y\�4��2���*��V 
m5`�=h�X���D*U�Q�GŨ[�\��W�9
+ˢP'���J6��n��N���L
����ln�<NY�L�zp��wٯ8�
+� uw#�
t��?����TCL�n�$�L| �>n�*�m��,�|	x�~@w��k�u�N8d eᗃ"�F��~� H����@
���˘�~
�O�B������l}������_b~�u�'�B��&��{�cu(৳����5}#�
3�-.3��$"_
+
��{�lr��?޿ov�_e��
�Y� ���0wU˞��*��� �|
{W�`
�
�}�Gq����ȇ#��%��Z‰�@z��'�te+�{�{�|�M2
B��G&??�}iR����?}�I�6�N����V�%/�cԁ�����؛�9Ҋ
��fsD��Ed
䶈��|���LD)�@Ɋ�xƕ܈�P��("���FdyOD�@~="��rk����*W��h1��
9̘RW[��y\�D����C4��Y����./*�)���S
i|��
c���W� ǘ]��{�j룕E�
+_]}]�ߘX�[�c��z
��z�����ݾ��ʜ�i�K&
�܀�~��]�n�|W
+�z�ex=��zw����*�5.�2����7Hsi5-'7U��*���
��H� M�:��J��ȃ>MĿ�#�k
�C+��Ar�6����!f�Q�
��H�xʡ����E��o�yT�yD����'G
m���Y��
+�C[
��z�1�����ŋ�'�_��zYr#ڬ�%z�4�N%Ш���Ȝbe/�ը�J|��pc����o7��

{���Ҏb�z�3g\#�/C���q�j�0B�D���SUEa�'r�Y��}
�P+,d�` H�
D
endstream
endobj
138 0 obj
<</Ascent 1168/CapHeight 791/Descent -331/Flags 32/FontBBox[-129 -331 1261 1168]/FontFamily(Impact)/FontFile2 141 0 R/FontName/MHJYDM+Impact/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 204/Type/FontDescriptor/XHeight 648>>
endobj
141 0 obj
<</Filter/FlateDecode/Length 9107/Length1 14462>>stream
+H��V	xM���>�^!ABBDĹ79	"�RĔ����T*�� B����)� �1���5Sc5��Q�&�O��P�{h����|}�{y�{{}��w���k��}A �c$�

��;<a�h��$G��揎(0�c&�)��
�D �aq)��ڞy��>�w�'M�{R��
+Pk�%�F��r|�/����UO�xWk��Y�}���X��g������D{��;
4	��Z%G��{�y@�
ޯ��N�Mn[چ�\@LO����s�
 �l_O��j�
�v�� �+e�er�̧��QR'8���Q�*
B����/-�O��NP^	c�^�9Ԣ}
+���f�� ���|7�"�F���Q��m�(�c���
��ר��R���[����<�{6�j����>��Q�&�~M�5�o�2�V��mӶ]p�
;u	��^�n�{��ջO߰~���0p��!

���Ȩh���0*qtR�)�Ƨ�M�8)}�ӦϘ9k����f̛�`���K�.�Z�be���k֮[�O6lܔ�y��m��n߱s��={���?���_
<t���c8q��S������.|]p��7�^.����k�_�q��nk��Rd�[z��dD̠���tQ_\�*͐I����e�I��ɑ�r�
����⥘��Bi��U��J%M��lS�+y&������l������V�v���h�i�ev3{����������Xo���mR�
+�IuV]Uw�S�Q��Aj����R�
���Ju���
P����s�%�P��޵[:YB,Q�K�e�+��v>!����+�_���2���V��ry���5��R[��(���6�����5e�����뙽��2�,ǯT���[�Yj���-������}�?֒��t]���$L^� �=-{R�[�㲓e'ʎ�
+˼��N@9K3JW۞�f�
�
؞�f��������l^6ϒĒ�6C�ҝ�k�Wo)�����s/
W
�Z���%A%�����������5�`��z[=�nV�=�~��kw�;�M�P�����hǸ�
�vi�^Zw���5�i>�/��x2�V��sq"Q�W�Z���.���z���ߜ�S�R
�b.2D6V�'��Rdbvb���>�J<�S,�, 	��
�
���c
�� �#�,��%��k\D!��������5\�w�G<
c9n�{\G~�,D"Fa4���1��X�C
+�#��������)���̎i8�͘�����+
�(�
+9PU�F�(�kr��T�jB'�3��>բ��JnT��;�#�O�� ��
򢆤����M>���QcjB��GM�^�&5'jAH-)�ޡVԚޥ6Ԗ�Q0��;Ԟ:PG�D�)�B�
�G]�u�
ԓza�So�C})��Qz��)������;
�A4���4��ч4�")��i��H��8��E�4�(��i
��]ܣ����ZQ�[(�|&Ta�A
�9���
��
��|��#�E.V�NX&BpD�2��k����ΙX��'����E�u{�B��1�3�p������R�\�+i>����fN�3{"�l鮟�
��)U(pB(
+��/����>�{Ϩ��Eߍ���	W9���k'x��y��6]*�|v���8�]h*,̧�����!���
�Z�v�d^e�E���a�'��
Wǚ�Pу��#8��Ό���
���/D��(�����|�#z3���S�1�k2[[3W�i�~�
Q
��/[1�scgb!��9^����[_�C3x��b��P��w������%Z�
b(�M���^���	sa?goAy�rV�fV=f�
�9�(<����(F>���<ʡ�Q����u���l�##��~Q`B �=
e��b��2ù
+$p��X&p6�d,˹��Z������
�1�������
ήG\~'g�;g��m�M)4�2(�߼l�D[)��q:A��?��h(�D��&��!b�8/~�%Yj%��2�5R��I�g����t����!�XŸ���B���L_͞��
���P
8���C�gc��{�K_�x�/�
�T��r��t�mW�\��,�8O�E��ӗ9K5��C��S�g\�^��IԀkQE%R���+Lg��
�>̝DGSX�02�ܠ��'����u�サ��-{eٲl{�k�`K�]$i��nj�F22�4-t&�pK&kS(�i

� ��NW��?hi�!�$L'��th��L�'���Գ+ۃ��վ�=�ܽ��G��ӎ��
�5~�S�JZH+�H"�$�]g/9D����]��8�
+���M}�z�z�z����3��6�Nz%�EO҇���G
b�g�3?cn1��#�s��zV?�]�`W�
�h�����pee]���:�d��'�h�nM�Sm�Q�=in�.>���x��t�gP����3��~܍N��h�
B_C
��G� �۽��_�	£��3� �A���"�	;�J��m�$��(�ȉ��"�~�*���'�Y�
�K��3�y����_�`�oL/�E��X�2ɇ��,�t�|� 
�����
�cX͏��~��
�_�Z��������_���������kŶ֦Ɔ�5u�=�ښU+�]�*���*�W�9JK�Ŷ�Bk����3�昌���)��[BQNqE�%tuyԱF�1FT�Z��pQM�[���m����j��41ˉH�9I��A�K��Ma�����k���]��
���dr
+�r��=.K� �/�c
+�1�Ǎ�
 s�RB®y�F��ԑ �`��
!()�BP5A��R,��m
+KA�G<n�
+�
+�)���
+
+h�(���ז�&Tw�4�p��3I�Fks�B<6V�XD]�R�t
+A�s�-�ǝ�gÊ1��h0|	�d��S�`D]� >�����%��e�0���)���W�������`� �p��a�x)�ׁ�*Ou3�� ���N1
+�qyG�U*+�?[�㿔��z$N


��s�X�,Q���=�u�����;�Z��N��/��lj�%�Fi�*V/��	� ��ʁ%aA!�6�6ֆ�m����N@��2ۡ&�q���
 �_-��8:'{��
+�%ȁ|�Vjk��)� �,�j�f�{��+�b9�B���0)�Q!�y5��I?��2�)�
sh�1��u��DU�ܢ�hH�L-J��G��9��/R
��3��Y�����x,+���8徰+&O;\Qy&�	A)�rH�BrT�%3S��
+r��W�%E]Jf.O;��LDa���4f�Xa�A"Y�8(5S�I��P��;Th� ������1 ���̠Z�X����Ӓe).H�X|]v����
hp
+�	��#
��К$�������j�[��'��L��{�fA-�
�yH]
�df�M�"X&�J�h�3�Z.St,��eMQ�
k[Z2�%Q	[
�H��
�ĮY��_�.D`s�=OQȤc��y��H�Q�su޼�~{�F���ី��/n`��'�)�d���[�p�Щ>⨹G~z���~
��p�l��bB3d�f��#_�~
��x(�	�I_ %�D�^	m�9�1����`M������`Ť�P0�s�n��&I�g��1��*�~J�.x�o���n���[
+���X��r\T�ӗCR��
[ZZ��Vc����5�O]�~ r��x�t��v�{+�<OD�ݺ����hW9��ɗO��`��W��c�ײ�7�ߢF:�V=˙�`y
����ޢ�*���/�q���f
E�!��d�,�g��.�5%3������
��H]������hk���ކc��_[nݾ��fgo�p"�O}bAq����U��mF��lX)��;o+v`f{��K釯��������-=�B���

�M:N��'������EEjK��)�d)n�1
+��s�A��y-ycX�0���I���K�I���%T�,�65���x��/����g���j^(����7�����C���.Z�2��5�O�
Y���jOK�K��L'4�5�)�*3k��-��ƺ\ӊ��z���y��"��J����X��HU(�½�w�`ë";o;f�^����fVԌ�A(�
m�����`?.�Q�H��zqs�
k
�G�'��w����֤'��nڑ�r�ZYEժ©X�c����D^{{�ǟ�/�������;?y�kc����yg�����v�.�����
@K!4��Y
��K�Ӆ�>B뭦���
��g�U$��
:a�
+��-5�pZ�UT',�
b�yP���Z�
�dž}]{���c[;�5��_ ��.����*�
���޴e���;ǏNx�q�@j�v_����o��݀oq!������v�6f�B�;b�aY
�Ī��J�FD��X�خ���3|���,�f	��UQV
e4Z�c
�B�n�a���*V�h�ZM�F[=�
�A��S��&�hl�6c[��F����G��oF�1���ͽ���������S���dE�f��J��w��7��N��)1
��BRzJ�%�)��u����8 ;Nln�|�}{oO��wO+:�����OZ�w߾��_�~��=�˖��c��
x�D�ɨ��|?
�4|���x�
�x���ݬ,hR�2�X�cvF���>QGz�)�
����u
��!$R~��~��\]�Yu�y��eY�?l���UZ�35+�m���b��yG�66�<i��m���J���e�-

[YGt��-��!9���jM���f�&y��	��U
{��&f:�+�Z�x��`T�eAr��7�̈��dr��� UC(&p���&�`�@��S����jt�Q��"��v���o����?$�%����R��oi��j^b���Mtz3ܲ��Y�2��le���!�?j�>sR���ZR���*6��G��
틧ѐ�����4D��6H�$9Y����MuTncJ�a��FJKj��H)�w�Z�_C1�~]����F�?�3�r��r
mc��� 3D
8w5�b�~���H�IB�uEU���S�f3!*5���Ԏ������
��N�_0i��GX�*1
^_��9M[j��vjKe������x4���^`��G��rD��
�����]m5x�5� [...]
+
+��]�?���`���	6nwR'�;A37�����n6�=oj3�F����{
��� C碰Ȗ�sAoZ+�X��w�V��@���>5%Y�z?V�#k����Or��lV���$��v�Ճ
���@WRu����ftZ��Y��0��i6�d�d(xA5��
W�3$
�&E�8F��L8�X�1>ލ���U�D���i�
�'��t9�K��`?��D�}~zZ:��

���7j{
Y�����oU\j�s��.H��Nu�~�9���w�O�s�	�y99#KƎ�1e��?���١`E}0{�
�{���+��*{~���`A�+�����`2��e�>ľ����.�9��na~��O��
+��n���6"�
�Us��K{�5��b��+$�k�[0���{ٲ�y��~�9s�|����Û�>t��_f޿����[��C0y^SV�
T2Y6�J+Ll�4���,�^F)a&+|�9�M���C6�,I�q����iЁ^��L&�+�D$�o#�nVy�s.T�$�e5�c�j��^�
U4�R��j~N���!;�����^R���c睒�97��Ջ-�na�[�v��WêU�Ӑ8�P
�Rb
c
�x��/ޥ��=v���Q����?��9�o�^P��g
g�
�dP�qf�V
+h���d �jV���t�U�����d6�
:81��@D[9q�D�aߦn�l��Ѷ��c�6Zj�
���Y�Pjj�w�q�%��Y{{b��y���U�*�	?Z�1���!JU�c�-�bK�5��U��Ǧ�tŐ�S�.{_����I~�������
O�����'S�̽߳�l������#$��@~�yq�
K�>I0
+�ȡ_~(칿�
�
��2�L��4�9�F�6��׵��+�����Q
]
�$�}�9�Iu�Pn�}��h#�m�H�c�$IK���Y�[G|<�DI��
+�Bi	�ړ�i:~OE{|�M���9F`�P�a-k�O�'�r�/%�
��z1���T��c�
+��
+�W��A��߀��<�֬%S�!�>���	\	��
����,���-����v<���=��'؀�"6�HR�y�F`d�!�
n+�X�`��;�?��I[I)����C}�,ܳ���:=X
�lrDX�^��-��E�1	��O_�G�����
]v�
��ˀ_OA��m��E���	��A��"�qħ�y��Nv���E����yN��E
+�&
C��������I����H�I>�#l7�>���dŀX�?�=����|?tU��3����>@Z�A�\�y|��~�3�<�B��/}$W�.|�D{ ��>�;�H�Fn�U�>]V��7F��\x#v�ȋ����7�� ��
J�z���\���G����p�:�4 n�
1��H
�Hbt�B;�F{B=B#���tN���t}��'���}ʐ+9Z�'Q��?��hW��xn]cB;˟�yX�X���/t~�Ξ�E�܋=*O�o�$[�Qh�I[������
����-�l�$425������+���?��
㗁�C�a?n���$b� �3`_F�
+�E��0F�-��V
I��c�zc�8���w{wk��c
��5ls�q
�q���&��F6�]�1�3��Ԣ�4)�$��Q>4mSU*�X�J\UU�iPU#U�TK��HAUU���7�k	Qi��
7��{���y��̛�Ø�l�W7��8[d}?HS���������/)�(��jo�z{ZBQyn���[{w_`L�"
Sk$kQ��Q��w|!u��rokM�;���;�P�C-�K9S�/
���U�P�
y���Q�Qꓩ31��H�I_a궊s
�!C������T�u|Gʱ�5Z�@�g"
��A�*@Q�Z���e�<Y��}Ӕ���ԧZ(�S�Lo?mCN�χ}1��
�a����w����>
�a���_�/���׹�#���0��[^}�^�1��î
�VU{���h�Ae�𮿊r�X�<y�i��I�
�W���u�;Ͻ\����:�Y��Ӑ�����.t����~*}�RM�EЧi��GK>��-�)W�忋�JG�� R�6 ��s�pc�����;�})��>q7�z�
�A�^��ֈ�:�#��i ]�&�Y�u�sCލ���{5�F�A�-��W���=}����
�縶gu;-�wG�/����
ڥ�-��%�
`�]��
9��h�D0�1r�.m�������o3h�<�����G�N�=���7�P� �B&�/�&��1u������履�wu�Jܯ�_�_|
w-MA��I�-�7�N�5�Q�Sz��1`��a��D��2��c ��P
���ۦ��{��^�
��(�>1k�kk{�f?��9h���Ë��O���W�ڟ�,�6h�OCK�������=n��F_��蟴�����2h9��_�\_%�����E�py�@��5�Q�����A��
r-
����
Z@)�g�)�{���B���G<> ~��i@
>o���U���,sS�/��u����@g�'�WjFz{�-=����k�x��*�԰��nSh���ν�/�O�g��4��]��΁f��%n���c}f���e5�z�z���ͦxW)�'�ʩ
�\+�#
tŨ���+�:���g'�=ʢ����X�
���qT=
Ԃ��xv�r����Au�B��b�N�
{i�M�1J'���h��M�P��8�����z �=�g
tޑ�能���V��;�rQo1�0^f>HŐ6�=���u��!���s~�^f���ש|"��etK�r�	ڗ
���e$���;�T�h�w<�=b���$�����.��7�����
�k�2RfT]l]i��#�s�-
^i\�s|�����#Y�'�F�m�@�m��
ے��G�"�9��/�
��4>���r�,�����y�$0h�$R��>�M
�
��=�͎�������û쑅�@�(B�|���i�=�� [...]
&vۃ��`bk�y%��ർJRQ��v�q��}�+�}�Q��+A���L�K��-�f$���%
��U�
o��e��c`t�^���|�2�9�3�X�I��
�7�(˝�e
�U�w�\џr	�m?e/4�Ff{��\��ip
�(��˔���ü��R�=�zy-Q�j��G~�+��Ξ�rp4��(��Wr�h���Yc\�
+�k�F��L�05!m���u7���׀7��?��� 3�Rޖs��5WzGs�M��\¥�Yk�b�L3
�	|h����f ���A ��,��Έ,����������T���� �~h�Wصi����%��7"3T�m<?R�^K��2;���׸�� ���
����b[7���E�a�}
{��F��c��Y7
+��뮁��c�t; �ƈ�
�3��\��!Z�A6�V�[z�(���c	�)��1�&0	h"ӶtXFmk�[�򔈌�u�:��]8�
<��0
��5�H��I��|��B��I^&��2L�
+�/�B�!)�A-�<e���e�7
+�
$+K�����)�����xi8�O�tS_���
�
=[��3�
}�>]O�u=�k:�pd������M3�I�bG�c[ҿ8*������I��5rcK4�*���%YjL�5oo�$�; M��
A�페/E�s���گ�O
?��ю�P~����=����d�d�
�
��/G�($�"����{�r㡐A&�w
���T�T��d���r��<K����~�_�����Xų8�
Qq%hL���T5�@�P���$&�	W�#�{Z�x���Nюu;\:��ґ�=�
���5*I59Gs�4oдPGr��hr U%���TῬT̈́x���9ZS�;&��T�Ƃ�T��g�8���}�=��;��
��Y	��f*$ 
�|e��X�j�41l`v���4�š;a����v��4����
@� �bc�
endstream
endobj
132 0 obj
<</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>>
endobj
131 0 obj
[/ICCBased 142 0 R]
endobj
142 0 obj
<</Filter/FlateDecode/Length 2574/N 3>>stream
+H���yTSw�oɞ����c
[���5la�
QIBH�ADED���2�mtFOE�.�c��}���0��8�׎�8G�Ng�����9�w���߽��� �'����0
 �֠�J��b�	 
+  2y�.-;!��K�Z�	���^�i�"L��0���-��
 @8(��r�;q��7�L��y��&�Q��q�4�j���|�9��
+�V��)g�B�0�i�W��8#�8wթ��8_�٥ʨQ����Q�j@�&�A)/��g�>'K�� �t�;\��
ӥ$պF�ZUn���
�(4T�%)뫔�0C&�����Z��i���8��bx��E���B�;�����P���ӓ̹�A�
om?�W=
+�x������- �����[��� 0�
���}��y)7ta�����>j���T�7���@���tܛ�`q�2��ʀ��&���6�Z�L�Ą?
�_
��yxg)˔z���çL�U���*�u�Sk�Se�O4?׸�c����.� �
 �� R�
߁��-��2�5������	��S�>ӣV����d�`r��n~��Y�&�+`��;�A4�� 
���A9� =�-�
t�
�
l�`;��~p����	�Gp
|	��[`L��`<� "A
�
YA�+��Cb(��R�,� *�T�2B-�
+�ꇆ�
�n���Q�t�}MA�0�a
l������S�
x	��k�&�^���>�0|>_�'��,�G
!"F$H:R��!z��F�Qd?r
9�\A&�G�
��rQ
��h������E��]�a�4z�Bg�����E#H	�*B=��0H�I��p�p�0MxJ$�D1��D, V���ĭ����KĻ�Y�dE�"E��I2���E�B�G��t�4MzN��
���r!YK� ���?%_&�#���(��0J:EAi��Q�(�()ӔWT6U@���P+���!�~��m���D
�e�Դ�!��h�Ӧh/�
�']B/����ҏӿ�?a0n�hF!��X���8����܌k�c&5S�����
6�l��Ia�2c�K�M�A�!�E�#��ƒ�d�V��(�k��e���l
����}�}�C�q�9
+N'��)�].�u�J�r�
+��
w�G�	xR^���[�oƜc
h�g�`>b���$���*~� �:����E���b��~���,m,�-��ݖ,�Y��¬�*�6X�[ݱF�=�3�뭷Y��~dó	���t�
��i
�z�f�6�~`{�v���.�Ng����#{�}�}������
��j���
���c1X6���f
m
�
��;
'
_9	�r�:�8�q�:��˜�O:ϸ8������u��Jq���nv=���M���m���R 4	�
+n�3ܣ�k�Gݯz=�
�
[=��=�<�=G</z�^�^j��^��	ޡ�Z�Q�B�0FX'�+������t���<�u�-���{���_�_�ߘ�-G�,�
}���/���Hh
8�m�W�2p[���AiA��N�#8$X�?�A�KHI�{!7�<q��W�y(!46�-���a�a���a�W��	��@�@�`l���YĎ��H,�$����(�(Y�h�7��ъ���b<b*b��<�����~�L&Y&9
��%�u�M�s�s��NpJP%�M�I
JlN<�DHJIڐtCj'�KwKg�C��%�N��d�
�|�ꙪO=��%�mL���u�v�x:H��oL��!Ȩ��C&13#s$�/Y����������=�Osbs�rn��sO�1��v�=ˏ��ϟ\�h٢���#��¼����oZ<]T�Ut}�`IÒsK��V-���Y,+>TB(�/�S�,]6*�-���W:#��7�*���e��^YDY�}U�j��AyT�`�#�D=���"�b{ų���+�ʯ [...]
چ
���k�5%4��m�7�lqlio�Z�lG+�Z�z�͹��mzy��]�����?u�u�w|�"űN���wW&���e֥ﺱ*|����j��5k��yݭ���ǯg��^y�kEk�����l�D_p߶������7Dm����o꿻1m��l�{��Mś�
n�L�l�<9��O �[����$�����h�՛B���
�����d�Ҟ@���
�����i�ءG���&����v��V�ǥ8��������n��R�ĩ7���
����u��\�ЭD���-������ �u��`�ֲK�³8���%�������y��h��Y�ѹJ�º;���.���!������
+�����z���p���g���_���X���Q���K���F���Aǿ�=ȼ�:ɹ�8ʷ�6˶�5̵�5͵�6ζ�7ϸ�9к�<Ѿ�?���D���I���N���U���\���d���l���v��ۀ�܊�ݖ�
ޢ�)߯�6��D���S���c���s����
����2��F���[���p������(��@���X���r������4���P���m��������8���W���w����)���K���m��
 ����
endstream
endobj
130 0 obj
<</LastModified(D:20120301145415-07'00')/Private 143 0 R>>
endobj
143 0 obj
<</AIMetaData 144 0 R/AIPrivateData1 145 0 R/AIPrivateData2 146 0 R/AIPrivateData3 147 0 R/ContainerVersion 11/CreatorVersion 15/NumBlock 3/RoundtripStreamType 1/RoundtripVersion 15>>
endobj
144 0 obj
<</Length 946>>stream
+%!PS-Adobe-3.0 
%%Creator: Adobe Illustrator(R) 15.0
%%AI8_CreatorVersion: 15.0.0
%%For: (meg pirrung) ()
%%Title: (biom-logos.ai)
%%CreationDate: 3/1/12 2:54 PM
%%Canvassize: 16383
%%BoundingBox: 112 -575 760 -31
%%HiResBoundingBox: 112.5 -574.4824 759.0479 -31.5947
%%DocumentProcessColors: Cyan Magenta Yellow Black
%AI5_FileFormat 11.0
%AI12_BuildNumber: 399
%AI3_ColorUsage: Color
%AI7_ImageSettings: 0
%%RGBProcessColor: 0 0 0 ([Registration])
%AI3_Cropmarks: 82 -588 904 0
%AI3_TemplateBox: 400.5 -300.5 400.5 -300.5
%AI3_TileBox: 115 -582 849 -6
%AI3_DocumentPreview: None
%AI5_ArtSize: 14400 14400
%AI5_RulerUnits: 6
%AI9_ColorModel: 1
%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0
%AI5_TargetResolution: 800
%AI5_NumLayers: 1
%AI9_OpenToView: -112 7 1 1298 756 18 1 0 44 134 0 0 0 1 1 0 1 1 0 1
%AI5_OpenViewLayers: 7
%%PageOrigin:0 -600
%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9
%AI9_Flatten: 1
%AI12_CMSettings: 00.MS
%%EndComments

endstream
endobj
145 0 obj
<</Length 17647>>stream
+%%BoundingBox: 112 -575 760 -31
%%HiResBoundingBox: 112.5 -574.4824 759.0479 -31.5947
%AI7_Thumbnail: 128 108 8
%%BeginData: 17496 Hex Bytes
%0000330000660000990000CC0033000033330033660033990033CC0033FF
%0066000066330066660066990066CC0066FF009900009933009966009999
%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66
%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333
%3333663333993333CC3333FF3366003366333366663366993366CC3366FF
%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99
%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033
%6600666600996600CC6600FF6633006633336633666633996633CC6633FF
%6666006666336666666666996666CC6666FF669900669933669966669999
%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33
%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF
%9933009933339933669933999933CC9933FF996600996633996666996699
%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33
%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF
%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399
%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933
%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF
%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC
%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699
%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33
%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100
%000011111111220000002200000022222222440000004400000044444444
%550000005500000055555555770000007700000077777777880000008800
%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB
%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF
%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF
%524C45FD4FFF3085FD06FF8437A9FD75FF0E073684FFFFA9300E0DAFFD75
%FFFD040E365AFD040EA9FD74FFA80E0D0E0D0E070E0D0E07A9FD75FF5A0E
%0E300E300E0E0E5BAFFD76FFA95AFD040E36AFFD3FFFAFFD39FF8536070E
%3085A9FD2EFFA87E5A855A845A855A8584FD06FF365AFFFFFFA8850EA9FD
%04FFA885300E0D30305AA8FD04FFAF5A845A855A845AA9FFFFA8855A845A
%855A5A84FD0BFF5A5B5A85300E5A85A8FD05FF527DFD09FF7D27A8FD08FF
%7D52A8FD0FFFA908FD090E30A9FD04FF300E0E857E360E0E85FFFFFF8436
%0E0E0E300E0E0E3685FFFFFF85FD070E5AFFFF8508FD050E0785FD0AFF5A
%36FD04FF36858436FFFFA8FFFFF8F8FD09FF7D52A8FD08FF52F8A8FD0FFF
%840E0D0E0E0E0D0E0E0E0D0E0EA9FFFFFF30070E0E0E0D0E07A9FFFFA80E
%070E0E0E0D0E0E0E070E84FFFFA90E0E0D0E0E0E075AFFFF5A0E0E0E0D0E
%0E0E5AFD0AFF360EFF8485FF5A84AF0E8427F827A8F8277D27F852A82727
%27F852F8A827F827A852F8F87D27F87DFD0FFFA90E0E0E300E0E08FD050E
%30FFFFFF84360E300E0E0E85FFFFFF360E0E0E300E300E300E0E0E36FFFF
%84FD040E300E0E30FFFF5A0E300E0E0E300E85FD0AFF3636FFFFAFAF0EFF
%FF3728F852F8FD0427F87DF827F852272727F827F852F827F82752F827F8
%A8FD0FFF840E0D0E0D0E3085FD040E0D0EA8FD04FF5A070E0EA9FFFFFFA9
%070E0E0E0736FF5A070E0E0E07A9FF85070E0E0E0D0E0D0EA8FF300E0D0E
%0E0E0D0E5AFD0AFF360EFFA8AFFF5AA8FF0E28F87DF827F827F82752F8F8
%F85227F827F827F87D7DA85252F8F827F87DFD0FFFAF0E0E0E360E5BFFA9
%0E0E0E300EA9FFFFFF5B0E360E300EA9FFFF840E0E300E0E5AFF5A0E0E30
%0E0E84FF840E0E300E360E0E0EFFFF360E360E300E360E85FD0AFF3036FF
%AF84FF5AFFFF3705207DF8FD0427F87DF827F852FD0527F87DA87D522727
%F852F8A8FD0FFF840E0E0E0D0E36FF840E0E0E0D0E84FFFF5B070E0D0E0E
%0E0DAFFF85070E0E0E0785FF85070E0E0E0785FFA90D0E0E0E0D0E0E0E84
%FF0E0E0D0E0E0E0D0E5AFD0AFF8536FFA885FF84A8FF3028F852F827F827
%27F852F852522727F827F852F852F827F85227F827F87DFD0FFFA9FD050E
%5BFFAFFD050E85FFFF36FD040E300E0E84FF840E0E300E0E5AFF7E0E0E30
%0E0E5AFF850E0E300E0E0E300E85A9FD040E300E0E0885FD0BFF85AFFFFF
%FF30AFAF377E4BF827A82727A8F8F827A8527DF82727F87D52F827A852F8
%27F852F8A8FD0FFF840E0D0E0E0E30FF840E0D0E0D0E84FFFF5A070E0E0E
%0D0E0DA9FF85070E0D0E075AFF85070E0D0E075AFFA90D0E0D0E0E0E0D0E
%5A85070E0E0E0D0E0E0E5AFD0AFF5A07300E0E07300E0E07A9CFFFFFFFA8
%FFFFFFA8FFA827F8F852FFA8FD05FFA8FFFFFFA8A8A8FD0FFFA90E300E30
%0E5BFF850E360E0E0EFFFFFF360E0E300E360E0E85FF840E0E360E0E5AFF
%7E0E0E360E0E5AFF850E0E360E36300E0E5B5A0E0E360E300E300E85FD0A
%FF36FD040EA9FFFF5A3728F8A8FD16FFA87DA8277DFD0FFF840E0D0E0E0E
%0D300E0E0D3030A9FFFFFF5A070E0E0E0D0E0EA9FF85070E0D0E075AFF85
%070E0D0E075AFFA90E0E0D0E0E5A0D0E0E360D0E36300D0E0E0E5AFD0AFF
%5A070E0E5AFF85A9FF0E28F85252A8A85252FFFF7D52A8A8527D7D52FF7D
%7DA85252A8F8F827527DFF527DA8A8527D52A8FD06FFA90E0E0E300E0E0E
%300E0E0EA9FD04FF360E0E30FD040EA9FF5AFD050E5AFF5AFD050E5AFF84
%FD040E365A300E300E0E0E85300E0E300E85FD0AFF360E0E0E5AFF7EAFFF
%3728F827F82727F8F82752F827F852FD04F8A827F8F827F82727F827F852
%27F8F82752F827F827FD06FF840E0D0E0D0E0D0E070E0E0E075AFFFFFF5A
%070E0D0E0E0E07A9FF84070E0E0E075BFF84070E0E0E075BFF85070E0E0E
%0D850E0E0D0E0E0E5A360D0E0D0E5AFD0AFF5A070E075BFF8584FF3628F8
%7DF827F827527DF8F827F8F8F827A8F87DF827F87DF82727F852F827F827
%52F827F87DF827FD06FFAF0E0E0E360E367E370E300E300E85FFFF360E0E
%360E300E30A9FF5A0E0E300E0E5AFF5A0E0E300E0E5AFF840E0E300E3685
%360E360E0E0EA9300E0E360E85FD0AFF360E0E0E5AFF84AFFF5B28F87DF8
%27A8F8F87D27F852527DF87DFF2752277D7D27F82752F87DF852F8525227
%27F87D2727FD06FF840E0E0E0D0E36FF840E0E0E0D0E36FFFF5A0E0E0D0E
%0E0E0DA9FF85070E0E0E0785FF85070E0E0E0785FFA90D0E0E0E0DA9300E
%0D0E0E0EA8360E0E0D0E5AFD0AFF5A0E0E075BFF8584FF3028F87DF82752
%7D27F8F827A82727F852FF2727F852F87DF82727F852F827F82752F827F8
%7DF827FD06FFA9FD050E5BFFAFFD050E5BFFFF36FD040E300E0E84FF840E
%0E300E0E5AFF7E0E0E300E0E5AFF850E0E300E30A95BFD050EFFFD040E08
%85FD0AFF360E0E0E30FFFFFFA93727F827F82727F8272752F827F852F852
%FF52F8277DF827F82752F827F85227F8F82727F87DF8F8FD06FF840E0D0E
%0E0E30FF840E0D0E0E0E30FFFF5A070E0E0E0D0E0DA9FF85070E0D0E075A
%FF85070E0D0E075AFFA90D0E0D0E0EAF5A0E0E0E0736A930070E0E0E5AFD
%0AFF5A070E0E0E30855A300E59527D52FFFF7D52FFFF7D27A8A8527DFF7D
%5252FF527D527DA85252527DFF5252A8A852A8527DFD06FFA90E300E300E
%5BFFAF0E300E300E5BFFFF360E0E300E360E0E85FF840E0E360E0E5AFF7E
%0E0E360E0E5AFF850E0E360E30AF850E300E0E5AFF0E0E0E300E85FD0AFF
%360E0EFFFF5B36FFAF36A9FD04FF7D7DFFFFFF7D27A8FD20FF840E0D0E0E
%0E36FFA80E0D0E0E0E30FFFF5A070E0E0E0D0E0EA9FF850E0E0D0E075AFF
%85070E0D0E0785FFA90E0E0D0E0EFF840E0E0E075BFF300D0E0E0E5AFD0A
%FF5A0730FFFF7E85FFFF0EA97D527DA8F8F8527D7D52527D7DFF52A8FD16
%FF5A365B3685FFA90E0E0E300E5AFF610E0E0E300E5AFFFF360E0E30FD04
%0EA9FF84FD050E5AFF5AFD050E84FF84FD040E36FFAFFD040E5AFF300E0E
%300E85FD0AFF360E0EFFFFAFA8FFFF372EF827F82727F827FD05F8277DF8
%7DFD16FF070E070E36FF840E0D0E0D0E0E0E070E0E0E0D0E36FFFF5A070E
%0D0E0E0E07A9FFFF0D0E0E0E07305A30070E0E0E0DAFFF85070E0E0E0DFF
%A80E070E0785FF360D0E0D0E5AFD0AFF5A070EA8FFA9FFA8FF3028F87DF8
%52F82752F8527DF87D2727F8FD17FF300E360E61FFAF0E0E0E360E0E0E30
%0E300E360E85FFFF360E0E360E300E0E85FFFF850E0E0E360E0E0E360E30
%0E61FFFF840E0E300E36FFFF0E300E0EA9FF300E0E360E85FD0AFF360E0E
%FFFD04AFFF377E52F8F852272752F8A87DF87D52F852FD17FF0E0E070E5A
%FF840E0E0E0D0E0E0E0D0E0E0E0736AFFFFF5A070E0D0E0E0E0DAFFFFFFF
%5A070E0D0E0E0E0D0E0736A9FFFF85070E0E0E0DFFFF30070E0EAFFF360E
%0E0D0E5AFD0AFF5A070EFFAF84A984FF3628F87DF852F82752F87D7DF852
%F827F8FD17FF3630360E85FFA90E360E300E360E300E36365BA9FFFFFFA9
%36FD050E85FD05FF850E0E08FD040E85FD04FF850E0E360E36FFFF5A0E0E
%36FFFF30300E300E85FD0AFF5A0E0EFFA9AFA9A9FF5B28F827F82727F827
%F8A852F827277DF87DFD16FFA9FFFFFFAFFFFFFFA8FFA9FFA8FFA9FFA8FD
%07FFA8855A5A5AAFFD08FF84845A8584FD07FFA9FFA8FFAFFFFFFFA9FFA8
%FFFFFFA8FFA9FFA9FD0BFF300E5A5A305A307E84FF527D52A87D52527DA8
%A8527D7DFF52A8FD67FF84360E300E5B84FD7CFFA9FDFCFFFDFCFFFDFCFF
%FD87FF6185FD07FF5AAFFD75FF0E0E30A9FFFFA95A0D0E84FD75FF360E0E
%0E5A5A360E0E0E85FD75FF0E0E0D0E070E070E0E0E7EFD75FF5B0E0E0E30
%0E360E0E0EAFFD2DFFAFFFA9FFAFFFA9FD0BFFA9FFAFFD07FFA9855A857E
%A9FD08FFA9FFAFFFA9FD05FFAFFFA9FFAFFFA9FD0EFFA9300E0E0E0D365A
%FD2EFF84300E300E360E300E365A85FD05FF360E300E3630FD04FFAF3030
%0E0E080E0E3684FD04FFA90E300E360E300E85FFFF840E0E300E360E0E5A
%FD0FFF360E0E0E5AFD2FFF85070E0D0E070E0D0E070E0736A8FFFFFF0D0E
%0D0E070EA9FFFFA90D0E070E0E0E070E070E5AFFFFFF840E0D0E070E0D0E
%36FFFF5A070E0D0E070E0784FD0DFFA90E0E070E070E0EA9FD2DFF840E0E
%300E360E0E0E360E0E0E85FFFFFF370E360E3630FFFFFF0E0E0E36FD080E
%A9FFFFAF0E0E0E360E300E5BFFFF5A0E0E300E360E0E5AFD0CFFAF0E0E5A
%855A85360E5AFD05FF7DFD09FFA8A8FD08FFA8A8FD12FFA90D0E0E0E0D0E
%0E0E0DFD040EFD0BFF5AFD040EAF5A5A8485070E075BFFFF840E0E0E0DFD
%040EFFFF36070E0E0E0D0E0785FD0CFF5A0E0EA95A3630A90E0E7EFD04FF
%27A8FD12FFA827FD12FF850E0E300E0E36FF5A0E0E300E0E84FFFF855A85
%7E857EFFFF5A0E300E36FD04FF7E0E0E0E30FFFFA9FD050E300E0EA9FF30
%0E0E30FD040E7EFD0CFF5B0E0E8536070E85363085A17D52FF52FF7D7D7D
%FFA8FD047DA8A87D52A8A87D52A8A852FD12FFA90D0E0D0E075AFFA90D0E
%0D0E0D85FFFF0E0E070E070EA8FF300E0D0E0E85FFFFA836070E0D30A8FF
%840E0D0E0E0E0D0E0DA9A80E0D0E0D0E0E0E0785FD0CFF5A0E07A97E5A5A
%850E852F51A87D27525252A87D52527DA8F85252527DA8527D52FF277D52
%FD12FF850E0E360E0E36FFA90E0E360E0E84FFFF360E360E0E0EFFFF360E
%360E0E30FFFFAFFD050EFFFFA90E300E300E300E0E84FF0E0E0E360E300E
%0E7EFD0CFF610E30855B3036855B852F76FFFF5252527DFFA85227FFFFFD
%0452FFFFFFA87D7D52527DFD12FFA90E0E0D0E0E5AFFAF0E0E0D0E0E85FF
%FF0E0E0D0E0E0EAFFF0E0E0D0E0EAFFFFFFF85070E0E0EA8FF840E0D0E0E
%0E0D0E0784840E0E0E0D0E0E0E0785FD0CFF5A0E0DA9300E07855A852E52
%FFFF27525252FFA82752A8FF27525252FFFF7D277DFF277D52FD12FF84FD
%050E5AFF84FD050EA9FFFF36FD050EFFFF360E0E0E36FD04FFA9FD040EFF
%FFA90E0E0E300E360E0E5A850E0E0E300E300E0E5AFD0CFF5B5A5A84855A
%8584368484517D527D52A8527D27A87D525227527D7D52527D527D7D527D
%7DFD12FF85070E0E0E07365A36070E0D0E36FFFFFFFD040E0730FFFFFD04
%0E0DFD04FFA90D0E070EA9FF840E0D0E0D30300E0736360E07360E0E0D0E
%0784FD0CFF5AFD040E360E0E070E5AFFA8FD05FFA8FFFF7DA8FF27A8FFFF
%A8A8FFFFA8A8A8FFA8FD12FF840E0E300E360E0E0E360E3684FD04FF360E
%300E300EFFFF360E300E36FD04FFA90E0E300EFFFFAF0E0E0E300E5B0E30
%0E360E0E5A360E360E0E5AFD0CFF850E0E0E3630360E0E0E85FD0AFF7D52
%527DFD1EFFA90D0E0E0E0D0E0E0E0D0E0E3684FFFFFFFD040E0D30FFFFFD
%050EFD04FFA90E0E0D30A9FF840E0E0E0D305A0E0D0E0E0E0D850E0E0D0E
%0785FD0CFF5A0E0E5A5A615A850E0E2F7CFD0AFFA8A8FD0EFF7DFD10FF85
%0E0E300E0E0E360E0E0E300E0EA9FFFF360E300E0E0EFFFF300E300E30FD
%04FF84FD040EFFFFA9FD050E850E0E0E300E0E8436FD040E7EFD0CFF5B07
%36A90E080E84610E5A52FFA8FFFFFFA8FFFFFFA8FFFFFFA8FD06FFA8A8FF
%527DA8FFFFFFA8FFFFFFA8FD09FFA90D0E0D0E075AFF5B0D0E0D0E075AFF
%FF0E0E0D0E0D0EA8FF0E0E0D0E0EFD04FFA9070E0D0EA8FF840E0D0E0D0E
%84360D0E0D0E0EA90D0E0E0E0785FD0CFF5A0E30850D0E075B5A0E2F2752
%52527D527D52A8277D27A8277DF827FFA827FD045227527D52A8277D27A8
%27525252FD07FF850E0E360E0E36FFA90E0E360E0E36FFFF360E360E0E0E
%FFFF360E360E36FD04FF85FD040EFFFFA90E300E0E0EAF360E0E360E36A9
%360E300E0E7EFD0CFF61085B850E0E0E5A850E5A51FFA85227A8FFFF527D
%FF525252FFA827FF527D7DFF7D7D52FFFF5252A8FF7D5252FFFF27FD07FF
%A90E0E0D0E0E5AFFAF0E0E0D0E0E36FFFF0E0E0D0E0E0EAFFF0E0E0D0E0E
%FD04FFA90D0E0E0EA8FF840E0D0E0E0EA85A0E0E0D0E30FFFD040E0785FD
%0CFF5A0E30A90E0E07855A0E2F76FFFF27A8527D2752527D527D52FFFF7D
%52527D527D525252A8FF27527DFF7D5252FFA827FD07FF84FD050E36FFA8
%FD050E36FFFF36FD050EFFFF360E0E0E36FD04FFA9FD040EFFFFA9FD050E
%FF5AFD040E5BFF300E300E0E5AFD0CFF610E30845B3036845B0E5926FF7D
%5252A8A852277DFF7D5252FFFFA82752A827FF7D52527D2752527DFF5252
%52FFFF27FD07FF85070E0E0E075AFFA9070E0E0E0736FFFFFD040E0730AF
%FFFD040E0DFD04FFA90D0E0730AFFF840E0D0E070EA985070E0E0E36FF0E
%0E0D0E0784FD0CFF5A0E0D365A615A5A0D0E5A7D527DA8A8527D7DFF527D
%7DA87DFFFFFF52A8FF7D527D7DA8527D7DFF527D7DFF7DFFFF7DFD07FF84
%0E0E300E0E5AFF840E0E300E0E36FFFF360E300E300EFFFF5B0E300E36FD
%04FFA90E0E0E30FFFFAF0E0E0E300EFF850E0E300E85FF360E360E0E5AFD
%0CFF85FD090E85FD26FF850E0E0D36FFA90D0E0E0E0D365A300D0E0E0E07
%5AFFFFFD040E0D30FFFF360E0E0E0785FFFFFF5A0E0E0736FFFF840E0E0E
%0D30AFA90D0E0E0E7EFF0E0E0D0E0785FD0CFF5A0E5A36070E0E365A0E5A
%FD0AFFA8A8FD1AFF5AFD040EFF850E0E30FD070E300E0E5AFFFF360E300E
%0E0EFFFFA90E300E0E0E3636360E300E0E7EFFFFA9FD050EFFAF300E0E0E
%A9FF36FD040E7EFD0CFF5B0EFFA90E0E0E85FF0E85FFA8A8FF527DA8FFA8
%FD1DFF84070E0D30FFA90D0E0D0E0E0E0D0E0E0E0D0E07A9FFFF0E0E0D0E
%0D0EA8FFFF5A070E0E0E070E0D0E0D0E30FFFFFF840E0D0E0D0EA8FF0E0E
%0D0EA8FFFD040E0785FD0CFF5A0E84A9360E0EA984365AFD045227527D27
%5252275252A852A8FD16FF5AFD040EFF85FD0C0E85FFFFFF3008FD040EFD
%04FF5B0E0E0E30FD040E36FD04FFA908FD040EFFFF36080E0EFFFF36FD04
%0E5AFD0CFF5B0EA95AA908855A8530617DFF7D7D52FFFF52FFFF27A87D27
%A8FD17FFA95A855A85FFFF5A855A855A855A855A8584FD05FF7E845A855A
%85AFFD04FFA95A360E300E5A84FD05FFA9845A855A85FFFF845A5A85FFFF
%7E855A855AA9FD0CFF5A0E84308436843684362F7C7D525252A8FF27FFFF
%7D7DA8F8A8FD3DFFAFFD28FF850EA90E85AF850EA9365327FF7D52527D52
%27A8FF525227A827FD66FFA85A5A0E0DFF300E5A85FF7D527D7DA8527D7D
%FFFFA852A8FF7DA8FD67FF850E300E0E3085FD7BFFA8A9A9FDFAFFA95A85
%5A845A855A845A855A845A855A845A855A845A855A845A855A845A855A84
%5A855A845A855A845A855A845AA9FD51FF840E080E070E0E0E07FD100E0F
%FD0B0E0FFD080E5AFD51FF85075B5A8536307E850D0E0E0E070606FD090E
%05060DFD080E06060E0E0E0D0E0E0E075BFD51FF840EAFFFAFFF5A85840E
%0E300E0DF8060E0E0D360E0E0E300E0600300E0E0E360E0E0E30F8F80D30
%0E0E0E300E0E5AFD51FF850DAFA85AFF8584A906F8F80606F8000DF8F800
%0DF805F80500050600F8050705F8F80600F80E0D0E0E0E0D0E075AFD51FF
%850EA9FFA9FF5AFFAF05F828F805F806F80505F800F805050005F805F806
%F805F806F805F8F80E360E300E360E0E5AFD51FF850EAFFFAFFF85A9AFF8
%F806F800F800000006F805F806F805FD04F80607060600F8F800F8FD050E
%0D0E0E5AFD51FF840EA9FF5AFFA9FFA905F806F805F806F80506F8F8F805
%00F805F805F80D060DF805F805F8000E0E0E30FD040E5AFD51FF8507AFFF
%85FFAFFFAFF8F805F800F800F8F806F806F805F800F8F800F800F8F8F805
%FD04F80E0E0E0D0E0E0E075AFD07FFA9FFA9FD47FF840EA9FFA9FF5AFFAF
%2FF8F8052FF8060605F806072806F8F805F80DF8F8050DF8050005F8050E
%300E360E300E0E5AFFFF360E0E0E0DFD040EFD07FFA8855A5A5A5B5A5A5A
%5B5A5A5A5B5A5A5A5B5A5A5A5B5A5A5A5B5A5A5A5B5A5A5A5B5A5A5A5B5A
%5A5A5B7EFD14FF8507305A85360E06060E0E0D0E0E0E0D0E0D0E0E0DF8F8
%F807FD040E0D0E0E0E0D06000D0DFD070E075BFFFFA9FD080E84FD05FF5A
%0E070E0E0E080E0E0E08FD0B0E08FD070E08FD0B0E080E30AFFD12FF840E
%84FFAFFF36F8F80E0E370E0E0E370E0E0E360E0E0D300E0E0D300E0E0E0D
%F80606060E0E0D300E0E0E300E0E5AFFFFFF36070E0E0E0D0E0D36FD04FF
%5A0E0D0E0D300E0E0D300E0E070E0E0E0D0E0E0E070E0E0E0D300E0E070E
%0E0E0D300D0E0D0E0E0E0D0E0E0E0D0E0EA9FD11FF850DFFA85BFF84F800
%F8000605F8000706F8F80605F805F80606F80600F80500F8F805F80D00F8
%F80DF800F800075AFFFFFF840E0E300E360E0E0EA9FFFFA90E0E0E84FD07
%FFAF850E0E36FF5A0E0E85A9FD05FFA9850E0E84FFFF5B0E360E300E360E
%0E36FFFF8530FD11FF840EAFFF5AFF7EF80005F805F806F806F806F80500
%F800050606F805F806F806F806000500F806F805000028F80D5AFD04FF30
%0E0E0E0D0E0E0E30FFFF36070E0EA9FF855A855A855AAFFF5B0736FF8507
%A9FFAF7E855A8584FFFF8507A9FFFF840E0D0E0E0E0D0E0EA9FFFF840E7E
%FD10FF850EFFA985FF84F80505F800F8F80706F8F8000005F80E00050000
%0606F8F800F80505F805F806F805F80505F8065BFD04FF850E300E0E0E30
%0E0EA9AFFD040E85FFFD040E080E0EFF840E36FF5A36FF85FD040E080E0E
%85FF3685FF84FF300E0E300E0E0E36FF85A9AF0E36FD10FF840EAFFF5AFF
%7EF80006F80D0705F805F8060706F8F80E06F8050506F805F805F80605F8
%00F806F800000506F80D5BFD05FF30070E0E0E0D0E075A5A0E0E0E07A9AF
%0E070E0E0E0D0EA8A90736FF5A5AFF300E0D0E0E0E0D0E30FF3085A936FF
%85070E0D0E0E0E5AFF0EAF840E0DA9FD0FFF8507AFFF85FF7EF80000F8F8
%F806F8F8F80000F800F80E06F8F806F80000F800F80005F805F806F805F8
%0505F8065BFD05FF840E0E300E360E0E0E360E300E0EA9FFFD070EFF840E
%36FF5A85FF360E360E300E360E36FF5B85FF0EAFFF300E360E0E0EFF850E
%AFAF0E0E84FD0FFF840E36FFFFAF0D00F805000D0005000D0505F80D0005
%0E0DF8F80706F805F8060005F8050605F80507050506F80D5BFD06FFFD04
%0E0D0E0E0E0D0E0E0E0DA9FF300E300E0E0E85FF360736FF5A5AFF0E0E0D
%0E0E0E0D0E30FF3685FF0E30FF5A0E0D0E075AFF5A0EFF840E075AFD0FFF
%85070E0E300D0E0D0E0DFD070E0D0E0D0E0D0E0E0E070E0E0E0D0E0E0E07
%0E0D0E0D0E0E0E070E0D0E075BFD06FF850E300E0E0E300E0E0E300E0E84
%FD08FF850E0E30FF5A85FF360E0E0E300E0E0E36FF5B84FF0E0EA9FFFD04
%0EA9FF0E30AFA90E0E5AFD0FFF840EA9FF5A36FFFF360E0E370E0706370E
%15070006150E370E0E0E300E0E0E360E360E360E360E360E36FD040E5AFD
%06FFA80E0D0E0E0E0D0E0E0E0D0E0D85FF855A855A855AA9A95A0736FF5A
%5AFF0D0E0E0E0DFD040EFF3685A80E075AFF36070E30FF5A0E0DFF840E07
%5AFD0FFF850DAFFFA95AFFFF5A0606060DF8F8050606060006060E000D5A
%AFA8300D85A8FFA9FFA8FFA9FFA8FFAFFF8436075AFD06FF610E360E300E
%360E300E360E0E85FFFD070EAFFF0E36FF5A85FF360E300E360E300E37FF
%5B84FF0E0E0EFF850E0EA9FF360E36AFAF0E0E5AFD0FFF850EA9FFAFA9FF
%FF2FF8F8F80000F805FD04F8000006F80685FFFF5A85FD0EFFAF0E5AFD05
%FFAF0E0E0D0E0E0E0D0E0E0E0D0E0EA9A9300E0E0D0E0E0E5AFF0E36FF5B
%5AFFFD040E0D0E0E0E30FF3685A9300E0E84FF0E0EFFA9070E0DFF840E07
%5BFD0FFF850EAFFFFFFFAFFF53F806F805F80006F80606F8060000F80E0E
%AFFD12FF5A5AFD05FF5AFD040E300E0E0E36FD040E85FFFD050E300E5BFF
%3636FF5A5BFF360E300E0E0E300E5AFF3685FF0E0E0E5AFF5B5AFF360E0E
%0EA9AF0E0E7EFD0FFF840EA9FFA8FFA9FF2F06F8F800050006F80D07F806
%06F8050E0E5AFD12FF8536FD04FFA90E070E0E0E0D0E075A5A0E0E0E07A9
%A90E070E070E070E84FF0D36FF5A0DFF5A0E070E070E070E7EFF0DA9AF0E
%070E0DAFA8AFA80E0D0E0EFF840E0DA9FD0FFF8507AFA985A885FF2EF806
%F805F80506F80607F806F800F80D0EAFFFFFA8FD0FFF305AFD04FF850E36
%0E300E360E30AFA936FF360EA9FF7E8584857E85A9FF840E36FF5A0EA9FF
%A98584855A85AFFF840EA9FF0E300E0E5AFFFF610E360E30AFAF0E36FD10
%FF840EFFFF84FF85FF2EF800F80005F805F82F06F8F80506F80685FFFF5A
%37FD0EFF840E5AFD04FF0E0E0D0E0E0E0D0E36FFA95BFF5A0785FD08FF7E
%0E0736FF5A07305AA9FD05FFAF5A0E07A9A90E0D0E0E0EA8FF0E0E0D0E0E
%AF840E5AFD10FF85075B5A3636365A3001060607FD0406070D0506060E06
%075AA9843007365A5A5A855A5A5A855A5A5A85360E075BFFFFFF7EFD040E
%300E0E0EAFFFFF84FD040E360E300E360E30FD050E36FD050E300E360E30
%FD050E360E0E0E300E30FD050E300E0E0EFD11FF85360E3630360E363037
%30373637363736363037363730373636303630360E360E300E360E300E36
%0E300E3630365AFFFFAF30070E0E0E0D0E075AFD04FF300E0E0E070E0D0E
%070E0D0E0D0E0E0E070E0E0E0D0E0D0E070E0D0E0D0E0E0E070E0E0E0D0E
%0D0E0D0E0E0E0D0E07A9FD14FFA9FFFFFFA9FFFFFFA9FFFFFFA9FFFFFFA9
%FFFFFFA9FFFFFFA8FFFFFFA9FFFFFFA9FFFFFFA9FFFFFFA9FD05FF8508FD
%070EA9FD05FF5AFD2C0EA9FD43FF5A5A365A365A30365AFD07FF845A0E36
%303630363036303630363036303630363036303630363036303630363036
%30363036303630365AAFFDFCFFFD45FFFF
%%EndData

endstream
endobj
146 0 obj
<</Length 65536>>stream
+%AI12_CompressedDatax�����0�x�G�=MV�_wLW�{�%,�����PPU�ľ,��Ų���s��ɭH�))
*��D8g���׏/�û��E?
D=����b��l�֣�޷����n�U_��UO��n~[��7��b��ܬ�F���
���~����n��o��}����ܭp��rs�_m�n
��W���d���񍼑����&������o����?���"����i}�\�
m��J����i/Ϣ^?�p�ߗ?-
�7
R�-$�JzyZ�$/�AZ&9<5��>�/ֻ������x��l�����{���•y��,V����j~���f��[�O���n�Z��x���o��������v����bq��;���\�9���`8��o�z5zZ�����َ���W��_
���m�����o���b��ـW"�~�f�*�|�w�ƒ ��t�����|�x���.�^%������X�h��(�y���E�
���@h at kE0�����������߬<
���%�@���|姧�b��z��I�<
�m�+��>?[�i�T���o�y�}���lVO;��¼�����qA�
~xX���'�����CSR��U֓5�$='�}����b#؄iQ�G ������o��� ��vy��ì���A����;
+c��k�q���w

D��^�K����
'�� �p�(_���
+<�� �.����6��#��Z�����v��f���-[��x3������n�Z�o��ۧ���{������6q�}bη̩����r
8�f���f��������i|AO��?��
]�G�����Yz�,�=kj^�l��
߻����{7ܕ'���o}r���'{��������:�X���|�<����qq�Xw��i�Z�n
�[���w7���|}�z����	����n
������Z�[���>��
֛�����pz���j��Nت���������}�X��?U�E�>�w��{�����~��?�>��a������x�A�m~_�,��]���#`��v���So`/��n���Z�o���ٹo<@��8�G����!c��M���lG�wХ��=�!D�)�F�n���z��[��D��f����Oo�s�(x�)��o�F͉�7K�Fx���gs�B�v����qa;H_��ݻ��#���z(:�>3��sS��o��[]��7}�7��7��g����
����/|�!���{�q?��"����淴 xI�7�@|�o��W�
�C������s��)��?^��<����v���o�WU[g����tS{�������yE���������{���pyx;���'���2����d
� @��4_���f�~
r��[���4H[ a�"d!q���-竻�77��{b�7�����a	-B�Ey��v�ez�WnO����
�C��,n&��KJ [...]
�k�q���[�6^��o��ۇ�M�����޶�b	|��9̑k�՝�(��~3�����
ޥ^4߽���m���
���E�f�m�
��~�lV���m]WS-�ߎw�H�X��ߤo��	��ֽ��������s� H�Z�6���}_;���-�
>y5?"I�]-^����Pk8@�� ����n�P�|7XP��w3��m0E����~� �eo����
 �6��3�Ba�zӻ�
V��M�@����4�h��y�r����?�h��!��4-჌s�b�T2ͨF�I)���F��4���3��L3=�L�4�3��t3=��z)hv��B��T��b��Nj�'���j�s
^�wz�מ;��hb��`k3�ج{?�f�����5h�
��ZT�s��y�DZ�)��$�I�'��E���-ʓT��$�#�g�
���%�t���Q9�&��8�q<N��8��x4��g�h�&�$���
J1N���d2�̦�TM�i2M��4�|ZL�P�-(pǔf��,�"�(]b(�B�]R�?��2�n�uQ��l
_����gB�$�_#��J	=ƒSɠ�TEB���dFe:����Qœ47�f*���a��D��A����F0��q	s�C�`�S���>c@��h4�݄�����h�*F9�
 ��⑂"���Ќ�H*���p��$�7�j*�o)}���T�����ď$��X�^<�����w�O`��i$�C�8
��[
s�M�	���+����r��rT��,�𛗰>˴LJU���R� o��bX��(r(Y�i��
+�� 6#��a��y��BI�8��ʣl�P���0����,��d*�2	X �
Sh.�O��4J�d���9&�[�?*���0�湌�q�qgq�8�e
Z� ?�jp)U���T�R�4aNR�.
+�DŒ�LaF�zVʲ���d4/83\"���%L
N�P��d�`�q�T!i�f4S��z�p�p���$0c
+�LŒͲ���2��
��˳��F���3�Z�D��Y��<&4�2���a�	X�`:�:�U��;�3�s�ı����D���SД��
+"�>X]�8J
����h9� ��u�
)�F at g#6�XD
+ʙ?M�
+1���LRZ���<.�!-�-���
և
�5Q
+Z1��<*J�y�w	D�a�3�v� 8��� ��(
�a��&��i�`�c��&|���4+=�c@١FX at W�YIs;�s
�*s��'7��;�Ӌ�SLx�'ެ��Eb�ǖ�ij
Bh\Q{ʾ��^�g��L��Icc�'(�=e���~ޗbO�����xSI��xO�H"<|񰦡T�	s�7��K�^
����@�XJ$�#�oX€�(�Dp#�İ�p����4�D�aM=���� ���E� ��U w@�0Bf
i�
F
o�6��$I��
"���#�1p
�� '�IX��&PL��`i#�-���R��3�y�)t �6��eD�
�H�GD�'@ځ��C*�#	q̌�AA|aH
u
��&�ϐ�BQ@�b��`r`6���5��MH֚
I��1��W�7�)G ��
+� �F�J"�)#ѡ Ab�q
Dr2�24��!XZ�M-�b
��@62�"`1�Ra��P�X)��
��2� I,8J
+�!!-2
���|=�����N9N8�6�u*�D�$�����vj�vV��Q���̥ qmF2�"�u�\k	#�O�)�f�+(�-d�/��1���MIk�Fo `��P��0������Rk�5� �NQa��Ѭ�.Z�'�s!�E�!���<Q�Ēq$q&$q	K��Eҧ�������F�I\���X�YT�\K�FI욒L��׈dR|� �E�]H8g R��FĻ�FaŮX�]��SUQLg���d.�H�N�BY�ʄ'pE,p��I�*I���S��%	 3��ƴ��ƙ���i���BZ
�
���2��G��Lta�*}0$����0��H�!L��=8�7���"���?�:�8F
0	eY���
+
����8d��� ���K���ݠhp)�FAs5"��
B(Q��Bq�>��C��9�P
���	!�iH~49���׽iڬ*���R35�Ss\�Č���|�3�2�eJ�3+��#Qc
�PI�d��4���D��Z�dZ9�o�Y6�Z�e�E�K�E�aC��#&cGB�!,�J�)�MEQ}.L�y(�-dI�6�h��L˷LV�.l�!��
4�42Z���O��E
.�bU���HI�ET*҃%;R�]�Y~�K�T��ex�����iCC�4ԥ�*u � �&>�0d—����
+�BhrQSCA�*�J2����S_`DMHf�"�DK3-dI-�*+k��aD�&,ЖB�-#�@c-�r1�NHn,�a�7dX��? �
+V�o�uʰU��a×
��sp�
����J-
+-�|`WVlY�5r�Ҷc���o�UY�r�c`a�Δ֐%�%����I�t�ħ��������Jk%
���F�L�C�E�Z 
js���N2δ�ɂ&
��0�'\��ɕ$U�L)H�

(Cq�*K��d�:�/H�I��RۓRmQr�;cU*�])�-Kš�8YͲ�v%c��H�I�c-�3��8�1�KmY�YS�T��'�e1
+Z����`� �戆?��%�
#��,S�9��z	Ɩ3���
��\���և�1 at h��1�X�f֯0�r�X{�g�=
%�+U��[��XOBl�
�T5_I#T9�QN�Ȫ|�u��
�Xj�UT*�����{qPN8,e�Mܗ#RNU*����ʴ�EY�
j�sbdM-c*+Y�Z�7*?��J�S��GZ�WVHL�hXXS��
+�SO��u(�ϊ{�K�
�R��7���:�f�
+ĉ�ף��T �ե7��+�/�����w�v4�ơ�1fڷ��� q!r2)͍� Y���w
t
+�eFBlĨ�H.ѐŞ$$���a%	mBD8$�loD�-�	�ilb
�/ A6%��[Ѧ8Ԣٌ�;Jsm>
�Cy
yKL|��6�"���V���Me�+��n��<��"��C��]�AK����~c�Cdb�����7�I�Bj���SvR��4�	��b��9�&��Ē;�-�+'��
�O�o�h~ܨ�e�VZ��ܹ?J[ XH�=+ J>S��J��jC�Hؖm,ٙ�c�{L
�X�'�G�IC���n���&m�f�_z�5T
��Я�Ԓ���5Q�ǰL��ZZ�3P��X�g�H�����P��'Z�7��DxVj� R1���f.0��A��ϩ
69>�k��N i�ƛLۏ
+moY+RՎĖ�&;Y���
�!1ް�(�(�*"���
f��XZ�����0e
+# P�ia��k�N�HGr}G7	4#%Z�$b I k�������
��!�S^�K�dž]��>�R�U�t�Oߩ�}
�F�;�D��m����S7���� �}�\
�b�?s��f�D�Q����z^[c��X�kh������
�iW�q�n��
YJ�
 ���j��V;
������&lԅQՌ��5����ft6�/BG �n�}�U��C�(r��� ksF�c���[���d��;�ڱrg�;V�g�<����LP��#`u�(|F�S�E�j�J�
+8%yk���|YKZikL�VI�Z�',�B������
��`�g��Y��*/�u���Y��*/�u�ê�ST�� B���дW0����VyD!gf��ɤ��ָ��%E�̊� �:��Ws̫@4�*��
�Ju/e�͛�
3vM�l0UaW�Y�	�C���
��P�J�

+�o�������|u�W�=����@o�
������q��Qm���j�� �p����xi����� �
2��ꦙuu���G����#m��!�@*�(�Ⱥ�c"�V8
/�u����ڤV E%�55�z��M�� _�����'�� e�>�JU�����\ve�M����U�gA��D�}m�pF
+fD���y�Mth#;���nx�	u�ȷ�%r��3��m\�"s��(H͑��H�����Q�$�����/k��[E
��PXo>�f���/G�&�
E���P���p�	�&
�:"q� ZQ��� U
��G��zBa���ٗ}P6h��VG�7$�K_���).wAk=���DY�hys�eA

��	a4ܒ-�aP�Ț(s2X���
#k�@m9�g�m�cJ����
��/��ߔ�V�l�i�rA$VQ�㔨)G=���"��1F$�H��zl�9�9
�9Ad�
" �%oF��Y�r7��BG>$��	
�gl�&�Dɥ6X�)��mІ-^! ʅ��D�0 q��( ��� �u�\<�85 ʄ*6�V5�f���N{u$B���AɂBb��?:h�/eP�AU���#.]�VJ` ������G(�%	JZ)YPrW-���A��_�8�P1ʪ�j3��
:-���m���
v �Ӧ{�
�j�Q'���T��خG���
3m�3ѩl��Um�%o�TM�*��2��G"P
+�*�8f�2R�*i~9z՘3bY
�j�XG$�N8�rJ"�1*
+��rL��j-��pdc['�x�aR� WcEDcB]M�+�� ��D��)�!�
kǍ���~<kO-dۏ���8�-:5��Yn�0����J����1�۬��D{^����-U�jb�^�Q97�yU1g�|��Nʐv���[�$gdZ��Hf��A���$�M��]�֡D�ڠ�ќ�-?f�ϔ���b���ˏ��~Mi���N�
��d$(CP�䌤�$��C��)
+O�`��O~Hd��؋�PO��Ʉo8<?,k
D���i�gr��a1�p
)�)�}���hɛ��d��޼+�_"��
�Dz(�~�b�8$wќ�{
H�v�
�ͩ�#���a���r � .�5��򣷔��Ju�Vu�h	����<g�Hu�gQ�O�z��~!��b�EH�]�hL���
�,tx'�/즠*��Ku�O�+Y��v��{y����b#�7�5+:ڋ(���qz�}�1��c�䒞j�t�QxH�$vC��v;k�H�gi��Z�6�AM;Gԃ��aBGHV*.���ﻶf�K
�!�a|!��YHlA���̧́Ls(�o,�fa#�Ҙ��P� q�����d;,���	E�9��j����)�
A�>T#����+i��*��1>d9�����C/"�R������gE&��f��E&��f��E&��f�C�l��q�^�F�B�ٍ��}���>��Dԙ����	�tԜ��TuO:���̨�ZP�7+�:
�p��P{��z�d�������[Qx-O��)�eZ6<Mu�I�C��P�5�Ǘ}��c�#��Y�T�()j{%�k�c�m6(��p&��')�F٤�T2�`�!+S��K
+pp!+(� �f� 	�F�A`#��f�𨈬	�A�dTסP���_9���o�nV�.�z�Q�+�
ꮍ��
�)�����sn�.�йQ��=_�qh��
.�T�Y�q
2�w�����b�+u�_Lnn$&c�����ܒ�T��&���]3!�M���p��t`VB�6-\Sߧh- .)�f�~�L� ?Ex�Q
NA�xD�8c"��9����D�
���1�C ǝ0�@I�&!|7�ƭ�n�v)���O��3#�g3�|9W�C'��9�tJσdB���lI���6"���u\񎐱�~-O�п���.�`krF���!H�
"�xDA�zX��1���2��*��J�9�xg㼴7 )0P^A$wL!������b�]�L��>&�S����u�'��9Q}D�hf:ܓ��C�D;����a����"�9K�LB;��\5�~� �r&���~��� ��j
+��O
B1��T�K�Ɵ%t���\	�՟�i��3��2���/$��Ru�xa�:�R���A	
?�S�x��|F�G�p�����9�DC
���':�v�
m4����lNl��*�8́8�!�D���11w�A8BG�P��J$΄�$~4Na��g6)��鈼��
ˣ�<�'��Q:&>�D�ń~�g��L�� ��Y�
�c�6Hl��ٯ��F֎M�$,�,�m0���~����V2��f'S�
ow2���+��m��H��DdwW)o��ۇ�����_�j��Z�	�!��f-�>2�{[�
+-
+f#��
����WF�4�cf��TF��ёn&���Ku�4�
� �/E
OH>-�)�)�jb��K��<-3�V�M��}�����_��{+�[��&�FS��������o#�Ǻa��%�v������gv�
�>��/L�gC�L�>8vөy��<��
�L�ʊ)�O�1�|�����i���
q�$2�4k>g5�F6�WjS�qίR��*e��t)��J��yb�`���B����|	��x$�X^Y�~��\�ǎ�7^�tJg���g��oJ����g.������  e�R��\�:3��L�����q�8?�q���P����N?MU��U\��	�1�:A�)m�4;vR�c�v�
�ZR�u���<5
2O%���Ư4Aީ�v
�a2>&/�'��/jY��z
+��ʣ
�1^j?��9��9��
��9�A#~xEs���
�
ea��Y4Z����Z4F[�/n�e�:#!�g�$2N�F��0��f^P �k�)�hcD��RH&S�N|i(�2A���c��H'
�`��	!�L����e�D�k���.mc5�:x>u;����*�e~�:Yz���b��dnDt��{UI#�[u2t�\dEi���d��J�v�n{�
��(�E9�
r�a��
+�NP�I�)Q���/79^�G�6�,�D`��@��ņ؀���&�R"�%�B
r�=�$�{!&� ���
4:� �-aB�Y���

g#>aⶃ�!��Z�<��l��a�\�{���p��@c�s��Ib��ȅ���׌���
b>TG4����2v�����n&�����`�[����U
�
8���X�=���峠��Y�6V����̔=�\�>��w
����?n�V,��uk����[?��Iw;H|'X�
�Z\"??�Rؘ�5&m����jt��D���a���!�2�:�{b�~i�WeFvIJ�g������&t�PyCᕗo"�;�
+?!�X�v:f(�]���!1�7�^yF'�F�٢b�Z��W�]+�1
.o�Բ�vAnI�a;�������7m�ӂh%I��
h2���/U
�n���َb����jV"���Fޯ�RҚ�f:-�T[��&����d1JiT�b;��1f�RVD���<���7��
��a�`xEJ��8CÄ"���*�[��R�}*u�&�iF����q��	�ژ2�D�T&<6i�dor��<��H�N�1��F,3
��o�r��s�6��$�
Y)tָI��
+�2��oZ��t�������r��)�+�*�='���f�&��.��dJg�`yE��Rxy-2=�y�S�tV
�
r�as��ԛbQ��d�ZN
�ѸLl��̇����	�J&l��
G�����
�X�_5
q"����7n�<���h\��+
��
�
ȭ�l\�{]4�N���F皲~�9j�]5�Κ���xk�
�M��f��f�ۦ�q�n�#��?]��?=ہ;�g��fz���n�g��f�)Vy:�"���x �Z����4��ua���O�*�P��jݭ���
n��_I�x�5��Xz�=�T����0l�Lus�@���
�V��C�-��Y%iSk��
bVF�̰�,`u�5hl�:y�V�5��@�Qrՙ�M^/]�Y��+"f����6�TTr�%|-a&���Ʃ�@P#3�
�W��+�"XAF��A�C�� =d�z��_�2
+���g��,�WRt|`!S��B�J���^��+Ϭ ��1����o��iP,
H�ȯ��M�_��
+A��&�8-�+v��6�9-@�V@�ʪ�
��V�H�t΢�N �T�/�����[���d���9��5f�4�
P
+�ڴV���̥�A���BF��
�_��f
JX�z6z�ٯ?.����_端D�
U�W���j��{�Qܕnk�
���o
�-)A0[/L��
��;됉�h
���ЮA���
3�a&�{d��
��uf�(��ؙ��h[�����V_�o�ɗ#�v�h;QI
+��c�r�?��c�l�3��
pB�����{�F^�dK����鸖�Ḗ�-��st�;��;��䕯�iJ�)��Ю�h.�i5e����|�6T�䟑:R��tR���$��7!�u�Δtj�`t�*� #�c���tD�
m 
#|��b�M���
��?&��qan���A7
r��p��]4+��4";Cl3h���HN�����b֔ˤ���콙���Y�#��,���2�~
��7#�y����t2��
��A[ox��^�d?K�9@|�wNi�+:�\h�mP�4�t�=�Hg3�6�}]%m��h�oӊ���û1��PX_a�[�
}���z;3��Px��$��9�~�QmggӾN�zVh[�������Ϻ�
�:9m���3ӍO����E%�ޅһ���ג��.���DZ�C�6�H��zb�A�&��ۛ���
�/m�)�u��9闦�d�
��0���a����?L<
��Eޮ�*:ϵ���עrdx�y
+�
+&
+�!��ceq�~b��"DHK�N��'����������>f6�&a�� hE���"�SW=|�֑w؈ȵ�
�M�K�Wc9 )�%%ʾY�b��fB�0pVC ��J�&@G �b
J�2�z��Α�Y������[]Փ �7TB�1���&�1�^�,�d��e�0�R%���|1��i���R	i����khs�D�gj��Ӑ�58�-?��
�;���ϣ<D�h观@?�(�a~f���(?Qq'��~S�
b�:r���
=�@�����b9���m>���?�&6�ژ��cL�3�1�&nݏ]w��8�	DZ�X���G��?���\P{A"���8��Q������@y�B�
2�>e�po��I�¿��;
<<��?�
k��j���U�U�?n܀��Ҝ��#���jQJ'x;�:�M\��d
+�حPv�=�l�Ű��?����
PJ�����q���¸l ���5�q5rU¸��UO�j8.�K ќxΥ����4$�k���29) �%�P+��9�m�u�[]R
�5>.5`��W�2'S<��(
L����d�*ɘ�X��s��
;"e��d+�9�����gȏ�G�͗%6.]c(eH�*~�f�	
[�߰�Aú�r��X��ف�9�]���eL�"LdD�a��Q?���iƙ�'P�}���%�S�� �Jz-gh炖�;6a�,z3���5p�d��Pss�G�q��>�l�'���'~
+>�l�m�	S�|���P�,q��n at o؂n5g�'�6��F�p+zm3:�_-�'aW�����X�Թb��}�c�M�Ǫ���M�k��G"�&�}6*�y守��ye��0̎S�Wt
��NN�vSr����L������16��Us�Su
+Ą�S
�r$���~����
�`:k?m(�
`��Ѯ�!f��l����-S��	��̹&G?���hk\D�t���?��	8!.h�nDf���M耑)mI�7$ә"�%�������_�y.�E�
�Ё0�����a��'�%sEh�x�_
+~:?[�'[�T]�SL�xe앑Nt�o��4o�?�y;�x�� ���y�� �,r2V����DL�����l�c����b�Ll��Xa�IL8TF>N�L&�)��[5�
�M >ɐ2�˰��R��O���-]&b�e���
>��<ˢ�a� ��ـ��g�*-�:��P����.�G7��
<�#�9ӝ;�
��}�
���@
�&�u��Ɛ0Ƶ͎�&*�D&�n�cl�Ww$
����as�#�I�D���D�^b;_�9g�k��U��S3�������^Tح���~X���񉧊L�O����|yE�+��
�c-B�	7��{���m�	�g��=C�Y��ۢ���q��rcjȏ� \x84�'�N�`]Ǥ��.qd��j���i��I�[����
+�
=<�E
Ǖ2	����5����
����
9$F5
+R��BT]��
+R�L僨no.,1��U�LOt�
��>*�4�&,@�d�^.����iPN2hQG��C�"
�[B��8��|����i��	��h n
�����.g��jb�FnK?�:Dff-.�0�
������cJ��m-�f���
�<��|��w���7��e������œ
hM*��'Ǚ���S����s�K�ޔ��X"8����C*u��:T�P�C�
�C�� ����7��O#�̐�ш�/x�B��0d	�|��o[�v/
+�y�_�����:T;U��w�z��w�z��w�z��w�z��w�y��u�СB�
+�U��M�r��h!#�l��0��$���T���.ˤ��Qd�
�M��W����!�d�z���
>�08a����aH.�<�;��bG~� }J�[~r�X�p9��q"�ʯ%,>Ա�ႏ	�rkMPJy'���9}��"+�EM��O u0+�̚��K��k�V!�����,����RT6���;
D�j���zP������3�5-�p�A}�
�q ؇�5R �L"P��=��Ђ!�
��>�Dˡ
"T��x��
.��WS���
{��o��z����*�{6TRl���4Hд�7<�ub�P��d�H���y��qRg��p�S�ao~=�)@���1Ȱ������Ө0:
<�)�4����l:�Jp��Ї�d��
�s:a�CeK����sS�U�%��f|����h��8���M5q��e��'�({�
�'.-wh͢�GL�)
Z�j��͢;�F�G�p5�C5h�
��+Úe��cU�%q�Ma��8ڦ0ZqI
m�*��h��'��GO���s���#�K:c}Lg�����S~:�8�Ӂ�t�0�@<�P�C�:T����{�L'j4�Qy�V?fĶ�ȏI\>;����s
�ѳG}i�xV4:��ڏ�ǺM����]���AG���s��_�c�!
tTu
����ne6
vT�
�|tv�-� ��3N�Z5��
N."��2*j�ECo��35�DO#�q.�M�_���a�
�$�)6��~f �S��m�7��Ph�als���
t���k�7����u�L�P��
&i�>��RD�Z#��]�#'����c
�Ua�՜@h�
T���ܤ$�v�Y:�����/=�>��L��J	��A�ܐx�h��h�W����RZ�=�
��O�b%x�=�4� �\7�iVm4s3��
Ur�\�V웊ŕ��ZS�����7�k؊}ۀ8�V�J�Ħ�y�\��Gg�rdT�dL&ca{i>(�O�a�
�'���2l�
ѐ.��0#8��?���3c(j�
8��r�w�5}��ٹ|�tp�Yئ>�Ji��J�{%�e
�	N<TK�ј�cOj����C��
^9���`zQ��qj��=)>����e�%gq)Z��, �*r��ˇ�5��A��(�Gi�eU���Y@��
����f�P2Ie�t	L2�(��yv��@b��5y� ���.Z1�*@����+�l�Ը<�',o��6����x~
ސ����a�����h</�LY=��qk�'¬�(���xf���3K��J�
9NտS�1���s��0*?��OJ�l'b��:=t�����3R�6V�
ދ��
�/�p���� ��D���ld���[g��$�S�/%�L�x�Ք�چ	S�NQ9�*1'Y�l�IVC}�U�x���������B�m)�)V�^�Z=��5��!w��@�|"
+('

T�N�)G�=�4��-)ā��x�Q8<q��G��1�p��?@q�����Sv
+�W��<
+�AE��I�e�i�4�8�?~*�,�jM�9�JL���*-�x4E���*(���(�Ub��
�;%�k5x�n��!���[�ՠ�j�!C�ՠ�jp���V�����V�.���*�P�C�:T؛�� ��f��
yV�+)�͚y�����?)���������' �֜�0>%X�B�N
+Zkss�C
C�8EY�R�YL������
Q<���ή�z��f˼,U�\WI�zK�0�h	sf�0�1�Ж=a��c��:VB�D��2�9���+�`���Գe���0��{Tº���
+;˘	~4�&������K	�|
VDe훬���h<�h�AD� ��y8t@�h<��Si{ɘ��T
&�PE���
�����G�r���R#�;���L
|��0�P
?���Weށ�C�=�I�ՁV4W&�*������L����$
o��o��q���B��*��&?��S�� �T��N��N��ʹ�z
l	ʢr���)<秴u�?�p>�Ǟ��敇�^�O��

p�a;����Q�f�3!(�m��
+2�D�=
��
�!/&h"*!a.ڧ) L�a�C�(2G4��T?7I
<6i���D�ܤ��I&̅�UN
+b����=��m���%�E�}�>3z�š��]���а�It��a{��{���
!aGN{�
�t0�
��{��\�{&��Ċ�9	�
+�
�
�BG;��"!%Ӹ`��
6�M���G���Mt�������������m>��Z�z��V��Ǭ�=f�9�c�
{��c�
;��ײ�63�v3��Ǽ�=�] r��"w��] r��"w��] �����O;T�P�C�.��p�6f�+����"��-�9���X@�[��G�O�1���Z�+���o�s=���HV�B/���H�j���b�t:hqe<
���&U㜪QN3c��QN��X�r��u��؞"{*��4�L�JJ�?dg�3�IT�QZ��1I���C���GG��&�W�J��Yo����p�a��5�m�|K�&��Ed�=Uk��ʨF1e�Rz�ʋ�cs}:�z���SL48}���'dj�9
�1Yo?<Fk��|
+�!s<�F
g ,�
]>�
ig�S�&�:jʬW'�u�ۜsO⬡Xr
�Zg
v��EAΑ:e�LV��D����!��k�������(,���SCT)'uF�ShljK�z����J��U1�)c��n���`��3�j�i���h��2-M��
���BbJ��q�9e��7����o`
w�'�C�
�0h���>��U�6>���x at _
΁*�3f��/3�U\��9���	9�3����������D�X� wL��DS⁼��'�'g
�#��M�;�-��7E-R��<��il��*@`	�草��(
0�k0�e�(3\��
W���Z��kr��TҿA

,�s
�>�
�}
�s<2ǚ	�P����g�2|�
�e���x�ĩ����$]6I��\����#��?�$�
|�MY%��S�;E��􉅯�5���C�P�v��aU��V
7;�[Zx!E��
k#������{�g���md��'��_.@�x���,�ӃK��4���؊m�lI�D�)�Y�wIۼ���7}O�oi�*}�C��љ
���
��9������7��Z�5�L�uN�m�;�P\f�k��`��aP&�%��(�Chd�å.�.��
-�}C
1��Hs䔋��J�=
Q���y��Y��% � ��"�cEx2"G��#���Pը�jlT��F4DI�w�TR2QS��)QەSݛSO�
�ө���
�gX&y����3���;��r=�~]�Fɰ���Q����A
$��A��{��
��P�nh�oO��%�g�U�A"�Ν
+
7��a0���
�cװȀM
+�l�w��
oSF:���_���%�m������>S#�@V܏���M��5!4���!���IÎY)B+��n

)� �5�,W�T��:"���?<�cް� $��j�-��6����ǘB�%�;�`���F��,h&�sh���5,B�
`UBV�$-A]��2C
��)��\��J���y�8k�u�#�M�)e$��lS% A�1(#/#� e�Me��ߵ��V�׵��� *(-LQd��8*���ۊ-��T�6����6�*xu�<��U�����'��mR�T��,��,g2�ȇ��<�Y*@I<�^�ٶ���������z�\���=[�A|��Wb���|�[l��}9Y��7�������+Q���)�ў� ��� �d���A
+k��I�%��=}���?P�{/�}���G�;���'�Si��U�V{/����<���V�
�?��;����ɗ��dz��*U

s^G$�{@$����
�H�A���i6@H��K�T){p-�
�V��	�b5(�
+�g_4��uo��8 I˃�(5�c��
�μ�<���=�,
�Xl����� Ja���6��u@@PP����U�c���)o觮3���ڞyOu>�=���d��I��⣳����[����U�-�p����"
p +�2�?��
0Ͼhh�
+z>N�
�U�����{����N^
�$:�\�����T۫��_;�=�pռ�_'������c޳w>t�y��j{Ul3����]c�_�����a\��mcT�QB ��J>u	�|'L�_>k	c��Xi<�����}
=��4�N%���ߩ���oh��JFN%��}D�T�u*��Ǵ|r���+�$�[i�Һ?�(�'QۆU�C����"��� O%����%�ۓ���O�O%�MD�$Ʈ!x*����OT�}Q�;���T��$��rPdI�x�>�q�
�k|6�i����8}�63�c˩��޹l���f<M��0ړ��L���Ϟ��*͘�Sֻ@Q�Z׳�����O��L;6��j{P���zC���w�$��Y)#����@$r��|_2@�
f�k^�5i��
W�S�zj

�.���r\�IH��I+*��L�ܴenv'ý}-Y ���[�˜�Vgy��C���I�eJ�<*�{L��f
��O��q0�D8f��l��:Ԅq��/*�� յ�6�km��F
+	�*y������
����jO�T�F^�a���m���W��`�4M�k�({_~������
��T�:�	c�iY
�īflN�*�X1��"�j�x%O�_]o��굞��G�P���29 at 4���m_b���R]k�@mh��C��{�qϴ�D�
���Q������|}�� �$�e�9�-�4�!�sX�YZ�n÷�REZ��������~g
'i
P?��T����=�q��a����k�[
�
��a����ض��u ���Kˍ.�#r�s��"���t������z#ׂECG*�
��u��v���'��:���\�Y]&��6���A��������5���q�'�@�
���^�"��
N���
+ �g�V��f�9Cv�{���qW�{J��H1��8��
+md�Qs�/�j��(S�ֶ�\�X�y���3��d�,UuE�r���Q�y}��>{����	��ʽn�^�~%��6-i
+MЪ�����V}�����6Y��[�檨�W��3Q$�(K�@e���j��+�A�DI
�
�X얊�������ŮO���r�c���E��$����f���p�
��bQζ��@�Ŷ�ޝ���&kpm,.���M�w^��8��j����"w��C�+�P<(������dZ(���e�4�Ht\��DWb�S	����
�0�L�e�եL
��Z�dD�����[ݱ��b]�1MI
)�jf��Ҽ�P�~\���WG��|�y�B�`ڬ� b��n���dy�[n�����ߠ�˾��2��w�r�]����
����O�?mvs���޿_ï�^�F�
�k��4���B1�sXȢpP�yhP
�����MAJleƂX�a&҃"�
R(
�XW�q�Y(��z`�X�:���bR�Vu���
�D��Q�{�b
Ee'i�q�
�Xw�,��*fV%Y��15�q���+te"#[�e�E�o��1.�6	���ѐj4M�y�rS�'��D�`�����'�G�@�Xe

�B�6�HZJ�Ǖ�
�speH�7���Ʉ_�	����\S�l�TW�2�T9sb ��I�L�21pT��9J����f9��k�6�Zya�8�j��6:*=$���P[$
+m��q�@ D
1�5�!a�j
+y�9[�Ʊ�fT^jn�d+�,�����8f1& /e�1X�%��U~݃�Hte�X�l%T�D
o��
+�+m��LLR威Y��Y�!��8@#�U�������w��H��� �Fz�T�f�2�
�$&H�U3���A��Z�VF�6�!��1������Q��؊�e^�6���2����؃c��h
E�ӃtPF� Be�
Gex|�]��p̍�FZYf/+5s#�g�teRD�D��X
ǤкD'��Q�b�ZH*S�$����ݡ:�
I^��*�I�L��+��:HJ��,��4<�
ƍspmH�7�y�?
$э�4�̥4rN���W��AJ-����MW�?�3il�G�Ι^��(��R�5U&�ȵ��\
�I"͒)5J5.'�F�
3F�u��4 at j
��,3�@	���k��^X���*3�V������HK�)�B?$�ROn��T�����b�H��"�+b�H#��4��L�l��Il�腞eE�R�{����(K]i{�����U�<@Ʀ��֝��Ƅ2��>N���~R`�?
A�c���3*k���Iuu�U���R�C�F�N42&�����Y�?���22�KY�F�2��TJCZP�
ҤJ
K��eR+�P�'����L_��<OI�xTeb*+3pM8B�zșv�_��-^gǤȈ/���of�4#n�G��߽ͯ�~s���_��J��ܯ�p����M
��|����.��ͷ�]xq�����
m��/]���}��Z�o«�v�o�-Ww�A�&���?n����ju�˝?��
���ػ	pe�|��Ý!��l�ި�O�?����M'�M�jH~�Á��?.f���>ޟ8��k��WD8���rw�����dح7/�V�1F8����i�;cѵj`���z�������a�ܵ�.�GV{�A]���hN
�����v��v��ny۲QU�yXl���ġ
��?y<��G�٨{2
��UR#�|����:�w���w��v�l8���~_�����Iw�B"�/�߾�
��_�V�;��
:
�pw���y�?���h󴾃�F�#K�O
a0����f�x�����>���f;d��f��	�{I��tm}�]T�S�:u�E4�S�:u�S�:u�S�:u���K,�Խ֫{�̟
���h��g��l�񸻛,~[jW�G���@�~�j�Ȝd}�<Gd�U�bi�
e�7o
�6.���kC�}bXֺUSW�N���E��jR�ݩbq��Ǚ
�����i5߾@�z��3�7����[GuNE�>%9o*<[��mJM���CQ��?�o�8�5>‚�����
_�2_|�dv�Y?�����V}�A>m��o/o�S
[튅
�
�����t����GQ� �?v+-2�o7���o��cC�˃�t�%�,�?�	�^=����6���}��`���8_
�Z5h����
C�o��w��]����t��?J
�]����k Im Gf������J�Z�Z�L���b����
oům��'3���/��&}�h��t,.}���꫖Ū<�X޶�\��l8W��jې�5Z��X�|7������0_��w��û�j��}Y�Y*~�,b�t@����r5o��|�L$��üz�&���tj��
�+����y���C�ڵ��B�ֲ�����[G�>������/��i�`�����.����!������?s�w��?4H��[�]![�ޭ�.~���?���
t��ז��
l��r�RYeK����j~��_�w���ț�['GbZ�NNu��
�.�����|�p�.T?��ޮ�<6��1~7_�������t��O�Y}� �?o��V
�>�3#RW��ws��62�3��{3����I=:���K�TmỄ
�
.uvD
8U��z��je�U�6c<����)=������y;C��,W��mQ��?�e������n�=9�a���������Z
@8.�n��ܝ�W��bޮ�O7��Y�Xp�3�
R��-9���k4�������Q���p0��n�۩Kh� kM���P���{��i��NN"�g2
Le�x
���h�T�n
��c�m>J�	v�ڙ(���]�z���KU��)P�����ވO$�]˾
�i%X.	�)Z5�.��
�iYz���.
Ɛ�v��/�mcL��v����m����p�����0�Кo�]�.��
���a�p����an�e5�Tm��
�
.���]8�_E�:��]c�\J�ZF1.�}����w�V�������s`��C�m
��
+m�Dry,�u�YN�x߲
s
�Ӯ�t�
�C�-���7�ը}���9�]��?����?��`g��j�	��lZ�c�)�{B ~ծ���v��h�P��UCjEk׌t��h��-��c�R?F��.��/%hS�p'�u�g/=k�8�z֮	�X��'IҮ�j$�_�^|�j��t˦5�&ob�mٴkv>�e�id��.�7Dzд"���b�����i��[�Y��-3nz��wVl��ɯUԓ)����k�
��
�V�ׅwi�j{|��h���i�d�2�}yѺTb��X��5��]uxA
���m�z|�{?^������0��Ӏ�
Dgoo�6��v�U�m�2#����#-Y6��bh���SJZ�t.�

�_�6��	B���^�"���^������b�0�.w�����}n�
��h�k�ve G|U���$��
��D�r*�kj�3yh�����խ����]z���e��zi��7�5�������Տ���W-Ön`�N��ɛΝ�L�ѡ����G�;�}�'ku.�9�΅ܹ�{�
�O�:rk�,�
�� zF*�7o�
/0)t�S���tjܧ�ƽ_�V�߿~�],�_�2^|
�]��|��r�Z��.��l���|��}v�]wt�
M�ߝ��X6���I
�f���ꀞ�w/t���	W�.�NOxY���j{N�b
9Cm��5*����ry�Hh����8����g
��.�g�����Z�x�&��Q�6�
L3��V����[g�x�Y���i8p�i���sF���8K at y����f�ٝ:��gew�V&�;i#��:��_�3;�Sgw��G�ٝ:�Sgw��N��ӷ;=K�[
?�}n�?Lj�d�&�
ډC{�*d۶
~�v3���Ew꣸�<#�m�i����>N�a�FX�g�]�c#���f��ªˡ���r��|y��d����
�A�]H>���c��m�4� wF� rn�O�w�
�.e��=��@[)�t����
�l�@��S�o~�y��ɭ��Sf^��s�a��D��S��9�I�Nh��r'
���r���Û7��V���_ҁ��}`��c�ޟ8�v�y�ݮ
��n�@��ԛ?M�i9�9�	|Pi��m��I���w�� [...]
�>׼+��I��ݼm�f;Skgj��^��F����A��D�+���:D�)����UsjD'��&����C�Nh�vlMˢ
�
YӲq\W�l8W��iې�W��WG�u
+_��}�
+ߧ�7j׮�k�|�]��u_�h`��l0���i|�8:���C����.ky��^��SD�K�RD
�Oۻ
�YZ���!Z]‹�`�͞�d6�Z4����eV��rn���j�9&;������=��� ��
���w�O>��
�����׫��?��q��a~�ܽ�[���zp��A�s�
+N5��|x����p|¦�g��GJ�1n��U�&|��
},��n��,����@�:�;�����tCk�.���}��
+:rN"�v������Btk�&��+�l�]�U�?��ع��]��T��dX�gܟ�J[5������x�&"�Q�6�
��m<���n�<
*�����vq�hSp���R�ډ{�����{�S'�]$흪����O_f03�Q���A|�D�<l֋�!�.�Q�g�
��H��
��VX}�^�ϒ(�S�[�K)B+�P��)v�Lz0�.w��m�ִ�;��#{��~�V
�]ȑ8��$�
���R��]ȩԭeQ
�l<.��<��?[	��u~
��c�m��Yg�P�\��
�ؐ �S	}.|�Pi1g��3w4�LD��	��%����x�TD?�3��U�L̚v	|7��������D{��D��Z<�@G
�{�?���R�P�zPNf��H��O��UC6<�bt�J>8�R��֪�
��}J)>~h��Blk��
����v�Sd�跋v��
���9�Hp��ܶԠ��
[N�.q?�S��B�>UA[��(ګ��>�k���
���R�gX��9����|���/H�9{Z���ƕ|��m7�2n�dd�^��9��k�%�y	� ˾鰬�X6�{Q�]��F
����GL�>���+p��r�.�_(��Y��l�!l��hP�}�����|cHk)Cg�bL/�fl11�VL�	5Ax�Z�jVN<0��9�C$[v*ϳ�j�H.<*m�p�pTۆ����k��{�����v�?�[��O_
��ѫ���
�U)ּ�~��FDy��\=Z�]��
��j#�K/�߿ެė��� [...]
�4R����̊�>DJ)�PF2Kt�دs��~}_�>�T��Kz�����Q���I�U6�#�T>(ʤwO52WI/�QŽ�J*˳^,E�+�P�(�[1T����
��CԪ,m��]�ea�
M�0��襃$�cl��Tv��x��
R%Ӟ�R�)
��@�T��d:�e���;d�x]�PS$Y���+-��;��Ԩ�g셫����BmBw��V�
ު�e�H*-$�;Ƶ��
��P��m��=<$�̍7
�|ݎ ��Qbk�J
Y�
caj��m��iӌμՍ����ĕ��;Ƶ�������{U��}�L�!��s���
���د�~,��>���0l�f���T��{��ٯ���>r���`6L�af�M�f0���wKRi#	���5�D�3Ө
�~�7
�k�F
�e\/������̲8*{j�&I�<@)�S_�2W9v�
di)
�k�$)��Q���iTx58������.
�%,ɞk)d���
���*�i�:
TM�2��Y\��/Q��<�����{�A
J���?9�HYd���F�D�����2��|&č��S�==(�����L�xU)K���r�6�c�>^��,x�f<���Tʜ��⒪2��yN
�I,L�q�����
�����Xx�!xl�����M<�M�
�ϣi���L�^x A0">H�&��IÄ6b��� ��Cv�H��JW
	|+�O��Q�0'�fcZ4�ع��v� h�\,���=��p�)�P8@��Q��-�A�—AT ˀ��4Sl4O�3co�頌���� ^^�D1e&����B��
�5o�i�Ӫ���V��5�d�
+&&J�0���>*
+�*�ž��s��7y�"u0mI�2�O�
M�-�+I�d��"�^K��{�����-��W�w�����+�Pw��ūT
� ��?�t�خ�q��0���l��+U�3�mww3�lV�=k�|�c���W�x�	�:R�L �P6��i1_��
�/h�|�Zr�D�V��.����{n��W��}�U�����`�`�dڧ�j���{���?~�o����%�}⪌*�*�M�(�5S~�ï�J��'�I<�>����x
��PE`�x����ݰΨ��{�wwol��B�^
�yc��ɗ��Q'�끚w�\ ����* ,u��3)�)=#���[�?�
��/�</e//rT �G���F#x�p�
. SC�`���~b|�SU��b
��<(49
+I{�KJ�F|R��49JO��k�=8'�LQL��>ߌ@T������}ݽ���
1��K�
����'|k9H�3��o��IO�>�5�_ߠE�
������E��{m۷/ѽ
۝7RH1h܉̬�Wp��)=~�?�f��d�/^�>���
	�J��>��g7Ts�����V{�>�オ�����u����f��F�xp�+ŃR
+� 7d	��{dB 
+ �4U(F�e�|e�Ke3Ф�Ib����A_ǿz�%�k����� �兠N$������
`���i��_�JC�
�pIk=�����
��
I�X�s�yB4,}X�9t��{��$Q"����d\;�۳�2:�-��0���6�G�G�.J��Q:��25�����e��^�]��f@�����$R4�X	HE�t���O7 
�ڴ�g?)�OP: B[�
d
�V�L{R���X?��i�n��޳03�}�����y8��>x�H�x�%H)ȵe�+G������O��
u���'{7�ov?-n7�; 	�&�f�*u���~�a�����l'&a������������%
{�ʽ�I,~
QgbHm	�
J,QZ1,�^(C���}�_Z7O��d�����Տ��������V���YR�&K�
`�����)���bys��}�ɚ��_!���$-I�Ri��������S]	{d�B���ϋTI4b��
R����I��<�$O4Sk�3�3U,y�
�'Z��H��3%ϤA���h�3
D�$�m/�ɞ(!IJ�c+}&9�W{�O�&%�c�\�ВW��
D
�y6J�� Kd�K���et�[�

]qq\�DH������hŪ��J����%qPGd<��R��	�9,���zL�c�C�����]� �bPh��
+H"�`Y��W�҉��L���ʒ�j@���DQM����?��S0e�x���w�H:(��e��Q�Dtat���iNt��I��C&[/��6���ٙ?;!�sB���ٙ?�~��?�1�
�����l���� ˊ
���ȤA��
� ��4
m�}�F�k�5��YU�  �*4F>���S_�� ��	t���Bgg�,��/ov���YA;��@��
+�YA��
G�����=��5���3*i�J��Et���'�7}�̈́�La(pQ�V���GZ3�?0�"�p�A@�r�4��:)�}�XME
�(S�8��g�tt�K�W�P��G��+���S��˟�����c1z�D��:���?;��?�N����}FP-�����"h��q��/��!��l)���9�A�+�����T:(2Y�*M�v
+ p�F�����:���sC��Љc�8։c��8�^K
����
��>t�ص�1@":f���F�G�pG�Է���(��%1
Rq�zf4d����,��2��Ia��A�R��y��!kH�R�g���d!U��9bs��"����D�Ә̄��vt�k��������#�Z<�.Ӻ�M}`�;3a'�~H�t�v��0�S(��+�b`,1��,`�i��^���J1(�B�j*"��o���e�l6�◱�o�K���H͐;A7c*�%泹f
��L�Լ?����`y�LR�Y�I�R%��$��|�d�4<�@���J���e*	b���
v
})HR���s_=zƫ�<
4�	�I��1ť�q*
��
P'�;�ʂ���\�I���L��퀎�t v*�c�pU�0�Ea+�A ��V����`��mElpW�ӄ��7د��i쟇�x7��dJ�>Fߋ ݹ+������]�L�Wc:���f����
�1��:�p6�.j�f�[0��|�v��~���T�A���y���z [...]
�[�n�Ko��"��X
�[´�5
+�<��"V��Af
���e������J�$���pܨvw�(M�J��76K���I�K�~o������:Wک�IR���3��i�0ea��rL�[A*�7�)���g
^X��N�+ˆ+_��k @�>�m7묂; �Y ��;(�5o `��C�g�>��uRd�������N�2�{�Q��֤�ڧ,z��5�q\�s�\4��Ӧ}[q+rXΉ�
+9`�5��
+n�gs�<]}��>>qWr钵�4/�>9P�K� �(�I�xw���Bh&dO B�ALrn%\& �,�,�\LS��0F�c+�T���y�<l�P#���Rפt���[0߱u�پ�<ܯ��w/�dE��2�I#uU��wp
7SA
�M���y�<졈~;L@� ���Pf���&Oٙ���~���{A��
ӟ{������}�CjS���
��ûk�[���p��<�f�
䶙{'�{kK!�zKA\�K�X�R�>��T�{۳6,4���
F�G���^h��-Ȥ�4��=
)s��F�#�f�c��~��o,���E$U�DE����"�D������P����0�,�A�A�D`�r$a -�f�C+�J���m�^�O�q��5��.�4Ż@S^3���7=]�ӂ

{$�
����ꗅ2Ҹ�ō��1#��U[B>؞����WD
���V���A��#�_�,f�K��'ذԕ�Xr@��L�+��'Y4Z��D
�$����X�K�^6ϒ��4�~����GC7j�]��%�
���[d��7����dߋ�����4=��W�ʌ\\@�(�6��@�S�H���zabɵǞ�sxK�V
2�{�w(�ɲَ�l�F+U�E7
+���V�
�����d�B3�v6caBj
�X�=!Vd*H�ҟ�5��a�������ݠ���~��v�l��o²�T����*r�8�� �K0Ͱ���5����(���dK3�K�5D���7_{��5�`H'����h�%΂E
ӕ���c
X}�u��l����5c�;�����j����}
�X
Pu�E]�u/��ooeUHּ���l���]���N��~`��?�v��ӜL����@
��Y�V�l��f���\�_�u���k �dx�C?�I��.���u�T���
U��<Q��GiJAO��#-JN���%U�
+��1�5+�:
�� `���!� ���óp����2.i��n�Fa\l��7Q+yn[�t��%����B粗tl��i�C5z0��_던��%'��ҧ��S7s}�^�g���&g��
ޛ���)�Ÿz�D�~��p<WB�7waC����
+L6�L
�adʘ[(Q��@�S��F�1�y�^���2� 戬/4!=7Ę�o��B
�(�
�F�^B{��ꄘ�1��h+pwe���r��T�' �4}�S at H%�=����<�X�쩈�I���
YA�<�
7E�A��0�
+fK����ä�P�N��ph����-����V�[�c��h�o������ꪴ]�x�"*27q"�!Ӭ$nVp��ܛ���uȿ0��+��=��S�,��^�g
PZx����	��������AGч;�׹"`�\�h
-��U��y>��WD��^�U��O��9)#�/��a*�w�{�4kZ5�~P7���͵�*��v���76��7ajb�Ѧh�Q<+P��#��N{U����j�:Uҩ'0��눈芾������L�}۶yq�:ӧ�`�"����5��ڻ����V5�%@Ƙ^&q���|q���2ƣQ�rp,9�"�"^
�*!����)0��C�R��%�zE�,��P�(�٢H����%�ɗr�Lmƨ_�� ���:�@�D�h_ ��4?xf����o
+�Z at +�D��7t6	�rJF���(�]d$�ժ��)Ws+$q*�� )��
+>^l�0d����Y�S
I0m��
2�mE��&��U ���$3����(J�C>�]4�sE�D�Ɨ�AN�\��sE�l3�P�S:�O��S>X� �
)S�'J�q%���I
+t$�{�X' cT�$��7|9
q!��xz
+ܚ�o��S
�XxUE��$�L�CPA[J�;+a!���WvbI08�
@	���,^IH o1���t�s���0��f��y��y
V�����?u����͛&22\FD`��
���R��J��(�\  �����Ѓw� 
+������*�*(t@���Z��
+
Jʘ���k�q&ҹ�KQe at MBQ�P�c�mY�	t��a
+�@��VЋal3�&E)A#�	G�<���.B�J��b
Ot�r
+pa8�-�YP at t��})1����,�h)�>g�H��uf��݋]b�n���tp�?�,�n�A��Qp贌��D�n�b8�k���XJG	,�t
t�]?P���SZ!omT�4��'C�nU�X�G�~��Q�+���Ί�!� {���\����[G�u�����mC�Y��@^`,P��?̟�U2��%�N�,i* P��k1����1Y9�b�B
+
�K�G�
��?ث_�1w�m�Y]An�<GB� Es^�V��Y�4퐃�N��Ew�`$�ao�%�a4W3/D�B�=�*
+Su٩nX-"[��p��
a6 �����_��w�͏�G\^��E�ft��%Ac�^FR���[= ��*.�vP_��(�J
GA:^�G��
+^8��.G��x��I�c�AG���
�Ӣ F�8��r�:^
+�!-

+�� jf�"�ɚ]����DWS"�Xx3
	ˆOvfa�=v3��2i�􃰉��LD��|�<ۭ[E���!:�_�w�W��8��L�����r난�N9bV��f�@�z�ܺ@�P�^Wƽ����Ȼ�X������
�3��)�6�T�d0]��%���'E�g�����q4^9&��bGVD┬z�P�S-��/vC����]��e�k��Ճ��
���5�o),TLLTI�G� !���D��աY��'���lCD��&e�J2�%;�,2e}l=�af�����cXQa�H���
�&�n�
+��ߙ
�
��$p& H�MBڽlrG��\&&���

++�/�N���P
<B
Q >�ܲ(`�.�|�
+OWlJtl�A��Q��
+��#����݊U`uU^��P�U%+V�����Z}�%��9��A;MM�mv�K�9�x&�a?1 /�����H�ɽ�r�H#E�c�Į��$�����<���#�)��
�v3Ƒ���`�ɮv��3���,�S��
閝���,`�-sHv%{�vC�s���vãS,s�5([��|e1"QV]���hP@B����輀4�C�tc��3ӕ��v��&銫��y8��VO�%�T�
$b��:X�'���F��1��26��Y��HhC�ZY�Q����;��^Goit�0����ܴ��M2/�F�4�1��Y�6ю�"ا��3˪َ���L_v�D&;Ā��c4�ݝU�&WsHV�3
���y�u��AAJ����
+��,.�r
+�,;Zen%����U��WB�!+n�<P4D0fŲ
�
�)�Q�GG>����V�.A+��n�G����fGV����XE�	P+�3���G�,Zl> �A@C�\N�����n��8
�k���wrAK�Α
�g��F>�SR���%f^�k�hC��n�.��+/9e ߉��l���d�4vV	�c���k�#�[�������C��v�#�VU�_�����ʪ“��E0��"<
�Q�"�d�$΁'�:p'Q̓��ŪHNv��
�ȴʀĢI�j�dY`.
ԑ]P^��b��7���w at f`
+����ߘ�S�*�&�+xW���9F40�^{ 
�d^pO�������
T�L��SA3%P+�
�%���9�T+�%N(P-A~�e��`�2�t�Dg&�y�"���>d� �BAq)�D
 ����.�k��{E�
��[:�t���"�N;af�d �;�*�LR�
+d�N�T�:;�����bdO��3��,OP^fQ ��RJ
�"�@�rY銙5AT���B&�C]m�Vr�4
��,*�\���?SU�G͎�3�k�YØ#<��_�J�ħ"'bx��������8]_����V�d�~rH��&" $� J�
X�%��R�����a*�Q����Z�nk�f`��~�-Nt2�P
+��O�`�ĩ��
H�4�;�<	�^O���[KA��{ �E������i,B
�X~?"
f��N�]r�H�x��
���uLR��&<#WH��/"��w�E
	Ȁ
t�&h�������0q�kQkp�+�p�S$�1F����g��XeB���!4��'���6j�i�M����
�A��R�w�q��+�c_~����}�#I���$X0ALAS�IФ�_LsдeT���Ǜ�4
u���yP��	
`Sf'~	&������f�����ҙ=٥��i��*c��I���O
���f���.PA�P�����[��W�"�ۖ�I��n���1�zFG��*]��ɵ�'O<X>T�$SH&w������@�����`����Y�(�a(,��KF	m8 +H���#�>����ek!�8�N�9�u��	q��0��
�
K�.�@�� o��C�<�Lp!�|�ѣ`�+
"�
�p54��A`_�����'ar�LDd<�Cd)�B�y��J�&�fnܥ*t!����RĴ��+y at p��1ww�F<�Y@E'vI��9�Y��,��%�O�Z��P�',�y��� �����u� 8���L���wx<���
��Yp���
+�����qRPB8�����-+��Q
~�f�C2��s
]%�h:�GU�p
+m�*���!���3�Y���e�sƼ�06�������>�Q�&�N  �y 
›'k�G�dtЭ�*��,����
Qc�%ӈ�"12c���P'���2�5�f�T+C'G��
]��w�P1�.FIA!g6f4�YTv��$
�Uk�Dte�y�ӿf)��E�l�u�M�	!2�%3Y ���%�اPbR_��E��WE^BT
0`����_��D�R�H�xE�4#aTT)�
�?��i
'oDEe`�(L�TW���Ȝ@�g�1��I���&#���}$��
+���e��
�����Zc�@(�
ݛ0���#�0K�����ӶG?z�B����
�ct�g��aL�[3��^�
Se��CI8����L",�C$�@�mU��A_P�#�S�Nx��J&�L���؞5
�j�t"�2�
+�
��D�yVKdQ(
���^�8%�іY���r
+��y�- at 2� ��L 
��(#,�N�e�a�cA�dӎ@�~EIsl
:����Nl]H��@$�����:L�G�G0����+��IG&>�E��CS)@��*)��CG�$�
+/����`'E�̓�'ph���Pg)��U��k�E�
�$"���9�c
+��ǜ*~Y�s���$��(��dh%dD_�0R;e�4Zʪ
&3�_Pu�X!�������tr
T�ɒ(04�FSmVE�M���
7#C��?O�t��}�L�P�tꦀ
�Eo2!�c�!� �y`6D�t��M�vP��	�N�ޘ�I�rl�N#R�/&�Ԃ%�(�y֋^�HɈ��
���)�C)�T
)��) ���"3z�<��et�c��e�f,M�Y�lAX�n�B�Q�r�fb4��'���Z�"�bT�F,#�M��Ef� �|���V-QU9ʹnH�O1�@'G�īLIYp��������1A�#�A��@l����'�W�
c�
��Q�-�l䮰OP�`	�p��L���('(�)Q�	�L���cH%O5d��b�;RA #1xݲ���v�3�Kf����f/������(���I���BQ�:%�
H�<
 ��+ ��bPD<�T=d�$>A��<��"tɾ
�
���PzP�.лqx}����
P����^;�Mc @��
�tM0��̠���
�/H�Fy��8AbNp"���
+:˿**
+#�6M��{R�ZS>$:�C5�G�A
� 8Jx�'e�Kv�nq�K(q`

���>���*����K:��N,:^Ҁ4�(��q�n
=��
�u)��k��Q
ە|�}���\��k����"t��m݌@�F�Ĭ�̾��nT��%�k���if�jY	�f0�O�8�'F� :������$f�f��h�y�Ţi&T at G�k31�
1�nqw�&���GMHR�R�J?��␺��۹rx:�D�f��|��)�E�&|�d׉�v�I��yo��/G�b�.����*\ ��+���]��t�a}B��_��$�~��� ,�Zi,-ٌ���ƭ\��#+v*�-�_`t����ff���D�$=t�gY	����2�N��l��:چ�lvÎm��"��R����G��
+��s����u��ڍ����t�9�^
� ��z�
�-<=[��!
+�Kתk��GZ�N���L;�"�Od,ϖ�PVT�Q��D�Jb�,�r��S�]3f
�v`J�i�!�#�
�u;�xbK����2�(�>��eɕ��r��2E�c�
�.R���)$'&�.�,��(ٻUw-�fE� 4�����r�E4Me�*�C�5�
4+��$�$X)VT
�^U
���C:�p���T����G�1�
O��jS�̜����ӼQ�k��~X� �ȣ�Z�@�ω`r��rd�sXt� # ˔�K)
��q3��L��<��{��?@;"7h3U���Y›dV at W*�w��Sd K�Nu�M��$Q����
+�܈'�
�[�O
+<�\�9��TJ`n�,[kR���r�/b�<3��Lg�x���R��6,OB�I8;��ώV����!\x1�dbmX�W��_,����&�
+�e����u��O��haK�C.	��,�gw:�oX4��Sx~����(籀| �
+���n�yC Fw��
+���VT�Uͬ8����*�>Y��t��3���]LG��'�2�j�`Yv�x�YQ�@@tD�N,�$*&���@�,
���
��F��KX@�\dH�y�5����}1�	
&��z�����a='1S�,+�]"�S�@K!��q��O�*���{v5+	eB��Q��E�LI��Bi�(��s���0�
�
&P�a
nV
/���,��Z��?2�ZE�A��xl����2C7���X�������N�J	��O�3f<�f^�+����k��/<1��,)��Y.t�A��O��K���bDD�C��ժ�n-��Ly��U�shÇu��
0�c�NQ��X�b�^FqA
+��̠$��1��o�#���G9��9��2�E�rI�$�#�����tZf�	�t(�
^c⬈a�H�$Qp�d|Ւ�h'���5��-Y�
Q	�$<IE��bb/
�
+�
0q��'+
���ِ��^��C�I$ź14£�.��I�����{f�%�:��!����:�:R�"�`�P�����)�Lv59
g�
�;ˡ�:� ���+. at H�v�,�
�[f=��O:/�w�_ޏ���	{ɢB��ҽ'"YųP��iX�IH�bV<E�e���P�?��
�=���a�@7�>�%[��Y�ԏnf@�A�,��h$� cB]CiE�䣌�"Yˁ!��̲�L�O4��(<9����S&�2��0��@���Xl9�0���e�xE��*��5杆��C<�E�6�|&K[HC��	��NM�G_�|;�]C{X }�ȼ��S���l]# ��

^�;6|ʶoώ���5�c���;��Ე�΅�뺫0�*9���
Ѣ3h��*�
ca�u��@����ax2��$riY� 
��y��GdI��S	�>F�x�N	���Fa�
+E���ݟL
�H)��=�deW�T^cG�T(��Uq�9��( ��
�(���F�O�5
�� ����@�]�
�����H�
+D^���q�`��
+n(3Jx��P��̼�wvHx���zJ%7��n�8vJr<�KMb��9v��(s��;�)����)��t[çJ&�#pp�r���
�O�V��V��N�4ߚ>��}|
�Y���f�-8�
�cX�c�A��@M�&q���&��4�	|��i�N�y��?��

cx?�s�#���ꨬ�W���Ya�P��T�SR"*�$�0}��X�,{�Y(F��-����8�Bf���~Dj�v7v��!M�iv��w���L�=f���
��@"��1�F�Uf
���3'7��h�V-B���o˟�'�x?�*`Х2~���
i̎CO�u����i3<
+�*M��
+��RE��"�K����
"��+,ɪ�iY]`&���֎�awaw�������5"kl�#���y]�d�pW���w���/���FA�|� �5r��v��1u�7�����v�X��oeԏb�G�c8�zK����D23�:�b�%w0���3�
q܅��A$w�='G�
+3p�
+�m�'�@�M��57>�y�6�
IYu߷:%b�HĒ=i�9*NbHn�Ifr ��fn�VJ.�n,���fW3N���e{0�G(xxd(3��Ĝ2�5Ed�C�E<��GT1�<�Rm
��VO�G)��&
4�c
+Ya$
+�ܓ�hb��]� �P�e�Y�ػ��@�'\����F�)�MZ���[X8�X��b)�F
.���zS�\�.��;�0(��<F����_�'�O
��ɱ����{h@���kg�v>���D$��
��W���3��y:=?m�Tp��
�#$\�mc�G�7}4-�h��N.<�<�1=�
+O�1�B��<��ETA#�
��Ϡ�x����ˏ;H,ځ���SDZr]e��Mm�ҡ�����b�,�|2Y�j�P7�s�7���<���D�����.Um�]�S٥:�.�	v�pd�]�
mv���KK�٥%���Ky�]N/�d�f(�8�9����t:���ex����
v9:����.Y
+O!��t�\�꒣�V��)Bv
�:��W]�UGw�j��v��D;�Ѿ�6����\�� tS����I6O�E��\�#U�@�;
+1؋��/ӤPqRK�-�����)���;�-}k^��Nla׺ؖ�0e�a��.X�U�����P���5Y���R�gߌ
Na�qI���zV���5��{�#����Y\��E���(�ef!��c��%
��
�
+�F�O��X����R������n'��J��ѱ[�yDe�O;�\��
@_�0+&��b鴋o4�&�
��g�7�x���{�a��9)���F�s֫���w
�2Yl6�;��z٬Y�)F=��;�x�~+��ɪ���	w}yn�)U��L�8���H�/��?Z����:�ɺl"�<� �YP�6�t��n=�N_Q����2�jJ[�^����D�<��0�[o@�����XSa�q�d+�p
r�@�	t ð=L�!z�ω^�?h�Y�^�����CU�?~]���
�]󘱸0
���#�ϊQ.
���LG�y���Ν-D]
�G񠷠�-�C�Ǧ,�k®?߽_jx�岥�?�S��)O
��&2 �?�_u
ȪG�,����F�`\�Z*F=�,�j�BY�#zy�#��mg�!M�����]ӚE;����Ӧ���鑤�Ji�s>Ц��Q�O4����
�?t�Ɗ/�/E�۝��� ғy=w�
I4��o��6�4�3�&��'k�z��*�Rfƈ�U6 at T�^��u�r����b���~��|�=?�u��Z��B��ߛ
6�C�,��"�n��@
��#�z� O����.�Ԝ@�4�zfe���(�fFy�Ă�r��1-�47C޺F�D��DŽ����®�<��DSFճ�Y�\c	201I���i��u�
�~���z��,��
�ʖ�&��Zp{�)˕�+��`����
+��(3wE�-g=>�i;'�[g
+���b�^s�<�K�T,gY�!Hm�˾���h�U*3 =\��Ѯ|/xQc��3=���Y���c��8zA�N�T �.j����M�Z��S(8ad"�l��],'qD�G2c�a�@_?%����?�$]�����
+?����{����/y��`�����ا+�c'U���a�[v%�"���~|T�L_t�n}ѭ/��K�-��n}ѭ/��
����5I�� A�0oEa��0�/���E����"`�*S���"`_�W%`��"`_싀����T��쯏��E�m?��ն��&��
w2B>�z:O��!����G�$��\�'�|q�/.�Ņ~9.�P��/�ŀ4������2�̤�?�s�ˬ�M��'w��h'-˚������P1I<�j����Q�V4޸��3M���s��m�%N �Ⱦ�gV�σ��������k�3��k��_4�ϰ���������B���m�X��X�

��w�����|�7���g�.�A����t�"j%�Px]�lo����F�	�L7�Y.6�"���
�C�����P\A���x�2oR^�lK������J�FR6|w�5��Pf(O��k���"8c��Df�Z�7�{�v���M��	�I���'����[!�ES�)���[��}b�$+�H)�TQfI�E
sݺ�Wd�I��`�[I��Zd�ʭ��
+A��)�ާl��*��}�@ߑ^������!�_���9�Q���OI�U]�X`����_��{ү�� _��=�g�Y�V�_�����
+�4�'��wј/��@�>�n!I�U�
o�x&"I��;���W�W��s�����Ŧ�!����_��}��������*��~��k}/��jp�c{2�K�2���T{F�	l�fZ��Y��K�\lϙb�iV7f:���x� �Y��y�2^{�1�s�]��2��qc��^0���K���v�Sge�\�?�_�:��Ar&W�3ac�7�z�
U��
X���p��V�ӭ3���(�!^���ov~�k������ɵ����u����k�J��H�>�P��Z�R��)5�D������r��C�+�
S�[,��+5��������3�;6�jx�oF��IC���4~$MC^����8��bP�ly�Yo�bo�j�ކo��������kM��ʡ+�"�n„G
���S������_��u�D�Ę1��7z�3WLA@^����J舠�[�F3�?���sR�7�!�@B�Q���.���0_L����',�楟����M�e�З���-�rS�dh4�X;�/ZF�Z��+I�0L���1
?,DxŪT����a�0�TMA�VMbK�O���}�alv�u*p��7�G
L�Y~��k�'S���_d{�l���^�#;��֚���e��Y������nx����3w�d��ٍ�&��"s�Jn��0���
+x1,/�����<c��Ϲ0d��>�,"
^���N�����Um��O]�
������zz�U�W/"���X�Su�;���x��i����돼�G�$�Vz���ozF&�
+E�7��&
+8P�.�!@o��M}I�]0���?n8��T�#|�~�	n6�ex]��4)�����TEP%��%�
}�
����߬
+����
��
�H��w}�����r.��$������}E=Ȥ6
c�"�(���#DT4��,�����+�K��v��'C�����f�
���|��as��R���V�i+��`�"wr�xJ��+�H?8�2��
�~�l�s���'ϛ��
л�kF�����nW����%2�<�v�9�`��0+N��rŦ1Dmr��G����I��>i�n�\/_ʕ?��u�>0���\1�Xn���뢮�;�K�5?��Ox.������
љyI
����D_ �1��4v6n�u��3����̫���{�Y���oy���E�S��
+f,����+S�ʖ��4�
Z ]�p����.��ӓ�+P���5��
+���UMWE�
�
+��p�*�UV���I�����
^=�;��I�H��^�B��Ky�� �!�D��1
8o����
��
+ ��
A�fEe

T�����B�
�����=ڑf�h��f���)%�k�"��CG��]$�Y
-C��Ӯ�SЉ�I6���ȍ�:b��B	P<yV�lW����;�n�
�8::PU5i�]L�D��?BF��ծ��	���
��d��:Y�����L�j�i@
m��5�w�*s��

ib����lYb8�Z�55k�$���`�YURxyd���Y0б5A@
�f-
�Y�2-��uG�����i�*�"�� 
+:3zX�

�!��N�%R�%��жEI�	-5�0KP8E���Ƣ��€;�����ݤb.7���~
Y�Zf{���%{�<o7�IH��h���ʲ�.��i[6��A*��yY�h�NvH ����:Cd�"�<${
+��ڔ���ښ�*�7YP$ya�H��<>e� y�iֺ��%�cDI�(a���h
���ʨβ��T�]��.�a2� (�� ܕj��i���"���B�)�q6V�
(o�E�!� h��Ca`�*�ۄ�=
��#�Y�e�� 3��cK *�O���GH�E2eӌen?�"�dm? i�
M
+�B��x����
+E��K3;
k	���
��n�

��P�M3��
+�
�I/
��Y�F��sr��
������w��UD-7�iU�ⱂ�{v�$� �.����3
+r&2	��Q'��h����Oa�4-2��Q����PX)�	1�^9.�n���t��2��d	X�%�
��
l�h1���2 k�u��FU��BcO�’h��}��D�$��$0j��p���ن��2⨉���
*L�x$R.>����;��H�
+  �B{Ǣ�"/딚P�y��}#ᔮ�
��	�Q

=����Upo�Ŀ4�jVD�)T��f5����`���_���M���_ľlj)��G˥H@�׊�(xv,�9r-����BL%���d`�D��f�����9 �,����5w)�/�:B�ւ����B����3U�����(Xc���1��Z%��D�ٞb:p�X1<��']A�l��?P��}b�7j\95 at 1� ը﹪��Q!���i�8��.�J�6X��C���
_5?l�]#Sa���%
dr��ܻZz�tǿ`|*��+�A
��O)c��"U�9� ���(
+QZЮt��BPa�3�L�a�ZD
+Q�f��.1jÎ^؜�eЏ���M�ɋlkEUb2h	�2�K�D�`�40���֨J
Eyզ�@II\�y����SUjL �J�J��w�c���ENd̗J�P
+]v��T�d�ְ��

D�H7���m*("�Nإ�m�
+d�RA�PM�����$�8ʜ@�#*)`�4i`�G�
վc�ٰʸ
	
�EI�e(4D
E-�~��ά���X�I��&����k�I�%��ZUF�"kd�?,Nϑ
+�H-8:�#yA�v~�
��~�_K$�D�E���}wm�<�N�����:��#���-�
����*H�l#�%�ŭUKX��1��:.]}6��Ny���-�
���81@�� �`3� ��h{���Xq�}l|��ڬ��VP�8EUFE?ƔM�u+F;�˳6s	ۀg��
˝ۤ�t�e�?zc������m״];�"�&>���q5��@�>4BN�
+ϱW�?Z�N��ߖ�0������?�b�a�X�FD~�
q�"��*�&��FM�s
+R�����Q
y�u?%@t��ث��2��Yt�+a
2���� $��g�)(K#�W�A�g?1  �� �
Js�S��e��⠸��ZϞMzr����${ک��U̺��"�i5�P!���������V�qS+���z�G�|e�59��1(V`�} ��
�7<�-5���Q��� ��1��P�r�k�f�g��:ch�X
@����㫍ɹl��x��[�o^؅�4:b���aV����?贶fTv�Y�{�����rЋ���
�a�g�
�act�F,hv�
��1�ڝ�������X��6<�	|4�R�]����7?�,~$|��̛eA �ν_����f���`4�|g�+	��)�4:�?>
bXV%��l�ϟ�����>��
�'���M�f�!%��#KBD�T�'��5��y�^�����i)��%U�ɦe~rV��-Tm�zuP?�C�;�'���~V
���ߏ�|����n
?�=�ޠ�)�*�2ZEGa��)^�
�����O�LA��

�b��5z�5l����g�I;��Ά��p�(�F��'U�\�Ns�|�Ȳ(�
����l,�I�fW<=[N
��#*��V�iW������z����
ƊZ�ā�m�\v�����CO|8���H�<��_� D.���Z]O
j � �~n�FԈ��+����?1*�a���k/R��
d�a����8s=L
�ݞU�i$5W��p�����+9�-���[rKe.�D{����']���z�>�Þ���$������jxr��t^5���� Yl�V�� [...]
+ya4
�
F�Q2
�:�:6Koy���I�0:	-��`�-}.~1�þ5\�z>�0f<����ɰ75U�λ�A}_
�Fo��Y{���6�|����{F���4OAA�>g��]�^��{F��w�FTE�Q5��tz	�>i�
��h�?�(˳j&�f3	�YQ�g�i�)
�d�ٕi�g�b�F\� ���3�ic�5�m����Fq�x3�l:p����1�k�c��6~|:�pC���P_
L��خ�k��\�q3f�B��v��O�(wڕO›�;���^Ս�a����v��$0�N����r���0]E�e�N��,�
��{Y�j���>9G���u1l�6f���08O���o���� �0�p澧�3Ųa�ƹ�h#~�+�X�Z?��`�l 7��ovJ���
6�nb��#�P�	��{��`Elh~�3{�~5�x���]
�)��p��0>��u�G-�;�d;�^;|[�5uc�F]f.p
�9e,ccI�#s]��k�^�Zo���r���D���f�U2*�m�^Aj [...]
+(l
+�#�|�#�9���	�=��	�\�)���t>,"�y�,/�쭆�
�?g������k�|=���v'�^�p�%���2�f�
��)
��?��%�v~3z]<����B,�85^�`+�Ks���I�~8���;-ӁA] _�j��0����Aq �����a���f��v��&����
+<��^�)5&p)
+
*�3}Z[��]-��c,��z
_ۑ~cp��u`Ro�:v��[���#�n%�U	��ͦ��^�Wu�9�(�+�`c���7��~��-��i,6HV��M�@[s�y��1>�S:lW;
=x�M��q6���&"�ʒ%��#�f:��`2}�.�b����q�?��[��'59e���K�כ
깣ij�vwWLE��L���I�'���u����9�tp�<�
�z���O��vXˬ�g�����|Iy��k�^o�hyɯ���ٟ�ЋW���y�����B\}|m��9����'b�>�g�������{~���c��|x��[���=|<c�
w�M|,�c\;��#��moǵ�[~w���_��7��:VZ���7NE��q�_���~!��4P9���G������{��K|
�_v����rB��z�Hs�ad��r�g��ǝ?�;�[K�
+�rf;5�G��޺���s��{ߟI'��u�1]ZټOU�����D #`�K~~(��քԡx"�V�7��+���?W�+���
�_�B��NH{Éh����cɏ���]V��[oܱB�ە
�Ʒ�p=S!|
�G0͵�'(nԭ�˛�:g������Jؒ8��i��i��O��]�/*{��t�'�x����Pj���^�ܬ�'
��Dc��{��'\��zx��_Ym��[��af;sx�(��d}�`3�>�����Jg3���2,��g�qt�
�z�	���f<�k'� �j�a7�2�{j���I�6O���jHR[����hN��g��1������o�DX?�O
Vז��f�)&������~U��ʇ|��?��X>?����x~譅i���{�P,�V�k��r�~S�����%ek�'��^_�{}�r˻\9x�zS��l/���

p���Z����ӛw����N8N�
+5�
x�'_&�Ѹ?��p3�_5|F���z�W7���ԩwE��~���Ι
�����{{�{o0��x׏�"���r»q�t�
?�߼�R8荾�w�\+w�����}��8�T�����W��=yU����b'�W�H��K�w�\���^���ݣ3���Ϋ7��C���zʛ��={ӫ�o&�
�
���ó��{

ƽ٢��{�
+zs�ʡ���{�'������^
ߖ�7�����y��<�\�ާ���� oxKWyo妻�Vv��Z�8�6V�ok����9��{�������p��=,�}����j·�
��\.��{�r��Y�N�[�"�Z�/�o�G���Z`yk�����V�^��nߗ����r��XZ>|<l.gΖ�*'��E�|9�*,�r��C������>/�Z�su�PX�_B-_�q������ڥ�[��V|��^����}�r���[�'��!��*�}�/[U_���Η:=:�
乌/{����
�%_�m'���|�zw�W9�g��[�7��m��k_$k��j�ue�l�����|]	=��V����{�Z���Wv��ޕd�_[9�ᕓе�r���Y��l�<D�r+�M��J�丶�x�W����߻5�Y��WoN���p��ϟ�~e��OWw�	������k��㝠?�Fb��������x�W�����%��V˭Uo�(��5*竑�VwUR��V7s��j�
,�W����Փ�F{�����zw�_Z-rui�Ր�W۩���0
�^[�_���F�fM�z� [...]
�����k�Fl����7��7EW6;o� ��l�N�*
+��j��XT���@3�)�A�x9��0��h2�
���np�	��\�Q	�
%��/
�q��[�^��MM^���C��{ߺ�z_�;��⊱~��)��v��u�
�����A��>
�>���
�:X.�R/\5t��j��Onz��r�z;�"�����<�B��tc;ܹ�H�3���r߷q��7�/bz�Uj\��ۅF8��
���p<
?}�7���� �_
�O�E-<|��"���IDY-5#�Zz�
_�#W��H��� �<j7��G�v4|qQ�j�
M��g�1zwy�D��﹧ķ9������b�;�|��k�+��2׆~y�a �����`���k�a�;�/;����d�o��{=.;k!a��n
+�ɧ[�f=�/�X�
+�YߚL�ۢ"_Ĥ�r)��đ����ķ�&-_�qK~):H���muU:�
-K7�+ɸ]�K}q�/��Y�V���d�/_Fςr9����몲���S4��@�$�y�p�VJ�@Sy�oW��IQ�`%�l���F��j��YW��-'g����AW;N&$�nw�T���t�YL��8�'V���y����+�ߵ�������ff�
4ko�֨u7녝Ԓk��ْ����Tj��UH=f�*�Gk[�"w��|�v,�V���ʇ�E�!��^�{�	��&wv�+���b���|�r��=��ݍ����N��{z�~��|w��ۭwW���dco����w��������^�[�cѳ�h,��k�|��UZ�n���؈���z<]�}�_�^W�ok�Zbm���χ��q��%���D�W-����u1����`p�����R+7�JJ=;��"���u-�꾜�����z:��ӗ�x��޺ͬ]��3[њ�95���٠���
���a�i�0x
+��?��'��`�ӏ��\�qpSK�
�֛������x0�vxy_N
������P8=�5|��|��xT�2v�g��㝻��c�t���A6��n�;�Bbɟͯ�׳����� �:٭'�'�˺p������i\Iߟ^˾����C�,r��:K=q����p��=�X�	��/w��0�=������\�t�����^
)��@4�]�o�ŕݻh�^
���e~?zQ�?����C����
���Y�uP-]���|�����˻|���W�j\�O;��Im�䪺�~�&�Ғ�:�Z������׽�n�F9x|�9
�n^'���ˊz�z�,�>�
ڝ�X��mֲ{w����]+
����������t_y*�>w�އ��~��P��>z#�K�ǭ�����y>��)4�'����μwէ��~�
��L?x��|S
����K��7^�����a顸��.��r���0w^ں��JW��\��^�(k���%9���˝��bE�x}����^�uu4�#N6r;w	��ܺ�������Ͱڨ��WQ_��ϯ�~�[��[�\�uUk6z���ܪ�_n��ۧY�>ߔ\��-�j�u_w�j�ҸJ��F��[ln�ϵ��7Z�7��Vl;�j=	���Z at _k����v9��t6�Ƞst ^wj����������K��
-�ߵ�]���������<^�����~�_���][
�cN� �IQ����+x�
(�#G��}+A~���� [...]
]F�
�+`����Y�!��M�oآ1�2͞a�)w���[g�0<�^�x-:��S��)���D��U���zZO�� �����U*�n�ڙ0����������Ρm�i5_{c{�v�������
�8b���
+Ơ�fm+��L����"M�UkŊ�3����t�6{)�
LU�v�ۮU��m�����s���=�t��İ�QS�lb�
��]�^��=�ꎌz:�#��R�7oq�^ϕn탪h$�����z�f2���u0C�	W�*�"��,�y�>h����?�_0c��_����)V�[I��1�x�R����^%��f��m�zs������87��@�~�ܞGXY�n�l
lN'3�Z�iXc��^�9�^?�ԩ�S��5
����k]s�ޓ��uz(�}����^�>*)�
$��
	�0�	'P�%&||�՞pE�~l�g�j��.�b��c�+��#����k�#Hv��y��C�T��fW�}�j� �9�9�*�2�@�*���T$��>w���M��P��j<‘d]�_�ŏxm~U�}T��D�>s�n�af��\`�*1B�
+s��CS���
m���iV�v+���jf�v�Z���1�.��>b�Fb*��շ4*����U�bt�'����t�N/w�Mw:%��]�W��?b�_l�;�9��T��ژ'ಊ�v��*#lu��9g� �ϧ�P�ӭ
?�����rg��JҬw�W09������V���{�u����|cF����
�-� �&F��&&���ka���=f/��X��c�k��˰R������a-��ꜻ�N�s��)�]族|`�]�hx\�?I��#�8��<�@�z{�tcU�0�*�$ii��R�f6�i�\
l���
�n��]
�ڰUj��9D���\�
�e�8=o�&V\�F�Ư�ۧ�O	[�䏠7��H��S�1w�㞑c%�hY�>
m�Woa��<n�lY��jo�*;nu�U7����m­x.� �0��
+�׌1�����H����4od'�v�\�uZƴ�M�g�t�|6a�^|Ùn�s�O
�����C'ԩ�{O���@�{��;�F�%G�葶�i�>l���R F�nm�� �	6kt�l��>$��9
+
�4]w��
��
/u��h�!���1U�7@֦��Bx�i�m���˽N�8��0z
�ct/����sйp�O�^sH֋�
+�Q�Z����t ϥ
��ߠ����!�&�����L��@��<TN�A�mQ9{W�
 DϿ�*��&J�F����5�7�$�=�y��x���8M�z\�x
��s�y��3l���.��T���.
V�;��?�J`
���/޳6|����
��
���{`$�
+�{�h{���p�����<t�Z�c1�0
:�c�#
�K�I�{��?:CO����`���Ys�x�U}��
tfچ�z
l�lx���]�4�`|5���6lC���ﰝ"c��
�
 
��:U��z�3l7�B��b��.��݅���w��2L�N[5��Qg
V����Ƨ麋0M�-��}��,�����6Jki[���줭N����o�	`t
�u|"H�՚�u~?�W&Tm}\�����p��lLx��a��7�[g^؋`p@�m����
�_����_��������������/��1�o��>j�9l7<��sZ���ږq~^���w�zھ�Y�*�l
��g�D��ߪm���G�F`-Y/F�+��AZ�m�.�wO������I�7,���p��yI�q\?��z��Vb[O����F��
�%l+��Y���׃�ll[2����n9���Nt���Bj*��T����DŽtވ�:�>�Ϡ�U|�LJZ�N�5׮���*wT��؊�Wի���x!��ݩ���cl��y�m�#�Pj�?��+�%?+�;%U}�V�	�f���
�5����j��g�c�{k׬
r?���ԁ_���G�M����x>�k�1�+�%����e�<��I�[�q��J�n���e&i
�w��|��r���_�P�����y.ZT{������Q%��﭅{��a<�_}��c[G5qɯl]=����Z+�s�U[;�_�M�n��:�_��5C���f=-���';��h����m�K
n����܇u9�W|�j��ھ��o
+%�#5���Äv�u.ɽr���N��FP	��yU�r���$-n�f���
���'j��,����D�C��m���u��UOn�_Xc­p�{Åvw�Bj�u�l�zg{��v�D+i�;K�f/P)qd�� ع�J�De�7�z&Pc����)o�x!�JU����bqm%��.ϷRϻ�B�<��V�'� �����[|S�K߼�
m1�
Aӧ�Ә֌�����t��	���]��5[!lyɟ~�CW	��(��j�����
��&�{
+,��F(�џ�A9:q7�-8��Ŧ��[��a �j�	�Hބ���:kgW)ub[��r�p4N�rl%]p����Ųб�H=>��nd��`��\ܥK��z���68#��e���Fv?�|��m�_2�S�#��7���>[P-��:��=%N2����ǥJ&Yi������s�
�;w���ogl
K~�q��o�
��|��l���ugr�����kc��].�zhK:
���a�SM��u�e�>'}�ά������ ��Ih��������o�����s�Ͽ
����@�5P];P⅓�k�pX̤��%�v�K?���7:�BfUټ�5��r�}��6H�����Z���Z���]w�;/
 �[�ԋ�z$~|�o/�]$�z�
+��g��{�a뫩j|�i�\d2�Ao��4�m���Kco�����N��z
��~'�Q(� ϯac߬�vw�ޚ�X��
+N͋U
+���pf;-�-��u�ͪNb�D��Z�;�S����R�Us'|��2.�zW�Bp�)��'�1��
(��pFis��$���%��7�&��c�b�>�G%����}mw�IJk*�
Ψr8u!<�u�Xeh2Vǂ��U+�:�^���&b��w�/��
+�&GC�1�\��8
+N�M��)`�5��BM���<�Sz4!�-�G�I�l�[�ƞJVǠ�~�:�A�'xڽl���,��ܥ]x!Ɩa�?����6M��4
+�
���HM�=�;cX���4���$l��˞��yd861@
���g��8���)�


;���4����%�
�i�0�
mbot4I�[z;֩�.ξsa�Ȫ�:XK��)[e�
a�&

I�\2GjvQP��0_��G���i��fo�ϡ!-�ض���B����b�g�*W�*�7��{z�
���
�Xy�
c���q;��ƒ߿�
0��K6���3σ�zl��yC髛���W\�K*ג�� �Q1`�
��K5�uPX���~���ڔ�u��������
+�����:G��oT���޻��%�l�/���x~p�J������f&����Rqt�/���}�=~�L�P�1���`@E)lt�.aC�*_^�Շ���Qo�eZq���0~|}r�9�Kc�f�L�/�$�m?Dl�!2_w��9�ta�ؘ�^>ǩ�y?���AlN�'��-
+��󕡙�В߭
9�Sc�M�,�z�~N�ߔ�V���v��쾨�E���
;�)�曏NS��fc�&�BY�����pp�up.�v����n����Φ�V�p�E�����
s�A����>4
dΛ���,�bu�ṳrM�,
�T�w
To�I�P%�yy��S��j���	���x����Ø��p,mu�r��^���NgRB��f;�4U�:#\O۫�Y�J�<=��2���E��-�\�퍕车��G��\
�r�:5��?~~��ʤ�녃�UNm
K9.{\�::��A�k��$k������Y�X��q�q�>Wu��&ZZ�
a�뼰
�f��䐉�"��
kh|S���=3I�Խu�����U��ꠠƶ�o�A}�yG�>���+o�.;=!v��i
hvC�@���
�c{���Y?�
+�<��B?���K��˵��H&����0�/\o���&�y��0���M��
K~���Tga
o�,X���؂�Wt[��_NP⫩�d�?ܽ����}L�sͭLJ�B����-.�廚ͺvo"�\#xº�*G�T���6�*(˙v�4
��z*z���fDk��
³on?�cR��
ټ�h��<N���P�P_�ӡu���X�!*)+�w-�y�^ߪ
�^c�7wS�b3�]/-��coo�*Զ�w�5� ��2���V��eI�P|YɇeB�p��t�^5�`t{+�g����R�%z�s2�˱�}��k��%�2��o A՗�~��*^��p����ob��>��.����'�
++~���o;ډ�d�A at y��<oբ�
+��-X�W/&�1��VøV�F���
�
����{8����W|){(8M���|N4[\�q��n��ƶ�:?95�
�
�T�����JTe�R)�OV�
�8�n-�4�F��*���8a�
�<;o҂�(����N��
6M�$~Q��O↯����c�Q�Sn���ɫ=[:TL��n������E.!]
����y�yp���^V?x�
L!�\� ڱ�u���^}���ٍ$A
��;M�ԇ�U�"��vp���ؽ�.Eﺣ�7�VX]�g�}�y�_�!��6(�
r���t)�
X�o����x���
A��C�٬i�2�"ˈ���0A|�d�D���
б�FA�m�l�z#�.�U��U�^-�d��YAU�`��Q��3��
+W{���n�����)M����(!�._
�<Hk
���FZ	D
����)��{�)�r�#J`�W�p�;Ml��4��
�Ƿ|�����i%Ui��3
Y ��Y�ա��w^j�k�ڧ��N;o��~�L���~=����ě�e2���
�>
�m�&�����(Մ�|8�櫁�f�b�Z�� P�BT���w��+��M��i� ��
������r������n31n�
k�.e��<�����.��_`�i�f��@�)�jA}�ήb���7[��a+��
N}�T�$��w% .��kLL�I�^4� ��Xt�W�d
�?�m�#���`��}4?@��8��|��H\���#~
X\�V 6n�vf/�lBV
S��׎*�2�;��u��4o��[�\ķ���t
+�k%�����}������*��GX��
+�"tF�r�;IE�j�.��U6:���b��U"֤��-C/_�Gp�ѥ{�nĞ���Xv�	
s��n��	
���E&\=��f<_�V��((˯�ֲ�撔b�wkW:��z������Y.�^
+�
E�[�>��D
F�T2/'~}�p��};�d}ӗے)4�-�K����
+�׏����r�Zu1h
�\����
�t�un?֘k�M�J��`�
D��S�#�|��dV�]#!
�逦��ɩJ+�������\,uX9���

�
�s�x��"�(=X=�Z=
A�^��$XS���*�w���g���&�G�wx��=�̹��R.l�>����'��8&ڇ�wnT�1.������5�9�R�ծO
v2��Ht�����+�F]�|
+��<(4�.b�-�@ ���ZG篏�qm�?@���7�~�f9u|���2����#��E]��x�*����E��ouP�2σ�p&�fF��(��X�AXs,\Ӡ����;��.�שWy�>F�l�e�,�K3:e.I��b�OG�����{&��u7O��ΨiPQ�y�"UN��z��n�i#}W=L��I���
�� o*Z����l�rwj�� �I
�t,y�Z8�i�O�����v�P�Z|�*����f���	9��
�l�^]��|_�P6aw��d_���`í2#�k����c�}Eh9�Y�އ:@l�}�(U�1.`��
��>w_�F��g���1�;@����;?��gH��{��dYG��� �i[��U��S/72~> z���F��[��3`���r�^�K�����X�v�!��{m�������گMR���:\�F�O�㻠�>� �����'��@,����V�y�jsl.v;�tg�m���|�e���[��@Wُw��Q��8K=�o}��j� l
�N������ ��d���������t�I
�|����`%].mTЋ�Z�3K[˫���(�m�X����Sx/$�g�:+�aG��x'nd���V�@|+��x�Pۇ>���(���oƢVc@/r��m��(��ܮ�;RĻ�_M�smW�+��u�z�9�|��_��Z/����p�ػ�M����Aܿ,���ϋ#ܾ٘|N"��I��-�V��˭��]z�1� [...]
�l �
��K���7E�Ź��^l�{�A��Ɓ�b��u�k�B;J��k��pt
.oX
?y7�L�*G"�W�>�o�*4�"bV���U̹wNc ��r/G{8B��CRF/1L�N�� �{���T#��K~�`�N
�[��������W�'�l{>�\���=��@�@ .�s�?��S��{m�����t�f#�����䛚�F5�"ڋ`�
�
�!�cY}i޻��ǫ��q���rɬ��џ�)
����04%�wNw���_xw�F�kZ�C"�m#�*�Yo�~��<���T�T����(?���YU��Bغ���'Y�]���'��ީ��3�?@�/	�ly?���4�a7�թ8�t�ٌ����%,��ln5\>k�T��
('>�#�
�6|�
2��!������ Y3�4q�~.�:}Z>���S,
+�E��N��(c��*}C�u��2��Q�.�ry|�[�=�
��.7O1O`깸7�4|�t�f�<:���%p�.�n���jT�}�NW�����͝uJ5^�[F����[Í��
̍fT��
v�n�
�����������ŝ�9��5��.��o�S:T��ջz�|�]�A�A��r�:6�j:E���.Z'�\��&{T�Ȭ���c�
wګ�����S��\WG�Jì�V���o�;傣p�k��t�z�R>*݄&F�R�L�`�i��sy�̙t:z�-H0��ac��~Ư/
;mF6=�N���R_�)�=vǗ�ř:
���*�J�S�ij�����NG�e��s1�m������m������
��V�ϣ�a���廦S܋�m�s\-�tz�.��q���}g6��
;�
�7�k�uR1�J]��i�N�G����,-w��*���ҿ�����Y�
�z��L:-]��Ǜ���\o�Ӑi��qy}c��=G=�r� u��~
k�!�Nֱs�N��¾�Y�
t�����s헂˻�j�i�#�4�4�r��.���p�.&w{�..77w
t�]��Q.���
�N�Km�O�
���g&��4�����S��0�B���4�\��
A�Q=y����G�괴�����
�i1PȆz���F��w��Ξ�I� �k�O�Ӹ���h���@�66�N�#��B���z��A��;Ɲ��A������*1�Ü�����p�>o�N��N�X.�ӟA��
��u�V��Ѡ{b��f�>�����S��O�z�:;2�5ڃF��xj�Y��$S

���a�m����5��g��?�&���i�p�2���s��7�s��^
;l�s�������
�'6&�&ǽRa��|*����r�M]G
�����@��>��)�vR�I��;���
&����7%�O+���b�i+2�&���+vZn|�l��׽���ո
6�t��ͮ��Si�z����y��ף�3Qv6��!t'�n���?đEzh��d��#����a��>�ύ?}�
���C��ޜϮ�^����e~|Ζ��4�������P���V.�����_�?/,��
�d��iy>0����j4t�hR7e�K�t
�t��H���t\�#�ٕ;p���3�0���'d�
隿�h4�%ܟ�s�4��G��p�<���˱,��
���� ����Y\M����?�E[�s�p������9�2��;����n��
6
���b=ǤS$�"=g��ǔs�F��6�	�NAϑ:e�N���n��/ε��^�e�ܥG���
E�3��H�K�
+y��,0H�
�N��ȼ���+eԩ�%a��h�x�A���u:��IeU�z�X�0�d����F�:uyŹ�}�]�#H^���W�F�63����暻o���~�M��r3��*��YeM\A4f�H at a�A�� õ�ˆ++��f���iD�S�ڲ��}έ�ȅJ�/�����U�QL.*h����"0�Ғ&�}%�6�y�ϑ�AHفH �h�j�/��|�UY��+�^�De��\���_>���_�+B^�
�������
)�R,���hȃ3��}ބ4Cry
�2
�0��l����Ъ�/yw��"������\(�j���N�z~p��4'Ú����S����
+��i��I�?�\�z����y�#�O���-�Ec�$���%8�ԋ�o��d�犟
>Y����om���u�k�]�/NW~�"�
�M)dD|�3��hIO���Pv �ތ�R�~7
�t�aՔ�`����	B������k��ԍ����S�MukW-�cB�Mne�tj�'��n95腟����R��;d6j>�f\L>�OA��1mEj6A<!����b��.]C�9��g1�ZVWnS�y��Y�W:Z��l�֌K�K�F��a��L�Tcw�3�u 'O�_�
v��ފ�O��o���z��#����){h��J�/PAl�6�ɓ�Sڴ���o8�W�ό�O�?�r�91�d�0��̷	t�xT[�~=XZ�ZR�ӄei�$=c���;k����-E�؏L�����.ғ���O�֋��)sh�+���t���#�!��;��O�Y�H7��	���Y�N�#����ĪMI2���f�I�t\��fј��A6.�h��̓N�H��zŤ��NJ�)��I
+v-��T���Zqm�U��"

�Y��L�Jӱ��x�lcY����w���-�aS�8P�y���
�F��HW�\�S��BR��>�&U�vzeD���d(���x��(4q~(vT�d j�
�P��Y�k��
�lХBU�9g:9�%5AF��Ϯx��Bi����:01j�A�m��0F��� 5L�㍆�"Ԏ@�����= 4?�S}�t~���))�V��
��6�,N��$��2�7z_��9ZQ>�H�1��?��
}8r�޸_��t�
^q�ł�J8���R_��Zw�铍��Z��u�D���+[��=�J#��.�J֓C��RL`�=���08�IP��
���VY���|�P���<y�
M�d��Fg��XO�s�0�e/ml}R6_

{��$+��`k���7\M�E�V�6\|Լ�ί��Ѯk��Z��O�\F_^t�lPq"\^��0{�������-�y�ܭf~�Z�$�F�Ł�u4!�E��:;#�%Xtdn'{x�Y5�3! �ѹ��4k�:)�ձ�ee�2��7Ь��������IFDxg�ߣ�svyI���X��x����4�v�+U���
	M�<�x׈X��kێZ��j4x�w��x4:O�܊�렝�҉�_���Q�bcj�#&�1�7/������];�AjB��$v#F�lkx��Z8}L||fB��p)��D�x.�ރ!�6؅�i���wm��%B:한��>͝>��� Ac��
�)]
�z�����v�h����ٝ�
��{��M]g%j�
ą3$�h_TҀb� ��2ՠU�C��M>C�a��~� B��.�f���[E��%��ӚȺ��YԘ�ToMd
|���]�����W������u���0)Q 
+cю� �d41��g�vl$Ai;�7�^$Wzpc�~��`D�
+:v��
�1
/�F�
ˆ�ix!�-M�!j�H}���@�����RE;4����nv1iivw��ƈn��n��{�V${��
��МN�c�n�y!��G4�G���؎�ph�
���h1��F��1�j)e����ʂ�DI,颦82�o�����U��p�V���N��O��[yO�U�M�F�+�p:��/)"\^��aL1%mD��\��i��P�l#״��HKo��$��2�<�S�-4�g�Z�Qq�zo�����d�H��f��N����6X�1��[�*OD\�0V�ҸA
Ǫ*m�
+7�O�]�“rG�>.ׅ3ck�˻
�5�N@
팡�Fй�����;U"��h��0t�:�Se:}�J���팡�F�	9Uv��u*#�Ђ�`�t�û
�5�N���Cg����W�c��d��SK�6�氷���ko�*i��H���^�|K����4@���D��Ȥ&�3�M,9���ә�Xrsߙ�&Ҍt��(VTp���`a�u��2�_��Ȟ��9�NIG:���}!�ڙ�dHZ䣍�bHV�9�ec;&�5���H��E���
+1��
�[���S�
E��L�0���i�A���xwKo��m�"����D쳈X�
T���M೤�q���!XHgm��BD�T'wJ�'�CS����k��  ��AL'
L�T4y{ݾa��.A9<ә��0�7�̚� "'
�ϴ9����`y
��z_8>��bO
g7k�b� �J6ZY
j]<1a�D�B��e
/m
��e<���:�@g���?[
�-&��0���MM
��N�
"��Y8i�8�~��afvY1sW��I�R!8[1��7�Ԇ����E&˾�l���<��ni���7�i���h��W4���v����m��HYg
!PkR=�Pc*�C�M��&�c�E�g̈T���=#�:�9����ˋa�JcH��t1��&�J�尒\Z�)O��l�j9�yXMcj9�m��UI�V'�a���la��C
���9"�Z�p ��A������zy�a
��e�������Լ�9v�+d
����p6�\F��bH�3.f��sd�1�Nǰ���Im�)�'+]�֓Y��t$�"�9Ԝ��M,2<��Lm�>ُEn%���j�8���H�ֶ0�],2Z0�s��EF�H���mg�QY�aaH�96�
�6I��L%Q��p��s�}�8������X
����F�tL�0��:��u䬋������$��ˢc�9�|�4tA����m˨��:����v�Bb����:�$U�ۋ3�Y�ꡞ��O*z/`
��etf��~�pv�=����킇SFAˈ�
"T
�p[D�n��3���7
ng� 
N��4>pw<�
+�,!�T7gx8��B���s���L���2D��Zn����b&n
�����x�����c"�$�6�%IL�.Jb��?�
^D�0��
UZ��<�ЎFy�n4<�b'Ǫ0�\��x{�6�4���	�J�54p�
�I����=�;'��ʉ�%j��5��_�
5
3�����NpR,�����5
-��
�Cv
��W��
�!����[��۱E�k�i��YCc�3v٦��҂f3
klX�
#S��7�A�������"��o�T�0���#�"���
+�����D��]{@��vl�'2D*yhc��ʦ�"i�� # |	սd6Ax
�P8

s��!��	�'k���P8��s
Cᶰ[n�#�+w��a��
g
�%NaU @�n
�S�����:�o͑�+u��ӌ�jyl���j 8���
$0 Cc�D�[�0ӕ:���В��8�
�"tP~6:��mك�x�	O��9���<{܍�|�8�㬪�z�{I�nח���ҭ/���U퓮V�'7���ɥ
��_^���I�y���6����/
�xv�ͽ
+{��Jv��X,5 ��]
]�Δ�+���ލ��nCS��r���7
؍
+��t�<�.�f`7�݂5�+�<�
�v�oOc�fX��a���%E�j�ʟ�ɥ^�`7(q�e������$f�)��
��t�<�r�ړ9�nlv�$�;m��u*�����O'f�

,a�sm�i�>h�,�[��@|%`�6�|\��&�c������K}?��e����u]f�h�#N+�J
�>�f�U��{ې[M�|��b����
8YA{���2C�Y�/�:jse>��M<)!�oes崒�ѐ��}T�#��钞m�N�2�'��#,"g0$+��E�l槪�F�k7$�ZċN�P�R۾~
� �u�|�pW��-�����a�E��E�Ǻv�vG����F�����74�^��[��5��{@�a�Զ�}�錚"��v��sʑ�C�lgVl�h:S��^�tFX:�؞-�tF��Yl��h:m�.`���*8G�	7|>�}�錰t�l��C�d6�'��H8U[z���3�?�
�'4���Nh:��x��>�t+�4��n��
mVl[4�1�j�h:#,�J� [...]
+`1P[j@\_���Os����k�5>co��
�t�{�:yH��Ŏ��Χ�+j�N��m��I^%>�M X�
��ڨ��l7(qHĤ��Eu�-ϓ~H㥣,g�d]}VOa,5'��}HAa
|��'j�`fMb�;�G4�}�;��x�2w��r$�a�e��W��
�7�O���jB�2w�Uf,aJN�ܙ[O�;��Ѭ
�y�)t�s�;K���-�G�s&�s���
gQ̞�_�C��Բ���<�Q,��|�< �#��cYLP�<Z�ɀtb�x% 
̓8��I��s�t� �A)
 �F��Dg��NUل�\-�SA>�r�P�����t��,���/�m4�^vn�"
�؊���]�����VLi�)lمs��Հ�k
R����\�<+ 4V]o)��bk
)x��R~�C�KiZ��*�IkA-��g^��P7��
l)��*��!jj
�	�
�w��N��A���\h�v�Y���V�v��s��X�Ro;+58]���Y�*\R ��d��O���A��Z�
��
+w
+�Ү�ТӺ��U�3D>�D����N�򈯏M����9k{�%�W�s�Cv�pgX�UQ�N�9��H��C�
+Q�h;@�.\cۼ��ؘ 
ˋ9�I6�N�6&�\�|�����:YY�+���Yr���
��Њ>��H�o�</�1�I!'k�lK|��#�K0jp
��\C5>���cF0&+H�xi�ka
<9�I��S��|_�{
���s�0&�3�ݝ� �tb�Z�fxmN�
��А��
+��k�j,�
���}�&"�ld]�QCBX���4S�y�G3y��Q��SS��DE"�k5��
�
���p�\0�-�{�G(��by�g{�6���A=[���R��8jԟ3�W��"��!zW�Ԩv�]�n�K�+˭��I�{�V+��q^.D
��RO�.i�
_w�x�c�
FN)l*��y�Ly�Tx�p�o�K�����_M�@a��9�ouؘ�M;�W�s�N�G#�<cj�ؓE��hFѩ�[6��:�iX���us&ؿÀ)4m�y��Ax��ܷ23��gZ]fzg�����
U����Օi����mf���
+�w>TQK-
�w�4�4�R/�vz��S�'.
 �NzV�����|�+�D-r�3�{��&
�N��66_��O�v�QT�U�dX�]����ƏY�滚Q(����
���|HF�}4(G�0��&Q�ݹ2�]�.�M���ƒt�7A#�:Y��9
�� ����F��Eh�N����
NG�öqGqZVC2;�.��E��zb4$�LG ���r0$!J˰jF��>6VM�b�:��(�0�e��Ly�;w_�q��q;����k��@~���˃�v��}
0�����=�vY��ٲ�ǎ���0��x1[�3��"��i�F�̯5;9�Zϙ��L��~td�l�
���ݰ����>�xK�
+$!3Ovem�WLmU�3C���Y���&>kZ0Gg@��Z�K�:ρ.��n+��x�5V?$����M�
H��!i̝0$Y
sT�{('��̡�{�S�����~��
1?j�Oޘַn=.�+��-��d�l���O�����v�8��tpas�0���ۢ I1��yHL�pRQ�H{%G�b ���-��@|��F�b ɫ���	P��m�5
+�H��1]
�c�
�@�@|��Fj�df+Q �t����v(�GP�mE��L�N�E�d��?Y�Ϭ"�~��Yб=�s����TQ>Y��'���T��SQ>���;�S
	pI]��dP�4�>YYW��>7�������ɵ'T ���ʲ�q��M]?�8�]��I�;Ce�Yn(�~�V!�&�u]?�����ӷ��gz��]#�v��g-��F9��g�䢽66%gu��w�Ehе��g=5�~�u�
+�U�
T ���g=!%ۥ��b�����T�OwqUg�D��#S�>c{��g#T��
�f[��4A]?kUW%)�P�O�ں�~[����}��~&�,o�z|D1S�E;{ �K��
��)
*��~XG�C]?�W�S�!پ���+������S�i
D9�b��~����G]?�~�{�~֎.c���~{���k=>2�m=���x����Q��Z�'Es�����
̣m���g"�
U���淭맋YVU���F
�!�b~
	��Y���(����,��9�ǷU���
�
�������
�Ҧ��u�
��S7�Ϩ�]]�0�0��g�|$��g��%G��"�h���u���%k�[gm������笮�uU�=��#���k]?��+��~*��3̓�������k(��S����gc�'��gޥ�b;���t�����S��֚c���뷅�r��~$z��u�–U��G���
]�����
�=����Yq��
+沏�~˪~�<�c]?S%
���ѵ���٭�~��YW�3@�nU�Ϛ9�8���g�
�\
$X
{�rC���ISٴ�z2�qٰ+�J�Ss���հE�I
۰�ҧ���o��
f� �	����ح�D��7.�;����n�#~��Z.�U�
z]�ǣެ��9M����
��L��y:*�yn��u�]n\�G�ɬ����������o�h��7N}κ�.o���֙_f2�����%��\���
������
���p�c�����s/��mi��^��%�q���^��
�v���i�����R3�Om�,f���=4O�L���=s%�A
T��A5�~{T��{[.ߋ����_�#�)L�- -
�p>ݻ�-qc�U�N���ד#*ޟ��-�¾`|ia���6��F���K@�u���
�����˷��oY�I��7�N��5���)�	���3O:�U�]6O�O��<��&�8m�}=���>б7V��vԽ|���1��R[%���>O�/�m�	��Z��&s�:S�����7��k`nC�p���+u�UB�^W�r+��
g�b#㹘UN�Zx�Le��g��+4o�_	�k�h��t�1{\}��i؜����������(3n�"T|�
�(�1���'[

ư�F��G~�
Q�ďh�J��1Ə�2_���RT������
?5�����Xz-��%w'�_[����5
��@
�P�����(gP(E�p�X� ~Ԉ�1�nv���#��� [...]
+�>�p� K=>��
(���_0�A򏫨�),�r�K��"jY�����g�/�Z���}J�
+XU��4^�
+l5����"��[<��+���g�|�M��/7����쌂Y��QyB:�c��6~��6��)����z��z7�&����W����h�
+�=}�+Z`�̛~��s1��㛨羁|�
+-�������_�R�+�ic���wq4���ڧG���	q.�6�
+z��u�G2��R���(		bt�3����G�9���x M\��������& �h�����+�q�9o<]���p:�h�O��j�oA-E�>�KK�@O�����
�8��n$��ܞZ�^� .��W��Nܑ�E>B�ev掜[�����\J�ch�Ё��x�(����|!���?��D���ޢ@\)�(��'<
�O�p�[|SA�X����bjѻ0�������(���j
4�!�+
�&�/M4��u�M��|.X�D3�|\ 	���������b�|�wJ]hǩĴ�SP*D2����/��ҧ%���S
~��" zaaך4��gU�|b���fL ��2zJq��f���YO�,��9`�dIP���O]^I|;6� ��-��o��g=Y:���P��͎��h���/cY@\Y�Š��	#���2��v���s�MJ���sE��
u�9�P�l5�~6k�������Uf�s����%���	"%��1��+�n�����G�	~=
 [...]
+
�=�V��܌�^�=Uz�8�`K���W>O'��]���E�b}�d��a��E�y:���9„ܝ3!R�@����E�^�=�2
5��+����<65[���L���+��1�
�
sM��#\�~NV
B�$w���Ǡ����h_������Uj��;�]��^M9���� _ɩ���W��fz���"�'��U@�-s�8��=w~��b
Z�@�}x7:S6��mh`�w�8V�o�R��#�S�P9����	~WR��h�^)�lA��_Hx��0
肄$)�0c��c
��FYZV�B���k?�4�y����.
+tRB)��v�
¾`�kЃ�
�G#uZ���/C�o���YVFw��NS��=һ��6)
 ��۸e��ͭ�|�B��>�#y4J�
���%(�aU��'q	�8�`�E��|j���"�V��"��E:����%Ф��K��.[:�E���EȮ�%:u+�D�h.�E�c���;�"�
b��s����q��)e�a6�r���f��ϫ�����s�Q2m at A�A�,�LO��Y��ua
ƀ�>�4����4\��[t�i�f7�n�{!�J�i���͙���n(� Y	܄��F�Or1��#6�j��W�b
V�	laŨV�r*�v�Q�7�Y���=h6G���gLIu�=cr�]�3��Ϙr%�<cʕت	�79 @-�M莩�n����m�D�h
P.�i[�_E�}Gs�j7��n��xy
8˙n��_��v�I�Yɧ!_.�i�1�4�+hF���@đ�������zT7��~*8rH>��+a=S>���+R��e��\Z���$��!�2�ۊLJu�D~D�`������`�QFtKY�x��6���;�6}*/��jR�/���.��
�� +d��s .��!-(oD�8�z���0���h����S:\HO��t�Q>��a+2Z�|k�,䧵b�����[ڷJ&��}xmi�>B��'��L�
+��G6��Xّ	k|��ա�h����"2oÓ��J���6%(ʕY
�
[I����8�F78c���1�n�s`L
8�����p�m�y�mB
�[�% W��>ņJ���h�L� �|}D
T��/�Bj�s�Af����b<�!����`�zA��\F
/
ly�~F������(���r�
0E�)l�C�H��DT����ڣ� =�^�V��Ex-R/�PmD.���ri��!S�2\�|��	�d=���zesl�鶍�R~��B8:
+q���^в2A��5*������f�X�~n{���q�@��d�0�l=c}!����;aj�<
Ւ�^�`��W>�^���hΟO�t
WS��6ϕқ��I
�����(��wɚ�JY�е
�q�w�MO�t
m� n�wo5��Q�
��t�ϟ���n�����d=�!�:>��̧�c����&b���~?}��(*��D��[&y�����Q�lk⎌gW���ۗ�'ܾ¦���b�T��(�qi
��hH���D5�}j�7���J�2I�����\�/�:�P=(�_��f�ׂ'�O��=ޕ��
�ޤ��Kj�d%�ۅx�&��r�Yj��-���Յd��� B=u��x��}Q} f��+
�#�2�n����t�W�F7��*#x�x� ~O�I�x��yץ���[k��������u�	������S
��I���
�:�b��Z�j����Xb�d
#݆5�>�I�5���J/H�%2��$����J}/_b��>
��ЙoDX�����&]�SM���T��d�G�����T�( WE��㇥#o�
+r_]@��"��j�)��"��[�\&�`�Wx����t.�(Sg�A(
�t,�4�;�4R�
��řH�s)�Q�a9l�ۏH��Q�B��"
�Q�4�$��3�&��H#�1I��GD��+��D��g̈|�E���<��y��2���"�ѱ��
n�
��#�R��X'{WG��Շ��c�m$u��
��
�T�I������~s���I�•�����b�D��G4��E����N��o���n�L?ߵ:�����{
����ݓM
�~~��.kIX6$ ��W����G����sw�>,/���>���]x�@]LM>�RpBDu7��ʾQ;֭(�`+d�v
ZQR(܆sU��s{Q��	N��G
SD,��8f4�D����F0-�D4jl
�F���AI4�2� �ׇ9��U��E�����x�D��*�
�T]9)8�J ��
�4?*���_z�_�g|)m����u�'k�x'��j
�C���K#
�r��$8�#��i(~k1�A�=����
	�1~
H�
+js��@�Vt�B4�
�`_�,��od��.�j �
����M�(��T7��!{]D��ܾ-����LG��5�"o�2
����Ҭ�yQ�^�ݜB��ݴ�t+ƞ��|rt�䯂 �J���@��)���ų��o,
䓁�R�E�ny�
Z�T�%U�
*��8ʒ��T�T�0q� ����K$,f�ͧ0����)���.�~�
���s �E�Z�F�9x�t$;i �~&8�WNI�bcVf7jv;�X�:Sw'���!���Y�ARt^�,�\����n��k�*S+~�!n�?�ⴽ	tv�[��'p6��,��i�lu�R}�):�
�n��ɷ;���<@�B�I=�B��=�)
Cs	�"�m<;N�5B|��H�iE��u
0YG�
+䣉u#�������
9
������}�3����
�� ��.�� ��bgSRL�S4�#�o:#R��<���7A�L����4@���4Z�lNG �n[H!�ty�*R��P�Ĕ ����s`��)C��^
'P�m\^�?�����M��{)�=W_>L���jj�ޫt+O=_�9�&~��T���4�
+�F�۫�E��Y��5�0�����, JiFk݊
��m' ���`�^�^�Y�
[�1�Y'&�0
�:�7��w�Ob
1b�v��	�,E<FF
SyY�����`�P��"Yo�_跄Ɖ�������+�8�v-����N��#^R��&A���2|?��y���@�\�}KEF2�گTD���T���%�R)�
��2��
�`�.�t��~^���:7�"Z�SQ"ƃ(����aK���*
D�ҁ���c[!O�fr��:����W�.84��S�ȿ�:�w�<�e����뀺z�9
b��
ur��W:G7�6�QLj<�����IR
+y�<6��Jܐ�?�#�0g�/c$��Z%�
	_	���I�X���18J�h���μ晇�7�� 
X��k
��?����,��‡��|+�t���M��aj��
S?�5�}� ��d� U,N�`UOI�3��
�i��4���.����I��>'槤�0��)��g�4dk�d@]�#yt5����a���kC��D@|��L��'[^F�Po6ي��

�I:�z7+tFb�
�
:*��P%)K&84��qw,�����rt��F���$�	: �6�:q��Q
+�*k��X�2�f���`�p�7٦;|~�C�7uw���u��c=w��Dj��rG�>��䕅���I�_�&���$���m;q;1Zi�[aBF��E at .�
32]^�m�`�V�r���T�e�GT ��_Qm\�ARĶR�A "��^�o��Q?3!���>U�G�����P
+`���
Tjwb~t�4��
�dT�)�Z"D����
+�o�PfaJ�-@\
[�
cB��@<���P;�'�7BD�¨#�ϓs R:o���:mFX���Z��~Nx[<�*��E�XE�cI��h��� �3@���Jn��RZ�9�ޥ��3���?@~���K�Ǎ[�}�p	��d��79�p�1�
x
O�=c1;o!y�]�NVk���:�
��A�k�&�m�6��gg�[~�9���`�ذ4G�#����$$c�

}�=E�H_.,�`Z^�H ���Y�.!/{]H7Br��1F6bL� ;Xy�,]�Hc422���%@��K�T0R�C\�
��'��ۣ#&�̲�q�
?�8

R�bǤ��Xgr�

(�I(��kOPT]��X�S�AG�� 
E8�MpH
+q��[�
w���h�_�K͝g���҉Kp#�S����%|����/�ρ�$��8��
����U>��(���h�6X�t����r�9�@	�\�u0�HX�b!�(nrp�j!������ )��d:������Gw�^��
�����F; �G�c��"��z�
�_��-��-6|"��FH Dj�ѷ"fm�S,nߎ��
�hg?⫲�ۏЫ����ŏV.�qx�[f_���q��Bw/ozj�������m����a�5���n��܅
]^|��M�1��J
+rUHWe�u1,H��UX/�*e+���[.1�o�hq3
5����-�%��<�q�DSq��x:���t\i-P�z
S+8M;>�5��
+�
,��`��R/����o��1{+�����j���H� va
+
+��iw�F˻
endstream
endobj
147 0 obj
<</Length 4697>>stream
+J�>7U�
c�r�-�ԫl�8�Ď<�,
�Uю֞��6�s�Z����g�w�
X�����^\y]:����qn�"䤒QJ��Lx�Nj�Sf�<v
+)ҙ��|�ԇ+O�lI��^��R�~^�
+_n�N�v�t+E�Nw�;ݫT�ZkQ��1hf%j��&ڗ�K���X_�.���w[V]( ����B�Q�[��>
+�����L���u�U>�C���@�\9���K�z9
���+Nv�+ݳ�V�Z��袊C#�,;�0u��At��|wU�at���TUv�"1�]�#on�r-�Qyz8a��l

dQ��zC>,�h(�v�Y��{f���j���ϭ�pR���n����E�����g+�{��A�y���"����л塗���-�W�#�^�aݢ�G[�ҹɀK�}oigD�97"iLH�
�5�(�A�.�.�Td�T�������8t��d�q�ȱ8L����`o�ܷ��Ւc/�n�N��b断���B�K���n�n��ZO��Vn폖��h	�1��'�,�+�_�GLbu�������W�m���.�bnϮ
U��,ŕ:�
^Q
�W`?�M�?fp��t#���Nc��G��4F1
j�����W6�&�N]��@m���9��蒗-��d�����>ܮ�U��TX�I�ݻ�aΆ}i>f�Ơ�9���	P4�NM��+�ce�:E�O�L�
�4�2N��2�=�.9�r��ﰾ��
�c:��_g���!C�xM	�'��5!'"��Ĩ-�IX��cg�C�
���^ؐ�
K���%�b�
دe#-T����<N�҈m)g-^��(� o��{�]'R�=�d7ᴁ�?�e�_�4�k�Å
�vw��cS#�4�ќE���4LCE�਒p��OQA���#]�j�g�}�i�t��xL7�*�|D�s��$ �Y��w��+�Ɵ�¢��7y��������ʳ�����N�V���
a}5J�/�t���8�Ѕ|D���q
�R��%�RGI
ǂw����4'�O
}٧��:�ɷ�4��j�a�!�ȋV at K���Qy\�W��j�SJ�ߴn:�},H�FI��5A��s���U��Z��",�ˋ
�R��4��{�i�`x�pT���9:w�����UG�1$���v1
bRn!� O���&�k�P��	2Sc<dz_�F �y}-��㟇1Q��^c�ϛ<`E�W��M��
�DVbƏ� �	�����&^ٵ�&mJN
L���:�����NH�
8R�J��;e��-�	V'�|͋�����mZT��Y��B�9�g��sp*�!7Q�D�K�^7.@��}
+�P�_;!����)#(�-�pW��QQބ��z֍���

+4
�`��q�7���OL 
ybAa�F��
:��}�b��?_�o�F_���\m�
��uW�����Ҩ.��<!��-�Y���?7�'��c��R��+VNV���iWN_=Aw#����gَ�%Ļ������	i1�d
���6~%l��T������
��Z�h��8UT@��+IQ����0�x���AQ��+'�!��	N���h���m��
�$7ч�#�%���|^�+�X>�H}���ᴕC����I��P�ׯ,~OT���p���$o�[_���t\
rJ}�1N��l��C���w��Je�T��_l��������� �ʹ��6M~f���|~5��u��y�=�Yd���j��N��Ͽ��A�G㦤�&!)�&�e�vT{�4?[G�I���j�����-�P�
�E���.݁�*�#>k�����#��
+
���ʦ
>��h��c�I�骙wy1��_�
�[��N�q}Y���_Q-U%S#��b��n��xj�;,�������
�h�w[k8a�"����"� P�@��R!T#P̠�+>P�B5��*�(+�d
+֯8�ګ�
�*�W�ܬF���H�w�
aH ¡
����_G�~n�xV��
c0z��	BHLeP���/i�>����Y?΋��=x3�����X[�ԪWaE��׍����J�p�V���(ɠ��d����IȈHڢ�DP%u(��W��,�֛z������G��M8�W
�i���6
ąc?
R�6�^��g�>2�L�A{5�@���z��&������� `���P�?�(��#�`��*�3V�T��4�N��*��-�-��V�Zc���,
��#���jB��f���,���Mb}�
��u���t��Q���R�-�t�f;3-�"nA�zu|�\V�"��R�L����[��#�(�$TBt]�/'��
>���e!�-A�]џ���1
F�KN ���H�JQ��A ��H.�^�>��1�+#jygX�i����*h�`����Df
Թ#[K۠Sw�@�;<�mI
T�] U�W���q�oRAM��� m!�	v�.s
+g�(�b������I|z� �$�rی�U[��s1�8PK�I��i�<����2iNs���x3���3��}q���yFs��yNs�ͱ��aNs��U�œ�a�͉�nF4��(�9�
�4w����u���yF���g47��k���yFs��]N2�����i�<��y}�3�k����4w�ќ_1g9͝g4�W�<����۟1'�M�؎7^��|�3�<����4w������4w~"���9͝g4'δ4��$�)�r���yFs���ڜ�γ�c;�Ü��3�k3��4w��\��۬qFs�#;�i�<�����YFs|�
�47�6I��
�ՁipK� h�L�[y+
�ipKà`�#5
ni�>Ar���A�ח�4��aP�ALd��0�}O��-
��/L�[]�L�[��Of��0sq`�"��FX����&�5$��..��
U��#��q0�@
GgH�>t�օ? Ga�
��PA�F�|�e�_r?����&���7PWq�����#Y
��#Vt�l�  +� ��l X5n
�i�a{�i�'DR�'o{�<��R�.��[է��L� ���֥i�&C�ep�����!�ئ�q�g�����^���|�Y�������;��|��)�/�Meh&}�$�!�v�� ��
<�����u��y���3Y�� 
o
O��v� {�w���;��Pc�m�Q
�c4±�:(����⽕0R�u�%�.�7���{�������\�.�->3q�]�g�>�z���^���E	sA��=���
������u0��/\�+3W� <޸6h%�
�n�E�҉t�F
K�
Ŧ�

+��Ҋ�%��K
'.&E
D�T*�I0Ƀo�9��щt�I�1����-�IP1:���.���Ҭ��u1l:�NSỬ�
V�
�)~��ť8�[�I��
�
�
e����N
zB��F_L)�H)ۯjf�u�������4�:���16�а�=��8�
K�	<@&c���A4͠FR	�T�E�L&c�
���t�Ag��.@�)*�I�|,�*��3:���	|�?w�(��{GQ�&R��7�o��RqP�.
ˤ��jzhE��TM/E���T�K��q
����������p�WWh�t��D
Ng�C���
өL���G��/�oa���c����󕠹X��F�?s�Ħ��A��$��d򀣩�r�:�t2�D��#x&
�R��]:����bU��^��3��h�F������J��C�%

�.y|�.6#�
�Q��s��"o>Z}tS�$1��h�34Zp�cb\"
�L&b�d��K�_m�&��\"or��^}��Cfc4G'2�?x���A��M��3dc�T&��"�D[Es	��$�/�j�(4����
&�49oU]]�
�-{�tAGt/�M`�E�D�d(���.�L1,�.(��;I�@��N7~���J��v],�!:.|̢]Q����^�O�3�>b�	�S��d2�l j 5Ġ/˽0�O�Q�3��8D�e�����KU3WG�6iq�(�H
+��
�
6	�i�`��Y2�ARA��L�ix3���A��Q��a��L1��Y�
Y�A˗fTsd��$���������1�L��A��Ҥ�*�ϰi$&h%h$����h�c�J�OUW�E�^�>�
p%N�
OeK���[xF�
ZI�)<")��/7��"����<�'���W��6��櫚Y*.n������˛�%@]"~��rY�Y̭�]H�1.��	���C���S�o�?zHl2���zz�&� [(��dЉ�=PL��p)Z==m{��� 9�a�q�����
�e8�iV���aŻ��
+�d��@�"��!H���<�NS�%�ߦU-��~�.g�*��e����D�!qJ��Uy
f�� �ʆ��^���*�4��� :�ҩG
��.�V�D��t�SµFmH_���bs�pUsd����c2-\m�
ћ��V�Q����۝��owb�
���
]��߮T"ſ��/��7�z�A��J�ߓ�S	P���Ks�
���P,{�B7�N��6�b����7(�It�$-|�u%SH�e���X����^�O�gt�P
���Ĩ
�Mn�E/��(F��<D�ȏ^lG���KU3W�k�r��'A��f2�K�A�I��I�4��i<U�'�h���%`I��&��M���4��a����RTZ=�
Rȱ�M1C07�
+�b���
z�̐o񿝒ޭ����
�ͣQ��{6y�_-'�_��u5�_����b�@�
�.�+t}�����;�'�׽�z���? �=R
endstream
endobj
7 0 obj
<</Intent 17 0 R/Name(Layer 1)/Type/OCG/Usage 18 0 R>>
endobj
32 0 obj
<</Intent 41 0 R/Name(Layer 1)/Type/OCG/Usage 42 0 R>>
endobj
55 0 obj
<</Intent 64 0 R/Name(Layer 1)/Type/OCG/Usage 65 0 R>>
endobj
79 0 obj
<</Intent 88 0 R/Name(Layer 1)/Type/OCG/Usage 89 0 R>>
endobj
103 0 obj
<</Intent 112 0 R/Name(Layer 1)/Type/OCG/Usage 113 0 R>>
endobj
112 0 obj
[/View/Design]
endobj
113 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>>
endobj
88 0 obj
[/View/Design]
endobj
89 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>>
endobj
64 0 obj
[/View/Design]
endobj
65 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>>
endobj
41 0 obj
[/View/Design]
endobj
42 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>>
endobj
17 0 obj
[/View/Design]
endobj
18 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 15.0)/Subtype/Artwork>>>>
endobj
128 0 obj
[127 0 R]
endobj
148 0 obj
<</CreationDate(D:20120301102419-07'00')/Creator(Adobe Illustrator CS5)/ModDate(D:20120301145415-07'00')/Producer(Adobe PDF library 9.90)/Title(Web)>>
endobj
xref
0 149
0000000004 65535 f
+0000000016 00000 n
+0000000220 00000 n
+0000068361 00000 n
+0000000005 00000 f
+0000000006 00000 f
+0000000008 00000 f
+0000179214 00000 n
+0000000010 00000 f
+0000068412 00000 n
+0000000011 00000 f
+0000000012 00000 f
+0000000013 00000 f
+0000000014 00000 f
+0000000015 00000 f
+0000000016 00000 f
+0000000019 00000 f
+0000180037 00000 n
+0000180068 00000 n
+0000000020 00000 f
+0000000021 00000 f
+0000000022 00000 f
+0000000023 00000 f
+0000000024 00000 f
+0000000025 00000 f
+0000000026 00000 f
+0000000027 00000 f
+0000000028 00000 f
+0000000029 00000 f
+0000000030 00000 f
+0000000031 00000 f
+0000000033 00000 f
+0000179284 00000 n
+0000000034 00000 f
+0000000035 00000 f
+0000000036 00000 f
+0000000037 00000 f
+0000000038 00000 f
+0000000039 00000 f
+0000000040 00000 f
+0000000043 00000 f
+0000179921 00000 n
+0000179952 00000 n
+0000000044 00000 f
+0000000045 00000 f
+0000000046 00000 f
+0000000047 00000 f
+0000000048 00000 f
+0000000049 00000 f
+0000000050 00000 f
+0000000051 00000 f
+0000000052 00000 f
+0000000053 00000 f
+0000000054 00000 f
+0000000056 00000 f
+0000179355 00000 n
+0000000057 00000 f
+0000000058 00000 f
+0000000059 00000 f
+0000000060 00000 f
+0000000061 00000 f
+0000000062 00000 f
+0000000063 00000 f
+0000000066 00000 f
+0000179805 00000 n
+0000179836 00000 n
+0000000067 00000 f
+0000000068 00000 f
+0000000069 00000 f
+0000000070 00000 f
+0000000071 00000 f
+0000000072 00000 f
+0000000073 00000 f
+0000000074 00000 f
+0000000075 00000 f
+0000000076 00000 f
+0000000077 00000 f
+0000000078 00000 f
+0000000080 00000 f
+0000179426 00000 n
+0000000081 00000 f
+0000000082 00000 f
+0000000083 00000 f
+0000000084 00000 f
+0000000085 00000 f
+0000000086 00000 f
+0000000087 00000 f
+0000000090 00000 f
+0000179689 00000 n
+0000179720 00000 n
+0000000091 00000 f
+0000000092 00000 f
+0000000093 00000 f
+0000000094 00000 f
+0000000095 00000 f
+0000000096 00000 f
+0000000097 00000 f
+0000000098 00000 f
+0000000099 00000 f
+0000000100 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000179497 00000 n
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000179571 00000 n
+0000179603 00000 n
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000000000 00000 f
+0000072085 00000 n
+0000072455 00000 n
+0000071893 00000 n
+0000180153 00000 n
+0000068830 00000 n
+0000089902 00000 n
+0000087216 00000 n
+0000087102 00000 n
+0000070101 00000 n
+0000071329 00000 n
+0000071379 00000 n
+0000071967 00000 n
+0000071999 00000 n
+0000077660 00000 n
+0000072807 00000 n
+0000073067 00000 n
+0000077910 00000 n
+0000087253 00000 n
+0000089978 00000 n
+0000090179 00000 n
+0000091176 00000 n
+0000108876 00000 n
+0000174465 00000 n
+0000180180 00000 n
+trailer
<</Size 149/Root 1 0 R/Info 148 0 R/ID[<AD6884C34A9F4A90AA3FD9CB8A6BEF7C><2AFD4605F71B4AE08F15DB57D0784332>]>>
startxref
180348
%%EOF
\ No newline at end of file
diff --git a/licenses/numpydoc.txt b/licenses/numpydoc.txt
new file mode 100644
index 0000000..9329209
--- /dev/null
+++ b/licenses/numpydoc.txt
@@ -0,0 +1 @@
+numpydoc license is at biom-format/doc/sphinxext/numpydoc/LICENSE.txt
diff --git a/licenses/scikit-learn.txt b/licenses/scikit-learn.txt
new file mode 100644
index 0000000..f4cd189
--- /dev/null
+++ b/licenses/scikit-learn.txt
@@ -0,0 +1,35 @@
+------------------------------------------------------------------------------
+    The file doc/_static/copybutton.js has the following license:
+
+New BSD License
+
+Copyright (c) 2007–2014 The scikit-learn developers.
+All rights reserved.
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  a. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+  b. 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.
+  c. Neither the name of the Scikit-learn Developers  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 REGENTS 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.
+
diff --git a/licenses/scipy.txt b/licenses/scipy.txt
new file mode 100644
index 0000000..b72893b
--- /dev/null
+++ b/licenses/scipy.txt
@@ -0,0 +1,31 @@
+Copyright (c) 2001, 2002 Enthought, Inc.
+All rights reserved.
+
+Copyright (c) 2003-2012 SciPy Developers.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  a. Redistributions of source code must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+  b. 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.
+  c. Neither the name of Enthought nor the names of the SciPy Developers
+     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 HOLDERS 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.
+
diff --git a/scripts/biom b/scripts/biom
new file mode 100755
index 0000000..369c0bc
--- /dev/null
+++ b/scripts/biom
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+# __author__ = "Greg Caporaso"
+# __copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+# __credits__ = ["Daniel McDonald",
+#                "Greg Caporaso",
+#                "Jai Ram Rideout"]
+# __license__ = "BSD"
+# __url__ = "http://biom-format.org"
+# __version__ = "2.1.4"
+# __maintainer__ = "Greg Caporaso"
+# __email__ = "gregcaporaso at gmail.com"
+
+exec pyqi --driver-name biom --command-config-module biom.interfaces.optparse.config -- "$@"
diff --git a/scripts/serve-biom b/scripts/serve-biom
new file mode 100644
index 0000000..a4ca323
--- /dev/null
+++ b/scripts/serve-biom
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+exec pyqi serve-html-interface -m biom.interfaces.html.config "$@"
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 72f9d44..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[egg_info]
-tag_svn_revision = 0
-tag_date = 0
-tag_build = 
-
diff --git a/setup.py b/setup.py
index 0734278..f87da11 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 
 # ----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
 #
 # Distributed under the terms of the Modified BSD License.
 #
@@ -10,9 +10,9 @@
 # ----------------------------------------------------------------------------
 
 import os
-import sys
-from setuptools import setup, find_packages
+from setuptools import setup
 from setuptools.extension import Extension
+from glob import glob
 
 try:
     import numpy as np
@@ -35,7 +35,7 @@ __copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
 __credits__ = ["Greg Caporaso", "Daniel McDonald", "Jose Clemente",
                "Jai Ram Rideout", "Jorge Cañardo Alastuey", "Michael Hall"]
 __license__ = "BSD"
-__version__ = "2.1.5"
+__version__ = "2.1.4"
 __maintainer__ = "Daniel McDonald"
 __email__ = "mcdonadt at colorado.edu"
 
@@ -79,13 +79,6 @@ if USE_CYTHON:
     from Cython.Build import cythonize
     extensions = cythonize(extensions)
 
-install_requires = ["click", "numpy >= 1.3.0", "future >= 0.14.3",
-                    "scipy >= 0.13.0"]
-# HACK: for backward-compatibility with QIIME 1.9.x, pyqi must be installed.
-# pyqi is not used anymore in this project.
-if sys.version_info[0] < 3:
-    install_requires.append("pyqi")
-
 setup(name='biom-format',
       version=__version__,
       description='Biological Observation Matrix (BIOM) format',
@@ -97,16 +90,23 @@ setup(name='biom-format',
       maintainer_email=__email__,
       url='http://www.biom-format.org',
       test_suite='nose.collector',
-      packages=find_packages(),
-      include_package_data=True,
+      packages=['biom',
+                'biom/commands',
+                'biom/interfaces',
+                'biom/interfaces/optparse',
+                'biom/interfaces/optparse/config',
+                'biom/interfaces/html',
+                'biom/interfaces/html/config'
+                ],
       ext_modules=extensions,
       include_dirs=[np.get_include()],
-      install_requires=install_requires,
-      extras_require={'test': ["nose >= 0.10.1", "flake8"],
+      scripts=['scripts/biom',
+               'scripts/serve-biom'],
+      install_requires=["numpy >= 1.3.0",
+                        "pyqi == 0.3.2",
+                        "scipy >= 0.13.0"],
+      extras_require={'test': ["nose >= 0.10.1", "pep8", "flake8"],
                       'hdf5': ["h5py >= 2.2.0"]
                       },
-      classifiers=classifiers,
-      entry_points='''
-          [console_scripts]
-          biom=biom.cli:cli
-      ''')
+      classifiers=classifiers
+      )
diff --git a/tests/bench_tables/10000x10000x0.001_bench.biom.gz b/tests/bench_tables/10000x10000x0.001_bench.biom.gz
new file mode 100644
index 0000000..3a7f69d
Binary files /dev/null and b/tests/bench_tables/10000x10000x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x10000x0.001_bench_hdf5.biom.gz b/tests/bench_tables/10000x10000x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..678a9f6
Binary files /dev/null and b/tests/bench_tables/10000x10000x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x10000x0.010_bench.biom.gz b/tests/bench_tables/10000x10000x0.010_bench.biom.gz
new file mode 100644
index 0000000..f0d3c4c
Binary files /dev/null and b/tests/bench_tables/10000x10000x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x10000x0.010_bench_hdf5.biom.gz b/tests/bench_tables/10000x10000x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..3ed25c5
Binary files /dev/null and b/tests/bench_tables/10000x10000x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x10000x0.100_bench.biom.gz b/tests/bench_tables/10000x10000x0.100_bench.biom.gz
new file mode 100644
index 0000000..5072121
Binary files /dev/null and b/tests/bench_tables/10000x10000x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x10000x0.100_bench_hdf5.biom.gz b/tests/bench_tables/10000x10000x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..9503bd0
Binary files /dev/null and b/tests/bench_tables/10000x10000x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x1000x0.001_bench.biom.gz b/tests/bench_tables/10000x1000x0.001_bench.biom.gz
new file mode 100644
index 0000000..258d14f
Binary files /dev/null and b/tests/bench_tables/10000x1000x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x1000x0.001_bench_hdf5.biom.gz b/tests/bench_tables/10000x1000x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..040b0e6
Binary files /dev/null and b/tests/bench_tables/10000x1000x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x1000x0.010_bench.biom.gz b/tests/bench_tables/10000x1000x0.010_bench.biom.gz
new file mode 100644
index 0000000..9fe9315
Binary files /dev/null and b/tests/bench_tables/10000x1000x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x1000x0.010_bench_hdf5.biom.gz b/tests/bench_tables/10000x1000x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..d38b5d9
Binary files /dev/null and b/tests/bench_tables/10000x1000x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x1000x0.100_bench.biom.gz b/tests/bench_tables/10000x1000x0.100_bench.biom.gz
new file mode 100644
index 0000000..34f1ba0
Binary files /dev/null and b/tests/bench_tables/10000x1000x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x1000x0.100_bench_hdf5.biom.gz b/tests/bench_tables/10000x1000x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..05e1057
Binary files /dev/null and b/tests/bench_tables/10000x1000x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x100x0.001_bench.biom.gz b/tests/bench_tables/10000x100x0.001_bench.biom.gz
new file mode 100644
index 0000000..f820b48
Binary files /dev/null and b/tests/bench_tables/10000x100x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x100x0.001_bench_hdf5.biom.gz b/tests/bench_tables/10000x100x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..c305e14
Binary files /dev/null and b/tests/bench_tables/10000x100x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x100x0.010_bench.biom.gz b/tests/bench_tables/10000x100x0.010_bench.biom.gz
new file mode 100644
index 0000000..577b001
Binary files /dev/null and b/tests/bench_tables/10000x100x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x100x0.010_bench_hdf5.biom.gz b/tests/bench_tables/10000x100x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..9c936a9
Binary files /dev/null and b/tests/bench_tables/10000x100x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x100x0.100_bench.biom.gz b/tests/bench_tables/10000x100x0.100_bench.biom.gz
new file mode 100644
index 0000000..96db890
Binary files /dev/null and b/tests/bench_tables/10000x100x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x100x0.100_bench_hdf5.biom.gz b/tests/bench_tables/10000x100x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..9927cec
Binary files /dev/null and b/tests/bench_tables/10000x100x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x10x0.001_bench.biom.gz b/tests/bench_tables/10000x10x0.001_bench.biom.gz
new file mode 100644
index 0000000..7b43e38
Binary files /dev/null and b/tests/bench_tables/10000x10x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x10x0.001_bench_hdf5.biom.gz b/tests/bench_tables/10000x10x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..cc93c66
Binary files /dev/null and b/tests/bench_tables/10000x10x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x10x0.010_bench.biom.gz b/tests/bench_tables/10000x10x0.010_bench.biom.gz
new file mode 100644
index 0000000..39db347
Binary files /dev/null and b/tests/bench_tables/10000x10x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x10x0.010_bench_hdf5.biom.gz b/tests/bench_tables/10000x10x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..917c3b9
Binary files /dev/null and b/tests/bench_tables/10000x10x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10000x10x0.100_bench.biom.gz b/tests/bench_tables/10000x10x0.100_bench.biom.gz
new file mode 100644
index 0000000..c26c089
Binary files /dev/null and b/tests/bench_tables/10000x10x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/10000x10x0.100_bench_hdf5.biom.gz b/tests/bench_tables/10000x10x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..4bcc8b4
Binary files /dev/null and b/tests/bench_tables/10000x10x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x10000x0.001_bench.biom.gz b/tests/bench_tables/1000x10000x0.001_bench.biom.gz
new file mode 100644
index 0000000..c3e57cc
Binary files /dev/null and b/tests/bench_tables/1000x10000x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x10000x0.001_bench_hdf5.biom.gz b/tests/bench_tables/1000x10000x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..9445a34
Binary files /dev/null and b/tests/bench_tables/1000x10000x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x10000x0.010_bench.biom.gz b/tests/bench_tables/1000x10000x0.010_bench.biom.gz
new file mode 100644
index 0000000..7dccbcf
Binary files /dev/null and b/tests/bench_tables/1000x10000x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x10000x0.010_bench_hdf5.biom.gz b/tests/bench_tables/1000x10000x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..b1a4528
Binary files /dev/null and b/tests/bench_tables/1000x10000x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x10000x0.100_bench.biom.gz b/tests/bench_tables/1000x10000x0.100_bench.biom.gz
new file mode 100644
index 0000000..c96c75d
Binary files /dev/null and b/tests/bench_tables/1000x10000x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x10000x0.100_bench_hdf5.biom.gz b/tests/bench_tables/1000x10000x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..6fd3f08
Binary files /dev/null and b/tests/bench_tables/1000x10000x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x1000x0.001_bench.biom.gz b/tests/bench_tables/1000x1000x0.001_bench.biom.gz
new file mode 100644
index 0000000..f5bb429
Binary files /dev/null and b/tests/bench_tables/1000x1000x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x1000x0.001_bench_hdf5.biom.gz b/tests/bench_tables/1000x1000x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..6024a2f
Binary files /dev/null and b/tests/bench_tables/1000x1000x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x1000x0.010_bench.biom.gz b/tests/bench_tables/1000x1000x0.010_bench.biom.gz
new file mode 100644
index 0000000..343fa94
Binary files /dev/null and b/tests/bench_tables/1000x1000x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x1000x0.010_bench_hdf5.biom.gz b/tests/bench_tables/1000x1000x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..f76c530
Binary files /dev/null and b/tests/bench_tables/1000x1000x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x1000x0.100_bench.biom.gz b/tests/bench_tables/1000x1000x0.100_bench.biom.gz
new file mode 100644
index 0000000..0af2c79
Binary files /dev/null and b/tests/bench_tables/1000x1000x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x1000x0.100_bench_hdf5.biom.gz b/tests/bench_tables/1000x1000x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..a003a62
Binary files /dev/null and b/tests/bench_tables/1000x1000x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x100x0.001_bench.biom.gz b/tests/bench_tables/1000x100x0.001_bench.biom.gz
new file mode 100644
index 0000000..d12ba7a
Binary files /dev/null and b/tests/bench_tables/1000x100x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x100x0.001_bench_hdf5.biom.gz b/tests/bench_tables/1000x100x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..f1ccff0
Binary files /dev/null and b/tests/bench_tables/1000x100x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x100x0.010_bench.biom.gz b/tests/bench_tables/1000x100x0.010_bench.biom.gz
new file mode 100644
index 0000000..e6dd35c
Binary files /dev/null and b/tests/bench_tables/1000x100x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x100x0.010_bench_hdf5.biom.gz b/tests/bench_tables/1000x100x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..c356643
Binary files /dev/null and b/tests/bench_tables/1000x100x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x100x0.100_bench.biom.gz b/tests/bench_tables/1000x100x0.100_bench.biom.gz
new file mode 100644
index 0000000..598bc35
Binary files /dev/null and b/tests/bench_tables/1000x100x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x100x0.100_bench_hdf5.biom.gz b/tests/bench_tables/1000x100x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..929dc3f
Binary files /dev/null and b/tests/bench_tables/1000x100x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x10x0.001_bench.biom.gz b/tests/bench_tables/1000x10x0.001_bench.biom.gz
new file mode 100644
index 0000000..cd3f4ba
Binary files /dev/null and b/tests/bench_tables/1000x10x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x10x0.001_bench_hdf5.biom.gz b/tests/bench_tables/1000x10x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..bfc8115
Binary files /dev/null and b/tests/bench_tables/1000x10x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x10x0.010_bench.biom.gz b/tests/bench_tables/1000x10x0.010_bench.biom.gz
new file mode 100644
index 0000000..c89fd66
Binary files /dev/null and b/tests/bench_tables/1000x10x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x10x0.010_bench_hdf5.biom.gz b/tests/bench_tables/1000x10x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..fbbecf6
Binary files /dev/null and b/tests/bench_tables/1000x10x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/1000x10x0.100_bench.biom.gz b/tests/bench_tables/1000x10x0.100_bench.biom.gz
new file mode 100644
index 0000000..4eec5e0
Binary files /dev/null and b/tests/bench_tables/1000x10x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/1000x10x0.100_bench_hdf5.biom.gz b/tests/bench_tables/1000x10x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..bd46d90
Binary files /dev/null and b/tests/bench_tables/1000x10x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x10000x0.001_bench.biom.gz b/tests/bench_tables/100x10000x0.001_bench.biom.gz
new file mode 100644
index 0000000..44b472b
Binary files /dev/null and b/tests/bench_tables/100x10000x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/100x10000x0.001_bench_hdf5.biom.gz b/tests/bench_tables/100x10000x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..52bbad6
Binary files /dev/null and b/tests/bench_tables/100x10000x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x10000x0.010_bench.biom.gz b/tests/bench_tables/100x10000x0.010_bench.biom.gz
new file mode 100644
index 0000000..82ccee8
Binary files /dev/null and b/tests/bench_tables/100x10000x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/100x10000x0.010_bench_hdf5.biom.gz b/tests/bench_tables/100x10000x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..fb6bb65
Binary files /dev/null and b/tests/bench_tables/100x10000x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x10000x0.100_bench.biom.gz b/tests/bench_tables/100x10000x0.100_bench.biom.gz
new file mode 100644
index 0000000..75e768f
Binary files /dev/null and b/tests/bench_tables/100x10000x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/100x10000x0.100_bench_hdf5.biom.gz b/tests/bench_tables/100x10000x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..1a64722
Binary files /dev/null and b/tests/bench_tables/100x10000x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x1000x0.001_bench.biom.gz b/tests/bench_tables/100x1000x0.001_bench.biom.gz
new file mode 100644
index 0000000..3164d64
Binary files /dev/null and b/tests/bench_tables/100x1000x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/100x1000x0.001_bench_hdf5.biom.gz b/tests/bench_tables/100x1000x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..22c109c
Binary files /dev/null and b/tests/bench_tables/100x1000x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x1000x0.010_bench.biom.gz b/tests/bench_tables/100x1000x0.010_bench.biom.gz
new file mode 100644
index 0000000..940607c
Binary files /dev/null and b/tests/bench_tables/100x1000x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/100x1000x0.010_bench_hdf5.biom.gz b/tests/bench_tables/100x1000x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..9066a46
Binary files /dev/null and b/tests/bench_tables/100x1000x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x1000x0.100_bench.biom.gz b/tests/bench_tables/100x1000x0.100_bench.biom.gz
new file mode 100644
index 0000000..b385970
Binary files /dev/null and b/tests/bench_tables/100x1000x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/100x1000x0.100_bench_hdf5.biom.gz b/tests/bench_tables/100x1000x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..0401da3
Binary files /dev/null and b/tests/bench_tables/100x1000x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x100x0.001_bench.biom.gz b/tests/bench_tables/100x100x0.001_bench.biom.gz
new file mode 100644
index 0000000..1bd6093
Binary files /dev/null and b/tests/bench_tables/100x100x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/100x100x0.001_bench_hdf5.biom.gz b/tests/bench_tables/100x100x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..0c95cf6
Binary files /dev/null and b/tests/bench_tables/100x100x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x100x0.010_bench.biom.gz b/tests/bench_tables/100x100x0.010_bench.biom.gz
new file mode 100644
index 0000000..cb7eac0
Binary files /dev/null and b/tests/bench_tables/100x100x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/100x100x0.010_bench_hdf5.biom.gz b/tests/bench_tables/100x100x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..935cdf4
Binary files /dev/null and b/tests/bench_tables/100x100x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x100x0.100_bench.biom.gz b/tests/bench_tables/100x100x0.100_bench.biom.gz
new file mode 100644
index 0000000..37716c8
Binary files /dev/null and b/tests/bench_tables/100x100x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/100x100x0.100_bench_hdf5.biom.gz b/tests/bench_tables/100x100x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..df8b984
Binary files /dev/null and b/tests/bench_tables/100x100x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x10x0.001_bench.biom.gz b/tests/bench_tables/100x10x0.001_bench.biom.gz
new file mode 100644
index 0000000..a9de7da
Binary files /dev/null and b/tests/bench_tables/100x10x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/100x10x0.001_bench_hdf5.biom.gz b/tests/bench_tables/100x10x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..7ee4472
Binary files /dev/null and b/tests/bench_tables/100x10x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x10x0.010_bench.biom.gz b/tests/bench_tables/100x10x0.010_bench.biom.gz
new file mode 100644
index 0000000..fc9e088
Binary files /dev/null and b/tests/bench_tables/100x10x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/100x10x0.010_bench_hdf5.biom.gz b/tests/bench_tables/100x10x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..24be7ca
Binary files /dev/null and b/tests/bench_tables/100x10x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/100x10x0.100_bench.biom.gz b/tests/bench_tables/100x10x0.100_bench.biom.gz
new file mode 100644
index 0000000..1fc4566
Binary files /dev/null and b/tests/bench_tables/100x10x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/100x10x0.100_bench_hdf5.biom.gz b/tests/bench_tables/100x10x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..bb592b9
Binary files /dev/null and b/tests/bench_tables/100x10x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x10000x0.001_bench.biom.gz b/tests/bench_tables/10x10000x0.001_bench.biom.gz
new file mode 100644
index 0000000..f0dda1f
Binary files /dev/null and b/tests/bench_tables/10x10000x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/10x10000x0.001_bench_hdf5.biom.gz b/tests/bench_tables/10x10000x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..f0f3b69
Binary files /dev/null and b/tests/bench_tables/10x10000x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x10000x0.010_bench.biom.gz b/tests/bench_tables/10x10000x0.010_bench.biom.gz
new file mode 100644
index 0000000..5e7cb6f
Binary files /dev/null and b/tests/bench_tables/10x10000x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/10x10000x0.010_bench_hdf5.biom.gz b/tests/bench_tables/10x10000x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..18d47c8
Binary files /dev/null and b/tests/bench_tables/10x10000x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x10000x0.100_bench.biom.gz b/tests/bench_tables/10x10000x0.100_bench.biom.gz
new file mode 100644
index 0000000..0b26dbe
Binary files /dev/null and b/tests/bench_tables/10x10000x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/10x10000x0.100_bench_hdf5.biom.gz b/tests/bench_tables/10x10000x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..dc3a515
Binary files /dev/null and b/tests/bench_tables/10x10000x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x1000x0.001_bench.biom.gz b/tests/bench_tables/10x1000x0.001_bench.biom.gz
new file mode 100644
index 0000000..c657a24
Binary files /dev/null and b/tests/bench_tables/10x1000x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/10x1000x0.001_bench_hdf5.biom.gz b/tests/bench_tables/10x1000x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..cc419c5
Binary files /dev/null and b/tests/bench_tables/10x1000x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x1000x0.010_bench.biom.gz b/tests/bench_tables/10x1000x0.010_bench.biom.gz
new file mode 100644
index 0000000..dea9c87
Binary files /dev/null and b/tests/bench_tables/10x1000x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/10x1000x0.010_bench_hdf5.biom.gz b/tests/bench_tables/10x1000x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..c78777a
Binary files /dev/null and b/tests/bench_tables/10x1000x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x1000x0.100_bench.biom.gz b/tests/bench_tables/10x1000x0.100_bench.biom.gz
new file mode 100644
index 0000000..a01df41
Binary files /dev/null and b/tests/bench_tables/10x1000x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/10x1000x0.100_bench_hdf5.biom.gz b/tests/bench_tables/10x1000x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..9104dc2
Binary files /dev/null and b/tests/bench_tables/10x1000x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x100x0.001_bench.biom.gz b/tests/bench_tables/10x100x0.001_bench.biom.gz
new file mode 100644
index 0000000..28bf4a3
Binary files /dev/null and b/tests/bench_tables/10x100x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/10x100x0.001_bench_hdf5.biom.gz b/tests/bench_tables/10x100x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..96d142c
Binary files /dev/null and b/tests/bench_tables/10x100x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x100x0.010_bench.biom.gz b/tests/bench_tables/10x100x0.010_bench.biom.gz
new file mode 100644
index 0000000..72a2b6f
Binary files /dev/null and b/tests/bench_tables/10x100x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/10x100x0.010_bench_hdf5.biom.gz b/tests/bench_tables/10x100x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..111aa65
Binary files /dev/null and b/tests/bench_tables/10x100x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x100x0.100_bench.biom.gz b/tests/bench_tables/10x100x0.100_bench.biom.gz
new file mode 100644
index 0000000..53de930
Binary files /dev/null and b/tests/bench_tables/10x100x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/10x100x0.100_bench_hdf5.biom.gz b/tests/bench_tables/10x100x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..f90a0b3
Binary files /dev/null and b/tests/bench_tables/10x100x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x10x0.001_bench.biom.gz b/tests/bench_tables/10x10x0.001_bench.biom.gz
new file mode 100644
index 0000000..4bc708e
Binary files /dev/null and b/tests/bench_tables/10x10x0.001_bench.biom.gz differ
diff --git a/tests/bench_tables/10x10x0.001_bench_hdf5.biom.gz b/tests/bench_tables/10x10x0.001_bench_hdf5.biom.gz
new file mode 100644
index 0000000..4d18664
Binary files /dev/null and b/tests/bench_tables/10x10x0.001_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x10x0.010_bench.biom.gz b/tests/bench_tables/10x10x0.010_bench.biom.gz
new file mode 100644
index 0000000..7b85840
Binary files /dev/null and b/tests/bench_tables/10x10x0.010_bench.biom.gz differ
diff --git a/tests/bench_tables/10x10x0.010_bench_hdf5.biom.gz b/tests/bench_tables/10x10x0.010_bench_hdf5.biom.gz
new file mode 100644
index 0000000..6ab209a
Binary files /dev/null and b/tests/bench_tables/10x10x0.010_bench_hdf5.biom.gz differ
diff --git a/tests/bench_tables/10x10x0.100_bench.biom.gz b/tests/bench_tables/10x10x0.100_bench.biom.gz
new file mode 100644
index 0000000..42f8d00
Binary files /dev/null and b/tests/bench_tables/10x10x0.100_bench.biom.gz differ
diff --git a/tests/bench_tables/10x10x0.100_bench_hdf5.biom.gz b/tests/bench_tables/10x10x0.100_bench_hdf5.biom.gz
new file mode 100644
index 0000000..981342d
Binary files /dev/null and b/tests/bench_tables/10x10x0.100_bench_hdf5.biom.gz differ
diff --git a/tests/test_cli/test_show_install_info.py b/tests/test_cli/test_show_install_info.py
deleted file mode 100644
index 35cd63a..0000000
--- a/tests/test_cli/test_show_install_info.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-import unittest
-
-from biom.cli.installation_informer import _show_install_info
-
-
-class TestShowInstallInfo(unittest.TestCase):
-    def test_default(self):
-        # Not really sure what to specifically test here, as this information
-        # will change on a per-install basis. Just make sure the code is being
-        # exercised and we have some output.
-        obs = _show_install_info()
-        self.assertTrue(len(obs) > 0)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/test_cli/test_summarize_table.py b/tests/test_cli/test_summarize_table.py
deleted file mode 100644
index ff85bc4..0000000
--- a/tests/test_cli/test_summarize_table.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-from biom.cli.table_summarizer import _summarize_table
-from biom.parse import load_table
-
-import tempfile
-from unittest import TestCase, main
-
-
-class TestSummarizeTable(TestCase):
-
-    def setUp(self):
-        with tempfile.NamedTemporaryFile(mode='w') as fh:
-            fh.write(biom1)
-            fh.flush()
-            self.biom1 = load_table(fh.name)
-
-    def test_default(self):
-        """ TableSummarizer functions as expected
-
-        """
-        result = _summarize_table(self.biom1)
-        # test same alphanumeric content, order of samples is runtime
-        # dependent
-        self.assertEqual(sorted(result), sorted(summary_default))
-
-    def test_qualitative(self):
-        """ TableSummarizer functions as expected with qualitative=True
-
-        """
-        result = _summarize_table(self.biom1, qualitative=True)
-        # test same alphanumeric content, order of samples is runtime
-        # dependent
-        self.assertEqual(sorted(result), sorted(summary_qualitative))
-
-biom1 = ('{"id": "None","format": "Biological Observation Matrix 1.0.0",'
-    '"format_url": "http://biom-format.org","type": "OTU table",'
-    '"generated_by": "QIIME 1.6.0-dev","date": '
-    '"2013-02-09T09:30:11.550590","matrix_type": "sparse",'
-    '"matrix_element_type": "int","shape": [14, 9],"data": [[0,0,20],'
-    '[0,1,18],[0,2,18],[0,3,22],[0,4,4],[1,4,1],[2,0,1],[2,4,1],[2,5,1],'
-    '[3,6,1],[4,4,1],[5,7,20],[6,4,1],[7,4,1],[7,5,1],[8,4,1],[8,6,2],'
-    '[8,8,3],[9,7,2],[10,5,1],[11,4,9],[11,5,20],[11,6,1],[11,8,4],'
-    '[12,4,3],[12,6,19],[12,8,15],[13,0,1],[13,1,4],[13,2,4]],"rows": '
-    '[{"id": "295053", "metadata": {"taxonomy": ["k__Bacteria"]}},{"id": '
-    '"42684", "metadata": {"taxonomy": ["k__Bacteria", '
-    '"p__Proteobacteria"]}},{"id": "None11", "metadata": {"taxonomy": '
-    '["Unclassified"]}},{"id": "None10", "metadata": {"taxonomy": '
-    '["Unclassified"]}},{"id": "None7", "metadata": {"taxonomy": '
-    '["Unclassified"]}},{"id": "None6", "metadata": {"taxonomy": '
-    '["Unclassified"]}},{"id": "None5", "metadata": {"taxonomy": '
-    '["k__Bacteria"]}},{"id": "None4", "metadata": {"taxonomy": '
-    '["Unclassified"]}},{"id": "None3", "metadata": {"taxonomy": '
-    '["k__Bacteria"]}},{"id": "None2", "metadata": {"taxonomy": '
-    '["k__Bacteria"]}},{"id": "None1", "metadata": {"taxonomy": '
-    '["Unclassified"]}},{"id": "879972", "metadata": {"taxonomy": '
-    '["k__Bacteria"]}},{"id": "None9", "metadata": {"taxonomy": '
-    '["Unclassified"]}},{"id": "None8", "metadata": {"taxonomy": '
-    '["k__Bacteria"]}}],"columns": [{"id": "f2", "metadata": null},'
-    '{"id": "f1", "metadata": null},{"id": "f3", "metadata": null},'
-    '{"id": "f4", "metadata": null},{"id": "p2", "metadata": null},{"id":'
-    ' "p1", "metadata": null},{"id": "t1", "metadata": null},{"id": '
-    '"not16S.1", "metadata": null},{"id": "t2", "metadata": null}]}')
-
-summary_default = """Num samples: 9
-Num observations: 14
-Total count: 200
-Table density (fraction of non-zero values): 0.238
-
-Counts/sample summary:
- Min: 22.0
- Max: 23.0
- Median: 22.000
- Mean: 22.222
- Std. dev.: 0.416
- Sample Metadata Categories: None provided
- Observation Metadata Categories: taxonomy
-
-Counts/sample detail:
-p2: 22.0
-f1: 22.0
-f2: 22.0
-f3: 22.0
-f4: 22.0
-t2: 22.0
-not16S.1: 22.0
-t1: 23.0
-p1: 23.0"""
-
-summary_qualitative = """Num samples: 9
-Num observations: 14
-
-Observations/sample summary:
- Min: 1
- Max: 9
- Median: 3.000
- Mean: 3.333
- Std. dev.: 2.211
- Sample Metadata Categories: None provided
- Observation Metadata Categories: taxonomy
-
-Observations/sample detail:
-f4: 1
-f1: 2
-f3: 2
-not16S.1: 2
-f2: 3
-t2: 3
-t1: 4
-p1: 4
-p2: 9"""
-
-if __name__ == "__main__":
-    main()
diff --git a/tests/test_cli/test_table_normalizer.py b/tests/test_cli/test_table_normalizer.py
deleted file mode 100755
index 8e4feaf..0000000
--- a/tests/test_cli/test_table_normalizer.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2013, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-from unittest import TestCase, main
-
-import os
-
-import biom
-from biom.cli.table_normalizer import _normalize_table
-from biom.parse import parse_biom_table
-from biom.util import HAVE_H5PY
-from biom.exception import UnknownAxisError
-
-
-class TableNormalizerTests(TestCase):
-
-    def setUp(self):
-        """initialize objects for use in tests"""
-        self.cmd = _normalize_table
-
-        cwd = os.getcwd()
-        if '/' in __file__:
-            os.chdir(__file__.rsplit('/', 1)[0])
-        self.table = biom.load_table('test_data/test.json')
-        os.chdir(cwd)
-
-    def test_bad_inputs(self):
-        # relative_abund and pa
-        with self.assertRaises(ValueError):
-            self.cmd(self.table, relative_abund=True,
-                     presence_absence=True, axis="sample")
-        # no normalization type
-        with self.assertRaises(ValueError):
-            self.cmd(self.table, relative_abund=False,
-                     presence_absence=False, axis="sample")
-        # bad axis
-        with self.assertRaises(UnknownAxisError):
-            self.cmd(self.table, relative_abund=True,
-                     axis="nonsense")
-
-
-if __name__ == "__main__":
-    main()
diff --git a/tests/test_cli/test_uc_processor.py b/tests/test_cli/test_uc_processor.py
deleted file mode 100644
index 6c4493d..0000000
--- a/tests/test_cli/test_uc_processor.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-# -----------------------------------------------------------------------------
-
-import tempfile
-from unittest import TestCase, main
-
-import numpy as np
-
-import biom
-from biom.cli.uc_processor import _from_uc
-
-class TestUcProcessor(TestCase):
-
-    def setUp(self):
-        """Set up data for use in unit tests."""
-        self.cmd = _from_uc
-        self.uc_minimal = uc_minimal.split('\n')
-        self.uc = uc.split('\n')
-        self.rep_set = rep_set.split('\n')
-        self.rep_set_no_mapping = rep_set_no_mapping.split('\n')
-        self.rep_set_missing_id = rep_set_missing_id.split('\n')
-
-    def test_basic(self):
-        obs = self.cmd(self.uc_minimal)
-        expected = biom.Table(np.array([[1.0]]),
-                              observation_ids=['f2_1539'],
-                              sample_ids=['f2'])
-        self.assertEqual(obs, expected)
-
-    def test_basic_w_mapping(self):
-        obs = self.cmd(self.uc_minimal, self.rep_set)
-        expected = biom.Table(np.array([[1.0]]),
-                              observation_ids=['otu1'],
-                              sample_ids=['f2'])
-        self.assertEqual(obs, expected)
-
-    def test_rep_set_no_mapping(self):
-        self.assertRaises(ValueError, self.cmd, self.uc_minimal,
-                          self.rep_set_no_mapping)
-
-    def test_rep_set_missing_id(self):
-        self.assertRaises(ValueError, self.cmd, self.uc_minimal,
-                          self.rep_set_missing_id)
-
-    def test_uc(self):
-        obs = self.cmd(self.uc)
-        expected = biom.Table(np.array([[1.0, 1.0], [0.0, 1.0]]),
-                              observation_ids=['f2_1539', 'f3_1540'],
-                              sample_ids=['f2', 'f3'])
-        self.assertEqual(obs, expected)
-
-    def test_uc_w_mapping(self):
-        obs = self.cmd(self.uc, self.rep_set)
-        expected = biom.Table(np.array([[1.0, 1.0], [0.0, 1.0]]),
-                              observation_ids=['otu1', 'otu2'],
-                              sample_ids=['f2', 'f3'])
-        self.assertEqual(obs, expected)
-
-uc_minimal = """# uclust --input /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T/UclustExactMatchFilterrW47Ju.fasta --id 0.97 --tmpdir /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T --w 8 --stepwords 8 --usersort --maxaccepts 1 --stable_sort --maxrejects 8 --uc dn-otus/uclust_picked_otus/seqs_clusters.uc
-# version=1.2.22
-# Tab-separated fields:
-# 1=Type, 2=ClusterNr, 3=SeqLength or ClusterSize, 4=PctId, 5=Strand, 6=QueryStart, 7=SeedStart, 8=Alignment, 9=QueryLabel, 10=TargetLabel
-# Record types (field 1): L=LibSeed, S=NewSeed, H=Hit, R=Reject, D=LibCluster, C=NewCluster, N=NoHit
-# For C and D types, PctId is average id with seed.
-# QueryStart and SeedStart are zero-based relative to start of sequence.
-# If minus strand, SeedStart is relative to reverse-complemented seed.
-S	0	133	*	*	*	*	*	f2_1539	*
-"""
-
-uc = """# uclust --input /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T/UclustExactMatchFilterrW47Ju.fasta --id 0.97 --tmpdir /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T --w 8 --stepwords 8 --usersort --maxaccepts 1 --stable_sort --maxrejects 8 --uc dn-otus/uclust_picked_otus/seqs_clusters.uc
-# version=1.2.22
-# Tab-separated fields:
-# 1=Type, 2=ClusterNr, 3=SeqLength or ClusterSize, 4=PctId, 5=Strand, 6=QueryStart, 7=SeedStart, 8=Alignment, 9=QueryLabel, 10=TargetLabel
-# Record types (field 1): L=LibSeed, S=NewSeed, H=Hit, R=Reject, D=LibCluster, C=NewCluster, N=NoHit
-# For C and D types, PctId is average id with seed.
-# QueryStart and SeedStart are zero-based relative to start of sequence.
-# If minus strand, SeedStart is relative to reverse-complemented seed.
-S	0	133	*	*	*	*	*	f2_1539	*
-S	0	133	*	*	*	*	*	f3_1540	*
-H	0	141	100.0	+	0	0	133M8D	f3_42	f2_1539
-"""
-
-rep_set = """>otu1 f2_1539
-ACGT
->otu2 f3_1540
-ACCT
-"""
-
-rep_set_no_mapping = """>otu1
-ACGT
->otu2
-ACCT
-"""
-
-rep_set_missing_id = """>otu1 f99_1539
-ACGT
->otu2 f99_1539
-ACCT
-"""
-
-if __name__ == '__main__':
-    main()
diff --git a/tests/test_commands/__init__.py b/tests/test_commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_commands/test_data/json_obs_collapsed.biom b/tests/test_commands/test_data/json_obs_collapsed.biom
new file mode 100644
index 0000000..9510822
--- /dev/null
+++ b/tests/test_commands/test_data/json_obs_collapsed.biom
@@ -0,0 +1 @@
+{"id": "None","format": "Biological Observation Matrix 1.0.0","format_url": "http://biom-format.org","type": "OTU table","generated_by": "BIOM-Format 1.3.1","date": "2014-07-23T15:16:35.050451","matrix_type": "sparse","matrix_element_type": "float","shape": [4, 6],"data": [[0,0,2.0],[0,1,1.0],[0,2,1.0],[0,5,1.0],[1,2,1.0],[1,3,4.0],[1,5,2.0],[2,0,5.0],[2,1,1.0],[2,3,2.0],[2,4,3.0],[2,5,1.0],[3,1,1.0],[3,2,2.0]],"rows": [{"id": "p__Firmicutes", "metadata": {"GG_OTU_4": {"taxonomy": ["k__B [...]
\ No newline at end of file
diff --git a/tests/test_commands/test_data/json_sample_collapsed.biom b/tests/test_commands/test_data/json_sample_collapsed.biom
new file mode 100644
index 0000000..f6ecd3d
--- /dev/null
+++ b/tests/test_commands/test_data/json_sample_collapsed.biom
@@ -0,0 +1 @@
+{"id": "None","format": "Biological Observation Matrix 1.0.0","format_url": "http://biom-format.org","type": "OTU table","generated_by": "BIOM-Format 1.3.1","date": "2014-07-23T15:18:50.101682","matrix_type": "sparse","matrix_element_type": "float","shape": [5, 2],"data": [[0,1,1.0],[1,0,6.0],[1,1,6.0],[2,0,6.0],[2,1,1.0],[3,0,1.0],[3,1,4.0],[4,1,2.0]],"rows": [{"id": "GG_OTU_1", "metadata": {"taxonomy": ["k__Bacteria", "p__Proteobacteria", "c__Gammaproteobacteria", "o__Enterobacteriales [...]
\ No newline at end of file
diff --git a/tests/test_commands/test_data/test.biom b/tests/test_commands/test_data/test.biom
new file mode 100644
index 0000000..ea3c7c5
Binary files /dev/null and b/tests/test_commands/test_data/test.biom differ
diff --git a/tests/test_commands/test_installation_informer.py b/tests/test_commands/test_installation_informer.py
new file mode 100644
index 0000000..a8c4728
--- /dev/null
+++ b/tests/test_commands/test_installation_informer.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
+from biom.commands.installation_informer import InstallationInformer
+from unittest import TestCase, main
+
+
+class InstallationInformerTests(TestCase):
+
+    def setUp(self):
+        """Set up data for use in unit tests."""
+        self.cmd = InstallationInformer()
+
+    def test_default(self):
+        """Correctly returns info about the biom-format installation."""
+        # Not really sure what to specifically test here, as this information
+        # will change on a per-install basis. Just make sure the code is being
+        # exercised and we have some output.
+        obs = self.cmd()
+        self.assertEqual(obs.keys(), ['install_info_lines'])
+        self.assertTrue(len(obs['install_info_lines']) > 0)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tests/test_cli/test_add_metadata.py b/tests/test_commands/test_metadata_adder.py
similarity index 80%
rename from tests/test_cli/test_add_metadata.py
rename to tests/test_commands/test_metadata_adder.py
index 90111d3..9fafb29 100644
--- a/tests/test_cli/test_add_metadata.py
+++ b/tests/test_commands/test_metadata_adder.py
@@ -1,29 +1,34 @@
 #!/usr/bin/env python
 
 # -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
 #
 # Distributed under the terms of the Modified BSD License.
 #
 # The full license is in the file COPYING.txt, distributed with this software.
 # -----------------------------------------------------------------------------
 
-import tempfile
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout", "Jose Antonio Navas Molina"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
+from pyqi.core.exception import CommandError
+from biom.commands.metadata_adder import MetadataAdder
+from biom.parse import parse_biom_table
 from unittest import TestCase, main
 
-import biom
-from biom.cli.metadata_adder import _add_metadata
 
-
-class TestAddMetadata(TestCase):
+class MetadataAdderTests(TestCase):
 
     def setUp(self):
         """Set up data for use in unit tests."""
-        self.cmd = _add_metadata
-        with tempfile.NamedTemporaryFile('w') as fh:
-            fh.write(biom1)
-            fh.flush()
-            self.biom_table1 = biom.load_table(fh.name)
+        self.cmd = MetadataAdder()
+        self.biom_lines1 = biom1
+        self.biom_table1 = parse_biom_table(self.biom_lines1)
         self.sample_md_lines1 = sample_md1.split('\n')
         self.obs_md_lines1 = obs_md1.split('\n')
 
@@ -33,12 +38,15 @@ class TestAddMetadata(TestCase):
         # sample metadata to begin with. Don't perform any casting.
         obs = self.cmd(table=self.biom_table1,
                        sample_metadata=self.sample_md_lines1)
+        self.assertEqual(obs.keys(), ['table'])
 
+        obs, fmt = obs['table']
         self.assertEqual(obs.metadata()[obs.index('f4', 'sample')],
                          {'bar': '0.23', 'foo': '9', 'baz': 'abc;123'})
         self.assertEqual(obs.metadata()[obs.index('not16S.1', 'sample')],
                          {'bar': '-4.2', 'foo': '0', 'baz': '123;abc'})
         self.assertEqual(obs.metadata()[obs.index('f2', 'sample')], {})
+        self.assertEqual(fmt, 'hdf5')
 
     def test_add_sample_metadata_with_casting(self):
         """Correctly adds sample metadata with casting."""
@@ -46,12 +54,15 @@ class TestAddMetadata(TestCase):
                        sample_metadata=self.sample_md_lines1,
                        sc_separated=['baz'], int_fields=['foo'],
                        float_fields=['bar'])
+        self.assertEqual(obs.keys(), ['table'])
 
+        obs, fmt = obs['table']
         self.assertEqual(obs.metadata()[obs.index('f4', 'sample')],
                          {'bar': 0.23, 'foo': 9, 'baz': ['abc', '123']})
         self.assertEqual(obs.metadata()[obs.index('not16S.1', 'sample')],
                          {'bar': -4.2, 'foo': 0, 'baz': ['123', 'abc']})
         self.assertEqual(obs.metadata()[obs.index('f2', 'sample')], {})
+        self.assertEqual(fmt, 'hdf5')
 
     def test_add_observation_metadata_no_casting(self):
         """Correctly adds observation metadata without casting it."""
@@ -60,8 +71,11 @@ class TestAddMetadata(TestCase):
         # observations that aren't in the table are included. Don't perform any
         # casting.
         obs = self.cmd(table=self.biom_table1,
-                       observation_metadata=self.obs_md_lines1)
+                       observation_metadata=self.obs_md_lines1,
+                       output_as_json=True)
+        self.assertEqual(obs.keys(), ['table'])
 
+        obs, fmt = obs['table']
         metadata = obs.metadata(axis='observation')
         self.assertEqual(
             metadata[obs.index('None7', 'observation')],
@@ -72,13 +86,16 @@ class TestAddMetadata(TestCase):
         self.assertEqual(
             metadata[obs.index('None8', 'observation')],
             {'taxonomy': ['k__Bacteria']})
+        self.assertEqual(fmt, 'json')
 
     def test_add_observation_metadata_with_casting(self):
         """Correctly adds observation metadata with casting."""
         obs = self.cmd(table=self.biom_table1,
                        observation_metadata=self.obs_md_lines1,
                        sc_pipe_separated=['taxonomy'], int_fields=['foo'])
+        self.assertEqual(obs.keys(), ['table'])
 
+        obs, fmt = obs['table']
         metadata = obs.metadata(axis='observation')
         self.assertEqual(
             metadata[obs.index('None7', 'observation')],
@@ -89,6 +106,12 @@ class TestAddMetadata(TestCase):
         self.assertEqual(
             metadata[obs.index('None8', 'observation')],
             {'taxonomy': ['k__Bacteria']})
+        self.assertEqual(fmt, 'hdf5')
+
+    def test_no_metadata(self):
+        """Correctly raises error when not provided any metadata."""
+        with self.assertRaises(CommandError):
+            self.cmd(table=self.biom_table1)
 
 
 biom1 = ('{"id": "None","format": "Biological Observation Matrix 1.0.0","form'
diff --git a/tests/test_cli/test_table_converter.py b/tests/test_commands/test_table_converter.py
similarity index 50%
rename from tests/test_cli/test_table_converter.py
rename to tests/test_commands/test_table_converter.py
index be25e35..9b0568c 100644
--- a/tests/test_cli/test_table_converter.py
+++ b/tests/test_commands/test_table_converter.py
@@ -1,45 +1,44 @@
 #!/usr/bin/env python
 
 # -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
 #
 # Distributed under the terms of the Modified BSD License.
 #
 # The full license is in the file COPYING.txt, distributed with this software.
 # -----------------------------------------------------------------------------
 
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout", "Jose Antonio Navas Molina"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
 from os.path import abspath, dirname, join
-import tempfile
 
 import numpy as np
 
-from biom.cli.table_converter import _convert
-from biom.cli.util import write_biom_table
-from biom.parse import MetadataMap, load_table
+from pyqi.core.exception import CommandError
+from biom.commands.table_converter import TableConverter
+from biom.parse import MetadataMap, parse_biom_table
 from biom.table import Table
-from biom import load_table
-from biom.parse import biom_open, parse_biom_table
+from biom.util import biom_open
 from unittest import TestCase, main
-from io import StringIO
+from StringIO import StringIO
 
 
 class TableConverterTests(TestCase):
 
     def setUp(self):
         """Set up data for use in unit tests."""
-        self.cmd = _convert
-        self.output_filepath = tempfile.NamedTemporaryFile().name
+        self.cmd = TableConverter()
 
-        with tempfile.NamedTemporaryFile('w') as fh:
-            fh.write(biom1)
-            fh.flush()
-            self.biom_table1 = load_table(fh.name)
+        self.biom_lines1 = biom1
+        self.biom_table1 = parse_biom_table(self.biom_lines1)
 
-        self.biom_lines1 = biom1.split('\n')
-        with tempfile.NamedTemporaryFile('w') as fh:
-            fh.write(classic1)
-            fh.flush()
-            self.classic_biom1 = load_table(fh.name)
+        self.classic_lines1 = classic1.split('\n')
 
         self.sample_md1 = MetadataMap.from_file(sample_md1.split('\n'))
 
@@ -51,11 +50,11 @@ class TableConverterTests(TestCase):
 
     def test_classic_to_biom(self):
         """Correctly converts classic to biom."""
-        self.cmd(table=self.classic_biom1,
-                 output_filepath=self.output_filepath,
-                 to_json=True, table_type='OTU table')
+        obs = self.cmd(table=parse_biom_table(self.classic_lines1),
+                       to_json=True, table_type='OTU table')
+        self.assertEqual(obs.keys(), ['table'])
 
-        obs = load_table(self.output_filepath)
+        obs = parse_biom_table(obs['table'][0].to_json('testing'))
         self.assertEqual(type(obs), Table)
         self.assertEqual(len(obs.ids()), 9)
         self.assertEqual(len(obs.ids(axis='observation')), 14)
@@ -65,18 +64,18 @@ class TableConverterTests(TestCase):
     def test_classic_to_biom_with_metadata(self):
         """Correctly converts classic to biom with metadata."""
         # No processing of metadata.
-        obs = self.cmd(table=self.classic_biom1,
-                       output_filepath=self.output_filepath,
+        obs = self.cmd(table=parse_biom_table(self.classic_lines1),
                        sample_metadata=self.sample_md1, to_json=True,
                        table_type='OTU table', process_obs_metadata='naive')
+        self.assertEqual(obs.keys(), ['table'])
 
-        obs = load_table(self.output_filepath)
+        obs = parse_biom_table(obs['table'][0].to_json('testing'))
         self.assertEqual(type(obs), Table)
         self.assertEqual(len(obs.ids()), 9)
         self.assertEqual(len(obs.ids(axis='observation')), 14)
         self.assertNotEqual(obs.metadata(), None)
         self.assertNotEqual(obs.metadata(axis='observation'), None)
-        self.assertEqual(obs.metadata()[obs.index(u'p2', u'sample')],
+        self.assertEqual(obs.metadata()[obs.index('p2', 'sample')],
                          {'foo': 'c;b;a'})
         self.assertEqual(obs.metadata()[obs.index('not16S.1', 'sample')],
                          {'foo': 'b;c;d'})
@@ -85,12 +84,12 @@ class TableConverterTests(TestCase):
             {'taxonomy': 'Unclassified'})
 
         # With processing of metadata (currently only supports observation md).
-        obs = self.cmd(table=self.classic_biom1,
-                       output_filepath=self.output_filepath,
+        obs = self.cmd(table=parse_biom_table(self.classic_lines1),
                        sample_metadata=self.sample_md1, table_type='OTU table',
                        process_obs_metadata='sc_separated', to_json=True)
+        self.assertEqual(obs.keys(), ['table'])
 
-        obs = load_table(self.output_filepath)
+        obs = parse_biom_table(obs['table'][0].to_json('testing'))
         self.assertEqual(type(obs), Table)
         self.assertEqual(len(obs.ids()), 9)
         self.assertEqual(len(obs.ids(axis='observation')), 14)
@@ -104,118 +103,141 @@ class TableConverterTests(TestCase):
             obs.index('None11', 'observation')],
             {'taxonomy': ['Unclassified']})
 
-    def test_biom_to_classic1(self):
+    def test_biom_to_classic(self):
         """Correctly converts biom to classic."""
-        self.cmd(table=self.biom_table1,
-                       output_filepath=self.output_filepath,
+        obs = self.cmd(table=parse_biom_table(self.biom_lines1),
                        to_tsv=True, header_key='taxonomy')
+        self.assertEqual(obs.keys(), ['table'])
+        self.assertEqual(obs['table'][0], classic1)
 
-        self.assertEqual(load_table(self.output_filepath), self.classic_biom1)
-
-    def test_biom_to_classic2(self):
-        """Correctly converts biom to classic with metadata renaming."""
-        self.cmd(table=self.biom_table1,
-                       output_filepath=self.output_filepath, to_tsv=True,
+        obs = self.cmd(table=parse_biom_table(self.biom_lines1), to_tsv=True,
                        header_key='taxonomy', output_metadata_id='foo')
-        obs = load_table(self.output_filepath)
-        self.assertTrue('foo' in obs.metadata(axis='observation')[0])
+        self.assertEqual(obs.keys(), ['table'])
+        obs_md_col = obs['table'][0].split('\n')[1].split('\t')[-1]
+        self.assertEqual(obs_md_col, 'foo')
+
+    def test_invalid_input(self):
+        """Correctly handles invalid input by raising a CommandError."""
+        # Too many ops.
+        with self.assertRaises(CommandError):
+            self.cmd(table_file=self.biom_lines1,
+                     sparse_biom_to_dense_biom=True,
+                     biom_to_classic_table=True)
+
+        # biom -> classic, but supply classic
+        with self.assertRaises(CommandError):
+            self.cmd(table_file=self.classic_lines1,
+                     biom_to_classic_table=True)
+
+        # sparse biom -> dense biom, but supply classic
+        with self.assertRaises(CommandError):
+            self.cmd(table_file=self.classic_lines1,
+                     sparse_biom_to_dense_biom=True)
+
+        # dense biom -> sparse biom, but supply classic
+        with self.assertRaises(CommandError):
+            self.cmd(table_file=self.classic_lines1,
+                     dense_biom_to_sparse_biom=True)
+
+        # Unknown observation processor.
+        with self.assertRaises(CommandError):
+            self.cmd(table_file=self.classic_lines1,
+                     process_obs_metadata='foo')
+
+        # classic -> biom, but supply biom
+        with self.assertRaises(CommandError):
+            self.cmd(table_file=StringIO(self.biom_lines1),
+                     process_obs_metadata='sc_separated')
 
     def test_json_to_hdf5_collapsed_samples(self):
         """Correctly converts json to HDF5 changing the sample metadata"""
         with biom_open(self.json_collapsed_samples) as f:
-            obs = self.cmd(table=parse_biom_table(f),
-                           output_filepath=self.output_filepath, to_hdf5=True,
+            obs = self.cmd(table=parse_biom_table(f), to_hdf5=True,
                            collapsed_samples=True)
-        obs = load_table(self.output_filepath)
+        self.assertEqual(obs.keys(), ['table'])
         exp = Table(np.array([[0., 1.], [6., 6.], [6., 1.],
                               [1., 4.], [0., 2.]]),
-                    observation_ids=[u'GG_OTU_1', u'GG_OTU_2', u'GG_OTU_3',
-                                     u'GG_OTU_4', u'GG_OTU_5'],
-                    sample_ids=[u'skin', u'gut'],
+                    observation_ids=['GG_OTU_1', 'GG_OTU_2', 'GG_OTU_3',
+                                     'GG_OTU_4', 'GG_OTU_5'],
+                    sample_ids=['skin', 'gut'],
                     observation_metadata=[
-                        {u'taxonomy': [u'k__Bacteria', u'p__Proteobacteria',
-                                       u'c__Gammaproteobacteria',
-                                       u'o__Enterobacteriales',
-                                       u'f__Enterobacteriaceae',
-                                       u'g__Escherichia', u's__']},
-                        {u'taxonomy': [u'k__Bacteria', u'p__Cyanobacteria',
-                                       u'c__Nostocophycideae',
-                                       u'o__Nostocales', u'f__Nostocaceae',
-                                       u'g__Dolichospermum', u's__']},
-                        {u'taxonomy': [u'k__Archaea', u'p__Euryarchaeota',
-                                       u'c__Methanomicrobia',
-                                       u'o__Methanosarcinales',
-                                       u'f__Methanosarcinaceae',
-                                       u'g__Methanosarcina', u's__']},
-                        {u'taxonomy': [u'k__Bacteria', u'p__Firmicutes',
-                                       u'c__Clostridia', u'o__Halanaerobiales',
-                                       u'f__Halanaerobiaceae',
-                                       u'g__Halanaerobium',
-                                       u's__Halanaerobiumsaccharolyticum']},
-                        {u'taxonomy': [u'k__Bacteria', u'p__Proteobacteria',
-                                       u'c__Gammaproteobacteria',
-                                       u'o__Enterobacteriales',
-                                       u'f__Enterobacteriaceae',
-                                       u'g__Escherichia', u's__']}],
+                        {'taxonomy': ['k__Bacteria', 'p__Proteobacteria',
+                                      'c__Gammaproteobacteria',
+                                      'o__Enterobacteriales',
+                                      'f__Enterobacteriaceae',
+                                      'g__Escherichia', 's__']},
+                        {'taxonomy': ['k__Bacteria', 'p__Cyanobacteria',
+                                      'c__Nostocophycideae', 'o__Nostocales',
+                                      'f__Nostocaceae', 'g__Dolichospermum',
+                                      's__']},
+                        {'taxonomy': ['k__Archaea', 'p__Euryarchaeota',
+                                      'c__Methanomicrobia',
+                                      'o__Methanosarcinales',
+                                      'f__Methanosarcinaceae',
+                                      'g__Methanosarcina', 's__']},
+                        {'taxonomy': ['k__Bacteria', 'p__Firmicutes',
+                                      'c__Clostridia', 'o__Halanaerobiales',
+                                      'f__Halanaerobiaceae',
+                                      'g__Halanaerobium',
+                                      's__Halanaerobiumsaccharolyticum']},
+                        {'taxonomy': ['k__Bacteria', 'p__Proteobacteria',
+                                      'c__Gammaproteobacteria',
+                                      'o__Enterobacteriales',
+                                      'f__Enterobacteriaceae',
+                                      'g__Escherichia', 's__']}],
                     sample_metadata=[
-                        {u'collapsed_ids': [u'Sample4', u'Sample5',
-                                            u'Sample6']},
-                        {u'collapsed_ids': [u'Sample1', u'Sample2',
-                                            u'Sample3']}
+                        {'collapsed_ids': ['Sample5', 'Sample4', 'Sample6']},
+                        {'collapsed_ids': ['Sample1', 'Sample3', 'Sample2']}
                         ],
-                    type=u'OTU table')
-        self.assertEqual(obs, exp)
+                    type='OTU table')
+        self.assertEqual(obs['table'][0], exp)
 
     def test_json_to_hdf5_collapsed_metadata(self):
         """Correctly converts json to HDF5 changing the observation metadata"""
         with biom_open(self.json_collapsed_obs) as f:
-            t = parse_biom_table(f)
-            obs = self.cmd(table=t,
-                           output_filepath=self.output_filepath, to_hdf5=True,
+            obs = self.cmd(table=parse_biom_table(f), to_hdf5=True,
                            collapsed_observations=True)
-        obs = load_table(self.output_filepath)
+        self.assertEqual(obs.keys(), ['table'])
         exp = Table(np.array([[2., 1., 1., 0., 0., 1.],
                               [0., 0., 1., 4., 0., 2.],
                               [5., 1., 0., 2., 3., 1.],
                               [0., 1., 2., 0., 0., 0.]]),
-                    observation_ids=[u'p__Firmicutes', u'p__Euryarchaeota',
-                                     u'p__Cyanobacteria',
-                                     u'p__Proteobacteria'],
-                    sample_ids=[u'Sample1', u'Sample2', u'Sample3',
-                                u'Sample4', u'Sample5', u'Sample6'],
+                    observation_ids=['p__Firmicutes', 'p__Euryarchaeota',
+                                     'p__Cyanobacteria', 'p__Proteobacteria'],
+                    sample_ids=['Sample1', 'Sample2', 'Sample3',
+                                'Sample4', 'Sample5', 'Sample6'],
                     observation_metadata=[
-                        {u'collapsed_ids': [u'GG_OTU_4']},
-                        {u'collapsed_ids': [u'GG_OTU_3']},
-                        {u'collapsed_ids': [u'GG_OTU_2']},
-                        {u'collapsed_ids': [u'GG_OTU_1', u'GG_OTU_5']}],
+                        {'collapsed_ids': ['GG_OTU_4']},
+                        {'collapsed_ids': ['GG_OTU_3']},
+                        {'collapsed_ids': ['GG_OTU_2']},
+                        {'collapsed_ids': ['GG_OTU_1', 'GG_OTU_5']}],
                     sample_metadata=[
-                        {u'LinkerPrimerSequence': u'CATGCTGCCTCCCGTAGGAGT',
-                         u'BarcodeSequence': u'CGCTTATCGAGA',
-                         u'Description': u'human gut',
-                         u'BODY_SITE': u'gut'},
-                        {u'LinkerPrimerSequence': u'CATGCTGCCTCCCGTAGGAGT',
-                         u'BarcodeSequence': u'CATACCAGTAGC',
-                         u'Description': u'human gut',
-                         u'BODY_SITE': u'gut'},
-                        {u'LinkerPrimerSequence': u'CATGCTGCCTCCCGTAGGAGT',
-                         u'BarcodeSequence': u'CTCTCTACCTGT',
-                         u'Description': u'human gut',
-                         u'BODY_SITE': u'gut'},
-                        {u'LinkerPrimerSequence': u'CATGCTGCCTCCCGTAGGAGT',
-                         u'BarcodeSequence': u'CTCTCGGCCTGT',
-                         u'Description': u'human skin',
-                         u'BODY_SITE': u'skin'},
-                        {u'LinkerPrimerSequence': u'CATGCTGCCTCCCGTAGGAGT',
-                         u'BarcodeSequence': u'CTCTCTACCAAT',
-                         u'Description': u'human skin',
-                         u'BODY_SITE': u'skin'},
-                        {u'LinkerPrimerSequence': u'CATGCTGCCTCCCGTAGGAGT',
-                         u'BarcodeSequence': u'CTAACTACCAAT',
-                         u'Description': u'human skin',
-                         u'BODY_SITE': u'skin'}],
-                    type=u'OTU table')
-
-        self.assertEqual(obs, exp)
+                        {'LinkerPrimerSequence': 'CATGCTGCCTCCCGTAGGAGT',
+                         'BarcodeSequence': 'CGCTTATCGAGA',
+                         'Description': 'human gut',
+                         'BODY_SITE': 'gut'},
+                        {'LinkerPrimerSequence': 'CATGCTGCCTCCCGTAGGAGT',
+                         'BarcodeSequence': 'CATACCAGTAGC',
+                         'Description': 'human gut',
+                         'BODY_SITE': 'gut'},
+                        {'LinkerPrimerSequence': 'CATGCTGCCTCCCGTAGGAGT',
+                         'BarcodeSequence': 'CTCTCTACCTGT',
+                         'Description': 'human gut',
+                         'BODY_SITE': 'gut'},
+                        {'LinkerPrimerSequence': 'CATGCTGCCTCCCGTAGGAGT',
+                         'BarcodeSequence': 'CTCTCGGCCTGT',
+                         'Description': 'human skin',
+                         'BODY_SITE': 'skin'},
+                        {'LinkerPrimerSequence': 'CATGCTGCCTCCCGTAGGAGT',
+                         'BarcodeSequence': 'CTCTCTACCAAT',
+                         'Description': 'human skin',
+                         'BODY_SITE': 'skin'},
+                        {'LinkerPrimerSequence': 'CATGCTGCCTCCCGTAGGAGT',
+                         'BarcodeSequence': 'CTAACTACCAAT',
+                         'Description': 'human skin',
+                         'BODY_SITE': 'skin'}],
+                    type='OTU table')
+        self.assertEqual(obs['table'][0], exp)
 
 
 biom1 = """
diff --git a/tests/test_commands/test_table_normalizer.py b/tests/test_commands/test_table_normalizer.py
new file mode 100755
index 0000000..d994366
--- /dev/null
+++ b/tests/test_commands/test_table_normalizer.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+__author__ = "Michael Shaffer"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Michael Shaffer"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+from biom.commands.table_normalizer import TableNormalizer
+from biom.parse import parse_biom_table
+from unittest import TestCase, main
+from biom.util import HAVE_H5PY
+from pyqi.core.exception import CommandError
+
+
+class TableNormalizerTests(TestCase):
+
+    def setUp(self):
+        """initialize objects for use in tests"""
+        self.cmd = TableNormalizer()
+        self.biom_path = 'test_data/test.biom'
+
+    def test_correct_table_type(self):
+        table = self.cmd(biom_table=self.biom_path, relative_abund=True,
+                         axis="sample")['table']
+        if HAVE_H5PY:
+            self.assertEqual(table[1], "hdf5")
+        else:
+            self.assertEqual(table[1], "json")
+
+    def test_bad_inputs(self):
+        # relative_abund and pa
+        with self.assertRaises(CommandError):
+            self.cmd(biom_table=self.biom_path, relative_abund=True,
+                     presence_absence=True, axis="sample")
+        # no normalization type
+        with self.assertRaises(CommandError):
+            self.cmd(biom_table=self.biom_path, relative_abund=False,
+                     presence_absence=False, axis="sample")
+        # bad axis
+        with self.assertRaises(CommandError):
+            self.cmd(biom_table=self.biom_path, relative_abund=True,
+                     axis="nonsense")
+
+if __name__ == "__main__":
+    main()
diff --git a/tests/test_cli/test_subset_table.py b/tests/test_commands/test_table_subsetter.py
similarity index 65%
rename from tests/test_cli/test_subset_table.py
rename to tests/test_commands/test_table_subsetter.py
index f3d8265..e118c5a 100644
--- a/tests/test_cli/test_subset_table.py
+++ b/tests/test_commands/test_table_subsetter.py
@@ -1,31 +1,43 @@
+#!/usr/bin/env python
+
 # -----------------------------------------------------------------------------
-# Copyright (c) 2011-2015, The BIOM Format Development Team.
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
 #
 # Distributed under the terms of the Modified BSD License.
 #
 # The full license is in the file COPYING.txt, distributed with this software.
 # -----------------------------------------------------------------------------
 
-import os
-import unittest
-
-import numpy.testing as npt
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
 
-from biom.cli.table_subsetter import _subset_table
+import os
+from pyqi.core.exception import CommandError
+from biom.commands.table_subsetter import TableSubsetter
 from biom.parse import parse_biom_table
+from unittest import TestCase, main
+import numpy.testing as npt
 from biom.util import HAVE_H5PY
 
 
-class TestSubsetTable(unittest.TestCase):
+class TableSubsetterTests(TestCase):
+
     def setUp(self):
         """Set up data for use in unit tests."""
+        self.cmd = TableSubsetter()
         self.biom_str1 = biom1
 
     def test_subset_samples(self):
         """Correctly subsets samples in a table."""
-        obs = _subset_table(json_table_str=self.biom_str1, axis='sample',
-                       ids=['f4', 'f2'], hdf5_biom=None)
-        obs = parse_biom_table(list(obs[0]))
+        obs = self.cmd(json_table_str=self.biom_str1, axis='sample',
+                       ids=['f4', 'f2'])
+        self.assertEqual(obs.keys(), ['subsetted_table'])
+        obs = parse_biom_table(list(obs['subsetted_table'][0]))
         self.assertEqual(len(obs.ids()), 2)
         self.assertEqual(len(obs.ids(axis='observation')), 14)
         self.assertTrue('f4' in obs.ids())
@@ -33,9 +45,10 @@ class TestSubsetTable(unittest.TestCase):
 
     def test_subset_observations(self):
         """Correctly subsets observations in a table."""
-        obs = _subset_table(json_table_str=self.biom_str1, axis='observation',
-                       ids=['None2', '879972'], hdf5_biom=None)
-        obs = parse_biom_table(list(obs[0]))
+        obs = self.cmd(json_table_str=self.biom_str1, axis='observation',
+                       ids=['None2', '879972'])
+        self.assertEqual(obs.keys(), ['subsetted_table'])
+        obs = parse_biom_table(list(obs['subsetted_table'][0]))
         self.assertEqual(len(obs.ids()), 9)
         self.assertEqual(len(obs.ids(axis='observation')), 2)
         self.assertTrue('None2' in obs.ids(axis='observation'))
@@ -43,15 +56,15 @@ class TestSubsetTable(unittest.TestCase):
 
     def test_invalid_input(self):
         """Correctly raises politically correct error upon invalid input."""
-        with self.assertRaises(ValueError):
-            _subset_table(hdf5_biom=None, json_table_str=self.biom_str1, axis='foo',
+        with self.assertRaises(CommandError):
+            self.cmd(json_table_str=self.biom_str1, axis='foo',
                      ids=['f2', 'f4'])
 
-        with self.assertRaises(ValueError):
-            _subset_table(hdf5_biom=None, json_table_str=None, axis='sample', ids=['f2', 'f4'])
+        with self.assertRaises(CommandError):
+            self.cmd(axis='sample', ids=['f2', 'f4'])
 
-        with self.assertRaises(ValueError):
-            _subset_table(json_table_str=self.biom_str1, hdf5_biom='foo',
+        with self.assertRaises(CommandError):
+            self.cmd(json_table_str=self.biom_str1, hdf5_table='foo',
                      axis='sample', ids=['f2', 'f4'])
 
     @npt.dec.skipif(HAVE_H5PY is False, msg='H5PY is not installed')
@@ -60,16 +73,16 @@ class TestSubsetTable(unittest.TestCase):
         cwd = os.getcwd()
         if '/' in __file__:
             os.chdir(__file__.rsplit('/', 1)[0])
-        obs = _subset_table(hdf5_biom='test_data/test.biom', axis='sample',
-                           ids=[u'Sample1', u'Sample2', u'Sample3'],
-                           json_table_str=None)
+        obs = self.cmd(hdf5_table='test_data/test.biom', axis='sample',
+                       ids=['Sample1', 'Sample2', 'Sample3'])
         os.chdir(cwd)
-        obs = obs[0]
+        self.assertEqual(obs.keys(), ['subsetted_table'])
+        obs = obs['subsetted_table'][0]
         self.assertEqual(len(obs.ids()), 3)
         self.assertEqual(len(obs.ids(axis='observation')), 5)
-        self.assertTrue(u'Sample1' in obs.ids())
-        self.assertTrue(u'Sample2' in obs.ids())
-        self.assertTrue(u'Sample3' in obs.ids())
+        self.assertTrue('Sample1' in obs.ids())
+        self.assertTrue('Sample2' in obs.ids())
+        self.assertTrue('Sample3' in obs.ids())
 
     @npt.dec.skipif(HAVE_H5PY is False, msg='H5PY is not installed')
     def test_subset_observations_hdf5(self):
@@ -77,16 +90,16 @@ class TestSubsetTable(unittest.TestCase):
         cwd = os.getcwd()
         if '/' in __file__:
             os.chdir(__file__.rsplit('/', 1)[0])
-        obs = _subset_table(hdf5_biom='test_data/test.biom', axis='observation',
-                           ids=[u'GG_OTU_1', u'GG_OTU_3', u'GG_OTU_5'],
-                           json_table_str=None)
+        obs = self.cmd(hdf5_table='test_data/test.biom', axis='observation',
+                       ids=['GG_OTU_1', 'GG_OTU_3', 'GG_OTU_5'])
         os.chdir(cwd)
-        obs = obs[0]
+        self.assertEqual(obs.keys(), ['subsetted_table'])
+        obs = obs['subsetted_table'][0]
         self.assertEqual(len(obs.ids()), 4)
         self.assertEqual(len(obs.ids(axis='observation')), 3)
-        self.assertTrue(u'GG_OTU_1' in obs.ids(axis='observation'))
-        self.assertTrue(u'GG_OTU_3' in obs.ids(axis='observation'))
-        self.assertTrue(u'GG_OTU_5' in obs.ids(axis='observation'))
+        self.assertTrue('GG_OTU_1' in obs.ids(axis='observation'))
+        self.assertTrue('GG_OTU_3' in obs.ids(axis='observation'))
+        self.assertTrue('GG_OTU_5' in obs.ids(axis='observation'))
 
 
 biom1 = ('{"id": "None","format": "Biological Observation Matrix 1.0.0",'
@@ -118,5 +131,6 @@ biom1 = ('{"id": "None","format": "Biological Observation Matrix 1.0.0",'
          ' "p1", "metadata": null},{"id": "t1", "metadata": null},{"id": '
          '"not16S.1", "metadata": null},{"id": "t2", "metadata": null}]}')
 
+
 if __name__ == "__main__":
-    unittest.main()
+    main()
diff --git a/tests/test_commands/test_table_summarizer.py b/tests/test_commands/test_table_summarizer.py
new file mode 100644
index 0000000..ddd91ce
--- /dev/null
+++ b/tests/test_commands/test_table_summarizer.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+__author__ = "Greg Caporaso"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Greg Caporaso", "Jai Ram Rideout", "Jose Antonio Navas Molina"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Greg Caporaso"
+__email__ = "gregcaporaso at gmail.com"
+
+from biom.commands.table_summarizer import TableSummarizer
+from biom.parse import parse_biom_table
+from unittest import TestCase, main
+
+
+class TableSummarizerTests(TestCase):
+
+    def setUp(self):
+        """ initialize objects for use in tests """
+        self.biom1_lines = biom1
+        self.summary_default_lines = summary_default.split('\n')
+        self.summary_qualitative_lines = summary_qualitative.split('\n')
+
+    def test_default(self):
+        """ TableSummarizer functions as expected
+
+        """
+        t = TableSummarizer()
+        actual = t(table=(parse_biom_table(self.biom1_lines),
+                          self.biom1_lines.split('\n')),
+                   qualitative=False)
+        self.assertEqual(actual['biom_summary'], self.summary_default_lines)
+
+    def test_qualitative(self):
+        """ TableSummarizer functions as expected with qualitative=True
+
+        """
+        t = TableSummarizer()
+        actual = t(table=(parse_biom_table(self.biom1_lines),
+                          self.biom1_lines.split('\n')),
+                   qualitative=True)
+        self.assertEqual(
+            actual['biom_summary'],
+            self.summary_qualitative_lines)
+
+biom1 = ('{"id": "None","format": "Biological Observation Matrix 1.0.0",'
+         '"format_url": "http://biom-format.org","type": "OTU table",'
+         '"generated_by": "QIIME 1.6.0-dev","date": '
+         '"2013-02-09T09:30:11.550590","matrix_type": "sparse",'
+         '"matrix_element_type": "int","shape": [14, 9],"data": [[0,0,20],'
+         '[0,1,18],[0,2,18],[0,3,22],[0,4,4],[1,4,1],[2,0,1],[2,4,1],[2,5,1],'
+         '[3,6,1],[4,4,1],[5,7,20],[6,4,1],[7,4,1],[7,5,1],[8,4,1],[8,6,2],'
+         '[8,8,3],[9,7,2],[10,5,1],[11,4,9],[11,5,20],[11,6,1],[11,8,4],'
+         '[12,4,3],[12,6,19],[12,8,15],[13,0,1],[13,1,4],[13,2,4]],"rows": '
+         '[{"id": "295053", "metadata": {"taxonomy": ["k__Bacteria"]}},{"id": '
+         '"42684", "metadata": {"taxonomy": ["k__Bacteria", '
+         '"p__Proteobacteria"]}},{"id": "None11", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None10", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None7", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None6", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None5", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}},{"id": "None4", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None3", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}},{"id": "None2", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}},{"id": "None1", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "879972", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}},{"id": "None9", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None8", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}}],"columns": [{"id": "f2", "metadata": null},'
+         '{"id": "f1", "metadata": null},{"id": "f3", "metadata": null},'
+         '{"id": "f4", "metadata": null},{"id": "p2", "metadata": null},{"id":'
+         ' "p1", "metadata": null},{"id": "t1", "metadata": null},{"id": '
+         '"not16S.1", "metadata": null},{"id": "t2", "metadata": null}]}')
+
+summary_default = """Num samples: 9
+Num observations: 14
+Total count: 200
+Table density (fraction of non-zero values): 0.238
+
+Counts/sample summary:
+ Min: 22.0
+ Max: 23.0
+ Median: 22.000
+ Mean: 22.222
+ Std. dev.: 0.416
+ Sample Metadata Categories: None provided
+ Observation Metadata Categories: taxonomy
+
+Counts/sample detail:
+ p2: 22.0
+ f1: 22.0
+ f2: 22.0
+ f3: 22.0
+ f4: 22.0
+ t2: 22.0
+ not16S.1: 22.0
+ t1: 23.0
+ p1: 23.0"""
+
+summary_qualitative = """Num samples: 9
+Num observations: 14
+
+Observations/sample summary:
+ Min: 1
+ Max: 9
+ Median: 3.000
+ Mean: 3.333
+ Std. dev.: 2.211
+ Sample Metadata Categories: None provided
+ Observation Metadata Categories: taxonomy
+
+Observations/sample detail:
+ f4: 1
+ f1: 2
+ f3: 2
+ not16S.1: 2
+ f2: 3
+ t2: 3
+ t1: 4
+ p1: 4
+ p2: 9"""
+
+if __name__ == "__main__":
+    main()
diff --git a/tests/test_cli/test_validate_table.py b/tests/test_commands/test_table_validator.py
similarity index 99%
rename from tests/test_cli/test_validate_table.py
rename to tests/test_commands/test_table_validator.py
index ab3df4f..59e4d15 100644
--- a/tests/test_cli/test_validate_table.py
+++ b/tests/test_commands/test_table_validator.py
@@ -24,7 +24,7 @@ from shutil import copy
 
 import numpy.testing as npt
 
-from biom.cli.table_validator import TableValidator
+from biom.commands.table_validator import TableValidator
 from biom.util import HAVE_H5PY
 
 
diff --git a/tests/test_data/empty.biom b/tests/test_data/empty.biom
new file mode 100644
index 0000000..ac05afd
Binary files /dev/null and b/tests/test_data/empty.biom differ
diff --git a/tests/test_data/no-contents.biom b/tests/test_data/no-contents.biom
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_data/test.biom b/tests/test_data/test.biom
new file mode 100644
index 0000000..324ac7a
Binary files /dev/null and b/tests/test_data/test.biom differ
diff --git a/tests/test_data/test.json b/tests/test_data/test.json
new file mode 100644
index 0000000..91c698a
--- /dev/null
+++ b/tests/test_data/test.json
@@ -0,0 +1 @@
+{"id": "No Table ID","format": "Biological Observation Matrix 1.0.0","format_url": "http://biom-format.org","generated_by": "BIOM-Format 2.0.0-dev","date": "2014-06-02T10:08:43.174137","matrix_element_type": "float","shape": [5, 6],"data": [[0,2,1.0],[1,0,5.0],[1,1,1.0],[1,3,2.0],[1,4,3.0],[1,5,1.0],[2,2,1.0],[2,3,4.0],[2,5,2.0],[3,0,2.0],[3,1,1.0],[3,2,1.0],[3,5,1.0],[4,1,1.0],[4,2,1.0]],"rows": [{"id": "GG_OTU_1", "metadata": {"taxonomy": ["k__Bacteria", "p__Proteobacteria", "c__Gammap [...]
\ No newline at end of file
diff --git a/tests/test_data/test.json.gz b/tests/test_data/test.json.gz
new file mode 100644
index 0000000..b042894
Binary files /dev/null and b/tests/test_data/test.json.gz differ
diff --git a/tests/test_interfaces/__init__.py b/tests/test_interfaces/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_interfaces/test_optparse/__init__.py b/tests/test_interfaces/test_optparse/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_interfaces/test_optparse/test_input_handler.py b/tests/test_interfaces/test_optparse/test_input_handler.py
new file mode 100644
index 0000000..9e2317c
--- /dev/null
+++ b/tests/test_interfaces/test_optparse/test_input_handler.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------------
+# Copyright (c) 2011-2013, The BIOM Format Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+# -----------------------------------------------------------------------------
+
+__author__ = "Jai Ram Rideout"
+__copyright__ = "Copyright 2011-2013, The BIOM Format Development Team"
+__credits__ = ["Jai Ram Rideout"]
+__license__ = "BSD"
+__url__ = "http://biom-format.org"
+__maintainer__ = "Jai Ram Rideout"
+__email__ = "jai.rideout at gmail.com"
+
+import os
+from shutil import rmtree
+from tempfile import mkdtemp
+from unittest import TestCase, main
+from biom.interfaces.optparse.input_handler import (
+    load_biom_table, load_biom_table_with_file_contents, load_json_document,
+    load_metadata)
+from biom.parse import MetadataMap
+from biom.table import Table
+
+
+class InputHandlerTests(TestCase):
+
+    def setUp(self):
+        self.output_dir = mkdtemp()
+
+        self.biom_fp = os.path.join(self.output_dir, 'test.biom')
+        with open(self.biom_fp, 'w') as f:
+            f.write(biom1)
+
+        self.md_fp = os.path.join(self.output_dir, 'md.txt')
+        with open(self.md_fp, 'w') as f:
+            f.write(sample_md1)
+
+    def tearDown(self):
+        rmtree(self.output_dir)
+
+    def test_load_biom_table(self):
+        """Correctly parses and loads a BIOM table."""
+        obs = load_biom_table(self.biom_fp)
+        self.assertEqual(type(obs), Table)
+
+    def test_load_biom_table_with_file_contents(self):
+        """Correctly parses and loads a BIOM table, also returning the file."""
+        obs = load_biom_table_with_file_contents(self.biom_fp)
+        self.assertEqual(len(obs), 2)
+        self.assertEqual(type(obs[0]), Table)
+        self.assertEqual(type(obs[1]), file)
+        obs[1].close()
+
+    def test_load_json_document(self):
+        """Correctly parses and loads a JSON document."""
+        obs = load_json_document(self.biom_fp)
+        self.assertEqual(type(obs), dict)
+        self.assertEqual(obs['type'], 'OTU table')
+
+    def test_load_metadata(self):
+        """Correctly parses and loads a metadata map."""
+        obs = load_metadata(self.md_fp)
+        self.assertEqual(type(obs), MetadataMap)
+        self.assertEqual(obs['t1'], {'foo': 't;b;c'})
+
+        obs = load_metadata(None)
+        self.assertTrue(obs is None)
+
+
+biom1 = ('{"id": "None","format": "Biological Observation Matrix 1.0.0",'
+         '"format_url": "http://biom-format.org","type": "OTU table",'
+         '"generated_by": "QIIME 1.6.0-dev","date": '
+         '"2013-02-09T09:30:11.550590","matrix_type": "sparse",'
+         '"matrix_element_type": "int","shape": [14, 9],"data": [[0,0,20],'
+         '[0,1,18],[0,2,18],[0,3,22],[0,4,4],[1,4,1],[2,0,1],[2,4,1],[2,5,1],'
+         '[3,6,1],[4,4,1],[5,7,20],[6,4,1],[7,4,1],[7,5,1],[8,4,1],[8,6,2],'
+         '[8,8,3],[9,7,2],[10,5,1],[11,4,9],[11,5,20],[11,6,1],[11,8,4],'
+         '[12,4,3],[12,6,19],[12,8,15],[13,0,1],[13,1,4],[13,2,4]],"rows": '
+         '[{"id": "295053", "metadata": {"taxonomy": ["k__Bacteria"]}},{"id": '
+         '"42684", "metadata": {"taxonomy": ["k__Bacteria", '
+         '"p__Proteobacteria"]}},{"id": "None11", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None10", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None7", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None6", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None5", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}},{"id": "None4", "metadata": {"taxonomy": '
+         ' ["Unclassified"]}},{"id": "None3", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}},{"id": "None2", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}},{"id": "None1", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "879972", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}},{"id": "None9", "metadata": {"taxonomy": '
+         '["Unclassified"]}},{"id": "None8", "metadata": {"taxonomy": '
+         '["k__Bacteria"]}}],"columns": [{"id": "f2", "metadata": null},{"id":'
+         ' "f1", "metadata": null},{"id": "f3", "metadata": null},{"id": "f4",'
+         ' "metadata": null},{"id": "p2", "metadata": null},{"id": "p1",'
+         ' "metadata": null},{"id": "t1", "metadata": null},{"id": "not16S.1",'
+         ' "metadata": null},{"id": "t2", "metadata": null}]}')
+
+sample_md1 = """#SampleID\tfoo
+f4\ta;b;c
+not16S.1\tb;c;d
+f2\ta;c;d
+f1\ta;b;c
+p2\tc;b;a
+f3\ta;b;c
+t1\tt;b;c
+p1\tp;b;c
+t2\tt;2;z
+"""
+
+
+if __name__ == '__main__':
+    main()
diff --git a/tests/test_parse.py b/tests/test_parse.py
index 5be8d62..02813b4 100644
--- a/tests/test_parse.py
+++ b/tests/test_parse.py
@@ -9,14 +9,13 @@
 # -----------------------------------------------------------------------------
 
 import os
-from io import StringIO
+from StringIO import StringIO
 import json
 from unittest import TestCase, main
 
-import numpy as np
 import numpy.testing as npt
 
-from biom.parse import generatedby, MetadataMap, parse_biom_table, parse_uc
+from biom.parse import generatedby, MetadataMap, parse_biom_table
 from biom.table import Table
 from biom.util import HAVE_H5PY, __version__
 if HAVE_H5PY:
@@ -163,7 +162,7 @@ class ParseTests(TestCase):
         self.assertEqual(tab.metadata(), None)
         self.assertEqual(tab.metadata(axis='observation'), None)
 
-        tablestring = u'''{
+        tablestring = '''{
             "id":null,
             "format": "Biological Observation Matrix 0.9.1-dev",
             "format_url": "http://biom-format.org",
@@ -356,7 +355,7 @@ K00507	0.0	0.0	Metabolism; Lipid Metabolism; Biosynthesis of unsaturated fatt\
 y acids|Organismal Systems; Endocrine System; PPAR signaling pathway
 """
 
-biom_minimal_sparse = u"""
+biom_minimal_sparse = """
     {
         "id":null,
         "format": "Biological Observation Matrix v0.9",
@@ -1554,139 +1553,5 @@ classic_otu_table1_no_tax = """#Full OTU Counts
 415	0	0	0	0	0	7	0	2	2
 416	0	1	0	0	1	0	0	0	0"""
 
-
-class ParseUcTests(TestCase):
-
-    def test_empty(self):
-        """ empty uc file returns empty Table
-        """
-        actual = parse_uc(uc_empty.split('\n'))
-        expected = Table(np.array([[]]),
-                         observation_ids=[],
-                         sample_ids=[])
-        self.assertEqual(actual, expected)
-
-    def test_minimal(self):
-        """ single new seed observed
-        """
-        actual = parse_uc(uc_minimal.split('\n'))
-        expected = Table(np.array([[1.0]]),
-                         observation_ids=['f2_1539'],
-                         sample_ids=['f2'])
-        self.assertEqual(actual, expected)
-
-    def test_lib_minimal(self):
-        """ single library seed observed
-        """
-        actual = parse_uc(uc_lib_minimal.split('\n'))
-        expected = Table(np.array([[1.0]]),
-                         observation_ids=['295053'],
-                         sample_ids=['f2'])
-        self.assertEqual(actual, expected)
-
-    def test_invalid(self):
-        """ invalid query sequence identifier detected
-        """
-        self.assertRaises(ValueError, parse_uc, uc_invalid_id.split('\n'))
-
-    def test_seed_hits(self):
-        """ multiple new seeds observed
-        """
-        actual = parse_uc(uc_seed_hits.split('\n'))
-        expected = Table(np.array([[2.0, 1.0], [0.0, 1.0]]),
-                         observation_ids=['f2_1539', 'f3_44'],
-                         sample_ids=['f2', 'f3'])
-        self.assertEqual(actual, expected)
-
-    def test_mixed_hits(self):
-        """ new and library seeds observed
-        """
-        actual = parse_uc(uc_mixed_hits.split('\n'))
-        expected = Table(np.array([[2.0, 1.0], [0.0, 1.0], [1.0, 0.0]]),
-                         observation_ids=['f2_1539', 'f3_44', '295053'],
-                         sample_ids=['f2', 'f3'])
-        self.assertEqual(actual, expected)
-
-
-# no hits or library seeds
-uc_empty = """# uclust --input /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T/UclustExactMatchFilterrW47Ju.fasta --id 0.97 --tmpdir /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T --w 8 --stepwords 8 --usersort --maxaccepts 1 --stable_sort --maxrejects 8 --uc dn-otus/uclust_picked_otus/seqs_clusters.uc
-# version=1.2.22
-# Tab-separated fields:
-# 1=Type, 2=ClusterNr, 3=SeqLength or ClusterSize, 4=PctId, 5=Strand, 6=QueryStart, 7=SeedStart, 8=Alignment, 9=QueryLabel, 10=TargetLabel
-# Record types (field 1): L=LibSeed, S=NewSeed, H=Hit, R=Reject, D=LibCluster, C=NewCluster, N=NoHit
-# For C and D types, PctId is average id with seed.
-# QueryStart and SeedStart are zero-based relative to start of sequence.
-# If minus strand, SeedStart is relative to reverse-complemented seed.
-"""
-
-# label not in qiime post-split-libraries format
-uc_invalid_id = """# uclust --input /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T/UclustExactMatchFilterrW47Ju.fasta --id 0.97 --tmpdir /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T --w 8 --stepwords 8 --usersort --maxaccepts 1 --stable_sort --maxrejects 8 --uc dn-otus/uclust_picked_otus/seqs_clusters.uc
-# version=1.2.22
-# Tab-separated fields:
-# 1=Type, 2=ClusterNr, 3=SeqLength or ClusterSize, 4=PctId, 5=Strand, 6=QueryStart, 7=SeedStart, 8=Alignment, 9=QueryLabel, 10=TargetLabel
-# Record types (field 1): L=LibSeed, S=NewSeed, H=Hit, R=Reject, D=LibCluster, C=NewCluster, N=NoHit
-# For C and D types, PctId is average id with seed.
-# QueryStart and SeedStart are zero-based relative to start of sequence.
-# If minus strand, SeedStart is relative to reverse-complemented seed.
-S	0	133	*	*	*	*	*	1539	*
-"""
-
-# contains single new (de novo) seed hit
-uc_minimal = """# uclust --input /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T/UclustExactMatchFilterrW47Ju.fasta --id 0.97 --tmpdir /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T --w 8 --stepwords 8 --usersort --maxaccepts 1 --stable_sort --maxrejects 8 --uc dn-otus/uclust_picked_otus/seqs_clusters.uc
-# version=1.2.22
-# Tab-separated fields:
-# 1=Type, 2=ClusterNr, 3=SeqLength or ClusterSize, 4=PctId, 5=Strand, 6=QueryStart, 7=SeedStart, 8=Alignment, 9=QueryLabel, 10=TargetLabel
-# Record types (field 1): L=LibSeed, S=NewSeed, H=Hit, R=Reject, D=LibCluster, C=NewCluster, N=NoHit
-# For C and D types, PctId is average id with seed.
-# QueryStart and SeedStart are zero-based relative to start of sequence.
-# If minus strand, SeedStart is relative to reverse-complemented seed.
-S	0	133	*	*	*	*	*	f2_1539	*
-"""
-
-# contains single library (reference) seed hit
-uc_lib_minimal = """# uclust --input /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T/UclustExactMatchFilterrW47Ju.fasta --id 0.97 --tmpdir /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T --w 8 --stepwords 8 --usersort --maxaccepts 1 --stable_sort --maxrejects 8 --uc dn-otus/uclust_picked_otus/seqs_clusters.uc
-# version=1.2.22
-# Tab-separated fields:
-# 1=Type, 2=ClusterNr, 3=SeqLength or ClusterSize, 4=PctId, 5=Strand, 6=QueryStart, 7=SeedStart, 8=Alignment, 9=QueryLabel, 10=TargetLabel
-# Record types (field 1): L=LibSeed, S=NewSeed, H=Hit, R=Reject, D=LibCluster, C=NewCluster, N=NoHit
-# For C and D types, PctId is average id with seed.
-# QueryStart and SeedStart are zero-based relative to start of sequence.
-# If minus strand, SeedStart is relative to reverse-complemented seed.
-L	3	1389	*	*	*	*	*	295053	*
-H	3	133	100.0	+	0	0	519I133M737I	f2_1539	295053
-"""
-
-# contains new seed (de novo) hits only
-uc_seed_hits = """# uclust --input /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T/UclustExactMatchFilterrW47Ju.fasta --id 0.97 --tmpdir /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T --w 8 --stepwords 8 --usersort --maxaccepts 1 --stable_sort --maxrejects 8 --uc dn-otus/uclust_picked_otus/seqs_clusters.uc
-# version=1.2.22
-# Tab-separated fields:
-# 1=Type, 2=ClusterNr, 3=SeqLength or ClusterSize, 4=PctId, 5=Strand, 6=QueryStart, 7=SeedStart, 8=Alignment, 9=QueryLabel, 10=TargetLabel
-# Record types (field 1): L=LibSeed, S=NewSeed, H=Hit, R=Reject, D=LibCluster, C=NewCluster, N=NoHit
-# For C and D types, PctId is average id with seed.
-# QueryStart and SeedStart are zero-based relative to start of sequence.
-# If minus strand, SeedStart is relative to reverse-complemented seed.
-S	0	133	*	*	*	*	*	f2_1539	*
-H	0	141	100.0	+	0	0	133M8D	f3_42	f2_1539
-H	0	141	100.0	+	0	0	133M8D	f2_43	f2_1539
-S	0	133	*	*	*	*	*	f3_44	*
-"""
-
-# contains library (reference) and new seed (de novo) hits
-uc_mixed_hits = """# uclust --input /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T/UclustExactMatchFilterrW47Ju.fasta --id 0.97 --tmpdir /var/folders/xq/0kh93ng53bs6zzk091w_bbsr0000gn/T --w 8 --stepwords 8 --usersort --maxaccepts 1 --stable_sort --maxrejects 8 --uc dn-otus/uclust_picked_otus/seqs_clusters.uc
-# version=1.2.22
-# Tab-separated fields:
-# 1=Type, 2=ClusterNr, 3=SeqLength or ClusterSize, 4=PctId, 5=Strand, 6=QueryStart, 7=SeedStart, 8=Alignment, 9=QueryLabel, 10=TargetLabel
-# Record types (field 1): L=LibSeed, S=NewSeed, H=Hit, R=Reject, D=LibCluster, C=NewCluster, N=NoHit
-# For C and D types, PctId is average id with seed.
-# QueryStart and SeedStart are zero-based relative to start of sequence.
-# If minus strand, SeedStart is relative to reverse-complemented seed.
-S	0	133	*	*	*	*	*	f2_1539	*
-H	0	141	100.0	+	0	0	133M8D	f3_42	f2_1539
-H	0	141	100.0	+	0	0	133M8D	f2_43	f2_1539
-S	0	133	*	*	*	*	*	f3_44	*
-L	3	1389	*	*	*	*	*	295053	*
-H	3	133	100.0	+	0	0	519I133M737I	f2_1539	295053
-"""
-
 if __name__ == '__main__':
     main()
diff --git a/tests/test_table.py b/tests/test_table.py
index 6e6f21e..adfe0ba 100644
--- a/tests/test_table.py
+++ b/tests/test_table.py
@@ -13,14 +13,12 @@ import os
 from json import loads
 from tempfile import NamedTemporaryFile
 from unittest import TestCase, main
-from io import StringIO
+from StringIO import StringIO
 
-from future.utils import viewkeys
 import numpy.testing as npt
 import numpy as np
 from scipy.sparse import lil_matrix, csr_matrix, csc_matrix
 
-from biom import example_table
 from biom.exception import UnknownAxisError, UnknownIDError, TableException
 from biom.util import unzip, HAVE_H5PY, H5PY_VLEN_STR
 from biom.table import (Table, prefer_self, index_list, list_nparray_to_sparse,
@@ -46,57 +44,6 @@ __email__ = "daniel.mcdonald at colorado.edu"
 
 
 class SupportTests(TestCase):
-
-    def test_head(self):
-        # example table is 2 x 3, so no change in contained data
-        exp = example_table
-        obs = example_table.head()
-        self.assertIsNot(obs, exp)
-        self.assertEqual(obs, exp)
-
-    def test_head_bounded(self):
-        obs = example_table.head(1)
-        from collections import defaultdict
-        exp = Table(np.array([[0., 1., 2.]]), ['O1'], ['S1', 'S2', 'S3'],
-                             [{'taxonomy': ['Bacteria', 'Firmicutes']}],
-                             [{'environment': 'A'}, {'environment': 'B'},
-                              {'environment': 'A'}])
-
-        self.assertEqual(obs, exp)
-
-        obs = example_table.head(m=2)
-        exp = Table(np.array([[0., 1.], [3., 4.]]), ['O1', 'O2'], ['S1', 'S2'],
-                             [{'taxonomy': ['Bacteria', 'Firmicutes']},
-                              {'taxonomy': ['Bacteria', 'Bacteroidetes']}],
-                             [{'environment': 'A'}, {'environment': 'B'}])
-        self.assertEqual(obs, exp)
-
-    def test_head_overstep(self):
-        # silently works
-        exp = example_table
-        obs = example_table.head(10000)
-        self.assertIsNot(obs, exp)
-        self.assertEqual(obs, exp)
-
-    def test_head_zero_or_neg(self):
-        with self.assertRaises(IndexError):
-            example_table.head(0)
-
-        with self.assertRaises(IndexError):
-            example_table.head(-1)
-
-        with self.assertRaises(IndexError):
-            example_table.head(m=0)
-
-        with self.assertRaises(IndexError):
-            example_table.head(m=-1)
-
-        with self.assertRaises(IndexError):
-            example_table.head(0, 5)
-
-        with self.assertRaises(IndexError):
-            example_table.head(5, 0)
-
     def test_table_sparse_nparray(self):
         """beat the table sparsely to death"""
         # nparray test
@@ -377,11 +324,11 @@ class TableTests(TestCase):
         t = Table.from_hdf5(h5py.File('test_data/test.biom'))
         os.chdir(cwd)
 
-        npt.assert_equal(t.ids(), (u'Sample1', u'Sample2', u'Sample3',
-                                   u'Sample4', u'Sample5', u'Sample6'))
+        npt.assert_equal(t.ids(), ('Sample1', 'Sample2', 'Sample3',
+                                   'Sample4', 'Sample5', 'Sample6'))
         npt.assert_equal(t.ids(axis='observation'),
-                         (u'GG_OTU_1', u'GG_OTU_2', u'GG_OTU_3',
-                          u'GG_OTU_4', u'GG_OTU_5'))
+                         ('GG_OTU_1', 'GG_OTU_2', 'GG_OTU_3',
+                          'GG_OTU_4', 'GG_OTU_5'))
         exp_obs_md = ({u'taxonomy': [u'k__Bacteria',
                                      u'p__Proteobacteria',
                                      u'c__Gammaproteobacteria',
@@ -455,7 +402,7 @@ class TableTests(TestCase):
     @npt.dec.skipif(HAVE_H5PY is False, msg='H5PY is not installed')
     def test_from_hdf5_sample_subset(self):
         """Parse a sample subset of a hdf5 formatted BIOM table"""
-        samples = [u'Sample2', u'Sample4', u'Sample6']
+        samples = ['Sample2', 'Sample4', 'Sample6']
 
         cwd = os.getcwd()
         if '/' in __file__:
@@ -463,9 +410,9 @@ class TableTests(TestCase):
         t = Table.from_hdf5(h5py.File('test_data/test.biom'), ids=samples)
         os.chdir(cwd)
 
-        npt.assert_equal(t.ids(), [u'Sample2', u'Sample4', u'Sample6'])
+        npt.assert_equal(t.ids(), ['Sample2', 'Sample4', 'Sample6'])
         npt.assert_equal(t.ids(axis='observation'),
-                         [u'GG_OTU_2', u'GG_OTU_3', u'GG_OTU_4', u'GG_OTU_5'])
+                         ['GG_OTU_2', 'GG_OTU_3', 'GG_OTU_4', 'GG_OTU_5'])
         exp_obs_md = ({u'taxonomy': [u'k__Bacteria',
                                      u'p__Cyanobacteria',
                                      u'c__Nostocophycideae',
@@ -519,7 +466,7 @@ class TableTests(TestCase):
     @npt.dec.skipif(HAVE_H5PY is False, msg='H5PY is not installed')
     def test_from_hdf5_observation_subset(self):
         """Parse a observation subset of a hdf5 formatted BIOM table"""
-        observations = [u'GG_OTU_1', u'GG_OTU_3', u'GG_OTU_5']
+        observations = ['GG_OTU_1', 'GG_OTU_3', 'GG_OTU_5']
 
         cwd = os.getcwd()
         if '/' in __file__:
@@ -528,10 +475,9 @@ class TableTests(TestCase):
                             ids=observations, axis='observation')
         os.chdir(cwd)
 
-        npt.assert_equal(t.ids(), [u'Sample2', u'Sample3', u'Sample4',
-                                   u'Sample6'])
+        npt.assert_equal(t.ids(), ['Sample2', 'Sample3', 'Sample4', 'Sample6'])
         npt.assert_equal(t.ids(axis='observation'),
-                         [u'GG_OTU_1', u'GG_OTU_3', u'GG_OTU_5'])
+                         ['GG_OTU_1', 'GG_OTU_3', 'GG_OTU_5'])
         exp_obs_md = ({u'taxonomy': [u'k__Bacteria',
                                      u'p__Proteobacteria',
                                      u'c__Gammaproteobacteria',
@@ -650,7 +596,7 @@ class TableTests(TestCase):
 
         def bc_formatter(grp, category, md, compression):
             name = 'metadata/%s' % category
-            data = np.array([m[category].upper().encode('utf8') for m in md])
+            data = np.array([m[category].upper() for m in md])
             grp.create_dataset(name, shape=data.shape, dtype=H5PY_VLEN_STR,
                                data=data, compression=compression)
 
@@ -771,7 +717,7 @@ class TableTests(TestCase):
         self.assertEqual(sorted(sparse_rich.ids()),
                          sorted(['Fing', 'Key', 'NA']))
         self.assertEqual(sorted(sparse_rich.ids(axis='observation')),
-                         list(map(str, [0, 1, 3, 4, 7])))
+                         map(str, [0, 1, 3, 4, 7]))
         for i, obs_id in enumerate(sparse_rich.ids(axis='observation')):
             if obs_id == '0':
                 self.assertEqual(sparse_rich._observation_metadata[i],
@@ -812,7 +758,7 @@ class TableTests(TestCase):
         self.assertEqual(sorted(sparse_rich.ids()),
                          sorted(['Fing', 'Key', 'NA']))
         self.assertEqual(sorted(sparse_rich.ids(axis='observation')),
-                         list(map(str, [0, 1, 3, 4, 7])))
+                         map(str, [0, 1, 3, 4, 7]))
         for i, obs_id in enumerate(sparse_rich.ids(axis='observation')):
             if obs_id == '0':
                 self.assertEqual(sparse_rich._observation_metadata[i],
@@ -899,10 +845,10 @@ class TableTests(TestCase):
 
     def test_metadata_sample(self):
         """Return the sample metadata"""
-        obs = self.st_rich.metadata()
-        exp = [{'barcode': 'aatt'}, {'barcode': 'ttgg'}]
+        obs = sorted(self.st_rich.metadata())
+        exp = sorted([{'barcode': 'aatt'}, {'barcode': 'ttgg'}])
         for o, e in zip(obs, exp):
-            self.assertDictEqual(o, e)
+            self.assertEqual(o, e)
 
     def test_metadata_observation_id(self):
         """returns the observation metadata for a given id"""
@@ -916,10 +862,11 @@ class TableTests(TestCase):
 
     def test_metadata_observation(self):
         """returns the observation metadata"""
-        obs = self.st_rich.metadata(axis='observation')
-        exp = [{'taxonomy': ['k__a', 'p__b']}, {'taxonomy': ['k__a', 'p__c']}]
+        obs = sorted(self.st_rich.metadata(axis='observation'))
+        exp = sorted([{'taxonomy': ['k__a', 'p__b']},
+                      {'taxonomy': ['k__a', 'p__c']}])
         for o, e in zip(obs, exp):
-            self.assertDictEqual(o, e)
+            self.assertEqual(o, e)
 
     def test_index_invalid_input(self):
         """Correctly handles invalid input."""
@@ -1539,21 +1486,6 @@ class SparseTableTests(TestCase):
         obs = self.st1.update_ids(id_map, axis='observation', inplace=True)
         npt.assert_equal(self.st1._observation_ids, np.array(['41', '42']))
 
-    def test_update_ids_nochange_bug(self):
-        """ids are updated as expected"""
-        # update observation ids
-        exp = self.st1.copy()
-        id_map = {'1': '1', '2': '2'}
-        obs = self.st1.update_ids(id_map, axis='observation', inplace=False)
-        self.assertEqual(obs, exp)
-
-        # test having one ID remain unchanged
-        exp = self.st1.copy()
-        exp._observation_ids = np.array(['1', '3'])
-        id_map = {'1': '1', '2': '3'}
-        obs = self.st1.update_ids(id_map, axis='observation', inplace=False)
-        self.assertEqual(obs, exp)
-
     def test_update_ids_cache_bug(self):
         obs = self.st1.update_ids({'1': 'x', '2': 'y'}, axis='observation',
                                   inplace=False)
@@ -2577,8 +2509,9 @@ class SparseTableTests(TestCase):
         obs_king = dt_rich.collapse(bin_f, norm=False, axis='observation')
         self.assertEqual(obs_king, exp_king)
 
-        with errstate(all='raise'), self.assertRaises(TableException):
-            dt_rich.collapse(bin_f, min_group_size=10, axis='observation')
+        self.assertRaises(
+            TableException, dt_rich.collapse, bin_f, min_group_size=10,
+            axis='observation')
 
         # Test out include_collapsed_metadata=False.
         exp = Table(np.array([[24, 27, 30]]),
@@ -2624,9 +2557,8 @@ class SparseTableTests(TestCase):
             axis='sample').sort(axis='sample')
         self.assertEqual(obs_bc, exp_bc)
 
-        with errstate(all='raise'), self.assertRaises(TableException):
-            dt_rich.collapse(bin_f, min_group_size=10)
-
+        self.assertRaises(TableException, dt_rich.collapse,
+                          bin_f, min_group_size=10)
         # Test out include_collapsed_metadata=False.
         exp = Table(np.array([[12, 6], [18, 9], [24, 12]]),
                     ['1', '2', '3'],
@@ -2844,8 +2776,8 @@ class SparseTableTests(TestCase):
     def test_to_json_dense_int(self):
         """Get a BIOM format string for a dense table of integers"""
         # check by round trip
-        obs_ids = list(map(str, range(5)))
-        samp_ids = list(map(str, range(10)))
+        obs_ids = map(str, range(5))
+        samp_ids = map(str, range(10))
         obs_md = [{'foo': i} for i in range(5)]
         samp_md = [{'bar': i} for i in range(10)]
         data = np.reshape(np.arange(50), (5, 10))
@@ -2880,8 +2812,8 @@ class SparseTableTests(TestCase):
     def test_to_json_dense_int_directio(self):
         """Get a BIOM format string for a dense table of integers"""
         # check by round trip
-        obs_ids = list(map(str, range(5)))
-        samp_ids = list(map(str, range(10)))
+        obs_ids = map(str, range(5))
+        samp_ids = map(str, range(10))
         obs_md = [{'foo': i} for i in range(5)]
         samp_md = [{'bar': i} for i in range(10)]
         data = np.reshape(np.arange(50), (5, 10))
@@ -2922,8 +2854,8 @@ class SparseTableTests(TestCase):
     def test_to_json_sparse_int(self):
         """Get a BIOM format string for a sparse table of integers"""
         # check by round trip
-        obs_ids = list(map(str, range(5)))
-        samp_ids = list(map(str, range(10)))
+        obs_ids = map(str, range(5))
+        samp_ids = map(str, range(10))
         obs_md = [{'foo': i} for i in range(5)]
         samp_md = [{'bar': i} for i in range(10)]
         data = [[0, 0, 10], [1, 1, 11], [2, 2, 12], [3, 3, 13], [4, 4, 14],
@@ -2959,8 +2891,8 @@ class SparseTableTests(TestCase):
     def test_to_json_sparse_int_directio(self):
         """Get a BIOM format string for a sparse table of integers"""
         # check by round trip
-        obs_ids = list(map(str, range(5)))
-        samp_ids = list(map(str, range(10)))
+        obs_ids = map(str, range(5))
+        samp_ids = map(str, range(10))
         obs_md = [{'foo': i} for i in range(5)]
         samp_md = [{'bar': i} for i in range(10)]
         data = [[0, 0, 10], [1, 1, 11], [2, 2, 12], [3, 3, 13], [4, 4, 14],
@@ -3033,7 +2965,7 @@ class SparseTableTests(TestCase):
 
     def test_bin_samples_by_metadata(self):
         """Yield tables binned by sample metadata"""
-        f = lambda id_, md: md.get('age', np.inf)
+        f = lambda id_, md: md['age']
         obs_ids = ['a', 'b', 'c', 'd']
         samp_ids = ['1', '2', '3', '4']
         data = {(0, 0): 1, (0, 1): 2, (0, 2): 3, (0, 3): 4,
@@ -3045,7 +2977,7 @@ class SparseTableTests(TestCase):
         t = Table(data, obs_ids, samp_ids, obs_md, samp_md)
         obs_bins, obs_tables = unzip(t.partition(f))
 
-        exp_bins = (2, 4, np.inf)
+        exp_bins = (2, 4, None)
         exp1_data = {(0, 0): 1, (0, 1): 3, (1, 0): 5, (1, 1): 7, (2, 0): 8,
                      (2, 1): 10, (3, 0): 12, (3, 1): 14}
         exp1_obs_ids = ['a', 'b', 'c', 'd']
@@ -3065,7 +2997,7 @@ class SparseTableTests(TestCase):
         exp3_obs_ids = ['a', 'b', 'c', 'd']
         exp3_samp_ids = ['4']
         exp3_obs_md = [{}, {}, {}, {}]
-        exp3_samp_md = [{}]
+        exp3_samp_md = [{'age': None}]
         exp3 = Table(exp3_data, exp3_obs_ids, exp3_samp_ids, exp3_obs_md,
                      exp3_samp_md)
         exp_tables = (exp1, exp2, exp3)
@@ -3154,10 +3086,8 @@ class SparseTableTests(TestCase):
         exp_phy2 = Table(exp_phy2_data, exp_phy2_obs_ids, exp_phy2_samp_ids,
                          observation_metadata=exp_phy2_obs_md)
         obs_bins, obs_phy = unzip(t.partition(func_phy, axis='observation'))
-        self.assertIn(obs_phy[0], [exp_phy1, exp_phy2])
-        self.assertIn(obs_phy[1], [exp_phy1, exp_phy2])
-        self.assertIn(obs_bins[0], [('k__a', 'p__b'), ('k__a', 'p__c')])
-        self.assertIn(obs_bins[1], [('k__a', 'p__b'), ('k__a', 'p__c')])
+        self.assertEqual(obs_phy, [exp_phy1, exp_phy2])
+        self.assertEqual(obs_bins, [('k__a', 'p__b'), ('k__a', 'p__c')])
 
     def test_get_table_density(self):
         """Test correctly computes density of table."""
@@ -3338,7 +3268,7 @@ class SupportTests2(TestCase):
         obs = list_sparse_to_sparse(ins)
         self.assertEqual((obs != exp).sum(), 0)
 
-legacy_otu_table1 = u"""# some comment goes here
+legacy_otu_table1 = """# some comment goes here
 #OTU id\tFing\tKey\tNA\tConsensus Lineage
 0\t19111\t44536\t42 \tBacteria; Actinobacteria; Actinobacteridae; Propioniba\
 cterineae; Propionibacterium
@@ -3351,7 +3281,7 @@ ae; Corynebacteriaceae
 aphylococcaceae
 4\t589\t2074\t34\tBacteria; Cyanobacteria; Chloroplasts; vectors
 """
-otu_table1 = u"""# Some comment
+otu_table1 = """# Some comment
 #OTU ID\tFing\tKey\tNA\tConsensus Lineage
 0\t19111\t44536\t42\tBacteria; Actinobacteria; Actinobacteridae; \
 Propionibacterineae; Propionibacterium
diff --git a/tests/test_util.py b/tests/test_util.py
index 782544d..2a7b542 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -285,7 +285,7 @@ class UtilTests(TestCase):
 
     def test_biom_open_json(self):
         with biom_open(get_data_path('test.json')) as f:
-            self.assertTrue(hasattr(f, 'read'))
+            self.assertTrue(isinstance(f, file))
 
     def test_biom_open_gz(self):
         with biom_open(get_data_path('test.json.gz')) as f:

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-biom-format.git



More information about the debian-med-commit mailing list