Full Code of marcotcr/lime for AI

master fd7eb2e6f760 cached
63 files
39.2 MB
10.3M tokens
1172 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (41,144K chars total). Download the full file to get everything.
Repository: marcotcr/lime
Branch: master
Commit: fd7eb2e6f760
Files: 63
Total size: 39.2 MB

Directory structure:
gitextract_jwcrr_g_/

├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── benchmark/
│   ├── __init__.py
│   ├── table_perf.py
│   └── text_perf.py
├── binder/
│   └── environment.yml
├── citation.bib
├── doc/
│   ├── blog_post.md
│   ├── conf.py
│   ├── index.rst
│   ├── lime.rst
│   └── notebooks/
│       ├── Latin Hypercube Sampling.ipynb
│       ├── Lime - basic usage, two class case.ipynb
│       ├── Lime - multiclass.ipynb
│       ├── Lime with Recurrent Neural Networks.ipynb
│       ├── Submodular Pick examples.ipynb
│       ├── Tutorial - Faces and GradBoost.ipynb
│       ├── Tutorial - Image Classification Keras.ipynb
│       ├── Tutorial - MNIST and RF.ipynb
│       ├── Tutorial - continuous and categorical features.ipynb
│       ├── Tutorial - images - Pytorch.ipynb
│       ├── Tutorial - images.ipynb
│       ├── Tutorial_H2O_continuous_and_cat.ipynb
│       ├── Using lime for regression.ipynb
│       └── data/
│           ├── adult.csv
│           ├── co2_data.csv
│           ├── imagenet_class_index.json
│           └── mushroom_data.csv
├── lime/
│   ├── __init__.py
│   ├── bundle.js
│   ├── discretize.py
│   ├── exceptions.py
│   ├── explanation.py
│   ├── js/
│   │   ├── bar_chart.js
│   │   ├── explanation.js
│   │   ├── main.js
│   │   ├── predict_proba.js
│   │   └── predicted_value.js
│   ├── lime_base.py
│   ├── lime_image.py
│   ├── lime_tabular.py
│   ├── lime_text.py
│   ├── package.json
│   ├── style.css
│   ├── submodular_pick.py
│   ├── test_table.html
│   ├── tests/
│   │   ├── __init__.py
│   │   ├── test_discretize.py
│   │   ├── test_generic_utils.py
│   │   ├── test_lime_tabular.py
│   │   ├── test_lime_text.py
│   │   └── test_scikit_image.py
│   ├── utils/
│   │   ├── __init__.py
│   │   └── generic_utils.py
│   ├── webpack.config.js
│   └── wrappers/
│       ├── __init__.py
│       └── scikit_image.py
├── setup.cfg
└── setup.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Compiled python modules.
*.pyc

# Setuptools distribution folder.
/dist/

/lime/node_modules

# Python egg metadata, regenerated from source files by setuptools.
/*.egg-info

# Unit test / coverage reports
.cache

# Created by https://www.gitignore.io/api/pycharm

### PyCharm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml

# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml

# Gradle:
.idea/gradle.xml
.idea/libraries

# Mongo Explorer plugin:
.idea/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

### PyCharm Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721

# *.iml
# modules.xml
# .idea/misc.xml 
# *.ipr

# Pycharm
.idea


================================================
FILE: .travis.yml
================================================
dist: xenial
sudo: false
language: python
cache: pip
python:
  - "3.6"
  - "3.7"
# command to install dependencies
install:
  - python -m pip install -U pip
  - python -m pip install -e .[dev]
# command to run tests
script:
  - pytest lime
  - flake8 lime


================================================
FILE: CONTRIBUTING.md
================================================
## Contributing
I am delighted when people want to contribute to LIME. Here are a few things to keep in mind before sending in a pull request:
* We are now using flake8 as a style guide enforcer (I plan on adding eslint for javascript soon). Make sure your code passes the default flake8 execution.
* There must be a really good reason to change the external interfaces - I want to avoid breaking previous code as much as possible.
* If you are adding a new feature, please let me know the use case and the rationale behind how you did it (unless it's obvious)

If you want to contribute but don't know where to start, take a look at the [issues page](https://github.com/marcotcr/lime/issues), or at the list below.

# Roadmap
Here are a few high level features I want to incorporate in LIME. If you want to work incrementally in any of these, feel free to start a branch.

1. Creating meaningful tests that we can run before merging things. Right now I run the example notebooks and the few tests we have.
2. Creating a wrapper that computes explanations for a particular dataset, and suggests instances for the user to look at (similar to what we did in [the paper](http://arxiv.org/abs/1602.04938))
3. Making LIME work with images in a reasonable time. The explanations we used in the paper took a few minutes, which is too slow.
4. Thinking through what is needed to use LIME in regression problems. An obvious problem is that features with different scales make it really hard to interpret.
5. Figuring out better alternatives to discretizing the data for tabular data. Discretizing is definitely more interpretable, but we may just want to treat features as continuous.
6. Figuring out better ways to sample around a data point for tabular data. One example is sampling columns from the training set assuming independence, or some form of conditional sampling.


================================================
FILE: LICENSE
================================================
Copyright (c) 2016, Marco Tulio Correia Ribeiro
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

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 HOLDER 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.


================================================
FILE: MANIFEST.in
================================================
include lime/*.js
include LICENSE


================================================
FILE: README.md
================================================
# lime

[![Build Status](https://travis-ci.org/marcotcr/lime.svg?branch=master)](https://travis-ci.org/marcotcr/lime)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/marcotcr/lime/master)

This project is about explaining what machine learning classifiers (or models) are doing.
At the moment, we support explaining individual predictions for text classifiers or classifiers that act on tables (numpy arrays of numerical or categorical data) or images, with a package called lime (short for local interpretable model-agnostic explanations).
Lime is based on the work presented in [this paper](https://arxiv.org/abs/1602.04938) ([bibtex here for citation](https://github.com/marcotcr/lime/blob/master/citation.bib)). Here is a link to the promo video:

<a href="https://www.youtube.com/watch?v=hUnRCxnydCc" target="_blank"><img src="https://raw.githubusercontent.com/marcotcr/lime/master/doc/images/video_screenshot.png" width="450" alt="KDD promo video"/></a>

Our plan is to add more packages that help users understand and interact meaningfully with machine learning.

Lime is able to explain any black box classifier, with two or more classes. All we require is that the classifier implements a function that takes in raw text or a numpy array and outputs a probability for each class. Support for scikit-learn classifiers is built-in.

## Installation

The lime package is on [PyPI](https://pypi.python.org/pypi/lime). Simply run:

```sh
pip install lime
```

Or clone the repository and run:

```sh
pip install .
```

We dropped python2 support in `0.2.0`, `0.1.1.37` was the last version before that.

## Screenshots

Below are some screenshots of lime explanations. These are generated in html, and can be easily produced and embedded in ipython notebooks. We also support visualizations using matplotlib, although they don't look as nice as these ones.

#### Two class case, text

Negative (blue) words indicate atheism, while positive (orange) words indicate christian. The way to interpret the weights by applying them to the prediction probabilities. For example, if we remove the words Host and NNTP from the document, we expect the classifier to predict atheism with probability 0.58 - 0.14 - 0.11 = 0.31.

![twoclass](doc/images/twoclass.png)

#### Multiclass case

![multiclass](doc/images/multiclass.png)

#### Tabular data

![tabular](doc/images/tabular.png)

#### Images (explaining prediction of 'Cat' in pros and cons)

<img src="https://raw.githubusercontent.com/marcotcr/lime/master/doc/images/images.png" width=200 />

## Tutorials and API

For example usage for text classifiers, take a look at the following two tutorials (generated from ipython notebooks):

- [Basic usage, two class. We explain random forest classifiers.](https://marcotcr.github.io/lime/tutorials/Lime%20-%20basic%20usage%2C%20two%20class%20case.html)
- [Multiclass case](https://marcotcr.github.io/lime/tutorials/Lime%20-%20multiclass.html)

For classifiers that use numerical or categorical data, take a look at the following tutorial (this is newer, so please let me know if you find something wrong):

- [Tabular data](https://marcotcr.github.io/lime/tutorials/Tutorial%20-%20continuous%20and%20categorical%20features.html)
- [Tabular data with H2O models](https://marcotcr.github.io/lime/tutorials/Tutorial_H2O_continuous_and_cat.html)
- [Latin Hypercube Sampling](doc/notebooks/Latin%20Hypercube%20Sampling.ipynb)

For image classifiers:

- [Images - basic](https://marcotcr.github.io/lime/tutorials/Tutorial%20-%20images.html)
- [Images - Faces](https://github.com/marcotcr/lime/blob/master/doc/notebooks/Tutorial%20-%20Faces%20and%20GradBoost.ipynb)
- [Images with Keras](https://github.com/marcotcr/lime/blob/master/doc/notebooks/Tutorial%20-%20Image%20Classification%20Keras.ipynb)
- [MNIST with random forests](https://github.com/marcotcr/lime/blob/master/doc/notebooks/Tutorial%20-%20MNIST%20and%20RF.ipynb)
- [Images with PyTorch](https://github.com/marcotcr/lime/blob/master/doc/notebooks/Tutorial%20-%20images%20-%20Pytorch.ipynb)

For regression:

- [Simple regression](https://marcotcr.github.io/lime/tutorials/Using%2Blime%2Bfor%2Bregression.html)

Submodular Pick:

- [Submodular Pick](https://github.com/marcotcr/lime/tree/master/doc/notebooks/Submodular%20Pick%20examples.ipynb)

The raw (non-html) notebooks for these tutorials are available [here](https://github.com/marcotcr/lime/tree/master/doc/notebooks).

The API reference is available [here](https://lime-ml.readthedocs.io/en/latest/).

## What are explanations?

Intuitively, an explanation is a local linear approximation of the model's behaviour.
While the model may be very complex globally, it is easier to approximate it around the vicinity of a particular instance.
While treating the model as a black box, we perturb the instance we want to explain and learn a sparse linear model around it, as an explanation.
The figure below illustrates the intuition for this procedure. The model's decision function is represented by the blue/pink background, and is clearly nonlinear.
The bright red cross is the instance being explained (let's call it X).
We sample instances around X, and weight them according to their proximity to X (weight here is indicated by size).
We then learn a linear model (dashed line) that approximates the model well in the vicinity of X, but not necessarily globally. For more information, [read our paper](https://arxiv.org/abs/1602.04938), or take a look at [this blog post](https://www.oreilly.com/learning/introduction-to-local-interpretable-model-agnostic-explanations-lime).

<img src="https://raw.githubusercontent.com/marcotcr/lime/master/doc/images/lime.png" width=300px />

## Contributing

Please read [this](CONTRIBUTING.md).


================================================
FILE: benchmark/__init__.py
================================================



================================================
FILE: benchmark/table_perf.py
================================================
"""
A helper script for evaluating performance of changes to the tabular explainer, in this case different
implementations and methods for distance calculation.
"""

import time
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from lime.lime_tabular import LimeTabularExplainer


def interpret_data(X, y, func):
    explainer = LimeTabularExplainer(X, discretize_continuous=False, kernel_width=3)
    times, scores = [], []
    for r_idx in range(100):
        start_time = time.time()
        explanation = explainer.explain_instance(X[r_idx, :], func)
        times.append(time.time() - start_time)
        scores.append(explanation.score)
        print('...')

    return times, scores


if __name__ == '__main__':
    X_raw, y_raw = make_classification(n_classes=2, n_features=1000, n_samples=1000)
    clf = RandomForestClassifier()
    clf.fit(X_raw, y_raw)
    y_hat = clf.predict_proba(X_raw)

    times, scores = interpret_data(X_raw, y_hat, clf.predict_proba)
    print('%9.4fs %9.4fs %9.4fs' % (min(times), sum(times) / len(times), max(times)))
    print('%9.4f %9.4f% 9.4f' % (min(scores), sum(scores) / len(scores), max(scores)))

================================================
FILE: benchmark/text_perf.py
================================================
import time
import sklearn
import sklearn.ensemble
import sklearn.metrics
from sklearn.datasets import fetch_20newsgroups
from sklearn.pipeline import make_pipeline
from lime.lime_text import LimeTextExplainer


def interpret_data(X, y, func, class_names):
    explainer = LimeTextExplainer(class_names=class_names)
    times, scores = [], []
    for r_idx in range(10):
        start_time = time.time()
        exp = explainer.explain_instance(newsgroups_test.data[r_idx], func, num_features=6)
        times.append(time.time() - start_time)
        scores.append(exp.score)
        print('...')

    return times, scores

if __name__ == '__main__':
    categories = ['alt.atheism', 'soc.religion.christian']
    newsgroups_train = fetch_20newsgroups(subset='train', categories=categories)
    newsgroups_test = fetch_20newsgroups(subset='test', categories=categories)
    class_names = ['atheism', 'christian']

    vectorizer = sklearn.feature_extraction.text.TfidfVectorizer(lowercase=False)
    train_vectors = vectorizer.fit_transform(newsgroups_train.data)
    test_vectors = vectorizer.transform(newsgroups_test.data)
    rf = sklearn.ensemble.RandomForestClassifier(n_estimators=500)
    rf.fit(train_vectors, newsgroups_train.target)
    pred = rf.predict(test_vectors)
    sklearn.metrics.f1_score(newsgroups_test.target, pred, average='binary')
    c = make_pipeline(vectorizer, rf)

    interpret_data(train_vectors, newsgroups_train.target, c.predict_proba, class_names)

================================================
FILE: binder/environment.yml
================================================

name: lime-dev
channels:
  - conda-forge
dependencies:
  - python=3.7.*
  # lime install dependencies
  - matplotlib
  - numpy
  - scipy
  - scikit-learn
  - scikit-image
  - pyDOE2
  # for testing
  - flake8
  - pytest
  # for examples
  - jupyter
  - pandas
  - keras
  - pytorch::pytorch-cpu
  - tensorflow
  - h2oai::h2o
  - py-xgboost
  - pip: 
    # lime source code
    - -e ..


================================================
FILE: citation.bib
================================================
@inproceedings{lime,
  author    = {Marco Tulio Ribeiro and
               Sameer Singh and
               Carlos Guestrin},
  title     = {"Why Should {I} Trust You?": Explaining the Predictions of Any Classifier},
  booktitle = {Proceedings of the 22nd {ACM} {SIGKDD} International Conference on
               Knowledge Discovery and Data Mining, San Francisco, CA, USA, August
               13-17, 2016},
  pages     = {1135--1144},
  year      = {2016},
}


================================================
FILE: doc/blog_post.md
================================================
# LIME - Local Interpretable Model-Agnostic Explanations
In this post, we'll talk about the method for explaining the predictions of any classifier described in [this paper](http://arxiv.org/pdf/1602.04938v1.pdf), and implemented in [this open source package](https://github.com/marcotcr/lime).
# Motivation: why do we want to understand predictions?
Machine learning is a buzzword these days. With computers beating professionals in games like [Go](https://deepmind.com/alpha-go.html), many people have started asking if machines would also make for better [drivers](https://www.google.com/selfdrivingcar/), or even doctors.  

Many of the state of the art machine learning models are functionally black boxes, as it is nearly impossible to get a feeling for its inner workings. This brings us to a question of trust: do I trust that a certain prediction from the model is correct? Or do I even trust that the model is making reasonable predictions in general?
While the stakes are low in a Go game, they are much higher if a computer is replacing my doctor, or deciding if I am a suspect of terrorism ([Person of Interest](http://www.imdb.com/title/tt1839578/), anyone?). Perhaps more commonly, if a company is replacing some system with one based on machine learning, it has to trust that the machine learning model will behave reasonably well.

It seems intuitive that explaining the rationale behind individual predictions would make us better positioned to trust or mistrust the prediction, or the classifier as a whole. Even if we can't necesseraly understand how the model behaves on all cases, it may be possible (and indeed it is in most cases) to understand how it behaves in particular cases.

Finally, a word on accuracy. If you have had experience with machine learning, I bet you are thinking something along the lines of: "of course I know my model is going to perform well in the real world, I have really high cross validation accuracy! Why do I need to understand it's predictions when I know it gets it right 99% of the time?". As anyone who has used machine learning in the real world (not only in a static dataset) can attest, accuracy on cross validation can be very misleading. Sometimes data that shouldn't be available leaks into the training data accidentaly. Sometimes the way you gather data introduces correlations that will not exist in the real world, which the model exploits. Many other tricky problems can give us a false understanding of performance, even in [doing A/B tests](http://www.exp-platform.com/documents/puzzlingoutcomesincontrolledexperiments.pdf). I am not saying you shouldn't measure accuracy, but simply that it should not be your only metric for assessing trust.

# Lime: A couple of examples.
First, we give an example from text classification. The famous [20 newsgroups dataset](http://qwone.com/~jason/20Newsgroups/) is a benchmark in the field, and has been used to compare different models in several papers. We take two classes that are suposedly harder to distinguish, due to the fact that they share many words: Christianity and Atheism. Training a random forest with 500 trees, we get a test set accuracy of 92.4%, which is surprisingly high. If accuracy was our only measure of trust, we would definitely trust this algorithm.

Below is an explanation for an arbitrary instance in the test set, generated using [the lime package](https://github.com/marcotcr/lime).
![alt text](https://raw.githubusercontent.com/marcotcr/lime/master/doc/images/twoclass.png "Explanation")
This is a case where the classifier predicts the instance correctly, but for the wrong reasons. A little further exploration shows us that the word "Posting" (part of the email header) appears in 21.6% of the examples in the training set, only two times in the class 'Christianity'. This is repeated on the test set, where it appears in almost 20% of the examples, only twice in 'Christianity'. This kind of quirk in the dataset makes the problem much easier than it is in the real world, where this classifier would **not** be able to distinguish between christianity and atheism documents. This is hard to see just by looking at accuracy or raw data, but easy once explanations are provided. Such insights become common once you understand what models are actually doing, leading to models that generalize much better.

Note further how interpretable the explanations are: they correspond to a very sparse linear model (with only 6 features). Even though the underlying classifier is a complicated random forest, in the neighborhood of this example it behaves roughly as a linear model. Sure nenough, if we remove the words "Host" and "NNTP" from the example, the "atheism" prediction probability becomes close to 0.57 - 0.14 - 0.12 = 0.31.

Below is an image from our paper, where we explain Google's [Inception neural network](https://github.com/google/inception) on some arbitary images. In this case, we keep as explanations the parts of the image that are most positive towards a certain class. In this case, the classifier predicts Electric Guitar even though the image contains an acoustic guitar. The explanation reveals why it would confuse the two: the fretboard is very similar. Getting explanations for image classifiers is something that is not yet available in the lime package, but we are working on it.
![alt text](https://raw.githubusercontent.com/marcotcr/lime/master/doc/images/image_from_paper.png "Explanation")

# Lime: how we get explanations
Lime is short for Local Interpretable Model-Agnostic Explanations. Each part of the name reflects something that we desire in explanations. **Local** refers to local fidelity - i.e., we want the explanation to really reflect the behaviour of the classifier "around" the instance being predicted. This explanation is useless unless it is **interpretable** - that is, unless a human can make sense of it. Lime is able to explain any model without needing to 'peak' into it, so it is **model-agnostic**. We now give a high level overview of how lime works. For more details, check out our [pre-print](http://arxiv.org/pdf/1602.04938v1.pdf).

First, a word about **interpretability**. Some classifiers use representations that are not intuitive to users at all (e.g. word embeddings). Lime explains those classifiers in terms of interpretable representations (words), even if that is not the representation actually used by the classifier. Further, lime takes human limitations into account: i.e. the explanations are not too long. Right now, our package supports explanations that are sparse linear models (as presented before), although we are working on other representations.

In order to be **model-agnostic**, lime can't peak into the model. In order to figure out what parts of the interpretable input are contributing to the prediction, we perturb the input around its neighborhood and see how the model's predictions behave. We then weight these perturbed data points by their proximity to the original example, and learn an interpretable model on those and the associated predictions. For example, if we are trying to explain the prediction for the sentence "I hate this movie", we will perturb the sentence and get predictions on sentences such as "I hate movie", "I this movie", "I movie", "I hate", etc. Even if the original classifier takes many more words into account globally, it is reasonable to expect that around this example only the word "hate" will be relevant. Note that if the classifier uses some uninterpretable representation such as word embeddings, this still works: we just represent the perturbed sentences with word embeddings, and the explanation will still be in terms of words such as "hate" or "movie".

An illustration of this process is given below. The original model's decision function is represented by the blue/pink background, and is clearly nonlinear.
The bright red cross is the instance being explained (let's call it X).
We sample perturbed instances around X, and weight them according to their proximity to X (weight here is represented by size). We get original model's prediction on these perturbed instances, and then learn a linear model (dashed line) that approximates the model well in the vicinity of X. Note that the explanation in this case is not faithful globally, but it is faithful locally around X.
![alt text](https://raw.githubusercontent.com/marcotcr/lime/master/doc/images/lime.png "Intuition")

# Conclusion
I hope I've convinced you that understanding individual predictions from classifiers is an important problem. Having explanations lets you make an informed decision about how much you trust the prediction or the model as a whole, and provides insights that can be used to improve the model.

If you're interested in going more in-depth into how lime works, and the kinds of experiments we did to validate the usefulness of such explanations, [here is a link to our pre-print paper](http://arxiv.org/pdf/1602.04938v1.pdf).

If you are interested in trying lime for text classifiers, make sure you check out our [python package](https://github.com/marcotcr/lime/). Installation is as simple as typing:  
```pip install lime```  
The package is very easy to use. It is particulary easy to explain scikit-learn classifiers. In the github page we also link to a few tutorials, such as [this one](http://marcotcr.github.io/lime/tutorials/Lime%20-%20basic%20usage%2C%20two%20class%20case.html), with examples from scikit-learn.




================================================
FILE: doc/conf.py
================================================
# -*- coding: utf-8 -*-
#
# lime documentation build configuration file, created by
# sphinx-quickstart on Fri Mar 18 16:20:40 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys
import os

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__)))
libpath = os.path.join(curr_path, '../')
sys.path.insert(0, libpath)
sys.path.insert(0, curr_path)

import mock
MOCK_MODULES = ['numpy', 'scipy', 'scipy.sparse', 'scipy.special',
                'scipy.stats', 'scipy.stats.distributions', 'sklearn', 'sklearn.preprocessing',
                'sklearn.linear_model', 'matplotlib',
        'sklearn.datasets', 'sklearn.ensemble', 'sklearn.cross_validation',
        'sklearn.feature_extraction', 'sklearn.feature_extraction.text',
        'sklearn.metrics', 'sklearn.naive_bayes', 'sklearn.pipeline',
        'sklearn.utils', 'pyDOE2',]
# for mod_name in MOCK_MODULES:
#     sys.modules[mod_name] = mock.Mock()

import scipy
import scipy.stats
import scipy.stats.distributions
import lime
import lime.lime_text

import lime.lime_tabular
import lime.explanation
import lime.lime_base
import lime.submodular_pick

# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.mathjax',
    'sphinx.ext.napoleon',
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'

# The encoding of source files.
#source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = u'lime'
copyright = u'2016, Marco Tulio Ribeiro'
author = u'Marco Tulio Ribeiro'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'0.1'
# The full version, including alpha/beta/rc tags.
release = u'0.1'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']

# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []

# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False


# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'default'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}

# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []

# The name for this set of Sphinx documents.  If None, it defaults to
# "<project> v<release> documentation".
#html_title = None

# A shorter title for the navigation bar.  Default is the same as html_title.
#html_short_title = None

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None

# The name of an image file (relative to this directory) to use as a favicon of
# the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}

# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}

# If false, no module index is generated.
#html_domain_indices = True

# If false, no index is generated.
#html_use_index = True

# If true, the index is split into individual pages for each letter.
#html_split_index = False

# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None

# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'

# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}

# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'

# Output file base name for HTML help builder.
htmlhelp_basename = 'limedoc'

# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#'preamble': '',

# Latex figure (float) alignment
#'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (master_doc, 'lime.tex', u'lime Documentation',
     u'Marco Tulio Ribeiro', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False

# If true, show page references after internal links.
#latex_show_pagerefs = False

# If true, show URL addresses after external links.
#latex_show_urls = False

# Documents to append as an appendix to all manuals.
#latex_appendices = []

# If false, no module index is generated.
#latex_domain_indices = True


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'lime', u'lime Documentation',
     [author], 1)
]

# If true, show URL addresses after external links.
#man_show_urls = False


# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (master_doc, 'lime', u'lime Documentation',
     author, 'lime', 'One line description of project.',
     'Miscellaneous'),
]

autoclass_content = 'both'
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []

# If false, no module index is generated.
#texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False


================================================
FILE: doc/index.rst
================================================
.. lime documentation master file, created by
   sphinx-quickstart on Fri Mar 18 16:20:40 2016.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Local Interpretable Model-Agnostic Explanations (lime)
================================
In this page, you can find the Python API reference for the lime package (local interpretable model-agnostic explanations).
For tutorials and more information, visit `the github page <https://github.com/marcotcr/understanding-ml>`_.


.. toctree::
   :maxdepth: 2

   lime 



Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`



================================================
FILE: doc/lime.rst
================================================
lime package
============

Subpackages
-----------

.. toctree::

    lime.tests

Submodules
----------

lime\.discretize module
-----------------------

.. automodule:: lime.discretize
    :members:
    :undoc-members:
    :show-inheritance:

lime\.exceptions module
-----------------------

.. automodule:: lime.exceptions
    :members:
    :undoc-members:
    :show-inheritance:

lime\.explanation module
------------------------

.. automodule:: lime.explanation
    :members:
    :undoc-members:
    :show-inheritance:

lime\.lime\_base module
-----------------------

.. automodule:: lime.lime_base
    :members:
    :undoc-members:
    :show-inheritance:

lime\.lime\_image module
------------------------

.. automodule:: lime.lime_image
    :members:
    :undoc-members:
    :show-inheritance:

lime\.lime\_tabular module
--------------------------

.. automodule:: lime.lime_tabular
    :members:
    :undoc-members:
    :show-inheritance:

lime\.lime\_text module
-----------------------

.. automodule:: lime.lime_text
    :members:
    :undoc-members:
    :show-inheritance:


lime\.submodular\_pick module
-----------------------

.. automodule:: lime.submodular_pick
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: lime
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: doc/notebooks/Latin Hypercube Sampling.ipynb
================================================
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Latin Hypercube Sampling \n",
    "This notebooks walks through [Latin Hypercube Sampling](https://en.wikipedia.org/wiki/Latin_hypercube_sampling) (LHS) and explains how it differs from the standard [Gaussian Random Sampling](https://en.wikipedia.org/wiki/Normal_distribution) implemented in LIME.\n",
    "\n",
    "Standard Gaussian random sampling draws samples from a standard normal distribution Probability Density Function (PDF), $\\mathcal{N}(0,1)$. In practice, if we sample from $\\mathcal{N}(0,1)$ many times, we will begin to obtain enough samples to \"understand\" the space from which we are sampling.\n",
    "\n",
    "Some black-box models are computationally expensive, and in high dimensions, we require more samples from the standard normal distribution. We thus introduce a quasi-random process to reduce the needed number of sampled points while not losing our \"understanding\" of the space. LHS is a quasi-random process. LHS samples from a n-dimensional CDF (a n-dimensional hypercube) and places points spread out in the space. It is somewhat analogous to the problem of placing non-attacking rooks on a chessboard. The points are placed to sample all of the features in such a way that the points are distributed across the CDF. We then use a point percentile function (PPF) to go from the CDF to the PDF so we can do the same computations LIME does to the Gaussian points. \n",
    "\n",
    "This notebook walks through some examples of both sampling methods and shows how using LHS can save one run time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# imports \n",
    "from lime import lime_tabular\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.patches as mpatches \n",
    "from pyDOE2 import lhs\n",
    "from scipy.stats.distributions import norm\n",
    "\n",
    "np.random.seed(1) # for repeatability "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Visualizing the differnce between Gaussian sampling and LHS\n",
    "\n",
    "Let us consider a toy problem with $n=2$ features (for the ease of visualizing). We can compare what the sampled points for Gaussian sampling and LHS will look like. We compare these plots for $s = 25$ samples (to build intuition)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 2                                                      # number of features\n",
    "s = 25                                                     # number of samples\n",
    "\n",
    "gauss_data = np.random.normal(0,1,n*s).reshape(s,n)        # how lime generates the values\n",
    "lhs_data = lhs(n,s)                                        # lhs generated data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# visualizing the results in the cdf\n",
    "means = np.zeros(n)\n",
    "stdvs = np.array([1]*n)\n",
    "gaus_cdf = np.zeros((s,n))\n",
    "for i in range(n):\n",
    "    gaus_cdf[:,i] = norm(loc=means[i], scale=stdvs[i]).cdf(gauss_data[:,i])\n",
    "    \n",
    "    \n",
    "fig, (ax1, ax2) = plt.subplots(1, 2,sharey=True)\n",
    "\n",
    "ax1.scatter(gaus_cdf[:,0],gaus_cdf[:,1],color='tab:blue',label='Gaussian Sampling (cdf)')\n",
    "ax1.set_xlabel('feature 1')\n",
    "ax1.set_ylabel('feature 2')\n",
    "ax1.legend(shadow=True,fancybox=True)\n",
    "\n",
    "ax2.scatter(lhs_data[:,0], lhs_data[:,1],color='tab:orange',label='LHS (cdf)')\n",
    "ax2.set_xlabel('feature 1')\n",
    "ax2.legend(shadow=True, fancybox=True)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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XnklTz/9NKtWrWL79u1A6H/1wAMPMHLkSCoqKjjllFPIysria1/7GmvWrGk1bonRnq2xbU+kutLHni2AO1z6SFISmD17NoMHD478bNu2DYBvf/vbbNmyha9//etcc801vPDCC02+vvF5DU1/rn72s59x9dVXs27dOrp16xZ57lNPPUVubi4VFRVcdNFFQKgG4aWXXor7b0ubBDBrSSXVNQ277FXXHGLWksqEHeOnP/0pgwYN4hvf+AYQql658sorKSwsZOLEibzxxhstvr5jx460b9+eH/3oRyxcuJAOHToAUFJSwuWXX87999/fZLfDPXv2MHHiRAoKCpg6dWqDnilnn312ZL8DBgzggw+OnNPpgQceYNmyZZx22mncddddkaLh1q1bGT16NIWFhcyaNavBfr/zne+Qk5NDYWEhhw4dinxDKSwsbFCFdMkll0RuX3311Vbfw/HjxwMwdOjQyH5efvllLr74YgDGjBnDCSec0ORrP/30U4477rjI4169elFSUgLA5MmTefnll3nrrbfo27cv/fr1w8yYPHlyi/GceOKJkQ+sJFDHnrFtT6QUlz6mTp1KRUVF5KfuW/6xxx7LqlWrmD9/Pp07d+aiiy6K1ATU9+GHH9K5c8OJOJv6XK1YsSKy/bLLLmsxpkSd12mTALbtro5pezQGDhzI6tWrI4/vvfdeli1bxs6dO4FQ5u/SpQtr1qyhrKwsUr931FFHRb5lA+zfvz+yfeXKlUyYMIHFixdHLqr33Xcfv/71r9myZQtDhw49oufJf/zHf3DWWWexfv16nn766cj+gEjxEiA7O7vZ6ozCwkKmTp3Ks88+yxNPPAHAddddx7XXXsu6deuYN29ek/vNysoiJycn0miUlZXV4Bj1G5OiaViq229LsTan8fva+HhtGbS1f/9+cnNzY36dtOLsWyCn0fuakxvanmxelj4ayc7O5swzz+S2225j7ty5kc9efbm5uQ0+e9D85yraczxR53XaJIDueU3/sc1tj8aoUaPYv38/f/zjHyPb6g9F37NnD926dSMrK4s///nPkW/vvXv35o033uDLL79k9+7dLFu2DIC9e/eyZ88evvvd7zJ79uxI1cPGjRs5/fTTmTlzJp07dz6iGmfPnj306NEDoMlvEC3Zu3cvzz//fORxRUUFvXv3PmK/Dz/8cEz7rVNaWhq5HT58eJv2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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# visualizing the the distribution of points in the pdf\n",
    "# transformation lhs from cdf to pdf\n",
    "means = np.zeros(n)\n",
    "stdvs = np.array([1]*n)\n",
    "for i in range(n):\n",
    "    lhs_data[:, i] = norm(loc=means[i], scale=stdvs[i]).ppf(lhs_data[:, i])   \n",
    "\n",
    "fig, (ax1, ax2) = plt.subplots(1, 2,sharey=True)\n",
    "\n",
    "ax1.scatter(gauss_data[:,0],gauss_data[:,1],color='tab:blue',label='Gaussian Sampling (pdf)')\n",
    "ax1.set_xlabel('feature 1')\n",
    "ax1.set_ylabel('feature 2')\n",
    "ax1.legend(shadow=True,fancybox=True)\n",
    "\n",
    "ax2.scatter(lhs_data[:,0], lhs_data[:,1],color='tab:orange',label='LHS (pdf)')\n",
    "ax2.set_xlabel('feature 1')\n",
    "ax2.legend(shadow=True, fancybox=True)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Intuitively, it appears that the LHS method, since the points are better distributed through the space, would require fewer points to be generated. In both the CDF and PDF, we see LHS spreads out over the space more than the Gaussian sampling approach. \n",
    "\n",
    "Let us test this on the [Iris](https://en.wikipedia.org/wiki/Iris_flower_data_set) dataset. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# imports for the iris data set and model\n",
    "from sklearn.neural_network import MLPClassifier\n",
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import accuracy_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "model accuracy score:  0.9333333333333333\n"
     ]
    }
   ],
   "source": [
    "# train a black box model on the data set\n",
    "np.random.seed(1)\n",
    "iris = load_iris()\n",
    "train, test, labels_train, labels_test = train_test_split(iris.data, iris.target, train_size=0.80)\n",
    "clf = MLPClassifier(solver='lbfgs', alpha=1e-5,hidden_layer_sizes=(11,6), random_state=1)\n",
    "clf.fit(train, labels_train)\n",
    "print('model accuracy score: ',accuracy_score(labels_test, clf.predict(test)))\n",
    "\n",
    "# point to explain\n",
    "test_instance = test[8]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we have a pretty good black-box model, let's compare the top weight (as predicted by LIME). First, we will do it for just one run and fix the number of samples at $s = 5000$, which is the default number of samples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<html>\n",
       "        <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF8\">\n",
       "        <head><script>var lime =\n",
       "/******/ (function(modules) { // webpackBootstrap\n",
       "/******/ \t// The module cache\n",
       "/******/ \tvar installedModules = {};\n",
       "/******/\n",
       "/******/ \t// The require function\n",
       "/******/ \tfunction __webpack_require__(moduleId) {\n",
       "/******/\n",
       "/******/ \t\t// Check if module is in cache\n",
       "/******/ \t\tif(installedModules[moduleId])\n",
       "/******/ \t\t\treturn installedModules[moduleId].exports;\n",
       "/******/\n",
       "/******/ \t\t// Create a new module (and put it into the cache)\n",
       "/******/ \t\tvar module = installedModules[moduleId] = {\n",
       "/******/ \t\t\texports: {},\n",
       "/******/ \t\t\tid: moduleId,\n",
       "/******/ \t\t\tloaded: false\n",
       "/******/ \t\t};\n",
       "/******/\n",
       "/******/ \t\t// Execute the module function\n",
       "/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n",
       "/******/\n",
       "/******/ \t\t// Flag the module as loaded\n",
       "/******/ \t\tmodule.loaded = true;\n",
       "/******/\n",
       "/******/ \t\t// Return the exports of the module\n",
       "/******/ \t\treturn module.exports;\n",
       "/******/ \t}\n",
       "/******/\n",
       "/******/\n",
       "/******/ \t// expose the modules object (__webpack_modules__)\n",
       "/******/ \t__webpack_require__.m = modules;\n",
       "/******/\n",
       "/******/ \t// expose the module cache\n",
       "/******/ \t__webpack_require__.c = installedModules;\n",
       "/******/\n",
       "/******/ \t// __webpack_public_path__\n",
       "/******/ \t__webpack_require__.p = \"\";\n",
       "/******/\n",
       "/******/ \t// Load entry module and return exports\n",
       "/******/ \treturn __webpack_require__(0);\n",
       "/******/ })\n",
       "/************************************************************************/\n",
       "/******/ ([\n",
       "/* 0 */\n",
       "/***/ (function(module, exports, __webpack_require__) {\n",
       "\n",
       "\t/* WEBPACK VAR INJECTION */(function(global) {'use strict';\n",
       "\t\n",
       "\tObject.defineProperty(exports, \"__esModule\", {\n",
       "\t  value: true\n",
       "\t});\n",
       "\texports.PredictedValue = exports.PredictProba = exports.Barchart = exports.Explanation = undefined;\n",
       "\t\n",
       "\tvar _explanation = __webpack_require__(1);\n",
       "\t\n",
       "\tvar _explanation2 = _interopRequireDefault(_explanation);\n",
       "\t\n",
       "\tvar _bar_chart = __webpack_require__(3);\n",
       "\t\n",
       "\tvar _bar_chart2 = _interopRequireDefault(_bar_chart);\n",
       "\t\n",
       "\tvar _predict_proba = __webpack_require__(6);\n",
       "\t\n",
       "\tvar _predict_proba2 = _interopRequireDefault(_predict_proba);\n",
       "\t\n",
       "\tvar _predicted_value = __webpack_require__(7);\n",
       "\t\n",
       "\tvar _predicted_value2 = _interopRequireDefault(_predicted_value);\n",
       "\t\n",
       "\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n",
       "\t\n",
       "\tif (!global._babelPolyfill) {\n",
       "\t  __webpack_require__(8);\n",
       "\t}\n",
       "\t\n",
       "\t__webpack_require__(339);\n",
       "\t\n",
       "\texports.Explanation = _explanation2.default;\n",
       "\texports.Barchart = _bar_chart2.default;\n",
       "\texports.PredictProba = _predict_proba2.default;\n",
       "\texports.PredictedValue = _predicted_value2.default;\n",
       "\t//require('style-loader');\n",
       "\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))\n",
       "\n",
       "/***/ }),\n",
       "/* 1 */\n",
       "/***/ (function(module, exports, __webpack_require__) {\n",
       "\n",
       "\t'use strict';\n",
       "\t\n",
       "\tObject.defineProperty(exports, \"__esModule\", {\n",
       "\t  value: true\n",
       "\t});\n",
       "\t\n",
       "\tvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n",
       "\t\n",
       "\tvar _d2 = __webpack_require__(2);\n",
       "\t\n",
       "\tvar _d3 = _interopRequireDefault(_d2);\n",
       "\t\n",
       "\tvar _bar_chart = __webpack_require__(3);\n",
       "\t\n",
       "\tvar _bar_chart2 = _interopRequireDefault(_bar_chart);\n",
       "\t\n",
       "\tvar _lodash = __webpack_require__(4);\n",
       "\t\n",
       "\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n",
       "\t\n",
       "\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n",
       "\t\n",
       "\tvar Explanation = function () {\n",
       "\t  function Explanation(class_names) {\n",
       "\t    _classCallCheck(this, Explanation);\n",
       "\t\n",
       "\t    this.names = class_names;\n",
       "\t    if (class_names.length < 10) {\n",
       "\t      this.colors = _d3.default.scale.category10().domain(this.names);\n",
       "\t      this.colors_i = _d3.default.scale.category10().domain((0, _lodash.range)(this.names.length));\n",
       "\t    } else {\n",
       "\t      this.colors = _d3.default.scale.category20().domain(this.names);\n",
       "\t      this.colors_i = _d3.default.scale.category20().domain((0, _lodash.range)(this.names.length));\n",
       "\t    }\n",
       "\t  }\n",
       "\t  // exp: [(feature-name, weight), ...]\n",
       "\t  // label: int\n",
       "\t  // div: d3 selection\n",
       "\t\n",
       "\t\n",
       "\t  Explanation.prototype.show = function show(exp, label, div) {\n",
       "\t    var svg = div.append('svg').style('width', '100%');\n",
       "\t    var colors = ['#5F9EA0', this.colors_i(label)];\n",
       "\t    var names = ['NOT ' + this.names[label], this.names[label]];\n",
       "\t    if (this.names.length == 2) {\n",
       "\t      colors = [this.colors_i(0), this.colors_i(1)];\n",
       "\t      names = this.names;\n",
       "\t    }\n",
       "\t    var plot = new _bar_chart2.default(svg, exp, true, names, colors, true, 10);\n",
       "\t    svg.style('height', plot.svg_height + 'px');\n",
       "\t  };\n",
       "\t  // exp has all ocurrences of words, with start index and weight:\n",
       "\t  // exp = [('word', 132, -0.13), ('word3', 111, 1.3)\n",
       "\t\n",
       "\t\n",
       "\t  Explanation.prototype.show_raw_text = function show_raw_text(exp, label, raw, div) {\n",
       "\t    var opacity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n",
       "\t\n",
       "\t    //let colors=['#5F9EA0', this.colors(this.exp['class'])];\n",
       "\t    var colors = ['#5F9EA0', this.colors_i(label)];\n",
       "\t    if (this.names.length == 2) {\n",
       "\t      colors = [this.colors_i(0), this.colors_i(1)];\n",
       "\t    }\n",
       "\t    var word_lists = [[], []];\n",
       "\t    var max_weight = -1;\n",
       "\t    var _iteratorNormalCompletion = true;\n",
       "\t    var _didIteratorError = false;\n",
       "\t    var _iteratorError = undefined;\n",
       "\t\n",
       "\t    try {\n",
       "\t      for (var _iterator = exp[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n",
       "\t        var _step$value = _slicedToArray(_step.value, 3),\n",
       "\t            word = _step$value[0],\n",
       "\t            start = _step$value[1],\n",
       "\t            weight = _step$value[2];\n",
       "\t\n",
       "\t        if (weight > 0) {\n",
       "\t          word_lists[1].push([start, start + word.length, weight]);\n",
       "\t        } else {\n",
       "\t          word_lists[0].push([start, start + word.length, -weight]);\n",
       "\t        }\n",
       "\t        max_weight = Math.max(max_weight, Math.abs(weight));\n",
       "\t      }\n",
       "\t    } catch (err) {\n",
       "\t      _didIteratorError = true;\n",
       "\t      _iteratorError = err;\n",
       "\t    } finally {\n",
       "\t      try {\n",
       "\t        if (!_iteratorNormalCompletion && _iterator.return) {\n",
       "\t          _iterator.return();\n",
       "\t        }\n",
       "\t      } finally {\n",
       "\t        if (_didIteratorError) {\n",
       "\t          throw _iteratorError;\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t\n",
       "\t    if (!opacity) {\n",
       "\t      max_weight = 0;\n",
       "\t    }\n",
       "\t    this.display_raw_text(div, raw, word_lists, colors, max_weight, true);\n",
       "\t  };\n",
       "\t  // exp is list of (feature_name, value, weight)\n",
       "\t\n",
       "\t\n",
       "\t  Explanation.prototype.show_raw_tabular = function show_raw_tabular(exp, label, div) {\n",
       "\t    div.classed('lime', true).classed('table_div', true);\n",
       "\t    var colors = ['#5F9EA0', this.colors_i(label)];\n",
       "\t    if (this.names.length == 2) {\n",
       "\t      colors = [this.colors_i(0), this.colors_i(1)];\n",
       "\t    }\n",
       "\t    var table = div.append('table');\n",
       "\t    var thead = table.append('tr');\n",
       "\t    thead.append('td').text('Feature');\n",
       "\t    thead.append('td').text('Value');\n",
       "\t    thead.style('color', 'black').style('font-size', '20px');\n",
       "\t    var _iteratorNormalCompletion2 = true;\n",
       "\t    var _didIteratorError2 = false;\n",
       "\t    var _iteratorError2 = undefined;\n",
       "\t\n",
       "\t    try {\n",
       "\t      for (var _iterator2 = exp[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n",
       "\t        var _step2$value = _slicedToArray(_step2.value, 3),\n",
       "\t            fname = _step2$value[0],\n",
       "\t            value = _step2$value[1],\n",
       "\t            weight = _step2$value[2];\n",
       "\t\n",
       "\t        var tr = table.append('tr');\n",
       "\t        tr.style('border-style', 'hidden');\n",
       "\t        tr.append('td').text(fname);\n",
       "\t        tr.append('td').text(value);\n",
       "\t        if (weight > 0) {\n",
       "\t          tr.style('background-color', colors[1]);\n",
       "\t        } else if (weight < 0) {\n",
       "\t          tr.style('background-color', colors[0]);\n",
       "\t        } else {\n",
       "\t          tr.style('color', 'black');\n",
       "\t        }\n",
       "\t      }\n",
       "\t    } catch (err) {\n",
       "\t      _didIteratorError2 = true;\n",
       "\t      _iteratorError2 = err;\n",
       "\t    } finally {\n",
       "\t      try {\n",
       "\t        if (!_iteratorNormalCompletion2 && _iterator2.return) {\n",
       "\t          _iterator2.return();\n",
       "\t        }\n",
       "\t      } finally {\n",
       "\t        if (_didIteratorError2) {\n",
       "\t          throw _iteratorError2;\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t  };\n",
       "\t\n",
       "\t  Explanation.prototype.hexToRgb = function hexToRgb(hex) {\n",
       "\t    var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n",
       "\t    return result ? {\n",
       "\t      r: parseInt(result[1], 16),\n",
       "\t      g: parseInt(result[2], 16),\n",
       "\t      b: parseInt(result[3], 16)\n",
       "\t    } : null;\n",
       "\t  };\n",
       "\t\n",
       "\t  Explanation.prototype.applyAlpha = function applyAlpha(hex, alpha) {\n",
       "\t    var components = this.hexToRgb(hex);\n",
       "\t    return 'rgba(' + components.r + \",\" + components.g + \",\" + components.b + \",\" + alpha.toFixed(3) + \")\";\n",
       "\t  };\n",
       "\t  // sord_lists is an array of arrays, of length (colors). if with_positions is true,\n",
       "\t  // word_lists is an array of [start,end] positions instead\n",
       "\t\n",
       "\t\n",
       "\t  Explanation.prototype.display_raw_text = function display_raw_text(div, raw_text) {\n",
       "\t    var word_lists = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n",
       "\t    var colors = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];\n",
       "\t    var max_weight = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;\n",
       "\t    var positions = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;\n",
       "\t\n",
       "\t    div.classed('lime', true).classed('text_div', true);\n",
       "\t    div.append('h3').text('Text with highlighted words');\n",
       "\t    var highlight_tag = 'span';\n",
       "\t    var text_span = div.append('span').style('white-space', 'pre-wrap').text(raw_text);\n",
       "\t    var position_lists = word_lists;\n",
       "\t    if (!positions) {\n",
       "\t      position_lists = this.wordlists_to_positions(word_lists, raw_text);\n",
       "\t    }\n",
       "\t    var objects = [];\n",
       "\t    var _iteratorNormalCompletion3 = true;\n",
       "\t    var _didIteratorError3 = false;\n",
       "\t    var _iteratorError3 = undefined;\n",
       "\t\n",
       "\t    try {\n",
       "\t      var _loop = function _loop() {\n",
       "\t        var i = _step3.value;\n",
       "\t\n",
       "\t        position_lists[i].map(function (x) {\n",
       "\t          return objects.push({ 'label': i, 'start': x[0], 'end': x[1], 'alpha': max_weight === 0 ? 1 : x[2] / max_weight });\n",
       "\t        });\n",
       "\t      };\n",
       "\t\n",
       "\t      for (var _iterator3 = (0, _lodash.range)(position_lists.length)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n",
       "\t        _loop();\n",
       "\t      }\n",
       "\t    } catch (err) {\n",
       "\t      _didIteratorError3 = true;\n",
       "\t      _iteratorError3 = err;\n",
       "\t    } finally {\n",
       "\t      try {\n",
       "\t        if (!_iteratorNormalCompletion3 && _iterator3.return) {\n",
       "\t          _iterator3.return();\n",
       "\t        }\n",
       "\t      } finally {\n",
       "\t        if (_didIteratorError3) {\n",
       "\t          throw _iteratorError3;\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t\n",
       "\t    objects = (0, _lodash.sortBy)(objects, function (x) {\n",
       "\t      return x['start'];\n",
       "\t    });\n",
       "\t    var node = text_span.node().childNodes[0];\n",
       "\t    var subtract = 0;\n",
       "\t    var _iteratorNormalCompletion4 = true;\n",
       "\t    var _didIteratorError4 = false;\n",
       "\t    var _iteratorError4 = undefined;\n",
       "\t\n",
       "\t    try {\n",
       "\t      for (var _iterator4 = objects[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n",
       "\t        var obj = _step4.value;\n",
       "\t\n",
       "\t        var word = raw_text.slice(obj.start, obj.end);\n",
       "\t        var start = obj.start - subtract;\n",
       "\t        var end = obj.end - subtract;\n",
       "\t        var match = document.createElement(highlight_tag);\n",
       "\t        match.appendChild(document.createTextNode(word));\n",
       "\t        match.style.backgroundColor = this.applyAlpha(colors[obj.label], obj.alpha);\n",
       "\t        var after = node.splitText(start);\n",
       "\t        after.nodeValue = after.nodeValue.substring(word.length);\n",
       "\t        node.parentNode.insertBefore(match, after);\n",
       "\t        subtract += end;\n",
       "\t        node = after;\n",
       "\t      }\n",
       "\t    } catch (err) {\n",
       "\t      _didIteratorError4 = true;\n",
       "\t      _iteratorError4 = err;\n",
       "\t    } finally {\n",
       "\t      try {\n",
       "\t        if (!_iteratorNormalCompletion4 && _iterator4.return) {\n",
       "\t          _iterator4.return();\n",
       "\t        }\n",
       "\t      } finally {\n",
       "\t        if (_didIteratorError4) {\n",
       "\t          throw _iteratorError4;\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t  };\n",
       "\t\n",
       "\t  Explanation.prototype.wordlists_to_positions = function wordlists_to_positions(word_lists, raw_text) {\n",
       "\t    var ret = [];\n",
       "\t    var _iteratorNormalCompletion5 = true;\n",
       "\t    var _didIteratorError5 = false;\n",
       "\t    var _iteratorError5 = undefined;\n",
       "\t\n",
       "\t    try {\n",
       "\t      for (var _iterator5 = word_lists[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n",
       "\t        var words = _step5.value;\n",
       "\t\n",
       "\t        if (words.length === 0) {\n",
       "\t          ret.push([]);\n",
       "\t          continue;\n",
       "\t        }\n",
       "\t        var re = new RegExp(\"\\\\b(\" + words.join('|') + \")\\\\b\", 'gm');\n",
       "\t        var temp = void 0;\n",
       "\t        var list = [];\n",
       "\t        while ((temp = re.exec(raw_text)) !== null) {\n",
       "\t          list.push([temp.index, temp.index + temp[0].length]);\n",
       "\t        }\n",
       "\t        ret.push(list);\n",
       "\t      }\n",
       "\t    } catch (err) {\n",
       "\t      _didIteratorError5 = true;\n",
       "\t      _iteratorError5 = err;\n",
       "\t    } finally {\n",
       "\t      try {\n",
       "\t        if (!_iteratorNormalCompletion5 && _iterator5.return) {\n",
       "\t          _iterator5.return();\n",
       "\t        }\n",
       "\t      } finally {\n",
       "\t        if (_didIteratorError5) {\n",
       "\t          throw _iteratorError5;\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t\n",
       "\t    return ret;\n",
       "\t  };\n",
       "\t\n",
       "\t  return Explanation;\n",
       "\t}();\n",
       "\t\n",
       "\texports.default = Explanation;\n",
       "\n",
       "/***/ }),\n",
       "/* 2 */\n",
       "/***/ (function(module, exports, __webpack_require__) {\n",
       "\n",
       "\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;!function() {\n",
       "\t  var d3 = {\n",
       "\t    version: \"3.5.17\"\n",
       "\t  };\n",
       "\t  var d3_arraySlice = [].slice, d3_array = function(list) {\n",
       "\t    return d3_arraySlice.call(list);\n",
       "\t  };\n",
       "\t  var d3_document = this.document;\n",
       "\t  function d3_documentElement(node) {\n",
       "\t    return node && (node.ownerDocument || node.document || node).documentElement;\n",
       "\t  }\n",
       "\t  function d3_window(node) {\n",
       "\t    return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView);\n",
       "\t  }\n",
       "\t  if (d3_document) {\n",
       "\t    try {\n",
       "\t      d3_array(d3_document.documentElement.childNodes)[0].nodeType;\n",
       "\t    } catch (e) {\n",
       "\t      d3_array = function(list) {\n",
       "\t        var i = list.length, array = new Array(i);\n",
       "\t        while (i--) array[i] = list[i];\n",
       "\t        return array;\n",
       "\t      };\n",
       "\t    }\n",
       "\t  }\n",
       "\t  if (!Date.now) Date.now = function() {\n",
       "\t    return +new Date();\n",
       "\t  };\n",
       "\t  if (d3_document) {\n",
       "\t    try {\n",
       "\t      d3_document.createElement(\"DIV\").style.setProperty(\"opacity\", 0, \"\");\n",
       "\t    } catch (error) {\n",
       "\t      var d3_element_prototype = this.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = this.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;\n",
       "\t      d3_element_prototype.setAttribute = function(name, value) {\n",
       "\t        d3_element_setAttribute.call(this, name, value + \"\");\n",
       "\t      };\n",
       "\t      d3_element_prototype.setAttributeNS = function(space, local, value) {\n",
       "\t        d3_element_setAttributeNS.call(this, space, local, value + \"\");\n",
       "\t      };\n",
       "\t      d3_style_prototype.setProperty = function(name, value, priority) {\n",
       "\t        d3_style_setProperty.call(this, name, value + \"\", priority);\n",
       "\t      };\n",
       "\t    }\n",
       "\t  }\n",
       "\t  d3.ascending = d3_ascending;\n",
       "\t  function d3_ascending(a, b) {\n",
       "\t    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n",
       "\t  }\n",
       "\t  d3.descending = function(a, b) {\n",
       "\t    return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n",
       "\t  };\n",
       "\t  d3.min = function(array, f) {\n",
       "\t    var i = -1, n = array.length, a, b;\n",
       "\t    if (arguments.length === 1) {\n",
       "\t      while (++i < n) if ((b = array[i]) != null && b >= b) {\n",
       "\t        a = b;\n",
       "\t        break;\n",
       "\t      }\n",
       "\t      while (++i < n) if ((b = array[i]) != null && a > b) a = b;\n",
       "\t    } else {\n",
       "\t      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {\n",
       "\t        a = b;\n",
       "\t        break;\n",
       "\t      }\n",
       "\t      while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;\n",
       "\t    }\n",
       "\t    return a;\n",
       "\t  };\n",
       "\t  d3.max = function(array, f) {\n",
       "\t    var i = -1, n = array.length, a, b;\n",
       "\t    if (arguments.length === 1) {\n",
       "\t      while (++i < n) if ((b = array[i]) != null && b >= b) {\n",
       "\t        a = b;\n",
       "\t        break;\n",
       "\t      }\n",
       "\t      while (++i < n) if ((b = array[i]) != null && b > a) a = b;\n",
       "\t    } else {\n",
       "\t      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {\n",
       "\t        a = b;\n",
       "\t        break;\n",
       "\t      }\n",
       "\t      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;\n",
       "\t    }\n",
       "\t    return a;\n",
       "\t  };\n",
       "\t  d3.extent = function(array, f) {\n",
       "\t    var i = -1, n = array.length, a, b, c;\n",
       "\t    if (arguments.length === 1) {\n",
       "\t      while (++i < n) if ((b = array[i]) != null && b >= b) {\n",
       "\t        a = c = b;\n",
       "\t        break;\n",
       "\t      }\n",
       "\t      while (++i < n) if ((b = array[i]) != null) {\n",
       "\t        if (a > b) a = b;\n",
       "\t        if (c < b) c = b;\n",
       "\t      }\n",
       "\t    } else {\n",
       "\t      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {\n",
       "\t        a = c = b;\n",
       "\t        break;\n",
       "\t      }\n",
       "\t      while (++i < n) if ((b = f.call(array, array[i], i)) != null) {\n",
       "\t        if (a > b) a = b;\n",
       "\t        if (c < b) c = b;\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return [ a, c ];\n",
       "\t  };\n",
       "\t  function d3_number(x) {\n",
       "\t    return x === null ? NaN : +x;\n",
       "\t  }\n",
       "\t  function d3_numeric(x) {\n",
       "\t    return !isNaN(x);\n",
       "\t  }\n",
       "\t  d3.sum = function(array, f) {\n",
       "\t    var s = 0, n = array.length, a, i = -1;\n",
       "\t    if (arguments.length === 1) {\n",
       "\t      while (++i < n) if (d3_numeric(a = +array[i])) s += a;\n",
       "\t    } else {\n",
       "\t      while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a;\n",
       "\t    }\n",
       "\t    return s;\n",
       "\t  };\n",
       "\t  d3.mean = function(array, f) {\n",
       "\t    var s = 0, n = array.length, a, i = -1, j = n;\n",
       "\t    if (arguments.length === 1) {\n",
       "\t      while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j;\n",
       "\t    } else {\n",
       "\t      while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j;\n",
       "\t    }\n",
       "\t    if (j) return s / j;\n",
       "\t  };\n",
       "\t  d3.quantile = function(values, p) {\n",
       "\t    var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;\n",
       "\t    return e ? v + e * (values[h] - v) : v;\n",
       "\t  };\n",
       "\t  d3.median = function(array, f) {\n",
       "\t    var numbers = [], n = array.length, a, i = -1;\n",
       "\t    if (arguments.length === 1) {\n",
       "\t      while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a);\n",
       "\t    } else {\n",
       "\t      while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a);\n",
       "\t    }\n",
       "\t    if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5);\n",
       "\t  };\n",
       "\t  d3.variance = function(array, f) {\n",
       "\t    var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0;\n",
       "\t    if (arguments.length === 1) {\n",
       "\t      while (++i < n) {\n",
       "\t        if (d3_numeric(a = d3_number(array[i]))) {\n",
       "\t          d = a - m;\n",
       "\t          m += d / ++j;\n",
       "\t          s += d * (a - m);\n",
       "\t        }\n",
       "\t      }\n",
       "\t    } else {\n",
       "\t      while (++i < n) {\n",
       "\t        if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) {\n",
       "\t          d = a - m;\n",
       "\t          m += d / ++j;\n",
       "\t          s += d * (a - m);\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t    if (j > 1) return s / (j - 1);\n",
       "\t  };\n",
       "\t  d3.deviation = function() {\n",
       "\t    var v = d3.variance.apply(this, arguments);\n",
       "\t    return v ? Math.sqrt(v) : v;\n",
       "\t  };\n",
       "\t  function d3_bisector(compare) {\n",
       "\t    return {\n",
       "\t      left: function(a, x, lo, hi) {\n",
       "\t        if (arguments.length < 3) lo = 0;\n",
       "\t        if (arguments.length < 4) hi = a.length;\n",
       "\t        while (lo < hi) {\n",
       "\t          var mid = lo + hi >>> 1;\n",
       "\t          if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid;\n",
       "\t        }\n",
       "\t        return lo;\n",
       "\t      },\n",
       "\t      right: function(a, x, lo, hi) {\n",
       "\t        if (arguments.length < 3) lo = 0;\n",
       "\t        if (arguments.length < 4) hi = a.length;\n",
       "\t        while (lo < hi) {\n",
       "\t          var mid = lo + hi >>> 1;\n",
       "\t          if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1;\n",
       "\t        }\n",
       "\t        return lo;\n",
       "\t      }\n",
       "\t    };\n",
       "\t  }\n",
       "\t  var d3_bisect = d3_bisector(d3_ascending);\n",
       "\t  d3.bisectLeft = d3_bisect.left;\n",
       "\t  d3.bisect = d3.bisectRight = d3_bisect.right;\n",
       "\t  d3.bisector = function(f) {\n",
       "\t    return d3_bisector(f.length === 1 ? function(d, x) {\n",
       "\t      return d3_ascending(f(d), x);\n",
       "\t    } : f);\n",
       "\t  };\n",
       "\t  d3.shuffle = function(array, i0, i1) {\n",
       "\t    if ((m = arguments.length) < 3) {\n",
       "\t      i1 = array.length;\n",
       "\t      if (m < 2) i0 = 0;\n",
       "\t    }\n",
       "\t    var m = i1 - i0, t, i;\n",
       "\t    while (m) {\n",
       "\t      i = Math.random() * m-- | 0;\n",
       "\t      t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t;\n",
       "\t    }\n",
       "\t    return array;\n",
       "\t  };\n",
       "\t  d3.permute = function(array, indexes) {\n",
       "\t    var i = indexes.length, permutes = new Array(i);\n",
       "\t    while (i--) permutes[i] = array[indexes[i]];\n",
       "\t    return permutes;\n",
       "\t  };\n",
       "\t  d3.pairs = function(array) {\n",
       "\t    var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);\n",
       "\t    while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];\n",
       "\t    return pairs;\n",
       "\t  };\n",
       "\t  d3.transpose = function(matrix) {\n",
       "\t    if (!(n = matrix.length)) return [];\n",
       "\t    for (var i = -1, m = d3.min(matrix, d3_transposeLength), transpose = new Array(m); ++i < m; ) {\n",
       "\t      for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n; ) {\n",
       "\t        row[j] = matrix[j][i];\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return transpose;\n",
       "\t  };\n",
       "\t  function d3_transposeLength(d) {\n",
       "\t    return d.length;\n",
       "\t  }\n",
       "\t  d3.zip = function() {\n",
       "\t    return d3.transpose(arguments);\n",
       "\t  };\n",
       "\t  d3.keys = function(map) {\n",
       "\t    var keys = [];\n",
       "\t    for (var key in map) keys.push(key);\n",
       "\t    return keys;\n",
       "\t  };\n",
       "\t  d3.values = function(map) {\n",
       "\t    var values = [];\n",
       "\t    for (var key in map) values.push(map[key]);\n",
       "\t    return values;\n",
       "\t  };\n",
       "\t  d3.entries = function(map) {\n",
       "\t    var entries = [];\n",
       "\t    for (var key in map) entries.push({\n",
       "\t      key: key,\n",
       "\t      value: map[key]\n",
       "\t    });\n",
       "\t    return entries;\n",
       "\t  };\n",
       "\t  d3.merge = function(arrays) {\n",
       "\t    var n = arrays.length, m, i = -1, j = 0, merged, array;\n",
       "\t    while (++i < n) j += arrays[i].length;\n",
       "\t    merged = new Array(j);\n",
       "\t    while (--n >= 0) {\n",
       "\t      array = arrays[n];\n",
       "\t      m = array.length;\n",
       "\t      while (--m >= 0) {\n",
       "\t        merged[--j] = array[m];\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return merged;\n",
       "\t  };\n",
       "\t  var abs = Math.abs;\n",
       "\t  d3.range = function(start, stop, step) {\n",
       "\t    if (arguments.length < 3) {\n",
       "\t      step = 1;\n",
       "\t      if (arguments.length < 2) {\n",
       "\t        stop = start;\n",
       "\t        start = 0;\n",
       "\t      }\n",
       "\t    }\n",
       "\t    if ((stop - start) / step === Infinity) throw new Error(\"infinite range\");\n",
       "\t    var range = [], k = d3_range_integerScale(abs(step)), i = -1, j;\n",
       "\t    start *= k, stop *= k, step *= k;\n",
       "\t    if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k);\n",
       "\t    return range;\n",
       "\t  };\n",
       "\t  function d3_range_integerScale(x) {\n",
       "\t    var k = 1;\n",
       "\t    while (x * k % 1) k *= 10;\n",
       "\t    return k;\n",
       "\t  }\n",
       "\t  function d3_class(ctor, properties) {\n",
       "\t    for (var key in properties) {\n",
       "\t      Object.defineProperty(ctor.prototype, key, {\n",
       "\t        value: properties[key],\n",
       "\t        enumerable: false\n",
       "\t      });\n",
       "\t    }\n",
       "\t  }\n",
       "\t  d3.map = function(object, f) {\n",
       "\t    var map = new d3_Map();\n",
       "\t    if (object instanceof d3_Map) {\n",
       "\t      object.forEach(function(key, value) {\n",
       "\t        map.set(key, value);\n",
       "\t      });\n",
       "\t    } else if (Array.isArray(object)) {\n",
       "\t      var i = -1, n = object.length, o;\n",
       "\t      if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o);\n",
       "\t    } else {\n",
       "\t      for (var key in object) map.set(key, object[key]);\n",
       "\t    }\n",
       "\t    return map;\n",
       "\t  };\n",
       "\t  function d3_Map() {\n",
       "\t    this._ = Object.create(null);\n",
       "\t  }\n",
       "\t  var d3_map_proto = \"__proto__\", d3_map_zero = \"\\x00\";\n",
       "\t  d3_class(d3_Map, {\n",
       "\t    has: d3_map_has,\n",
       "\t    get: function(key) {\n",
       "\t      return this._[d3_map_escape(key)];\n",
       "\t    },\n",
       "\t    set: function(key, value) {\n",
       "\t      return this._[d3_map_escape(key)] = value;\n",
       "\t    },\n",
       "\t    remove: d3_map_remove,\n",
       "\t    keys: d3_map_keys,\n",
       "\t    values: function() {\n",
       "\t      var values = [];\n",
       "\t      for (var key in this._) values.push(this._[key]);\n",
       "\t      return values;\n",
       "\t    },\n",
       "\t    entries: function() {\n",
       "\t      var entries = [];\n",
       "\t      for (var key in this._) entries.push({\n",
       "\t        key: d3_map_unescape(key),\n",
       "\t        value: this._[key]\n",
       "\t      });\n",
       "\t      return entries;\n",
       "\t    },\n",
       "\t    size: d3_map_size,\n",
       "\t    empty: d3_map_empty,\n",
       "\t    forEach: function(f) {\n",
       "\t      for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]);\n",
       "\t    }\n",
       "\t  });\n",
       "\t  function d3_map_escape(key) {\n",
       "\t    return (key += \"\") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key;\n",
       "\t  }\n",
       "\t  function d3_map_unescape(key) {\n",
       "\t    return (key += \"\")[0] === d3_map_zero ? key.slice(1) : key;\n",
       "\t  }\n",
       "\t  function d3_map_has(key) {\n",
       "\t    return d3_map_escape(key) in this._;\n",
       "\t  }\n",
       "\t  function d3_map_remove(key) {\n",
       "\t    return (key = d3_map_escape(key)) in this._ && delete this._[key];\n",
       "\t  }\n",
       "\t  function d3_map_keys() {\n",
       "\t    var keys = [];\n",
       "\t    for (var key in this._) keys.push(d3_map_unescape(key));\n",
       "\t    return keys;\n",
       "\t  }\n",
       "\t  function d3_map_size() {\n",
       "\t    var size = 0;\n",
       "\t    for (var key in this._) ++size;\n",
       "\t    return size;\n",
       "\t  }\n",
       "\t  function d3_map_empty() {\n",
       "\t    for (var key in this._) return false;\n",
       "\t    return true;\n",
       "\t  }\n",
       "\t  d3.nest = function() {\n",
       "\t    var nest = {}, keys = [], sortKeys = [], sortValues, rollup;\n",
       "\t    function map(mapType, array, depth) {\n",
       "\t      if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array;\n",
       "\t      var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values;\n",
       "\t      while (++i < n) {\n",
       "\t        if (values = valuesByKey.get(keyValue = key(object = array[i]))) {\n",
       "\t          values.push(object);\n",
       "\t        } else {\n",
       "\t          valuesByKey.set(keyValue, [ object ]);\n",
       "\t        }\n",
       "\t      }\n",
       "\t      if (mapType) {\n",
       "\t        object = mapType();\n",
       "\t        setter = function(keyValue, values) {\n",
       "\t          object.set(keyValue, map(mapType, values, depth));\n",
       "\t        };\n",
       "\t      } else {\n",
       "\t        object = {};\n",
       "\t        setter = function(keyValue, values) {\n",
       "\t          object[keyValue] = map(mapType, values, depth);\n",
       "\t        };\n",
       "\t      }\n",
       "\t      valuesByKey.forEach(setter);\n",
       "\t      return object;\n",
       "\t    }\n",
       "\t    function entries(map, depth) {\n",
       "\t      if (depth >= keys.length) return map;\n",
       "\t      var array = [], sortKey = sortKeys[depth++];\n",
       "\t      map.forEach(function(key, keyMap) {\n",
       "\t        array.push({\n",
       "\t          key: key,\n",
       "\t          values: entries(keyMap, depth)\n",
       "\t        });\n",
       "\t      });\n",
       "\t      return sortKey ? array.sort(function(a, b) {\n",
       "\t        return sortKey(a.key, b.key);\n",
       "\t      }) : array;\n",
       "\t    }\n",
       "\t    nest.map = function(array, mapType) {\n",
       "\t      return map(mapType, array, 0);\n",
       "\t    };\n",
       "\t    nest.entries = function(array) {\n",
       "\t      return entries(map(d3.map, array, 0), 0);\n",
       "\t    };\n",
       "\t    nest.key = function(d) {\n",
       "\t      keys.push(d);\n",
       "\t      return nest;\n",
       "\t    };\n",
       "\t    nest.sortKeys = function(order) {\n",
       "\t      sortKeys[keys.length - 1] = order;\n",
       "\t      return nest;\n",
       "\t    };\n",
       "\t    nest.sortValues = function(order) {\n",
       "\t      sortValues = order;\n",
       "\t      return nest;\n",
       "\t    };\n",
       "\t    nest.rollup = function(f) {\n",
       "\t      rollup = f;\n",
       "\t      return nest;\n",
       "\t    };\n",
       "\t    return nest;\n",
       "\t  };\n",
       "\t  d3.set = function(array) {\n",
       "\t    var set = new d3_Set();\n",
       "\t    if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);\n",
       "\t    return set;\n",
       "\t  };\n",
       "\t  function d3_Set() {\n",
       "\t    this._ = Object.create(null);\n",
       "\t  }\n",
       "\t  d3_class(d3_Set, {\n",
       "\t    has: d3_map_has,\n",
       "\t    add: function(key) {\n",
       "\t      this._[d3_map_escape(key += \"\")] = true;\n",
       "\t      return key;\n",
       "\t    },\n",
       "\t    remove: d3_map_remove,\n",
       "\t    values: d3_map_keys,\n",
       "\t    size: d3_map_size,\n",
       "\t    empty: d3_map_empty,\n",
       "\t    forEach: function(f) {\n",
       "\t      for (var key in this._) f.call(this, d3_map_unescape(key));\n",
       "\t    }\n",
       "\t  });\n",
       "\t  d3.behavior = {};\n",
       "\t  function d3_identity(d) {\n",
       "\t    return d;\n",
       "\t  }\n",
       "\t  d3.rebind = function(target, source) {\n",
       "\t    var i = 1, n = arguments.length, method;\n",
       "\t    while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);\n",
       "\t    return target;\n",
       "\t  };\n",
       "\t  function d3_rebind(target, source, method) {\n",
       "\t    return function() {\n",
       "\t      var value = method.apply(source, arguments);\n",
       "\t      return value === source ? target : value;\n",
       "\t    };\n",
       "\t  }\n",
       "\t  function d3_vendorSymbol(object, name) {\n",
       "\t    if (name in object) return name;\n",
       "\t    name = name.charAt(0).toUpperCase() + name.slice(1);\n",
       "\t    for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) {\n",
       "\t      var prefixName = d3_vendorPrefixes[i] + name;\n",
       "\t      if (prefixName in object) return prefixName;\n",
       "\t    }\n",
       "\t  }\n",
       "\t  var d3_vendorPrefixes = [ \"webkit\", \"ms\", \"moz\", \"Moz\", \"o\", \"O\" ];\n",
       "\t  function d3_noop() {}\n",
       "\t  d3.dispatch = function() {\n",
       "\t    var dispatch = new d3_dispatch(), i = -1, n = arguments.length;\n",
       "\t    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);\n",
       "\t    return dispatch;\n",
       "\t  };\n",
       "\t  function d3_dispatch() {}\n",
       "\t  d3_dispatch.prototype.on = function(type, listener) {\n",
       "\t    var i = type.indexOf(\".\"), name = \"\";\n",
       "\t    if (i >= 0) {\n",
       "\t      name = type.slice(i + 1);\n",
       "\t      type = type.slice(0, i);\n",
       "\t    }\n",
       "\t    if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener);\n",
       "\t    if (arguments.length === 2) {\n",
       "\t      if (listener == null) for (type in this) {\n",
       "\t        if (this.hasOwnProperty(type)) this[type].on(name, null);\n",
       "\t      }\n",
       "\t      return this;\n",
       "\t    }\n",
       "\t  };\n",
       "\t  function d3_dispatch_event(dispatch) {\n",
       "\t    var listeners = [], listenerByName = new d3_Map();\n",
       "\t    function event() {\n",
       "\t      var z = listeners, i = -1, n = z.length, l;\n",
       "\t      while (++i < n) if (l = z[i].on) l.apply(this, arguments);\n",
       "\t      return dispatch;\n",
       "\t    }\n",
       "\t    event.on = function(name, listener) {\n",
       "\t      var l = listenerByName.get(name), i;\n",
       "\t      if (arguments.length < 2) return l && l.on;\n",
       "\t      if (l) {\n",
       "\t        l.on = null;\n",
       "\t        listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));\n",
       "\t        listenerByName.remove(name);\n",
       "\t      }\n",
       "\t      if (listener) listeners.push(listenerByName.set(name, {\n",
       "\t        on: listener\n",
       "\t      }));\n",
       "\t      return dispatch;\n",
       "\t    };\n",
       "\t    return event;\n",
       "\t  }\n",
       "\t  d3.event = null;\n",
       "\t  function d3_eventPreventDefault() {\n",
       "\t    d3.event.preventDefault();\n",
       "\t  }\n",
       "\t  function d3_eventSource() {\n",
       "\t    var e = d3.event, s;\n",
       "\t    while (s = e.sourceEvent) e = s;\n",
       "\t    return e;\n",
       "\t  }\n",
       "\t  function d3_eventDispatch(target) {\n",
       "\t    var dispatch = new d3_dispatch(), i = 0, n = arguments.length;\n",
       "\t    while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);\n",
       "\t    dispatch.of = function(thiz, argumentz) {\n",
       "\t      return function(e1) {\n",
       "\t        try {\n",
       "\t          var e0 = e1.sourceEvent = d3.event;\n",
       "\t          e1.target = target;\n",
       "\t          d3.event = e1;\n",
       "\t          dispatch[e1.type].apply(thiz, argumentz);\n",
       "\t        } finally {\n",
       "\t          d3.event = e0;\n",
       "\t        }\n",
       "\t      };\n",
       "\t    };\n",
       "\t    return dispatch;\n",
       "\t  }\n",
       "\t  d3.requote = function(s) {\n",
       "\t    return s.replace(d3_requote_re, \"\\\\$&\");\n",
       "\t  };\n",
       "\t  var d3_requote_re = /[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g;\n",
       "\t  var d3_subclass = {}.__proto__ ? function(object, prototype) {\n",
       "\t    object.__proto__ = prototype;\n",
       "\t  } : function(object, prototype) {\n",
       "\t    for (var property in prototype) object[property] = prototype[property];\n",
       "\t  };\n",
       "\t  function d3_selection(groups) {\n",
       "\t    d3_subclass(groups, d3_selectionPrototype);\n",
       "\t    return groups;\n",
       "\t  }\n",
       "\t  var d3_select = function(s, n) {\n",
       "\t    return n.querySelector(s);\n",
       "\t  }, d3_selectAll = function(s, n) {\n",
       "\t    return n.querySelectorAll(s);\n",
       "\t  }, d3_selectMatches = function(n, s) {\n",
       "\t    var d3_selectMatcher = n.matches || n[d3_vendorSymbol(n, \"matchesSelector\")];\n",
       "\t    d3_selectMatches = function(n, s) {\n",
       "\t      return d3_selectMatcher.call(n, s);\n",
       "\t    };\n",
       "\t    return d3_selectMatches(n, s);\n",
       "\t  };\n",
       "\t  if (typeof Sizzle === \"function\") {\n",
       "\t    d3_select = function(s, n) {\n",
       "\t      return Sizzle(s, n)[0] || null;\n",
       "\t    };\n",
       "\t    d3_selectAll = Sizzle;\n",
       "\t    d3_selectMatches = Sizzle.matchesSelector;\n",
       "\t  }\n",
       "\t  d3.selection = function() {\n",
       "\t    return d3.select(d3_document.documentElement);\n",
       "\t  };\n",
       "\t  var d3_selectionPrototype = d3.selection.prototype = [];\n",
       "\t  d3_selectionPrototype.select = function(selector) {\n",
       "\t    var subgroups = [], subgroup, subnode, group, node;\n",
       "\t    selector = d3_selection_selector(selector);\n",
       "\t    for (var j = -1, m = this.length; ++j < m; ) {\n",
       "\t      subgroups.push(subgroup = []);\n",
       "\t      subgroup.parentNode = (group = this[j]).parentNode;\n",
       "\t      for (var i = -1, n = group.length; ++i < n; ) {\n",
       "\t        if (node = group[i]) {\n",
       "\t          subgroup.push(subnode = selector.call(node, node.__data__, i, j));\n",
       "\t          if (subnode && \"__data__\" in node) subnode.__data__ = node.__data__;\n",
       "\t        } else {\n",
       "\t          subgroup.push(null);\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return d3_selection(subgroups);\n",
       "\t  };\n",
       "\t  function d3_selection_selector(selector) {\n",
       "\t    return typeof selector === \"function\" ? selector : function() {\n",
       "\t      return d3_select(selector, this);\n",
       "\t    };\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.selectAll = function(selector) {\n",
       "\t    var subgroups = [], subgroup, node;\n",
       "\t    selector = d3_selection_selectorAll(selector);\n",
       "\t    for (var j = -1, m = this.length; ++j < m; ) {\n",
       "\t      for (var group = this[j], i = -1, n = group.length; ++i < n; ) {\n",
       "\t        if (node = group[i]) {\n",
       "\t          subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j)));\n",
       "\t          subgroup.parentNode = node;\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return d3_selection(subgroups);\n",
       "\t  };\n",
       "\t  function d3_selection_selectorAll(selector) {\n",
       "\t    return typeof selector === \"function\" ? selector : function() {\n",
       "\t      return d3_selectAll(selector, this);\n",
       "\t    };\n",
       "\t  }\n",
       "\t  var d3_nsXhtml = \"http://www.w3.org/1999/xhtml\";\n",
       "\t  var d3_nsPrefix = {\n",
       "\t    svg: \"http://www.w3.org/2000/svg\",\n",
       "\t    xhtml: d3_nsXhtml,\n",
       "\t    xlink: \"http://www.w3.org/1999/xlink\",\n",
       "\t    xml: \"http://www.w3.org/XML/1998/namespace\",\n",
       "\t    xmlns: \"http://www.w3.org/2000/xmlns/\"\n",
       "\t  };\n",
       "\t  d3.ns = {\n",
       "\t    prefix: d3_nsPrefix,\n",
       "\t    qualify: function(name) {\n",
       "\t      var i = name.indexOf(\":\"), prefix = name;\n",
       "\t      if (i >= 0 && (prefix = name.slice(0, i)) !== \"xmlns\") name = name.slice(i + 1);\n",
       "\t      return d3_nsPrefix.hasOwnProperty(prefix) ? {\n",
       "\t        space: d3_nsPrefix[prefix],\n",
       "\t        local: name\n",
       "\t      } : name;\n",
       "\t    }\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.attr = function(name, value) {\n",
       "\t    if (arguments.length < 2) {\n",
       "\t      if (typeof name === \"string\") {\n",
       "\t        var node = this.node();\n",
       "\t        name = d3.ns.qualify(name);\n",
       "\t        return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name);\n",
       "\t      }\n",
       "\t      for (value in name) this.each(d3_selection_attr(value, name[value]));\n",
       "\t      return this;\n",
       "\t    }\n",
       "\t    return this.each(d3_selection_attr(name, value));\n",
       "\t  };\n",
       "\t  function d3_selection_attr(name, value) {\n",
       "\t    name = d3.ns.qualify(name);\n",
       "\t    function attrNull() {\n",
       "\t      this.removeAttribute(name);\n",
       "\t    }\n",
       "\t    function attrNullNS() {\n",
       "\t      this.removeAttributeNS(name.space, name.local);\n",
       "\t    }\n",
       "\t    function attrConstant() {\n",
       "\t      this.setAttribute(name, value);\n",
       "\t    }\n",
       "\t    function attrConstantNS() {\n",
       "\t      this.setAttributeNS(name.space, name.local, value);\n",
       "\t    }\n",
       "\t    function attrFunction() {\n",
       "\t      var x = value.apply(this, arguments);\n",
       "\t      if (x == null) this.removeAttribute(name); else this.setAttribute(name, x);\n",
       "\t    }\n",
       "\t    function attrFunctionNS() {\n",
       "\t      var x = value.apply(this, arguments);\n",
       "\t      if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x);\n",
       "\t    }\n",
       "\t    return value == null ? name.local ? attrNullNS : attrNull : typeof value === \"function\" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant;\n",
       "\t  }\n",
       "\t  function d3_collapse(s) {\n",
       "\t    return s.trim().replace(/\\s+/g, \" \");\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.classed = function(name, value) {\n",
       "\t    if (arguments.length < 2) {\n",
       "\t      if (typeof name === \"string\") {\n",
       "\t        var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1;\n",
       "\t        if (value = node.classList) {\n",
       "\t          while (++i < n) if (!value.contains(name[i])) return false;\n",
       "\t        } else {\n",
       "\t          value = node.getAttribute(\"class\");\n",
       "\t          while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false;\n",
       "\t        }\n",
       "\t        return true;\n",
       "\t      }\n",
       "\t      for (value in name) this.each(d3_selection_classed(value, name[value]));\n",
       "\t      return this;\n",
       "\t    }\n",
       "\t    return this.each(d3_selection_classed(name, value));\n",
       "\t  };\n",
       "\t  function d3_selection_classedRe(name) {\n",
       "\t    return new RegExp(\"(?:^|\\\\s+)\" + d3.requote(name) + \"(?:\\\\s+|$)\", \"g\");\n",
       "\t  }\n",
       "\t  function d3_selection_classes(name) {\n",
       "\t    return (name + \"\").trim().split(/^|\\s+/);\n",
       "\t  }\n",
       "\t  function d3_selection_classed(name, value) {\n",
       "\t    name = d3_selection_classes(name).map(d3_selection_classedName);\n",
       "\t    var n = name.length;\n",
       "\t    function classedConstant() {\n",
       "\t      var i = -1;\n",
       "\t      while (++i < n) name[i](this, value);\n",
       "\t    }\n",
       "\t    function classedFunction() {\n",
       "\t      var i = -1, x = value.apply(this, arguments);\n",
       "\t      while (++i < n) name[i](this, x);\n",
       "\t    }\n",
       "\t    return typeof value === \"function\" ? classedFunction : classedConstant;\n",
       "\t  }\n",
       "\t  function d3_selection_classedName(name) {\n",
       "\t    var re = d3_selection_classedRe(name);\n",
       "\t    return function(node, value) {\n",
       "\t      if (c = node.classList) return value ? c.add(name) : c.remove(name);\n",
       "\t      var c = node.getAttribute(\"class\") || \"\";\n",
       "\t      if (value) {\n",
       "\t        re.lastIndex = 0;\n",
       "\t        if (!re.test(c)) node.setAttribute(\"class\", d3_collapse(c + \" \" + name));\n",
       "\t      } else {\n",
       "\t        node.setAttribute(\"class\", d3_collapse(c.replace(re, \" \")));\n",
       "\t      }\n",
       "\t    };\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.style = function(name, value, priority) {\n",
       "\t    var n = arguments.length;\n",
       "\t    if (n < 3) {\n",
       "\t      if (typeof name !== \"string\") {\n",
       "\t        if (n < 2) value = \"\";\n",
       "\t        for (priority in name) this.each(d3_selection_style(priority, name[priority], value));\n",
       "\t        return this;\n",
       "\t      }\n",
       "\t      if (n < 2) {\n",
       "\t        var node = this.node();\n",
       "\t        return d3_window(node).getComputedStyle(node, null).getPropertyValue(name);\n",
       "\t      }\n",
       "\t      priority = \"\";\n",
       "\t    }\n",
       "\t    return this.each(d3_selection_style(name, value, priority));\n",
       "\t  };\n",
       "\t  function d3_selection_style(name, value, priority) {\n",
       "\t    function styleNull() {\n",
       "\t      this.style.removeProperty(name);\n",
       "\t    }\n",
       "\t    function styleConstant() {\n",
       "\t      this.style.setProperty(name, value, priority);\n",
       "\t    }\n",
       "\t    function styleFunction() {\n",
       "\t      var x = value.apply(this, arguments);\n",
       "\t      if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority);\n",
       "\t    }\n",
       "\t    return value == null ? styleNull : typeof value === \"function\" ? styleFunction : styleConstant;\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.property = function(name, value) {\n",
       "\t    if (arguments.length < 2) {\n",
       "\t      if (typeof name === \"string\") return this.node()[name];\n",
       "\t      for (value in name) this.each(d3_selection_property(value, name[value]));\n",
       "\t      return this;\n",
       "\t    }\n",
       "\t    return this.each(d3_selection_property(name, value));\n",
       "\t  };\n",
       "\t  function d3_selection_property(name, value) {\n",
       "\t    function propertyNull() {\n",
       "\t      delete this[name];\n",
       "\t    }\n",
       "\t    function propertyConstant() {\n",
       "\t      this[name] = value;\n",
       "\t    }\n",
       "\t    function propertyFunction() {\n",
       "\t      var x = value.apply(this, arguments);\n",
       "\t      if (x == null) delete this[name]; else this[name] = x;\n",
       "\t    }\n",
       "\t    return value == null ? propertyNull : typeof value === \"function\" ? propertyFunction : propertyConstant;\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.text = function(value) {\n",
       "\t    return arguments.length ? this.each(typeof value === \"function\" ? function() {\n",
       "\t      var v = value.apply(this, arguments);\n",
       "\t      this.textContent = v == null ? \"\" : v;\n",
       "\t    } : value == null ? function() {\n",
       "\t      this.textContent = \"\";\n",
       "\t    } : function() {\n",
       "\t      this.textContent = value;\n",
       "\t    }) : this.node().textContent;\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.html = function(value) {\n",
       "\t    return arguments.length ? this.each(typeof value === \"function\" ? function() {\n",
       "\t      var v = value.apply(this, arguments);\n",
       "\t      this.innerHTML = v == null ? \"\" : v;\n",
       "\t    } : value == null ? function() {\n",
       "\t      this.innerHTML = \"\";\n",
       "\t    } : function() {\n",
       "\t      this.innerHTML = value;\n",
       "\t    }) : this.node().innerHTML;\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.append = function(name) {\n",
       "\t    name = d3_selection_creator(name);\n",
       "\t    return this.select(function() {\n",
       "\t      return this.appendChild(name.apply(this, arguments));\n",
       "\t    });\n",
       "\t  };\n",
       "\t  function d3_selection_creator(name) {\n",
       "\t    function create() {\n",
       "\t      var document = this.ownerDocument, namespace = this.namespaceURI;\n",
       "\t      return namespace === d3_nsXhtml && document.documentElement.namespaceURI === d3_nsXhtml ? document.createElement(name) : document.createElementNS(namespace, name);\n",
       "\t    }\n",
       "\t    function createNS() {\n",
       "\t      return this.ownerDocument.createElementNS(name.space, name.local);\n",
       "\t    }\n",
       "\t    return typeof name === \"function\" ? name : (name = d3.ns.qualify(name)).local ? createNS : create;\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.insert = function(name, before) {\n",
       "\t    name = d3_selection_creator(name);\n",
       "\t    before = d3_selection_selector(before);\n",
       "\t    return this.select(function() {\n",
       "\t      return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);\n",
       "\t    });\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.remove = function() {\n",
       "\t    return this.each(d3_selectionRemove);\n",
       "\t  };\n",
       "\t  function d3_selectionRemove() {\n",
       "\t    var parent = this.parentNode;\n",
       "\t    if (parent) parent.removeChild(this);\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.data = function(value, key) {\n",
       "\t    var i = -1, n = this.length, group, node;\n",
       "\t    if (!arguments.length) {\n",
       "\t      value = new Array(n = (group = this[0]).length);\n",
       "\t      while (++i < n) {\n",
       "\t        if (node = group[i]) {\n",
       "\t          value[i] = node.__data__;\n",
       "\t        }\n",
       "\t      }\n",
       "\t      return value;\n",
       "\t    }\n",
       "\t    function bind(group, groupData) {\n",
       "\t      var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData;\n",
       "\t      if (key) {\n",
       "\t        var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue;\n",
       "\t        for (i = -1; ++i < n; ) {\n",
       "\t          if (node = group[i]) {\n",
       "\t            if (nodeByKeyValue.has(keyValue = key.call(node, node.__data__, i))) {\n",
       "\t              exitNodes[i] = node;\n",
       "\t            } else {\n",
       "\t              nodeByKeyValue.set(keyValue, node);\n",
       "\t            }\n",
       "\t            keyValues[i] = keyValue;\n",
       "\t          }\n",
       "\t        }\n",
       "\t        for (i = -1; ++i < m; ) {\n",
       "\t          if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) {\n",
       "\t            enterNodes[i] = d3_selection_dataNode(nodeData);\n",
       "\t          } else if (node !== true) {\n",
       "\t            updateNodes[i] = node;\n",
       "\t            node.__data__ = nodeData;\n",
       "\t          }\n",
       "\t          nodeByKeyValue.set(keyValue, true);\n",
       "\t        }\n",
       "\t        for (i = -1; ++i < n; ) {\n",
       "\t          if (i in keyValues && nodeByKeyValue.get(keyValues[i]) !== true) {\n",
       "\t            exitNodes[i] = group[i];\n",
       "\t          }\n",
       "\t        }\n",
       "\t      } else {\n",
       "\t        for (i = -1; ++i < n0; ) {\n",
       "\t          node = group[i];\n",
       "\t          nodeData = groupData[i];\n",
       "\t          if (node) {\n",
       "\t            node.__data__ = nodeData;\n",
       "\t            updateNodes[i] = node;\n",
       "\t          } else {\n",
       "\t            enterNodes[i] = d3_selection_dataNode(nodeData);\n",
       "\t          }\n",
       "\t        }\n",
       "\t        for (;i < m; ++i) {\n",
       "\t          enterNodes[i] = d3_selection_dataNode(groupData[i]);\n",
       "\t        }\n",
       "\t        for (;i < n; ++i) {\n",
       "\t          exitNodes[i] = group[i];\n",
       "\t        }\n",
       "\t      }\n",
       "\t      enterNodes.update = updateNodes;\n",
       "\t      enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;\n",
       "\t      enter.push(enterNodes);\n",
       "\t      update.push(updateNodes);\n",
       "\t      exit.push(exitNodes);\n",
       "\t    }\n",
       "\t    var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]);\n",
       "\t    if (typeof value === \"function\") {\n",
       "\t      while (++i < n) {\n",
       "\t        bind(group = this[i], value.call(group, group.parentNode.__data__, i));\n",
       "\t      }\n",
       "\t    } else {\n",
       "\t      while (++i < n) {\n",
       "\t        bind(group = this[i], value);\n",
       "\t      }\n",
       "\t    }\n",
       "\t    update.enter = function() {\n",
       "\t      return enter;\n",
       "\t    };\n",
       "\t    update.exit = function() {\n",
       "\t      return exit;\n",
       "\t    };\n",
       "\t    return update;\n",
       "\t  };\n",
       "\t  function d3_selection_dataNode(data) {\n",
       "\t    return {\n",
       "\t      __data__: data\n",
       "\t    };\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.datum = function(value) {\n",
       "\t    return arguments.length ? this.property(\"__data__\", value) : this.property(\"__data__\");\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.filter = function(filter) {\n",
       "\t    var subgroups = [], subgroup, group, node;\n",
       "\t    if (typeof filter !== \"function\") filter = d3_selection_filter(filter);\n",
       "\t    for (var j = 0, m = this.length; j < m; j++) {\n",
       "\t      subgroups.push(subgroup = []);\n",
       "\t      subgroup.parentNode = (group = this[j]).parentNode;\n",
       "\t      for (var i = 0, n = group.length; i < n; i++) {\n",
       "\t        if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {\n",
       "\t          subgroup.push(node);\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return d3_selection(subgroups);\n",
       "\t  };\n",
       "\t  function d3_selection_filter(selector) {\n",
       "\t    return function() {\n",
       "\t      return d3_selectMatches(this, selector);\n",
       "\t    };\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.order = function() {\n",
       "\t    for (var j = -1, m = this.length; ++j < m; ) {\n",
       "\t      for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) {\n",
       "\t        if (node = group[i]) {\n",
       "\t          if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);\n",
       "\t          next = node;\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return this;\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.sort = function(comparator) {\n",
       "\t    comparator = d3_selection_sortComparator.apply(this, arguments);\n",
       "\t    for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator);\n",
       "\t    return this.order();\n",
       "\t  };\n",
       "\t  function d3_selection_sortComparator(comparator) {\n",
       "\t    if (!arguments.length) comparator = d3_ascending;\n",
       "\t    return function(a, b) {\n",
       "\t      return a && b ? comparator(a.__data__, b.__data__) : !a - !b;\n",
       "\t    };\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.each = function(callback) {\n",
       "\t    return d3_selection_each(this, function(node, i, j) {\n",
       "\t      callback.call(node, node.__data__, i, j);\n",
       "\t    });\n",
       "\t  };\n",
       "\t  function d3_selection_each(groups, callback) {\n",
       "\t    for (var j = 0, m = groups.length; j < m; j++) {\n",
       "\t      for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {\n",
       "\t        if (node = group[i]) callback(node, i, j);\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return groups;\n",
       "\t  }\n",
       "\t  d3_selectionPrototype.call = function(callback) {\n",
       "\t    var args = d3_array(arguments);\n",
       "\t    callback.apply(args[0] = this, args);\n",
       "\t    return this;\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.empty = function() {\n",
       "\t    return !this.node();\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.node = function() {\n",
       "\t    for (var j = 0, m = this.length; j < m; j++) {\n",
       "\t      for (var group = this[j], i = 0, n = group.length; i < n; i++) {\n",
       "\t        var node = group[i];\n",
       "\t        if (node) return node;\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return null;\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.size = function() {\n",
       "\t    var n = 0;\n",
       "\t    d3_selection_each(this, function() {\n",
       "\t      ++n;\n",
       "\t    });\n",
       "\t    return n;\n",
       "\t  };\n",
       "\t  function d3_selection_enter(selection) {\n",
       "\t    d3_subclass(selection, d3_selection_enterPrototype);\n",
       "\t    return selection;\n",
       "\t  }\n",
       "\t  var d3_selection_enterPrototype = [];\n",
       "\t  d3.selection.enter = d3_selection_enter;\n",
       "\t  d3.selection.enter.prototype = d3_selection_enterPrototype;\n",
       "\t  d3_selection_enterPrototype.append = d3_selectionPrototype.append;\n",
       "\t  d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;\n",
       "\t  d3_selection_enterPrototype.node = d3_selectionPrototype.node;\n",
       "\t  d3_selection_enterPrototype.call = d3_selectionPrototype.call;\n",
       "\t  d3_selection_enterPrototype.size = d3_selectionPrototype.size;\n",
       "\t  d3_selection_enterPrototype.select = function(selector) {\n",
       "\t    var subgroups = [], subgroup, subnode, upgroup, group, node;\n",
       "\t    for (var j = -1, m = this.length; ++j < m; ) {\n",
       "\t      upgroup = (group = this[j]).update;\n",
       "\t      subgroups.push(subgroup = []);\n",
       "\t      subgroup.parentNode = group.parentNode;\n",
       "\t      for (var i = -1, n = group.length; ++i < n; ) {\n",
       "\t        if (node = group[i]) {\n",
       "\t          subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j));\n",
       "\t          subnode.__data__ = node.__data__;\n",
       "\t        } else {\n",
       "\t          subgroup.push(null);\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return d3_selection(subgroups);\n",
       "\t  };\n",
       "\t  d3_selection_enterPrototype.insert = function(name, before) {\n",
       "\t    if (arguments.length < 2) before = d3_selection_enterInsertBefore(this);\n",
       "\t    return d3_selectionPrototype.insert.call(this, name, before);\n",
       "\t  };\n",
       "\t  function d3_selection_enterInsertBefore(enter) {\n",
       "\t    var i0, j0;\n",
       "\t    return function(d, i, j) {\n",
       "\t      var group = enter[j].update, n = group.length, node;\n",
       "\t      if (j != j0) j0 = j, i0 = 0;\n",
       "\t      if (i >= i0) i0 = i + 1;\n",
       "\t      while (!(node = group[i0]) && ++i0 < n) ;\n",
       "\t      return node;\n",
       "\t    };\n",
       "\t  }\n",
       "\t  d3.select = function(node) {\n",
       "\t    var group;\n",
       "\t    if (typeof node === \"string\") {\n",
       "\t      group = [ d3_select(node, d3_document) ];\n",
       "\t      group.parentNode = d3_document.documentElement;\n",
       "\t    } else {\n",
       "\t      group = [ node ];\n",
       "\t      group.parentNode = d3_documentElement(node);\n",
       "\t    }\n",
       "\t    return d3_selection([ group ]);\n",
       "\t  };\n",
       "\t  d3.selectAll = function(nodes) {\n",
       "\t    var group;\n",
       "\t    if (typeof nodes === \"string\") {\n",
       "\t      group = d3_array(d3_selectAll(nodes, d3_document));\n",
       "\t      group.parentNode = d3_document.documentElement;\n",
       "\t    } else {\n",
       "\t      group = d3_array(nodes);\n",
       "\t      group.parentNode = null;\n",
       "\t    }\n",
       "\t    return d3_selection([ group ]);\n",
       "\t  };\n",
       "\t  d3_selectionPrototype.on = function(type, listener, capture) {\n",
       "\t    var n = arguments.length;\n",
       "\t    if (n < 3) {\n",
       "\t      if (typeof type !== \"string\") {\n",
       "\t        if (n < 2) listener = false;\n",
       "\t        for (capture in type) this.each(d3_selection_on(capture, type[capture], listener));\n",
       "\t        return this;\n",
       "\t      }\n",
       "\t      if (n < 2) return (n = this.node()[\"__on\" + type]) && n._;\n",
       "\t      capture = false;\n",
       "\t    }\n",
       "\t    return this.each(d3_selection_on(type, listener, capture));\n",
       "\t  };\n",
       "\t  function d3_selection_on(type, listener, capture) {\n",
       "\t    var name = \"__on\" + type, i = type.indexOf(\".\"), wrap = d3_selection_onListener;\n",
       "\t    if (i > 0) type = type.slice(0, i);\n",
       "\t    var filter = d3_selection_onFilters.get(type);\n",
       "\t    if (filter) type = filter, wrap = d3_selection_onFilter;\n",
       "\t    function onRemove() {\n",
       "\t      var l = this[name];\n",
       "\t      if (l) {\n",
       "\t        this.removeEventListener(type, l, l.$);\n",
       "\t        delete this[name];\n",
       "\t      }\n",
       "\t    }\n",
       "\t    function onAdd() {\n",
       "\t      var l = wrap(listener, d3_array(arguments));\n",
       "\t      onRemove.call(this);\n",
       "\t      this.addEventListener(type, this[name] = l, l.$ = capture);\n",
       "\t      l._ = listener;\n",
       "\t    }\n",
       "\t    function removeAll() {\n",
       "\t      var re = new RegExp(\"^__on([^.]+)\" + d3.requote(type) + \"$\"), match;\n",
       "\t      for (var name in this) {\n",
       "\t        if (match = name.match(re)) {\n",
       "\t          var l = this[name];\n",
       "\t          this.removeEventListener(match[1], l, l.$);\n",
       "\t          delete this[name];\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll;\n",
       "\t  }\n",
       "\t  var d3_selection_onFilters = d3.map({\n",
       "\t    mouseenter: \"mouseover\",\n",
       "\t    mouseleave: \"mouseout\"\n",
       "\t  });\n",
       "\t  if (d3_document) {\n",
       "\t    d3_selection_onFilters.forEach(function(k) {\n",
       "\t      if (\"on\" + k in d3_document) d3_selection_onFilters.remove(k);\n",
       "\t    });\n",
       "\t  }\n",
       "\t  function d3_selection_onListener(listener, argumentz) {\n",
       "\t    return function(e) {\n",
       "\t      var o = d3.event;\n",
       "\t      d3.event = e;\n",
       "\t      argumentz[0] = this.__data__;\n",
       "\t      try {\n",
       "\t        listener.apply(this, argumentz);\n",
       "\t      } finally {\n",
       "\t        d3.event = o;\n",
       "\t      }\n",
       "\t    };\n",
       "\t  }\n",
       "\t  function d3_selection_onFilter(listener, argumentz) {\n",
       "\t    var l = d3_selection_onListener(listener, argumentz);\n",
       "\t    return function(e) {\n",
       "\t      var target = this, related = e.relatedTarget;\n",
       "\t      if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) {\n",
       "\t        l.call(target, e);\n",
       "\t      }\n",
       "\t    };\n",
       "\t  }\n",
       "\t  var d3_event_dragSelect, d3_event_dragId = 0;\n",
       "\t  function d3_event_dragSuppress(node) {\n",
       "\t    var name = \".dragsuppress-\" + ++d3_event_dragId, click = \"click\" + name, w = d3.select(d3_window(node)).on(\"touchmove\" + name, d3_eventPreventDefault).on(\"dragstart\" + name, d3_eventPreventDefault).on(\"selectstart\" + name, d3_eventPreventDefault);\n",
       "\t    if (d3_event_dragSelect == null) {\n",
       "\t      d3_event_dragSelect = \"onselectstart\" in node ? false : d3_vendorSymbol(node.style, \"userSelect\");\n",
       "\t    }\n",
       "\t    if (d3_event_dragSelect) {\n",
       "\t      var style = d3_documentElement(node).style, select = style[d3_event_dragSelect];\n",
       "\t      style[d3_event_dragSelect] = \"none\";\n",
       "\t    }\n",
       "\t    return function(suppressClick) {\n",
       "\t      w.on(name, null);\n",
       "\t      if (d3_event_dragSelect) style[d3_event_dragSelect] = select;\n",
       "\t      if (suppressClick) {\n",
       "\t        var off = function() {\n",
       "\t          w.on(click, null);\n",
       "\t        };\n",
       "\t        w.on(click, function() {\n",
       "\t          d3_eventPreventDefault();\n",
       "\t          off();\n",
       "\t        }, true);\n",
       "\t        setTimeout(off, 0);\n",
       "\t      }\n",
       "\t    };\n",
       "\t  }\n",
       "\t  d3.mouse = function(container) {\n",
       "\t    return d3_mousePoint(container, d3_eventSource());\n",
       "\t  };\n",
       "\t  var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0;\n",
       "\t  function d3_mousePoint(container, e) {\n",
       "\t    if (e.changedTouches) e = e.changedTouches[0];\n",
       "\t    var svg = container.ownerSVGElement || container;\n",
       "\t    if (svg.createSVGPoint) {\n",
       "\t      var point = svg.createSVGPoint();\n",
       "\t      if (d3_mouse_bug44083 < 0) {\n",
       "\t        var window = d3_window(container);\n",
       "\t        if (window.scrollX || window.scrollY) {\n",
       "\t          svg = d3.select(\"body\").append(\"svg\").style({\n",
       "\t            position: \"absolute\",\n",
       "\t            top: 0,\n",
       "\t            left: 0,\n",
       "\t            margin: 0,\n",
       "\t            padding: 0,\n",
       "\t            border: \"none\"\n",
       "\t          }, \"important\");\n",
       "\t          var ctm = svg[0][0].getScreenCTM();\n",
       "\t          d3_mouse_bug44083 = !(ctm.f || ctm.e);\n",
       "\t          svg.remove();\n",
       "\t        }\n",
       "\t      }\n",
       "\t      if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX, \n",
       "\t      point.y = e.clientY;\n",
       "\t      point = point.matrixTransform(container.getScreenCTM().inverse());\n",
       "\t      return [ point.x, point.y ];\n",
       "\t    }\n",
       "\t    var rect = container.getBoundingClientRect();\n",
       "\t    return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ];\n",
       "\t  }\n",
       "\t  d3.touch = function(container, touches, identifier) {\n",
       "\t    if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches;\n",
       "\t    if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) {\n",
       "\t      if ((touch = touches[i]).identifier === identifier) {\n",
       "\t        return d3_mousePoint(container, touch);\n",
       "\t      }\n",
       "\t    }\n",
       "\t  };\n",
       "\t  d3.behavior.drag = function() {\n",
       "\t    var event = d3_eventDispatch(drag, \"drag\", \"dragstart\", \"dragend\"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_window, \"mousemove\", \"mouseup\"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_identity, \"touchmove\", \"touchend\");\n",
       "\t    function drag() {\n",
       "\t      this.on(\"mousedown.drag\", mousedown).on(\"touchstart.drag\", touchstart);\n",
       "\t    }\n",
       "\t    function dragstart(id, position, subject, move, end) {\n",
       "\t      return function() {\n",
       "\t        var that = this, target = d3.event.target.correspondingElement || d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = \".drag\" + (dragId == null ? \"\" : \"-\" + dragId), dragOffset, dragSubject = d3.select(subject(target)).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(target), position0 = position(parent, dragId);\n",
       "\t        if (origin) {\n",
       "\t          dragOffset = origin.apply(that, arguments);\n",
       "\t          dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ];\n",
       "\t        } else {\n",
       "\t          dragOffset = [ 0, 0 ];\n",
       "\t        }\n",
       "\t        dispatch({\n",
       "\t          type: \"dragstart\"\n",
       "\t        });\n",
       "\t        function moved() {\n",
       "\t          var position1 = position(parent, dragId), dx, dy;\n",
       "\t          if (!position1) return;\n",
       "\t          dx = position1[0] - position0[0];\n",
       "\t          dy = position1[1] - position0[1];\n",
       "\t          dragged |= dx | dy;\n",
       "\t          position0 = position1;\n",
       "\t          dispatch({\n",
       "\t            type: \"drag\",\n",
       "\t            x: position1[0] + dragOffset[0],\n",
       "\t            y: position1[1] + dragOffset[1],\n",
       "\t            dx: dx,\n",
       "\t            dy: dy\n",
       "\t          });\n",
       "\t        }\n",
       "\t        function ended() {\n",
       "\t          if (!position(parent, dragId)) return;\n",
       "\t          dragSubject.on(move + dragName, null).on(end + dragName, null);\n",
       "\t          dragRestore(dragged);\n",
       "\t          dispatch({\n",
       "\t            type: \"dragend\"\n",
       "\t          });\n",
       "\t        }\n",
       "\t      };\n",
       "\t    }\n",
       "\t    drag.origin = function(x) {\n",
       "\t      if (!arguments.length) return origin;\n",
       "\t      origin = x;\n",
       "\t      return drag;\n",
       "\t    };\n",
       "\t    return d3.rebind(drag, event, \"on\");\n",
       "\t  };\n",
       "\t  function d3_behavior_dragTouchId() {\n",
       "\t    return d3.event.changedTouches[0].identifier;\n",
       "\t  }\n",
       "\t  d3.touches = function(container, touches) {\n",
       "\t    if (arguments.length < 2) touches = d3_eventSource().touches;\n",
       "\t    return touches ? d3_array(touches).map(function(touch) {\n",
       "\t      var point = d3_mousePoint(container, touch);\n",
       "\t      point.identifier = touch.identifier;\n",
       "\t      return point;\n",
       "\t    }) : [];\n",
       "\t  };\n",
       "\t  var ε = 1e-6, ε2 = ε * ε, π = Math.PI, τ = 2 * π, τε = τ - ε, halfπ = π / 2, d3_radians = π / 180, d3_degrees = 180 / π;\n",
       "\t  function d3_sgn(x) {\n",
       "\t    return x > 0 ? 1 : x < 0 ? -1 : 0;\n",
       "\t  }\n",
       "\t  function d3_cross2d(a, b, c) {\n",
       "\t    return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n",
       "\t  }\n",
       "\t  function d3_acos(x) {\n",
       "\t    return x > 1 ? 0 : x < -1 ? π : Math.acos(x);\n",
       "\t  }\n",
       "\t  function d3_asin(x) {\n",
       "\t    return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);\n",
       "\t  }\n",
       "\t  function d3_sinh(x) {\n",
       "\t    return ((x = Math.exp(x)) - 1 / x) / 2;\n",
       "\t  }\n",
       "\t  function d3_cosh(x) {\n",
       "\t    return ((x = Math.exp(x)) + 1 / x) / 2;\n",
       "\t  }\n",
       "\t  function d3_tanh(x) {\n",
       "\t    return ((x = Math.exp(2 * x)) - 1) / (x + 1);\n",
       "\t  }\n",
       "\t  function d3_haversin(x) {\n",
       "\t    return (x = Math.sin(x / 2)) * x;\n",
       "\t  }\n",
       "\t  var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4;\n",
       "\t  d3.interpolateZoom = function(p0, p1) {\n",
       "\t    var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S;\n",
       "\t    if (d2 < ε2) {\n",
       "\t      S = Math.log(w1 / w0) / ρ;\n",
       "\t      i = function(t) {\n",
       "\t        return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * t * S) ];\n",
       "\t      };\n",
       "\t    } else {\n",
       "\t      var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);\n",
       "\t      S = (r1 - r0) / ρ;\n",
       "\t      i = function(t) {\n",
       "\t        var s = t * S, coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));\n",
       "\t        return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ];\n",
       "\t      };\n",
       "\t    }\n",
       "\t    i.duration = S * 1e3;\n",
       "\t    return i;\n",
       "\t  };\n",
       "\t  d3.behavior.zoom = function() {\n",
       "\t    var view = {\n",
       "\t      x: 0,\n",
       "\t      y: 0,\n",
       "\t      k: 1\n",
       "\t    }, translate0, center0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, duration = 250, zooming = 0, mousedown = \"mousedown.zoom\", mousemove = \"mousemove.zoom\", mouseup = \"mouseup.zoom\", mousewheelTimer, touchstart = \"touchstart.zoom\", touchtime, event = d3_eventDispatch(zoom, \"zoomstart\", \"zoom\", \"zoomend\"), x0, x1, y0, y1;\n",
       "\t    if (!d3_behavior_zoomWheel) {\n",
       "\t      d3_behavior_zoomWheel = \"onwheel\" in d3_document ? (d3_behavior_zoomDelta = function() {\n",
       "\t        return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1);\n",
       "\t      }, \"wheel\") : \"onmousewheel\" in d3_document ? (d3_behavior_zoomDelta = function() {\n",
       "\t        return d3.event.wheelDelta;\n",
       "\t      }, \"mousewheel\") : (d3_behavior_zoomDelta = function() {\n",
       "\t        return -d3.event.detail;\n",
       "\t      }, \"MozMousePixelScroll\");\n",
       "\t    }\n",
       "\t    function zoom(g) {\n",
       "\t      g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + \".zoom\", mousewheeled).on(\"dblclick.zoom\", dblclicked).on(touchstart, touchstarted);\n",
       "\t    }\n",
       "\t    zoom.event = function(g) {\n",
       "\t      g.each(function() {\n",
       "\t        var dispatch = event.of(this, arguments), view1 = view;\n",
       "\t        if (d3_transitionInheritId) {\n",
       "\t          d3.select(this).transition().each(\"start.zoom\", function() {\n",
       "\t            view = this.__chart__ || {\n",
       "\t              x: 0,\n",
       "\t              y: 0,\n",
       "\t              k: 1\n",
       "\t            };\n",
       "\t            zoomstarted(dispatch);\n",
       "\t          }).tween(\"zoom:zoom\", function() {\n",
       "\t            var dx = size[0], dy = size[1], cx = center0 ? center0[0] : dx / 2, cy = center0 ? center0[1] : dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]);\n",
       "\t            return function(t) {\n",
       "\t              var l = i(t), k = dx / l[2];\n",
       "\t              this.__chart__ = view = {\n",
       "\t                x: cx - l[0] * k,\n",
       "\t                y: cy - l[1] * k,\n",
       "\t                k: k\n",
       "\t              };\n",
       "\t              zoomed(dispatch);\n",
       "\t            };\n",
       "\t          }).each(\"interrupt.zoom\", function() {\n",
       "\t            zoomended(dispatch);\n",
       "\t          }).each(\"end.zoom\", function() {\n",
       "\t            zoomended(dispatch);\n",
       "\t          });\n",
       "\t        } else {\n",
       "\t          this.__chart__ = view;\n",
       "\t          zoomstarted(dispatch);\n",
       "\t          zoomed(dispatch);\n",
       "\t          zoomended(dispatch);\n",
       "\t        }\n",
       "\t      });\n",
       "\t    };\n",
       "\t    zoom.translate = function(_) {\n",
       "\t      if (!arguments.length) return [ view.x, view.y ];\n",
       "\t      view = {\n",
       "\t        x: +_[0],\n",
       "\t        y: +_[1],\n",
       "\t        k: view.k\n",
       "\t      };\n",
       "\t      rescale();\n",
       "\t      return zoom;\n",
       "\t    };\n",
       "\t    zoom.scale = function(_) {\n",
       "\t      if (!arguments.length) return view.k;\n",
       "\t      view = {\n",
       "\t        x: view.x,\n",
       "\t        y: view.y,\n",
       "\t        k: null\n",
       "\t      };\n",
       "\t      scaleTo(+_);\n",
       "\t      rescale();\n",
       "\t      return zoom;\n",
       "\t    };\n",
       "\t    zoom.scaleExtent = function(_) {\n",
       "\t      if (!arguments.length) return scaleExtent;\n",
       "\t      scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ];\n",
       "\t      return zoom;\n",
       "\t    };\n",
       "\t    zoom.center = function(_) {\n",
       "\t      if (!arguments.length) return center;\n",
       "\t      center = _ && [ +_[0], +_[1] ];\n",
       "\t      return zoom;\n",
       "\t    };\n",
       "\t    zoom.size = function(_) {\n",
       "\t      if (!arguments.length) return size;\n",
       "\t      size = _ && [ +_[0], +_[1] ];\n",
       "\t      return zoom;\n",
       "\t    };\n",
       "\t    zoom.duration = function(_) {\n",
       "\t      if (!arguments.length) return duration;\n",
       "\t      duration = +_;\n",
       "\t      return zoom;\n",
       "\t    };\n",
       "\t    zoom.x = function(z) {\n",
       "\t      if (!arguments.length) return x1;\n",
       "\t      x1 = z;\n",
       "\t      x0 = z.copy();\n",
       "\t      view = {\n",
       "\t        x: 0,\n",
       "\t        y: 0,\n",
       "\t        k: 1\n",
       "\t      };\n",
       "\t      return zoom;\n",
       "\t    };\n",
       "\t    zoom.y = function(z) {\n",
       "\t      if (!arguments.length) return y1;\n",
       "\t      y1 = z;\n",
       "\t      y0 = z.copy();\n",
       "\t      view = {\n",
       "\t        x: 0,\n",
       "\t        y: 0,\n",
       "\t        k: 1\n",
       "\t      };\n",
       "\t      return zoom;\n",
       "\t    };\n",
       "\t    function location(p) {\n",
       "\t      return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ];\n",
       "\t    }\n",
       "\t    function point(l) {\n",
       "\t      return [ l[0] * view.k + view.x, l[1] * view.k + view.y ];\n",
       "\t    }\n",
       "\t    function scaleTo(s) {\n",
       "\t      view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));\n",
       "\t    }\n",
       "\t    function translateTo(p, l) {\n",
       "\t      l = point(l);\n",
       "\t      view.x += p[0] - l[0];\n",
       "\t      view.y += p[1] - l[1];\n",
       "\t    }\n",
       "\t    function zoomTo(that, p, l, k) {\n",
       "\t      that.__chart__ = {\n",
       "\t        x: view.x,\n",
       "\t        y: view.y,\n",
       "\t        k: view.k\n",
       "\t      };\n",
       "\t      scaleTo(Math.pow(2, k));\n",
       "\t      translateTo(center0 = p, l);\n",
       "\t      that = d3.select(that);\n",
       "\t      if (duration > 0) that = that.transition().duration(duration);\n",
       "\t      that.call(zoom.event);\n",
       "\t    }\n",
       "\t    function rescale() {\n",
       "\t      if (x1) x1.domain(x0.range().map(function(x) {\n",
       "\t        return (x - view.x) / view.k;\n",
       "\t      }).map(x0.invert));\n",
       "\t      if (y1) y1.domain(y0.range().map(function(y) {\n",
       "\t        return (y - view.y) / view.k;\n",
       "\t      }).map(y0.invert));\n",
       "\t    }\n",
       "\t    function zoomstarted(dispatch) {\n",
       "\t      if (!zooming++) dispatch({\n",
       "\t        type: \"zoomstart\"\n",
       "\t      });\n",
       "\t    }\n",
       "\t    function zoomed(dispatch) {\n",
       "\t      rescale();\n",
       "\t      dispatch({\n",
       "\t        type: \"zoom\",\n",
       "\t        scale: view.k,\n",
       "\t        translate: [ view.x, view.y ]\n",
       "\t      });\n",
       "\t    }\n",
       "\t    function zoomended(dispatch) {\n",
       "\t      if (!--zooming) dispatch({\n",
       "\t        type: \"zoomend\"\n",
       "\t      }), center0 = null;\n",
       "\t    }\n",
       "\t    function mousedowned() {\n",
       "\t      var that = this, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window(that)).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(that);\n",
       "\t      d3_selection_interrupt.call(that);\n",
       "\t      zoomstarted(dispatch);\n",
       "\t      function moved() {\n",
       "\t        dragged = 1;\n",
       "\t        translateTo(d3.mouse(that), location0);\n",
       "\t        zoomed(dispatch);\n",
       "\t      }\n",
       "\t      function ended() {\n",
       "\t        subject.on(mousemove, null).on(mouseup, null);\n",
       "\t        dragRestore(dragged);\n",
       "\t        zoomended(dispatch);\n",
       "\t      }\n",
       "\t    }\n",
       "\t    function touchstarted() {\n",
       "\t      var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = \".zoom-\" + d3.event.changedTouches[0].identifier, touchmove = \"touchmove\" + zoomName, touchend = \"touchend\" + zoomName, targets = [], subject = d3.select(that), dragRestore = d3_event_dragSuppress(that);\n",
       "\t      started();\n",
       "\t      zoomstarted(dispatch);\n",
       "\t      subject.on(mousedown, null).on(touchstart, started);\n",
       "\t      function relocate() {\n",
       "\t        var touches = d3.touches(that);\n",
       "\t        scale0 = view.k;\n",
       "\t        touches.forEach(function(t) {\n",
       "\t          if (t.identifier in locations0) locations0[t.identifier] = location(t);\n",
       "\t        });\n",
       "\t        return touches;\n",
       "\t      }\n",
       "\t      function started() {\n",
       "\t        var target = d3.event.target;\n",
       "\t        d3.select(target).on(touchmove, moved).on(touchend, ended);\n",
       "\t        targets.push(target);\n",
       "\t        var changed = d3.event.changedTouches;\n",
       "\t        for (var i = 0, n = changed.length; i < n; ++i) {\n",
       "\t          locations0[changed[i].identifier] = null;\n",
       "\t        }\n",
       "\t        var touches = relocate(), now = Date.now();\n",
       "\t        if (touches.length === 1) {\n",
       "\t          if (now - touchtime < 500) {\n",
       "\t            var p = touches[0];\n",
       "\t            zoomTo(that, p, locations0[p.identifier], Math.floor(Math.log(view.k) / Math.LN2) + 1);\n",
       "\t            d3_eventPreventDefault();\n",
       "\t          }\n",
       "\t          touchtime = now;\n",
       "\t        } else if (touches.length > 1) {\n",
       "\t          var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];\n",
       "\t          distance0 = dx * dx + dy * dy;\n",
       "\t        }\n",
       "\t      }\n",
       "\t      function moved() {\n",
       "\t        var touches = d3.touches(that), p0, l0, p1, l1;\n",
       "\t        d3_selection_interrupt.call(that);\n",
       "\t        for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {\n",
       "\t          p1 = touches[i];\n",
       "\t          if (l1 = locations0[p1.identifier]) {\n",
       "\t            if (l0) break;\n",
       "\t            p0 = p1, l0 = l1;\n",
       "\t          }\n",
       "\t        }\n",
       "\t        if (l1) {\n",
       "\t          var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0);\n",
       "\t          p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ];\n",
       "\t          l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ];\n",
       "\t          scaleTo(scale1 * scale0);\n",
       "\t        }\n",
       "\t        touchtime = null;\n",
       "\t        translateTo(p0, l0);\n",
       "\t        zoomed(dispatch);\n",
       "\t      }\n",
       "\t      function ended() {\n",
       "\t        if (d3.event.touches.length) {\n",
       "\t          var changed = d3.event.changedTouches;\n",
       "\t          for (var i = 0, n = changed.length; i < n; ++i) {\n",
       "\t            delete locations0[changed[i].identifier];\n",
       "\t          }\n",
       "\t          for (var identifier in locations0) {\n",
       "\t            return void relocate();\n",
       "\t          }\n",
       "\t        }\n",
       "\t        d3.selectAll(targets).on(zoomName, null);\n",
       "\t        subject.on(mousedown, mousedowned).on(touchstart, touchstarted);\n",
       "\t        dragRestore();\n",
       "\t        zoomended(dispatch);\n",
       "\t      }\n",
       "\t    }\n",
       "\t    function mousewheeled() {\n",
       "\t      var dispatch = event.of(this, arguments);\n",
       "\t      if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), \n",
       "\t      translate0 = location(center0 = center || d3.mouse(this)), zoomstarted(dispatch);\n",
       "\t      mousewheelTimer = setTimeout(function() {\n",
       "\t        mousewheelTimer = null;\n",
       "\t        zoomended(dispatch);\n",
       "\t      }, 50);\n",
       "\t      d3_eventPreventDefault();\n",
       "\t      scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);\n",
       "\t      translateTo(center0, translate0);\n",
       "\t      zoomed(dispatch);\n",
       "\t    }\n",
       "\t    function dblclicked() {\n",
       "\t      var p = d3.mouse(this), k = Math.log(view.k) / Math.LN2;\n",
       "\t      zoomTo(this, p, location(p), d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1);\n",
       "\t    }\n",
       "\t    return d3.rebind(zoom, event, \"on\");\n",
       "\t  };\n",
       "\t  var d3_behavior_zoomInfinity = [ 0, Infinity ], d3_behavior_zoomDelta, d3_behavior_zoomWheel;\n",
       "\t  d3.color = d3_color;\n",
       "\t  function d3_color() {}\n",
       "\t  d3_color.prototype.toString = function() {\n",
       "\t    return this.rgb() + \"\";\n",
       "\t  };\n",
       "\t  d3.hsl = d3_hsl;\n",
       "\t  function d3_hsl(h, s, l) {\n",
       "\t    return this instanceof d3_hsl ? void (this.h = +h, this.s = +s, this.l = +l) : arguments.length < 2 ? h instanceof d3_hsl ? new d3_hsl(h.h, h.s, h.l) : d3_rgb_parse(\"\" + h, d3_rgb_hsl, d3_hsl) : new d3_hsl(h, s, l);\n",
       "\t  }\n",
       "\t  var d3_hslPrototype = d3_hsl.prototype = new d3_color();\n",
       "\t  d3_hslPrototype.brighter = function(k) {\n",
       "\t    k = Math.pow(.7, arguments.length ? k : 1);\n",
       "\t    return new d3_hsl(this.h, this.s, this.l / k);\n",
       "\t  };\n",
       "\t  d3_hslPrototype.darker = function(k) {\n",
       "\t    k = Math.pow(.7, arguments.length ? k : 1);\n",
       "\t    return new d3_hsl(this.h, this.s, k * this.l);\n",
       "\t  };\n",
       "\t  d3_hslPrototype.rgb = function() {\n",
       "\t    return d3_hsl_rgb(this.h, this.s, this.l);\n",
       "\t  };\n",
       "\t  function d3_hsl_rgb(h, s, l) {\n",
       "\t    var m1, m2;\n",
       "\t    h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h;\n",
       "\t    s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s;\n",
       "\t    l = l < 0 ? 0 : l > 1 ? 1 : l;\n",
       "\t    m2 = l <= .5 ? l * (1 + s) : l + s - l * s;\n",
       "\t    m1 = 2 * l - m2;\n",
       "\t    function v(h) {\n",
       "\t      if (h > 360) h -= 360; else if (h < 0) h += 360;\n",
       "\t      if (h < 60) return m1 + (m2 - m1) * h / 60;\n",
       "\t      if (h < 180) return m2;\n",
       "\t      if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;\n",
       "\t      return m1;\n",
       "\t    }\n",
       "\t    function vv(h) {\n",
       "\t      return Math.round(v(h) * 255);\n",
       "\t    }\n",
       "\t    return new d3_rgb(vv(h + 120), vv(h), vv(h - 120));\n",
       "\t  }\n",
       "\t  d3.hcl = d3_hcl;\n",
       "\t  function d3_hcl(h, c, l) {\n",
       "\t    return this instanceof d3_hcl ? void (this.h = +h, this.c = +c, this.l = +l) : arguments.length < 2 ? h instanceof d3_hcl ? new d3_hcl(h.h, h.c, h.l) : h instanceof d3_lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : new d3_hcl(h, c, l);\n",
       "\t  }\n",
       "\t  var d3_hclPrototype = d3_hcl.prototype = new d3_color();\n",
       "\t  d3_hclPrototype.brighter = function(k) {\n",
       "\t    return new d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)));\n",
       "\t  };\n",
       "\t  d3_hclPrototype.darker = function(k) {\n",
       "\t    return new d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)));\n",
       "\t  };\n",
       "\t  d3_hclPrototype.rgb = function() {\n",
       "\t    return d3_hcl_lab(this.h, this.c, this.l).rgb();\n",
       "\t  };\n",
       "\t  function d3_hcl_lab(h, c, l) {\n",
       "\t    if (isNaN(h)) h = 0;\n",
       "\t    if (isNaN(c)) c = 0;\n",
       "\t    return new d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c);\n",
       "\t  }\n",
       "\t  d3.lab = d3_lab;\n",
       "\t  function d3_lab(l, a, b) {\n",
       "\t    return this instanceof d3_lab ? void (this.l = +l, this.a = +a, this.b = +b) : arguments.length < 2 ? l instanceof d3_lab ? new d3_lab(l.l, l.a, l.b) : l instanceof d3_hcl ? d3_hcl_lab(l.h, l.c, l.l) : d3_rgb_lab((l = d3_rgb(l)).r, l.g, l.b) : new d3_lab(l, a, b);\n",
       "\t  }\n",
       "\t  var d3_lab_K = 18;\n",
       "\t  var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883;\n",
       "\t  var d3_labPrototype = d3_lab.prototype = new d3_color();\n",
       "\t  d3_labPrototype.brighter = function(k) {\n",
       "\t    return new d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);\n",
       "\t  };\n",
       "\t  d3_labPrototype.darker = function(k) {\n",
       "\t    return new d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);\n",
       "\t  };\n",
       "\t  d3_labPrototype.rgb = function() {\n",
       "\t    return d3_lab_rgb(this.l, this.a, this.b);\n",
       "\t  };\n",
       "\t  function d3_lab_rgb(l, a, b) {\n",
       "\t    var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;\n",
       "\t    x = d3_lab_xyz(x) * d3_lab_X;\n",
       "\t    y = d3_lab_xyz(y) * d3_lab_Y;\n",
       "\t    z = d3_lab_xyz(z) * d3_lab_Z;\n",
       "\t    return new d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));\n",
       "\t  }\n",
       "\t  function d3_lab_hcl(l, a, b) {\n",
       "\t    return l > 0 ? new d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : new d3_hcl(NaN, NaN, l);\n",
       "\t  }\n",
       "\t  function d3_lab_xyz(x) {\n",
       "\t    return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;\n",
       "\t  }\n",
       "\t  function d3_xyz_lab(x) {\n",
       "\t    return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;\n",
       "\t  }\n",
       "\t  function d3_xyz_rgb(r) {\n",
       "\t    return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055));\n",
       "\t  }\n",
       "\t  d3.rgb = d3_rgb;\n",
       "\t  function d3_rgb(r, g, b) {\n",
       "\t    return this instanceof d3_rgb ? void (this.r = ~~r, this.g = ~~g, this.b = ~~b) : arguments.length < 2 ? r instanceof d3_rgb ? new d3_rgb(r.r, r.g, r.b) : d3_rgb_parse(\"\" + r, d3_rgb, d3_hsl_rgb) : new d3_rgb(r, g, b);\n",
       "\t  }\n",
       "\t  function d3_rgbNumber(value) {\n",
       "\t    return new d3_rgb(value >> 16, value >> 8 & 255, value & 255);\n",
       "\t  }\n",
       "\t  function d3_rgbString(value) {\n",
       "\t    return d3_rgbNumber(value) + \"\";\n",
       "\t  }\n",
       "\t  var d3_rgbPrototype = d3_rgb.prototype = new d3_color();\n",
       "\t  d3_rgbPrototype.brighter = function(k) {\n",
       "\t    k = Math.pow(.7, arguments.length ? k : 1);\n",
       "\t    var r = this.r, g = this.g, b = this.b, i = 30;\n",
       "\t    if (!r && !g && !b) return new d3_rgb(i, i, i);\n",
       "\t    if (r && r < i) r = i;\n",
       "\t    if (g && g < i) g = i;\n",
       "\t    if (b && b < i) b = i;\n",
       "\t    return new d3_rgb(Math.min(255, r / k), Math.min(255, g / k), Math.min(255, b / k));\n",
       "\t  };\n",
       "\t  d3_rgbPrototype.darker = function(k) {\n",
       "\t    k = Math.pow(.7, arguments.length ? k : 1);\n",
       "\t    return new d3_rgb(k * this.r, k * this.g, k * this.b);\n",
       "\t  };\n",
       "\t  d3_rgbPrototype.hsl = function() {\n",
       "\t    return d3_rgb_hsl(this.r, this.g, this.b);\n",
       "\t  };\n",
       "\t  d3_rgbPrototype.toString = function() {\n",
       "\t    return \"#\" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);\n",
       "\t  };\n",
       "\t  function d3_rgb_hex(v) {\n",
       "\t    return v < 16 ? \"0\" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);\n",
       "\t  }\n",
       "\t  function d3_rgb_parse(format, rgb, hsl) {\n",
       "\t    var r = 0, g = 0, b = 0, m1, m2, color;\n",
       "\t    m1 = /([a-z]+)\\((.*)\\)/.exec(format = format.toLowerCase());\n",
       "\t    if (m1) {\n",
       "\t      m2 = m1[2].split(\",\");\n",
       "\t      switch (m1[1]) {\n",
       "\t       case \"hsl\":\n",
       "\t        {\n",
       "\t          return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100);\n",
       "\t        }\n",
       "\t\n",
       "\t       case \"rgb\":\n",
       "\t        {\n",
       "\t          return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2]));\n",
       "\t        }\n",
       "\t      }\n",
       "\t    }\n",
       "\t    if (color = d3_rgb_names.get(format)) {\n",
       "\t      return rgb(color.r, color.g, color.b);\n",
       "\t    }\n",
       "\t    if (format != null && format.charAt(0) === \"#\" && !isNaN(color = parseInt(format.slice(1), 16))) {\n",
       "\t      if (format.length === 4) {\n",
       "\t        r = (color & 3840) >> 4;\n",
       "\t        r = r >> 4 | r;\n",
       "\t        g = color & 240;\n",
       "\t        g = g >> 4 | g;\n",
       "\t        b = color & 15;\n",
       "\t        b = b << 4 | b;\n",
       "\t      } else if (format.length === 7) {\n",
       "\t        r = (color & 16711680) >> 16;\n",
       "\t        g = (color & 65280) >> 8;\n",
       "\t        b = color & 255;\n",
       "\t      }\n",
       "\t    }\n",
       "\t    return rgb(r, g, b);\n",
       "\t  }\n",
       "\t  function d3_rgb_hsl(r, g, b) {\n",
       "\t    var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2;\n",
       "\t    if (d) {\n",
       "\t      s = l < .5 ? d / (max + min) : d / (2 - max - min);\n",
       "\t      if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4;\n",
       "\t      h *= 60;\n",
       "\t    } else {\n",
       "\t      h = NaN;\n",
       "\t      s = l > 0 && l < 1 ? 0 : h;\n",
       "\t    }\n",
       "\t    return new d3_hsl(h, s, l);\n",
       "\t  }\n",
       "\t  function d3_rgb_lab(r, g, b) {\n",
       "\t    r = d3_rgb_xyz(r);\n",
       "\t    g = d3_rgb_xyz(g);\n",
       "\t    b = d3_rgb_xyz(b);\n",
       "\t    var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z);\n",
       "\t    return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));\n",
       "\t  }\n",
       "\t  function d3_rgb_xyz(r) {\n",
       "\t    return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4);\n",
       "\t  }\n",
       "\t  function d3_rgb_parseNumber(c) {\n",
       "\t    var f = parseFloat(c);\n",
       "\t    return c.charAt(c.length - 1) === \"%\" ? Math.round(f * 2.55) : f;\n",
       "\t  }\n",
       "\t  var d3_rgb_names = d3.map({\n",
       "\t    aliceblue: 15792383,\n",
       "\t    antiquewhite: 16444375,\n",
       "\t    aqua: 65535,\n",
       "\t    aquamarine: 8388564,\n",
       "\t    azure: 15794175,\n",
       "\t    beige: 16119260,\n",
       "\t    bisque: 16770244,\n",
       "\t    black: 0,\n",
       "\t    blanchedalmond: 16772045,\n",
       "\t    blue: 255,\n",
       "\t    blueviolet: 9055202,\n",
       "\t    brown: 10824234,\n",
       "\t    burlywood: 14596231,\n",
       "\t    cadetblue: 6266528,\n",
       "\t    chartreuse: 8388352,\n",
       "\t    chocolate: 13789470,\n",
       "\t    coral: 16744272,\n",
       "\t    cornflowerblue: 6591981,\n",
       "\t    cornsilk: 16775388,\n",
       "\t    crimson: 14423100,\n",
       "\t    cyan: 65535,\n",
       "\t    darkblue: 139,\n",
       "\t    darkcyan: 35723,\n",
       "\t    darkgoldenrod: 12092939,\n",
       "\t    darkgray: 11119017,\n",
       "\t    darkgreen: 25600,\n",
       "\t    darkgrey: 11119017,\n",
       "\t    darkkhaki: 12433259,\n",
       "\t    darkmagenta: 9109643,\n",
       "\t    darkolivegreen: 5597999,\n",
       "\t    darkorange: 16747520,\n",
       "\t    darkorchid: 10040012,\n",
       "\t    darkred: 9109504,\n",
       "\t    darksalmon: 15308410,\n",
       "\t    darkseagreen: 9419919,\n",
       "\t    darkslateblue: 4734347,\n",
       "\t    darkslategray: 3100495,\n",
       "\t    darkslategrey: 3100495,\n",
       "\t    darkturquoise: 52945,\n",
       "\t    darkviolet: 9699539,\n",
       "\t    deeppink: 16716947,\n",
       "\t    deepskyblue: 49151,\n",
       "\t    dimgray: 6908265,\n",
       "\t    dimgrey: 6908265,\n",
       "\t    dodgerblue: 2003199,\n",
       "\t    firebrick: 11674146,\n",
       "\t    floralwhite: 16775920,\n",
       "\t    forestgreen: 2263842,\n",
       "\t    fuchsia: 16711935,\n",
       "\t    gainsboro: 14474460,\n",
       "\t    ghostwhite: 16316671,\n",
       "\t    gold: 16766720,\n",
       "\t    goldenrod: 14329120,\n",
       "\t    gray: 8421504,\n",
       "\t    green: 32768,\n",
       "\t    greenyellow: 11403055,\n",
       "\t    grey: 8421504,\n",
       "\t    honeydew: 15794160,\n",
       "\t    hotpink: 16738740,\n",
       "\t    indianred: 13458524,\n",
       "\t    indigo: 4915330,\n",
       "\t    ivory: 16777200,\n",
       "\t    khaki: 15787660,\n",
       "\t    lavender: 15132410,\n",
       "\t    lavenderblush: 16773365,\n",
       "\t    lawngreen: 8190976,\n",
       "\t    lemonchiffon: 16775885,\n",
       "\t    lightblue: 11393254,\n",
       "\t    lightcoral: 15761536,\n",
       "\t    lightcyan: 14745599,\n",
       "\t    lightgoldenrodyellow: 16448210,\n",
       "\t    lightgray: 13882323,\n",
       "\t    lightgreen: 9498256,\n",
       "\t    lightgrey: 13882323,\n",
       "\t    lightpink: 16758465,\n",
       "\t    lightsalmon: 16752762,\n",
       "\t    lightseagreen: 2142890,\n",
       "\t    lightskyblue: 8900346,\n",
       "\t    lightslategray: 7833753,\n",
       "\t    lightslategrey: 7833753,\n",
       "\t    lightsteelblue: 11584734,\n",
       "\t    lightyellow: 16777184,\n",
       "\t    lime: 65280,\n",
       "\t    limegreen: 3329330,\n",
       "\t    linen: 16445670,\n",
       "\t    magenta: 16711935,\n",
       "\t    maroon: 8388608,\n",
       "\t    mediumaquamarine: 6737322,\n",
       "\t    mediumblue: 205,\n",
       "\t    mediumorchid: 12211667,\n",
       "\t    mediumpurple: 9662683,\n",
       "\t    mediumseagreen: 3978097,\n",
       "\t    mediumslateblue: 8087790,\n",
       "\t    mediumspringgreen: 64154,\n",
       "\t    mediumturquoise: 4772300,\n",
       "\t    mediumvioletred: 13047173,\n",
       "\t    midnightblue: 1644912,\n",
       "\t    mintcream: 16121850,\n",
       "\t    mistyrose: 16770273,\n",
       "\t    moccasin: 16770229,\n",
       "\t    navajowhite: 16768685,\n",
       "\t    navy: 128,\n",
       "\t    oldlace: 16643558,\n",
       "\t    olive: 8421376,\n",
       "\t    olivedrab: 7048739,\n",
       "\t    orange: 16753920,\n",
       "\t    orangered: 16729344,\n",
       "\t    orchid: 14315734,\n",
       "\t    palegoldenrod: 15657130,\n",
       "\t    palegreen: 10025880,\n",
       "\t    paleturquoise: 11529966,\n",
       "\t    palevioletred: 14381203,\n",
       "\t    papayawhip: 16773077,\n",
       "\t    peachpuff: 16767673,\n",
       "\t    peru: 13468991,\n",
       "\t    pink: 16761035,\n",
       "\t    plum: 14524637,\n",
       "\t    powderblue: 11591910,\n",
       "\t    purple: 8388736,\n",
       "\t    rebeccapurple: 6697881,\n",
       "\t    red: 16711680,\n",
       "\t    rosybrown: 12357519,\n",
       "\t    royalblue: 4286945,\n",
       "\t    saddlebrown: 9127187,\n",
       "\t    salmon: 16416882,\n",
       "\t    sandybrown: 16032864,\n",
       "\t    seagreen: 3050327,\n",
       "\t    seashell: 16774638,\n",
       "\t    sienna: 10506797,\n",
       "\t    silver: 12632256,\n",
       "\t    skyblue: 8900331,\n",
       "\t    slateblue: 6970061,\n",
       "\t    slategray: 7372944,\n",
       "\t    slategrey: 7372944,\n",
       "\t    snow: 16775930,\n",
       "\t    springgreen: 65407,\n",
       "\t    steelblue: 4620980,\n",
       "\t    tan: 13808780,\n",
       "\t    teal: 32896,\n",
       "\t    thistle: 14204888,\n",
       "\t    tomato: 16737095,\n",
       "\t    turquoise: 4251856,\n",
       "\t    violet: 15631086,\n",
       "\t    wheat: 16113331,\n",
       "\t    white: 16777215,\n",
       "\t    whitesmoke: 16119285,\n",
       "\t    yellow: 16776960,\n",
       "\t    yellowgreen: 10145074\n",
       "\t  });\n",
       "\t  d3_rgb_names.forEach(function(key, value) {\n",
       "\t    d3_rgb_names.set(key, d3_rgbNumber(value));\n",
       "\t  });\n",
       "\t  function d3_functor(v) {\n",
       "\t    return typeof v === \"function\" ? v : function() {\n",
       "\t      return v;\n",
       "\t    };\n",
       "\t  }\n",
       "\t  d3.functor = d3_functor;\n",
       "\t  d3.xhr = d3_xhrType(d3_identity);\n",
       "\t  function d3_xhrType(response) {\n",
       "\t    return function(url, mimeType, callback) {\n",
       "\t      if (arguments.length === 2 && typeof mimeType === \"function\") callback = mimeType, \n",
       "\t      mimeType = null;\n",
       "\t      return d3_xhr(url, mimeType, response, callback);\n",
       "\t    };\n",
       "\t  }\n",
       "\t  function d3_xhr(url, mimeType, response, callback) {\n",
       "\t    var xhr = {}, dispatch = d3.dispatch(\"beforesend\", \"progress\", \"load\", \"error\"), headers = {}, request = new XMLHttpRequest(), responseType = null;\n",
       "\t    if (this.XDomainRequest && !(\"withCredentials\" in request) && /^(http(s)?:)?\\/\\//.test(url)) request = new XDomainRequest();\n",
       "\t    \"onload\" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() {\n",
       "\t      request.readyState > 3 && respond();\n",
       "\t    };\n",
       "\t    function respond() {\n",
       "\t      var status = request.status, result;\n",
       "\t      if (!status && d3_xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) {\n",
       "\t        try {\n",
       "\t          result = response.call(xhr, request);\n",
       "\t        } catch (e) {\n",
       "\t          dispatch.error.call(xhr, e);\n",
       "\t          return;\n",
       "\t        }\n",
       "\t        dispatch.load.call(xhr, result);\n",
       "\t      } else {\n",
       "\t        dispatch.error.call(xhr, request);\n",
       "\t      }\n",
       "\t    }\n",
       "\t    request.onprogress = function(event) {\n",
       "\t      var o = d3.event;\n",
       "\t      d3.event = event;\n",
       "\t      try {\n",
       "\t        dispatch.progress.call(xhr, request);\n",
       "\t      } finally {\n",
       "\t        d3.event = o;\n",
       "\t      }\n",
       "\t    };\n",
       "\t    xhr.header = function(name, value) {\n",
       "\t      name = (name + \"\").toLowerCase();\n",
       "\t      if (arguments.length < 2) return headers[name];\n",
       "\t      if (value == null) delete headers[name]; else headers[name] = value + \"\";\n",
       "\t      return xhr;\n",
       "\t    };\n",
       "\t    xhr.mimeType = function(value) {\n",
       "\t      if (!arguments.length) return mimeType;\n",
       "\t      mimeType = value == null ? null : value + \"\";\n",
       "\t      return xhr;\n",
       "\t    };\n",
       "\t    xhr.responseType = function(value) {\n",
       "\t      if (!arguments.length) return responseType;\n",
       "\t      responseType = value;\n",
       "\t      return xhr;\n",
       "\t    };\n",
       "\t    xhr.response = function(value) {\n",
       "\t      response = value;\n",
       "\t      return xhr;\n",
       "\t    };\n",
       "\t    [ \"get\", \"post\" ].forEach(function(method) {\n",
       "\t      xhr[method] = function() {\n",
       "\t        return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments)));\n",
       "\t      };\n",
       "\t    });\n",
       "\t    xhr.send = function(method, data, callback) {\n",
       "\t      if (arguments.length === 2 && typeof data === \"function\") callback = data, data = null;\n",
       "\t      request.open(method, url, true);\n",
       "\t      if (mimeType != null && !(\"accept\" in headers)) headers[\"accept\"] = mimeType + \",*/*\";\n",
       "\t      if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]);\n",
       "\t      if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType);\n",
       "\t      if (responseType != null) request.responseType = responseType;\n",
       "\t      if (callback != null) xhr.on(\"error\", callback).on(\"load\", function(request) {\n",
       "\t        callback(null, request);\n",
       "\t      });\n",
       "\t      dispatch.beforesend.call(xhr, request);\n",
       "\t      request.send(data == null ? null : data);\n",
       "\t      return xhr;\n",
       "\t    };\n",
       "\t    xhr.abort = function() {\n",
       "\t      request.abort();\n",
       "\t      return xhr;\n",
       "\t    };\n",
       "\t    d3.rebind(xhr, dispatch, \"on\");\n",
       "\t    return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback));\n",
       "\t  }\n",
       "\t  function d3_xhr_fixCallback(callback) {\n",
       "\t    return callback.length === 1 ? function(error, request) {\n",
       "\t      callback(error == null ? request : null);\n",
       "\t    } : callback;\n",
       "\t  }\n",
       "\t  function d3_xhrHasResponse(request) {\n",
       "\t    var type = request.responseType;\n",
       "\t    return type && type !== \"text\" ? request.response : request.responseText;\n",
       "\t  }\n",
       "\t  d3.dsv = function(delimiter, mimeType) {\n",
       "\t    var reFormat = new RegExp('[\"' + delimiter + \"\\n]\"), delimiterCode = delimiter.charCodeAt(0);\n",
       "\t    function dsv(url, row, callback) {\n",
       "\t      if (arguments.length < 3) callback = row, row = null;\n",
       "\t      var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback);\n",
       "\t      xhr.row = function(_) {\n",
       "\t        return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row;\n",
       "\t      };\n",
       "\t      return xhr;\n",
       "\t    }\n",
       "\t    function response(request) {\n",
       "\t      return dsv.parse(request.responseText);\n",
       "\t    }\n",
       "\t    function typedResponse(f) {\n",
       "\t      return function(request) {\n",
       "\t        return dsv.parse(request.responseText, f);\n",
       "\t      };\n",
       "\t    }\n",
       "\t    dsv.parse = function(text, f) {\n",
       "\t      var o;\n",
       "\t      return dsv.parseRows(text, function(row, i) {\n",
       "\t        if (o) return o(row, i - 1);\n",
       "\t        var a = new Function(\"d\", \"return {\" + row.map(function(name, i) {\n",
       "\t          return JSON.stringify(name) + \": d[\" + i + \"]\";\n",
       "\t        }).join(\",\") + \"}\");\n",
       "\t        o = f ? function(row, i) {\n",
       "\t          return f(a(row), i);\n",
       "\t        } : a;\n",
       "\t      });\n",
       "\t    };\n",
       "\t    dsv.parseRows = function(text, f) {\n",
       "\t      var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol;\n",
       "\t      function token() {\n",
       "\t        if (I >= N) return EOF;\n",
       "\t        if (eol) return eol = false, EOL;\n",
       "\t        var j = I;\n",
       "\t        if (text.charCodeAt(j) === 34) {\n",
       "\t          var i = j;\n",
       "\t          while (i++ < N) {\n",
       "\t            if (text.charCodeAt(i) === 34) {\n",
       "\t              if (text.charCodeAt(i + 1) !== 34) break;\n",
       "\t              ++i;\n",
       "\t            }\n",
       "\t          }\n",
       "\t          I = i + 2;\n",
       "\t          var c = text.charCodeAt(i + 1);\n",
       "\t          if (c === 13) {\n",
       "\t            eol = true;\n",
       "\t            if (text.charCodeAt(i + 2) === 10) ++I;\n",
       "\t          } else if (c === 10) {\n",
       "\t            eol = true;\n",
       "\t          }\n",
       "\t          return text.slice(j + 1, i).replace(/\"\"/g, '\"');\n",
       "\t        }\n",
       "\t        while (I < N) {\n",
       "\t          var c = text.charCodeAt(I++), k = 1;\n",
       "\t          if (c === 10) eol = true; else if (c === 13) {\n",
       "\t            eol = true;\n",
       "\t            if (text.charCodeAt(I) === 10) ++I, ++k;\n",
       "\t          } else if (c !== delimiterCode) continue;\n",
       "\t          return text.slice(j, I - k);\n",
       "\t        }\n",
       "\t        return text.slice(j);\n",
       "\t      }\n",
       "\t      while ((t = token()) !== EOF) {\n",
       "\t        var a = [];\n",
       "\t        while (t !== EOL && t !== EOF) {\n",
       "\t          a.push(t);\n",
       "\t          t = token();\n",
       "\t        }\n",
       "\t        if (f && (a = f(a, n++)) == null) continue;\n",
       "\t        rows.push(a);\n",
       "\t      }\n",
       "\t      return rows;\n",
       "\t    };\n",
       "\t    dsv.format = function(rows) {\n",
       "\t      if (Array.isArray(rows[0])) return dsv.formatRows(rows);\n",
       "\t      var fieldSet = new d3_Set(), fields = [];\n",
       "\t      rows.forEach(function(row) {\n",
       "\t        for (var field in row) {\n",
       "\t          if (!fieldSet.has(field)) {\n",
       "\t            fields.push(fieldSet.add(field));\n",
       "\t          }\n",
       "\t        }\n",
       "\t      });\n",
       "\t      return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) {\n",
       "\t        return fields.map(function(field) {\n",
       "\t          return formatValue(row[field]);\n",
       "\t        }).join(delimiter);\n",
       "\t      })).join(\"\\n\");\n",
       "\t    };\n",
       "\t    dsv.formatRows = function(rows) {\n",
       "\t      return rows.map(formatRow).join(\"\\n\");\n",
       "\t    };\n",
       "\t    function formatRow(row) {\n",
       "\t      return row.map(formatValue).join(delimiter);\n",
       "\t    }\n",
       "\t    function formatValue(text) {\n",
       "\t      return reFormat.test(text) ? '\"' + text.replace(/\\\"/g, '\"\"') + '\"' : text;\n",
       "\t    }\n",
       "\t    return dsv;\n",
       "\t  };\n",
       "\t  d3.csv = d3.dsv(\",\", \"text/csv\");\n",
       "\t  d3.tsv = d3.dsv(\"\t\", \"text/tab-separated-values\");\n",
       "\t  var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_frame = this[d3_vendorSymbol(this, \"requestAnimationFrame\")] || function(callback) {\n",
       "\t    setTimeout(callback, 17);\n",
       "\t  };\n",
       "\t  d3.timer = function() {\n",
       "\t    d3_timer.apply(this, arguments);\n",
       "\t  };\n",
       "\t  function d3_timer(callback, delay, then) {\n",
       "\t    var n = arguments.length;\n",
       "\t    if (n < 2) delay = 0;\n",
       "\t    if (n < 3) then = Date.now();\n",
       "\t    var time = then + delay, timer = {\n",
       "\t      c: callback,\n",
       "\t      t: time,\n",
       "\t      n: null\n",
       "\t    };\n",
       "\t    if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer;\n",
       "\t    d3_timer_queueTail = timer;\n",
       "\t    if (!d3_timer_interval) {\n",
       "\t      d3_timer_timeout = clearTimeout(d3_timer_timeout);\n",
       "\t      d3_timer_interval = 1;\n",
       "\t      d3_timer_frame(d3_timer_step);\n",
       "\t    }\n",
       "\t    return timer;\n",
       "\t  }\n",
       "\t  function d3_timer_step() {\n",
       "\t    var now = d3_timer_mark(), delay = d3_timer_sweep() - now;\n",
       "\t    if (delay > 24) {\n",
       "\t      if (isFinite(delay)) {\n",
       "\t        clearTimeout(d3_timer_timeout);\n",
       "\t        d3_timer_timeout = setTimeout(d3_timer_step, delay);\n",
       "\t      }\n",
       "\t      d3_timer_interval = 0;\n",
       "\t    } else {\n",
       "\t      d3_timer_interval = 1;\n",
       "\t      d3_timer_frame(d3_timer_step);\n",
       "\t    }\n",
       "\t  }\n",
       "\t  d3.timer.flush = function() {\n",
       "\t    d3_timer_mark();\n",
       "\t    d3_timer_sweep();\n",
       "\t  };\n",
       "\t  function d3_timer_mark() {\n",
       "\t    var now = Date.now(), timer = d3_timer_queueHead;\n",
       "\t    while (timer) {\n",
       "\t      if (now >= timer.t && timer.c(now - timer.t)) timer.c = null;\n",
       "\t      timer = timer.n;\n",
       "\t    }\n",
       "\t    return now;\n",
       "\t  }\n",
       "\t  function d3_timer_sweep() {\n",
       "\t    var t0, t1 = d3_timer_queueHead, time = Infinity;\n",
       "\t    while (t1) {\n",
       "\t      if (t1.c) {\n",
       "\t        if (t1.t < time) time = t1.t;\n",
       "\t        t1 = (t0 = t1).n;\n",
       "\t      } else {\n",
       "\t        t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n;\n",
       "\t      }\n",
       "\t    }\n",
       "\t    d3_timer_queueTail = t0;\n",
       "\t    return time;\n",
       "\t  }\n",
       "\t  function d3_format_precision(x, p) {\n",
       "\t    return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1);\n",
       "\t  }\n",
       "\t  d3.round = function(x, n) {\n",
       "\t    return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x);\n",
       "\t  };\n",
       "\t  var d3_formatPrefixes = [ \"y\", \"z\", \"a\", \"f\", \"p\", \"n\", \"µ\", \"m\", \"\", \"k\", \"M\", \"G\", \"T\", \"P\", \"E\", \"Z\", \"Y\" ].map(d3_formatPrefix);\n",
       "\t  d3.formatPrefix = function(value, precision) {\n",
       "\t    var i = 0;\n",
       "\t    if (value = +value) {\n",
       "\t      if (value < 0) value *= -1;\n",
       "\t      if (precision) value = d3.round(value, d3_format_precision(value, precision));\n",
       "\t      i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);\n",
       "\t      i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3));\n",
       "\t    }\n",
       "\t    return d3_formatPrefixes[8 + i / 3];\n",
       "\t  };\n",
       "\t  function d3_formatPrefix(d, i) {\n",
       "\t    var k = Math.pow(10, abs(8 - i) * 3);\n",
       "\t    return {\n",
       "\t      scale: i > 8 ? function(d) {\n",
       "\t        return d / k;\n",
       "\t      } : function(d) {\n",
       "\t        return d * k;\n",
       "\t      },\n",
       "\t      symbol: d\n",
       "\t    };\n",
       "\t  }\n",
       "\t  function d3_locale_numberFormat(locale) {\n",
       "\t    var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping && locale_thousands ? function(value, width) {\n",
       "\t      var i = value.length, t = [], j = 0, g = locale_grouping[0], length = 0;\n",
       "\t      while (i > 0 && g > 0) {\n",
       "\t        if (length + g + 1 > width) g = Math.max(1, width - length);\n",
       "\t        t.push(value.substring(i -= g, i + g));\n",
       "\t        if ((length += g + 1) > width) break;\n",
       "\t        g = locale_grouping[j = (j + 1) % locale_grouping.length];\n",
       "\t      }\n",
       "\t      return t.reverse().join(locale_thousands);\n",
       "\t    } : d3_identity;\n",
       "\t    return function(specifier) {\n",
       "\t      var match = d3_format_re.exec(specifier), fill = match[1] || \" \", align = match[2] || \">\", sign = match[3] || \"-\", symbol = match[4] || \"\", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = \"\", suffix = \"\", integer = false, exponent = true;\n",
       "\t      if (precision) precision = +precision.substring(1);\n",
       "\t      if (zfill || fill === \"0\" && align === \"=\") {\n",
       "\t        zfill = fill = \"0\";\n",
       "\t        align = \"=\";\n",
       "\t      }\n",
       "\t      switch (type) {\n",
       "\t       case \"n\":\n",
       "\t        comma = t
Download .txt
gitextract_jwcrr_g_/

├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── benchmark/
│   ├── __init__.py
│   ├── table_perf.py
│   └── text_perf.py
├── binder/
│   └── environment.yml
├── citation.bib
├── doc/
│   ├── blog_post.md
│   ├── conf.py
│   ├── index.rst
│   ├── lime.rst
│   └── notebooks/
│       ├── Latin Hypercube Sampling.ipynb
│       ├── Lime - basic usage, two class case.ipynb
│       ├── Lime - multiclass.ipynb
│       ├── Lime with Recurrent Neural Networks.ipynb
│       ├── Submodular Pick examples.ipynb
│       ├── Tutorial - Faces and GradBoost.ipynb
│       ├── Tutorial - Image Classification Keras.ipynb
│       ├── Tutorial - MNIST and RF.ipynb
│       ├── Tutorial - continuous and categorical features.ipynb
│       ├── Tutorial - images - Pytorch.ipynb
│       ├── Tutorial - images.ipynb
│       ├── Tutorial_H2O_continuous_and_cat.ipynb
│       ├── Using lime for regression.ipynb
│       └── data/
│           ├── adult.csv
│           ├── co2_data.csv
│           ├── imagenet_class_index.json
│           └── mushroom_data.csv
├── lime/
│   ├── __init__.py
│   ├── bundle.js
│   ├── discretize.py
│   ├── exceptions.py
│   ├── explanation.py
│   ├── js/
│   │   ├── bar_chart.js
│   │   ├── explanation.js
│   │   ├── main.js
│   │   ├── predict_proba.js
│   │   └── predicted_value.js
│   ├── lime_base.py
│   ├── lime_image.py
│   ├── lime_tabular.py
│   ├── lime_text.py
│   ├── package.json
│   ├── style.css
│   ├── submodular_pick.py
│   ├── test_table.html
│   ├── tests/
│   │   ├── __init__.py
│   │   ├── test_discretize.py
│   │   ├── test_generic_utils.py
│   │   ├── test_lime_tabular.py
│   │   ├── test_lime_text.py
│   │   └── test_scikit_image.py
│   ├── utils/
│   │   ├── __init__.py
│   │   └── generic_utils.py
│   ├── webpack.config.js
│   └── wrappers/
│       ├── __init__.py
│       └── scikit_image.py
├── setup.cfg
└── setup.py
Download .txt
SYMBOL INDEX (1172 symbols across 22 files)

FILE: benchmark/table_perf.py
  function interpret_data (line 12) | def interpret_data(X, y, func):

FILE: benchmark/text_perf.py
  function interpret_data (line 10) | def interpret_data(X, y, func, class_names):

FILE: lime/bundle.js
  function __webpack_require__ (line 7) | function __webpack_require__(moduleId) {
  function _interopRequireDefault (line 71) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
  function sliceIterator (line 96) | function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = ...
  function _interopRequireDefault (line 108) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
  function _classCallCheck (line 110) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
  function Explanation (line 113) | function Explanation(class_names) {
  function d3_documentElement (line 407) | function d3_documentElement(node) {
  function d3_window (line 410) | function d3_window(node) {
  function d3_ascending (line 444) | function d3_ascending(a, b) {
  function d3_number (line 507) | function d3_number(x) {
  function d3_numeric (line 510) | function d3_numeric(x) {
  function d3_bisector (line 569) | function d3_bisector(compare) {
  function d3_transposeLength (line 630) | function d3_transposeLength(d) {
  function d3_range_integerScale (line 682) | function d3_range_integerScale(x) {
  function d3_class (line 687) | function d3_class(ctor, properties) {
  function d3_Map (line 709) | function d3_Map() {
  function d3_map_escape (line 742) | function d3_map_escape(key) {
  function d3_map_unescape (line 745) | function d3_map_unescape(key) {
  function d3_map_has (line 748) | function d3_map_has(key) {
  function d3_map_remove (line 751) | function d3_map_remove(key) {
  function d3_map_keys (line 754) | function d3_map_keys() {
  function d3_map_size (line 759) | function d3_map_size() {
  function d3_map_empty (line 764) | function d3_map_empty() {
  function map (line 770) | function map(mapType, array, depth) {
  function entries (line 794) | function entries(map, depth) {
  function d3_Set (line 836) | function d3_Set() {
  function d3_identity (line 854) | function d3_identity(d) {
  function d3_rebind (line 862) | function d3_rebind(target, source, method) {
  function d3_vendorSymbol (line 868) | function d3_vendorSymbol(object, name) {
  function d3_noop (line 877) | function d3_noop() {}
  function d3_dispatch (line 883) | function d3_dispatch() {}
  function d3_dispatch_event (line 898) | function d3_dispatch_event(dispatch) {
  function d3_eventPreventDefault (line 921) | function d3_eventPreventDefault() {
  function d3_eventSource (line 924) | function d3_eventSource() {
  function d3_eventDispatch (line 929) | function d3_eventDispatch(target) {
  function d3_selection (line 955) | function d3_selection(groups) {
  function d3_selection_selector (line 998) | function d3_selection_selector(selector) {
  function d3_selection_selectorAll (line 1016) | function d3_selection_selectorAll(selector) {
  function d3_selection_attr (line 1052) | function d3_selection_attr(name, value) {
  function d3_collapse (line 1076) | function d3_collapse(s) {
  function d3_selection_classedRe (line 1096) | function d3_selection_classedRe(name) {
  function d3_selection_classes (line 1099) | function d3_selection_classes(name) {
  function d3_selection_classed (line 1102) | function d3_selection_classed(name, value) {
  function d3_selection_classedName (line 1115) | function d3_selection_classedName(name) {
  function d3_selection_style (line 1144) | function d3_selection_style(name, value, priority) {
  function d3_selection_property (line 1165) | function d3_selection_property(name, value) {
  function d3_selection_creator (line 1204) | function d3_selection_creator(name) {
  function d3_selectionRemove (line 1224) | function d3_selectionRemove() {
  function bind (line 1239) | function bind(group, groupData) {
  function d3_selection_dataNode (line 1309) | function d3_selection_dataNode(data) {
  function d3_selection_filter (line 1331) | function d3_selection_filter(selector) {
  function d3_selection_sortComparator (line 1352) | function d3_selection_sortComparator(comparator) {
  function d3_selection_each (line 1363) | function d3_selection_each(groups, callback) {
  function d3_selection_enter (line 1395) | function d3_selection_enter(selection) {
  function d3_selection_enterInsertBefore (line 1428) | function d3_selection_enterInsertBefore(enter) {
  function d3_selection_on (line 1473) | function d3_selection_on(type, listener, capture) {
  function d3_selection_onListener (line 1512) | function d3_selection_onListener(listener, argumentz) {
  function d3_selection_onFilter (line 1524) | function d3_selection_onFilter(listener, argumentz) {
  function d3_event_dragSuppress (line 1534) | function d3_event_dragSuppress(node) {
  function d3_mousePoint (line 1562) | function d3_mousePoint(container, e) {
  function drag (line 1601) | function drag() {
  function dragstart (line 1604) | function dragstart(id, position, subject, move, end) {
  function d3_behavior_dragTouchId (line 1648) | function d3_behavior_dragTouchId() {
  function d3_sgn (line 1660) | function d3_sgn(x) {
  function d3_cross2d (line 1663) | function d3_cross2d(a, b, c) {
  function d3_acos (line 1666) | function d3_acos(x) {
  function d3_asin (line 1669) | function d3_asin(x) {
  function d3_sinh (line 1672) | function d3_sinh(x) {
  function d3_cosh (line 1675) | function d3_cosh(x) {
  function d3_tanh (line 1678) | function d3_tanh(x) {
  function d3_haversin (line 1681) | function d3_haversin(x) {
  function zoom (line 1718) | function zoom(g) {
  function location (line 1819) | function location(p) {
  function point (line 1822) | function point(l) {
  function scaleTo (line 1825) | function scaleTo(s) {
  function translateTo (line 1828) | function translateTo(p, l) {
  function zoomTo (line 1833) | function zoomTo(that, p, l, k) {
  function rescale (line 1845) | function rescale() {
  function zoomstarted (line 1853) | function zoomstarted(dispatch) {
  function zoomed (line 1858) | function zoomed(dispatch) {
  function zoomended (line 1866) | function zoomended(dispatch) {
  function mousedowned (line 1871) | function mousedowned() {
  function touchstarted (line 1886) | function touchstarted() {
  function mousewheeled (line 1956) | function mousewheeled() {
  function dblclicked (line 1969) | function dblclicked() {
  function d3_color (line 1977) | function d3_color() {}
  function d3_hsl (line 1982) | function d3_hsl(h, s, l) {
  function d3_hsl_rgb (line 1997) | function d3_hsl_rgb(h, s, l) {
  function d3_hcl (line 2017) | function d3_hcl(h, c, l) {
  function d3_hcl_lab (line 2030) | function d3_hcl_lab(h, c, l) {
  function d3_lab (line 2036) | function d3_lab(l, a, b) {
  function d3_lab_rgb (line 2051) | function d3_lab_rgb(l, a, b) {
  function d3_lab_hcl (line 2058) | function d3_lab_hcl(l, a, b) {
  function d3_lab_xyz (line 2061) | function d3_lab_xyz(x) {
  function d3_xyz_lab (line 2064) | function d3_xyz_lab(x) {
  function d3_xyz_rgb (line 2067) | function d3_xyz_rgb(r) {
  function d3_rgb (line 2071) | function d3_rgb(r, g, b) {
  function d3_rgbNumber (line 2074) | function d3_rgbNumber(value) {
  function d3_rgbString (line 2077) | function d3_rgbString(value) {
  function d3_rgb_hex (line 2100) | function d3_rgb_hex(v) {
  function d3_rgb_parse (line 2103) | function d3_rgb_parse(format, rgb, hsl) {
  function d3_rgb_hsl (line 2139) | function d3_rgb_hsl(r, g, b) {
  function d3_rgb_lab (line 2151) | function d3_rgb_lab(r, g, b) {
  function d3_rgb_xyz (line 2158) | function d3_rgb_xyz(r) {
  function d3_rgb_parseNumber (line 2161) | function d3_rgb_parseNumber(c) {
  function d3_functor (line 2318) | function d3_functor(v) {
  function d3_xhrType (line 2325) | function d3_xhrType(response) {
  function d3_xhr (line 2332) | function d3_xhr(url, mimeType, response, callback) {
  function d3_xhr_fixCallback (line 2407) | function d3_xhr_fixCallback(callback) {
  function d3_xhrHasResponse (line 2412) | function d3_xhrHasResponse(request) {
  function dsv (line 2418) | function dsv(url, row, callback) {
  function response (line 2426) | function response(request) {
  function typedResponse (line 2429) | function typedResponse(f) {
  function token (line 2448) | function token() {
  function formatRow (line 2510) | function formatRow(row) {
  function formatValue (line 2513) | function formatValue(text) {
  function d3_timer (line 2526) | function d3_timer(callback, delay, then) {
  function d3_timer_step (line 2544) | function d3_timer_step() {
  function d3_timer_mark (line 2561) | function d3_timer_mark() {
  function d3_timer_sweep (line 2569) | function d3_timer_sweep() {
  function d3_format_precision (line 2582) | function d3_format_precision(x, p) {
  function d3_formatPrefix (line 2599) | function d3_formatPrefix(d, i) {
  function d3_locale_numberFormat (line 2610) | function d3_locale_numberFormat(locale) {
  function d3_format_typeDefault (line 2731) | function d3_format_typeDefault(x) {
  function d3_date_utc (line 2735) | function d3_date_utc() {
  function d3_time_interval (line 2801) | function d3_time_interval(local, step, number) {
  function d3_time_interval_utc (line 2849) | function d3_time_interval_utc(method) {
  function d3_locale_timeFormat (line 2909) | function d3_locale_timeFormat(locale) {
  function d3_time_formatPad (line 3130) | function d3_time_formatPad(value, fill, width) {
  function d3_time_formatRe (line 3134) | function d3_time_formatRe(names) {
  function d3_time_formatLookup (line 3137) | function d3_time_formatLookup(names) {
  function d3_time_parseWeekdayNumber (line 3142) | function d3_time_parseWeekdayNumber(date, string, i) {
  function d3_time_parseWeekNumberSunday (line 3147) | function d3_time_parseWeekNumberSunday(date, string, i) {
  function d3_time_parseWeekNumberMonday (line 3152) | function d3_time_parseWeekNumberMonday(date, string, i) {
  function d3_time_parseFullYear (line 3157) | function d3_time_parseFullYear(date, string, i) {
  function d3_time_parseYear (line 3162) | function d3_time_parseYear(date, string, i) {
  function d3_time_parseZone (line 3167) | function d3_time_parseZone(date, string, i) {
  function d3_time_expandYear (line 3171) | function d3_time_expandYear(d) {
  function d3_time_parseMonthNumber (line 3174) | function d3_time_parseMonthNumber(date, string, i) {
  function d3_time_parseDay (line 3179) | function d3_time_parseDay(date, string, i) {
  function d3_time_parseDayOfYear (line 3184) | function d3_time_parseDayOfYear(date, string, i) {
  function d3_time_parseHour24 (line 3189) | function d3_time_parseHour24(date, string, i) {
  function d3_time_parseMinutes (line 3194) | function d3_time_parseMinutes(date, string, i) {
  function d3_time_parseSeconds (line 3199) | function d3_time_parseSeconds(date, string, i) {
  function d3_time_parseMilliseconds (line 3204) | function d3_time_parseMilliseconds(date, string, i) {
  function d3_time_zone (line 3209) | function d3_time_zone(d) {
  function d3_time_parseLiteralPercent (line 3213) | function d3_time_parseLiteralPercent(date, string, i) {
  function d3_time_formatMulti (line 3218) | function d3_time_formatMulti(formats) {
  function d3_adder (line 3249) | function d3_adder() {}
  function d3_adderSum (line 3266) | function d3_adderSum(a, b, o) {
  function d3_geo_streamGeometry (line 3277) | function d3_geo_streamGeometry(geometry, listener) {
  function d3_geo_streamLine (line 3322) | function d3_geo_streamLine(coordinates, listener, closed) {
  function d3_geo_streamPolygon (line 3328) | function d3_geo_streamPolygon(coordinates, listener) {
  function d3_geo_areaRingStart (line 3357) | function d3_geo_areaRingStart() {
  function d3_geo_cartesian (line 3375) | function d3_geo_cartesian(spherical) {
  function d3_geo_cartesianDot (line 3379) | function d3_geo_cartesianDot(a, b) {
  function d3_geo_cartesianCross (line 3382) | function d3_geo_cartesianCross(a, b) {
  function d3_geo_cartesianAdd (line 3385) | function d3_geo_cartesianAdd(a, b) {
  function d3_geo_cartesianScale (line 3390) | function d3_geo_cartesianScale(vector, k) {
  function d3_geo_cartesianNormalize (line 3393) | function d3_geo_cartesianNormalize(d) {
  function d3_geo_spherical (line 3399) | function d3_geo_spherical(cartesian) {
  function d3_geo_sphericalEqual (line 3402) | function d3_geo_sphericalEqual(a, b) {
  function point (line 3427) | function point(λ, φ) {
  function linePoint (line 3432) | function linePoint(λ, φ) {
  function lineStart (line 3472) | function lineStart() {
  function lineEnd (line 3475) | function lineEnd() {
  function ringPoint (line 3480) | function ringPoint(λ, φ) {
  function ringStart (line 3488) | function ringStart() {
  function ringEnd (line 3491) | function ringEnd() {
  function angle (line 3498) | function angle(λ0, λ1) {
  function compareRanges (line 3501) | function compareRanges(a, b) {
  function withinRange (line 3504) | function withinRange(x, range) {
  function d3_geo_centroidPoint (line 3558) | function d3_geo_centroidPoint(λ, φ) {
  function d3_geo_centroidPointXYZ (line 3563) | function d3_geo_centroidPointXYZ(x, y, z) {
  function d3_geo_centroidLineStart (line 3569) | function d3_geo_centroidLineStart() {
  function d3_geo_centroidLineEnd (line 3590) | function d3_geo_centroidLineEnd() {
  function d3_geo_centroidRingStart (line 3593) | function d3_geo_centroidRingStart() {
  function d3_geo_compose (line 3623) | function d3_geo_compose(a, b) {
  function d3_true (line 3632) | function d3_true() {
  function d3_geo_clipPolygon (line 3635) | function d3_geo_clipPolygon(segments, compare, clipStartInside, interpol...
  function d3_geo_clipPolygonLinkCircular (line 3694) | function d3_geo_clipPolygonLinkCircular(array) {
  function d3_geo_clipPolygonIntersection (line 3705) | function d3_geo_clipPolygonIntersection(point, points, other, entry) {
  function d3_geo_clip (line 3713) | function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) {
  function d3_geo_clipSegmentLength1 (line 3805) | function d3_geo_clipSegmentLength1(segment) {
  function d3_geo_clipBufferListener (line 3808) | function d3_geo_clipBufferListener() {
  function d3_geo_clipSort (line 3829) | function d3_geo_clipSort(a, b) {
  function d3_geo_clipAntimeridianLine (line 3833) | function d3_geo_clipAntimeridianLine(listener) {
  function d3_geo_clipAntimeridianIntersect (line 3872) | function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) {
  function d3_geo_clipAntimeridianInterpolate (line 3876) | function d3_geo_clipAntimeridianInterpolate(from, to, direction, listene...
  function d3_geo_pointInPolygon (line 3899) | function d3_geo_pointInPolygon(point, polygon) {
  function d3_geo_clipCircle (line 3928) | function d3_geo_clipCircle(radius) {
  function d3_geom_clipLine (line 4024) | function d3_geom_clipLine(x0, y0, x1, y1) {
  function d3_geo_clipExtent (line 4096) | function d3_geo_clipExtent(x0, y0, x1, y1) {
  function d3_geo_conic (line 4230) | function d3_geo_conic(projectAt) {
  function d3_geo_conicEqualArea (line 4238) | function d3_geo_conicEqualArea(φ0, φ1) {
  function albersUsa (line 4265) | function albersUsa(coordinates) {
  function d3_geo_pathAreaRingStart (line 4347) | function d3_geo_pathAreaRingStart() {
  function d3_geo_pathBoundsPoint (line 4369) | function d3_geo_pathBoundsPoint(x, y) {
  function d3_geo_pathBuffer (line 4375) | function d3_geo_pathBuffer() {
  function d3_geo_pathBufferCircle (line 4420) | function d3_geo_pathBufferCircle(radius) {
  function d3_geo_pathCentroidPoint (line 4436) | function d3_geo_pathCentroidPoint(x, y) {
  function d3_geo_pathCentroidLineStart (line 4441) | function d3_geo_pathCentroidLineStart() {
  function d3_geo_pathCentroidLineEnd (line 4455) | function d3_geo_pathCentroidLineEnd() {
  function d3_geo_pathCentroidRingStart (line 4458) | function d3_geo_pathCentroidRingStart() {
  function d3_geo_pathContext (line 4479) | function d3_geo_pathContext(context) {
  function d3_geo_resample (line 4519) | function d3_geo_resample(project) {
  function path (line 4599) | function path(object) {
  function reset (line 4638) | function reset() {
  function d3_geo_pathProjectStream (line 4644) | function d3_geo_pathProjectStream(project) {
  function d3_geo_transform (line 4661) | function d3_geo_transform(stream) {
  function d3_geo_transformPoint (line 4684) | function d3_geo_transformPoint(stream, point) {
  function d3_geo_projection (line 4706) | function d3_geo_projection(project) {
  function d3_geo_projectionMutator (line 4711) | function d3_geo_projectionMutator(projectAt) {
  function d3_geo_projectionRadians (line 4783) | function d3_geo_projectionRadians(stream) {
  function d3_geo_equirectangular (line 4788) | function d3_geo_equirectangular(λ, φ) {
  function forward (line 4796) | function forward(coordinates) {
  function d3_geo_identityRotation (line 4806) | function d3_geo_identityRotation(λ, φ) {
  function d3_geo_rotation (line 4810) | function d3_geo_rotation(δλ, δφ, δγ) {
  function d3_geo_forwardRotationλ (line 4813) | function d3_geo_forwardRotationλ(δλ) {
  function d3_geo_rotationλ (line 4818) | function d3_geo_rotationλ(δλ) {
  function d3_geo_rotationφγ (line 4823) | function d3_geo_rotationφγ(δφ, δγ) {
  function circle (line 4837) | function circle() {
  function d3_geo_circleInterpolate (line 4867) | function d3_geo_circleInterpolate(radius, precision) {
  function d3_geo_circleAngle (line 4884) | function d3_geo_circleAngle(cr, point) {
  function graticule (line 4897) | function graticule() {
  function lines (line 4903) | function lines() {
  function d3_geo_graticuleX (line 4969) | function d3_geo_graticuleX(y0, y1, dy) {
  function d3_geo_graticuleY (line 4977) | function d3_geo_graticuleY(x0, x1, dx) {
  function d3_source (line 4985) | function d3_source(d) {
  function d3_target (line 4988) | function d3_target(d) {
  function greatArc (line 4993) | function greatArc() {
  function d3_geo_interpolate (line 5020) | function d3_geo_interpolate(x0, y0, x1, y1) {
  function d3_geo_lengthLineStart (line 5045) | function d3_geo_lengthLineStart() {
  function d3_geo_azimuthal (line 5060) | function d3_geo_azimuthal(scale, angle) {
  function d3_geo_conicConformal (line 5086) | function d3_geo_conicConformal(φ0, φ1) {
  function d3_geo_conicEquidistant (line 5109) | function d3_geo_conicEquidistant(φ0, φ1) {
  function d3_geo_mercator (line 5131) | function d3_geo_mercator(λ, φ) {
  function d3_geo_mercatorProjection (line 5137) | function d3_geo_mercatorProjection(project) {
  function d3_geo_transverseMercator (line 5178) | function d3_geo_transverseMercator(λ, φ) {
  function d3_geom_pointX (line 5196) | function d3_geom_pointX(d) {
  function d3_geom_pointY (line 5199) | function d3_geom_pointY(d) {
  function hull (line 5205) | function hull(data) {
  function d3_geom_hullUpper (line 5227) | function d3_geom_hullUpper(points) {
  function d3_geom_hullOrder (line 5235) | function d3_geom_hullOrder(a, b) {
  function d3_geom_polygonInside (line 5289) | function d3_geom_polygonInside(p, a, b) {
  function d3_geom_polygonIntersect (line 5292) | function d3_geom_polygonIntersect(c, d, a, b) {
  function d3_geom_polygonClosed (line 5296) | function d3_geom_polygonClosed(coordinates) {
  function d3_geom_voronoiBeach (line 5301) | function d3_geom_voronoiBeach() {
  function d3_geom_voronoiCreateBeach (line 5305) | function d3_geom_voronoiCreateBeach(site) {
  function d3_geom_voronoiDetachBeach (line 5310) | function d3_geom_voronoiDetachBeach(beach) {
  function d3_geom_voronoiRemoveBeach (line 5316) | function d3_geom_voronoiRemoveBeach(beach) {
  function d3_geom_voronoiAddBeach (line 5352) | function d3_geom_voronoiAddBeach(site) {
  function d3_geom_voronoiLeftBreakPoint (line 5406) | function d3_geom_voronoiLeftBreakPoint(arc, directrix) {
  function d3_geom_voronoiRightBreakPoint (line 5418) | function d3_geom_voronoiRightBreakPoint(arc, directrix) {
  function d3_geom_voronoiCell (line 5424) | function d3_geom_voronoiCell(site) {
  function d3_geom_voronoiCloseCells (line 5437) | function d3_geom_voronoiCloseCells(extent) {
  function d3_geom_voronoiHalfEdgeOrder (line 5467) | function d3_geom_voronoiHalfEdgeOrder(a, b) {
  function d3_geom_voronoiCircle (line 5470) | function d3_geom_voronoiCircle() {
  function d3_geom_voronoiAttachCircle (line 5474) | function d3_geom_voronoiAttachCircle(arc) {
  function d3_geom_voronoiDetachCircle (line 5507) | function d3_geom_voronoiDetachCircle(arc) {
  function d3_geom_voronoiClipEdges (line 5517) | function d3_geom_voronoiClipEdges(extent) {
  function d3_geom_voronoiConnectEdge (line 5527) | function d3_geom_voronoiConnectEdge(edge, extent) {
  function d3_geom_voronoiEdge (line 5601) | function d3_geom_voronoiEdge(lSite, rSite) {
  function d3_geom_voronoiCreateEdge (line 5606) | function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) {
  function d3_geom_voronoiCreateBorderEdge (line 5615) | function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) {
  function d3_geom_voronoiSetEdgeEnd (line 5622) | function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) {
  function d3_geom_voronoiHalfEdge (line 5633) | function d3_geom_voronoiHalfEdge(edge, lSite, rSite) {
  function d3_geom_voronoiRedBlackTree (line 5647) | function d3_geom_voronoiRedBlackTree() {
  function d3_geom_voronoiRedBlackNode (line 5650) | function d3_geom_voronoiRedBlackNode(node) {
  function d3_geom_voronoiRedBlackRotateLeft (line 5813) | function d3_geom_voronoiRedBlackRotateLeft(tree, node) {
  function d3_geom_voronoiRedBlackRotateRight (line 5826) | function d3_geom_voronoiRedBlackRotateRight(tree, node) {
  function d3_geom_voronoiRedBlackFirst (line 5839) | function d3_geom_voronoiRedBlackFirst(node) {
  function d3_geom_voronoi (line 5843) | function d3_geom_voronoi(sites, bbox) {
  function d3_geom_voronoiVertexOrder (line 5872) | function d3_geom_voronoiVertexOrder(a, b) {
  function voronoi (line 5878) | function voronoi(data) {
  function sites (line 5889) | function sites(data) {
  function d3_geom_voronoiTriangleArea (line 5942) | function d3_geom_voronoiTriangleArea(a, b, c) {
  function quadtree (line 5960) | function quadtree(data) {
  function d3_geom_quadtreeCompatX (line 6055) | function d3_geom_quadtreeCompatX(d) {
  function d3_geom_quadtreeCompatY (line 6058) | function d3_geom_quadtreeCompatY(d) {
  function d3_geom_quadtreeNode (line 6061) | function d3_geom_quadtreeNode() {
  function d3_geom_quadtreeVisit (line 6070) | function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) {
  function d3_geom_quadtreeFind (line 6079) | function d3_geom_quadtreeFind(root, x, y, x0, y0, x3, y3) {
  function d3_interpolateRgb (line 6116) | function d3_interpolateRgb(a, b) {
  function d3_interpolateObject (line 6125) | function d3_interpolateObject(a, b) {
  function d3_interpolateNumber (line 6145) | function d3_interpolateNumber(a, b) {
  function d3_interpolateString (line 6152) | function d3_interpolateString(a, b) {
  function d3_interpolate (line 6186) | function d3_interpolate(a, b) {
  function d3_interpolateArray (line 6196) | function d3_interpolateArray(a, b) {
  function d3_ease_clamp (line 6247) | function d3_ease_clamp(f) {
  function d3_ease_reverse (line 6252) | function d3_ease_reverse(f) {
  function d3_ease_reflect (line 6257) | function d3_ease_reflect(f) {
  function d3_ease_quad (line 6262) | function d3_ease_quad(t) {
  function d3_ease_cubic (line 6265) | function d3_ease_cubic(t) {
  function d3_ease_cubicInOut (line 6268) | function d3_ease_cubicInOut(t) {
  function d3_ease_poly (line 6274) | function d3_ease_poly(e) {
  function d3_ease_sin (line 6279) | function d3_ease_sin(t) {
  function d3_ease_exp (line 6282) | function d3_ease_exp(t) {
  function d3_ease_circle (line 6285) | function d3_ease_circle(t) {
  function d3_ease_elastic (line 6288) | function d3_ease_elastic(a, p) {
  function d3_ease_back (line 6296) | function d3_ease_back(s) {
  function d3_ease_bounce (line 6302) | function d3_ease_bounce(t) {
  function d3_interpolateHcl (line 6306) | function d3_interpolateHcl(a, b) {
  function d3_interpolateHsl (line 6317) | function d3_interpolateHsl(a, b) {
  function d3_interpolateLab (line 6328) | function d3_interpolateLab(a, b) {
  function d3_interpolateRound (line 6337) | function d3_interpolateRound(a, b) {
  function d3_transform (line 6353) | function d3_transform(m) {
  function d3_transformDot (line 6369) | function d3_transformDot(a, b) {
  function d3_transformNormalize (line 6372) | function d3_transformNormalize(a) {
  function d3_transformCombine (line 6380) | function d3_transformCombine(a, b, k) {
  function d3_interpolateTransformPop (line 6394) | function d3_interpolateTransformPop(s) {
  function d3_interpolateTranslate (line 6397) | function d3_interpolateTranslate(ta, tb, s, q) {
  function d3_interpolateRotate (line 6411) | function d3_interpolateRotate(ra, rb, s, q) {
  function d3_interpolateSkew (line 6422) | function d3_interpolateSkew(wa, wb, s, q) {
  function d3_interpolateScale (line 6432) | function d3_interpolateScale(ka, kb, s, q) {
  function d3_interpolateTransform (line 6446) | function d3_interpolateTransform(a, b) {
  function d3_uninterpolateNumber (line 6460) | function d3_uninterpolateNumber(a, b) {
  function d3_uninterpolateClamp (line 6466) | function d3_uninterpolateClamp(a, b) {
  function d3_layout_bundlePath (line 6480) | function d3_layout_bundlePath(link) {
  function d3_layout_bundleAncestors (line 6493) | function d3_layout_bundleAncestors(node) {
  function d3_layout_bundleLeastCommonAncestor (line 6503) | function d3_layout_bundleLeastCommonAncestor(a, b) {
  function relayout (line 6515) | function relayout() {
  function resort (line 6581) | function resort() {
  function repulse (line 6628) | function repulse(node) {
  function position (line 6809) | function position(dimension, size) {
  function dragmove (line 6838) | function dragmove(d) {
  function d3_layout_forceDragstart (line 6844) | function d3_layout_forceDragstart(d) {
  function d3_layout_forceDragend (line 6847) | function d3_layout_forceDragend(d) {
  function d3_layout_forceMouseover (line 6850) | function d3_layout_forceMouseover(d) {
  function d3_layout_forceMouseout (line 6854) | function d3_layout_forceMouseout(d) {
  function d3_layout_forceAccumulate (line 6857) | function d3_layout_forceAccumulate(quad, alpha, charges) {
  function hierarchy (line 6887) | function hierarchy(root) {
  function d3_layout_hierarchyRebind (line 6943) | function d3_layout_hierarchyRebind(object, hierarchy) {
  function d3_layout_hierarchyVisitBefore (line 6949) | function d3_layout_hierarchyVisitBefore(node, callback) {
  function d3_layout_hierarchyVisitAfter (line 6959) | function d3_layout_hierarchyVisitAfter(node, callback) {
  function d3_layout_hierarchyChildren (line 6972) | function d3_layout_hierarchyChildren(d) {
  function d3_layout_hierarchyValue (line 6975) | function d3_layout_hierarchyValue(d) {
  function d3_layout_hierarchySort (line 6978) | function d3_layout_hierarchySort(a, b) {
  function d3_layout_hierarchyLinks (line 6981) | function d3_layout_hierarchyLinks(nodes) {
  function position (line 6993) | function position(node, x, dx, dy) {
  function depth (line 7008) | function depth(node) {
  function partition (line 7016) | function partition(d, i) {
  function pie (line 7030) | function pie(data) {
  function stack (line 7080) | function stack(data, index) {
  function d3_layout_stackX (line 7135) | function d3_layout_stackX(d) {
  function d3_layout_stackY (line 7138) | function d3_layout_stackY(d) {
  function d3_layout_stackOut (line 7141) | function d3_layout_stackOut(d, y0, y) {
  function d3_layout_stackOrderDefault (line 7208) | function d3_layout_stackOrderDefault(data) {
  function d3_layout_stackOffsetZero (line 7211) | function d3_layout_stackOffsetZero(data) {
  function d3_layout_stackMaxIndex (line 7216) | function d3_layout_stackMaxIndex(array) {
  function d3_layout_stackReduceSum (line 7226) | function d3_layout_stackReduceSum(d) {
  function d3_layout_stackSum (line 7229) | function d3_layout_stackSum(p, d) {
  function histogram (line 7234) | function histogram(data, i) {
  function d3_layout_histogramBinSturges (line 7278) | function d3_layout_histogramBinSturges(range, values) {
  function d3_layout_histogramBinFixed (line 7281) | function d3_layout_histogramBinFixed(range, n) {
  function d3_layout_histogramRange (line 7286) | function d3_layout_histogramRange(values) {
  function pack (line 7291) | function pack(d, i) {
  function d3_layout_packSort (line 7330) | function d3_layout_packSort(a, b) {
  function d3_layout_packInsert (line 7333) | function d3_layout_packInsert(a, b) {
  function d3_layout_packSplice (line 7340) | function d3_layout_packSplice(a, b) {
  function d3_layout_packIntersects (line 7344) | function d3_layout_packIntersects(a, b) {
  function d3_layout_packSiblings (line 7348) | function d3_layout_packSiblings(node) {
  function d3_layout_packLink (line 7412) | function d3_layout_packLink(node) {
  function d3_layout_packUnlink (line 7415) | function d3_layout_packUnlink(node) {
  function d3_layout_packTransform (line 7419) | function d3_layout_packTransform(node, x, y, k) {
  function d3_layout_packPlace (line 7429) | function d3_layout_packPlace(a, b, c) {
  function tree (line 7445) | function tree(d, i) {
  function wrapTree (line 7464) | function wrapTree(root0) {
  function firstWalk (line 7488) | function firstWalk(v) {
  function secondWalk (line 7504) | function secondWalk(v) {
  function apportion (line 7508) | function apportion(v, w, ancestor) {
  function sizeNode (line 7538) | function sizeNode(node) {
  function d3_layout_treeSeparation (line 7559) | function d3_layout_treeSeparation(a, b) {
  function d3_layout_treeLeft (line 7562) | function d3_layout_treeLeft(v) {
  function d3_layout_treeRight (line 7566) | function d3_layout_treeRight(v) {
  function d3_layout_treeMove (line 7570) | function d3_layout_treeMove(wm, wp, shift) {
  function d3_layout_treeShift (line 7578) | function d3_layout_treeShift(v) {
  function d3_layout_treeAncestor (line 7587) | function d3_layout_treeAncestor(vim, v, ancestor) {
  function cluster (line 7592) | function cluster(d, i) {
  function d3_layout_clusterY (line 7632) | function d3_layout_clusterY(children) {
  function d3_layout_clusterX (line 7637) | function d3_layout_clusterX(children) {
  function d3_layout_clusterLeft (line 7642) | function d3_layout_clusterLeft(node) {
  function d3_layout_clusterRight (line 7646) | function d3_layout_clusterRight(node) {
  function scale (line 7652) | function scale(children, k) {
  function squarify (line 7659) | function squarify(node) {
  function stickify (line 7686) | function stickify(node) {
  function worst (line 7703) | function worst(row, u) {
  function position (line 7714) | function position(row, u, rect, flush) {
  function treemap (line 7744) | function treemap(d) {
  function padFunction (line 7761) | function padFunction(node) {
  function padConstant (line 7765) | function padConstant(node) {
  function d3_layout_treemapPadNull (line 7796) | function d3_layout_treemapPadNull(node) {
  function d3_layout_treemapPad (line 7804) | function d3_layout_treemapPad(node, padding) {
  function d3_scaleExtent (line 7856) | function d3_scaleExtent(domain) {
  function d3_scaleRange (line 7860) | function d3_scaleRange(scale) {
  function d3_scale_bilinear (line 7863) | function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
  function d3_scale_nice (line 7869) | function d3_scale_nice(domain, nice) {
  function d3_scale_niceStep (line 7879) | function d3_scale_niceStep(step) {
  function d3_scale_polylinear (line 7893) | function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
  function d3_scale_linear (line 7911) | function d3_scale_linear(domain, range, interpolate, clamp) {
  function d3_scale_linearRebind (line 7963) | function d3_scale_linearRebind(scale, linear) {
  function d3_scale_linearNice (line 7966) | function d3_scale_linearNice(domain, m) {
  function d3_scale_linearTickRange (line 7971) | function d3_scale_linearTickRange(domain, m) {
  function d3_scale_linearTicks (line 7980) | function d3_scale_linearTicks(domain, m) {
  function d3_scale_linearTickFormat (line 7983) | function d3_scale_linearTickFormat(domain, m, format) {
  function d3_scale_linearPrecision (line 8011) | function d3_scale_linearPrecision(value) {
  function d3_scale_linearFormatPrecision (line 8014) | function d3_scale_linearFormatPrecision(type, range) {
  function d3_scale_log (line 8021) | function d3_scale_log(linear, base, positive, domain) {
  function d3_scale_pow (line 8094) | function d3_scale_pow(linear, exponent, domain) {
  function d3_scale_powPow (line 8128) | function d3_scale_powPow(e) {
  function d3_scale_ordinal (line 8142) | function d3_scale_ordinal(domain, ranger) {
  function d3_scale_quantile (line 8250) | function d3_scale_quantile(domain, range) {
  function d3_scale_quantize (line 8286) | function d3_scale_quantize(x0, x1, range) {
  function d3_scale_threshold (line 8320) | function d3_scale_threshold(domain, range) {
  function d3_scale_identity (line 8346) | function d3_scale_identity(domain) {
  function d3_zero (line 8368) | function d3_zero() {
  function arc (line 8373) | function arc() {
  function circleSegment (line 8451) | function circleSegment(r1, cw) {
  function d3_svg_arcInnerRadius (line 8496) | function d3_svg_arcInnerRadius(d) {
  function d3_svg_arcOuterRadius (line 8499) | function d3_svg_arcOuterRadius(d) {
  function d3_svg_arcStartAngle (line 8502) | function d3_svg_arcStartAngle(d) {
  function d3_svg_arcEndAngle (line 8505) | function d3_svg_arcEndAngle(d) {
  function d3_svg_arcPadAngle (line 8508) | function d3_svg_arcPadAngle(d) {
  function d3_svg_arcSweep (line 8511) | function d3_svg_arcSweep(x0, y0, x1, y1) {
  function d3_svg_arcCornerTangents (line 8514) | function d3_svg_arcCornerTangents(p0, p1, r1, rc, cw) {
  function d3_svg_line (line 8519) | function d3_svg_line(projection) {
  function d3_svg_lineLinear (line 8586) | function d3_svg_lineLinear(points) {
  function d3_svg_lineLinearClosed (line 8589) | function d3_svg_lineLinearClosed(points) {
  function d3_svg_lineStep (line 8592) | function d3_svg_lineStep(points) {
  function d3_svg_lineStepBefore (line 8598) | function d3_svg_lineStepBefore(points) {
  function d3_svg_lineStepAfter (line 8603) | function d3_svg_lineStepAfter(points) {
  function d3_svg_lineCardinalOpen (line 8608) | function d3_svg_lineCardinalOpen(points, tension) {
  function d3_svg_lineCardinalClosed (line 8611) | function d3_svg_lineCardinalClosed(points, tension) {
  function d3_svg_lineCardinal (line 8615) | function d3_svg_lineCardinal(points, tension) {
  function d3_svg_lineHermite (line 8618) | function d3_svg_lineHermite(points, tangents) {
  function d3_svg_lineCardinalTangents (line 8645) | function d3_svg_lineCardinalTangents(points, tension) {
  function d3_svg_lineBasis (line 8655) | function d3_svg_lineBasis(points) {
  function d3_svg_lineBasisOpen (line 8671) | function d3_svg_lineBasisOpen(points) {
  function d3_svg_lineBasisClosed (line 8691) | function d3_svg_lineBasisClosed(points) {
  function d3_svg_lineBundle (line 8710) | function d3_svg_lineBundle(points, tension) {
  function d3_svg_lineDot4 (line 8723) | function d3_svg_lineDot4(a, b) {
  function d3_svg_lineBasisBezier (line 8727) | function d3_svg_lineBasisBezier(path, x, y) {
  function d3_svg_lineSlope (line 8730) | function d3_svg_lineSlope(p0, p1) {
  function d3_svg_lineFiniteDifferences (line 8733) | function d3_svg_lineFiniteDifferences(points) {
  function d3_svg_lineMonotoneTangents (line 8741) | function d3_svg_lineMonotoneTangents(points) {
  function d3_svg_lineMonotone (line 8765) | function d3_svg_lineMonotone(points) {
  function d3_svg_lineRadial (line 8774) | function d3_svg_lineRadial(points) {
  function d3_svg_area (line 8785) | function d3_svg_area(projection) {
  function chord (line 8875) | function chord(d, i) {
  function subgroup (line 8879) | function subgroup(self, f, d, i) {
  function equals (line 8889) | function equals(a, b) {
  function arc (line 8892) | function arc(r, p, a) {
  function curve (line 8895) | function curve(r0, p0, r1, p1) {
  function d3_svg_chordRadius (line 8925) | function d3_svg_chordRadius(d) {
  function diagonal (line 8930) | function diagonal(d, i) {
  function d3_svg_diagonalProjection (line 8958) | function d3_svg_diagonalProjection(d) {
  function d3_svg_diagonalRadialProjection (line 8968) | function d3_svg_diagonalRadialProjection(projection) {
  function symbol (line 8976) | function symbol(d, i) {
  function d3_svg_symbolSize (line 8991) | function d3_svg_symbolSize() {
  function d3_svg_symbolType (line 8994) | function d3_svg_symbolType() {
  function d3_svg_symbolCircle (line 8997) | function d3_svg_symbolCircle(size) {
  function d3_selection_interruptNS (line 9046) | function d3_selection_interruptNS(ns) {
  function d3_transition (line 9058) | function d3_transition(groups, ns, id) {
  function d3_transition_tween (line 9130) | function d3_transition_tween(groups, name, value, tween) {
  function attrNull (line 9144) | function attrNull() {
  function attrNullNS (line 9147) | function attrNullNS() {
  function attrTween (line 9150) | function attrTween(b) {
  function attrTweenNS (line 9158) | function attrTweenNS(b) {
  function attrTween (line 9170) | function attrTween(d, i) {
  function attrTweenNS (line 9176) | function attrTweenNS(d, i) {
  function styleNull (line 9194) | function styleNull() {
  function styleString (line 9197) | function styleString(b) {
  function styleTween (line 9209) | function styleTween(d, i) {
  function d3_transition_text (line 9220) | function d3_transition_text(b) {
  function d3_transitionNamespace (line 9300) | function d3_transitionNamespace(name) {
  function d3_transitionNode (line 9303) | function d3_transitionNode(node, i, ns, id, inherit) {
  function axis (line 9380) | function axis(g) {
  function d3_svg_axisX (line 9475) | function d3_svg_axisX(selection, x0, x1) {
  function d3_svg_axisY (line 9481) | function d3_svg_axisY(selection, y0, y1) {
  function brush (line 9489) | function brush(g) {
  function redraw (line 9575) | function redraw(g) {
  function redrawX (line 9580) | function redrawX(g) {
  function redrawY (line 9584) | function redrawY(g) {
  function brushstart (line 9588) | function brushstart() {
  function d3_time_formatIsoNative (line 9781) | function d3_time_formatIsoNative(date) {
  function d3_time_scale (line 9828) | function d3_time_scale(linear, methods, format) {
  function d3_time_scaleDate (line 9878) | function d3_time_scaleDate(t) {
  function d3_json (line 9937) | function d3_json(request) {
  function d3_html (line 9943) | function d3_html(request) {
  function _interopRequireDefault (line 9968) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
  function _toConsumableArray (line 9970) | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i ...
  function _classCallCheck (line 9972) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
  function apply (line 10522) | function apply(func, thisArg, args) {
  function arrayAggregator (line 10542) | function arrayAggregator(array, setter, iteratee, accumulator) {
  function arrayEach (line 10562) | function arrayEach(array, iteratee) {
  function arrayEachRight (line 10583) | function arrayEachRight(array, iteratee) {
  function arrayEvery (line 10604) | function arrayEvery(array, predicate) {
  function arrayFilter (line 10625) | function arrayFilter(array, predicate) {
  function arrayIncludes (line 10649) | function arrayIncludes(array, value) {
  function arrayIncludesWith (line 10663) | function arrayIncludesWith(array, value, comparator) {
  function arrayMap (line 10684) | function arrayMap(array, iteratee) {
  function arrayPush (line 10703) | function arrayPush(array, values) {
  function arrayReduce (line 10726) | function arrayReduce(array, iteratee, accumulator, initAccum) {
  function arrayReduceRight (line 10751) | function arrayReduceRight(array, iteratee, accumulator, initAccum) {
  function arraySome (line 10772) | function arraySome(array, predicate) {
  function asciiToArray (line 10800) | function asciiToArray(string) {
  function asciiWords (line 10811) | function asciiWords(string) {
  function baseFindKey (line 10826) | function baseFindKey(collection, predicate, eachFunc) {
  function baseFindIndex (line 10848) | function baseFindIndex(array, predicate, fromIndex, fromRight) {
  function baseIndexOf (line 10869) | function baseIndexOf(array, value, fromIndex) {
  function baseIndexOfWith (line 10885) | function baseIndexOfWith(array, value, fromIndex, comparator) {
  function baseIsNaN (line 10904) | function baseIsNaN(value) {
  function baseMean (line 10917) | function baseMean(array, iteratee) {
  function baseProperty (line 10929) | function baseProperty(key) {
  function basePropertyOf (line 10942) | function basePropertyOf(object) {
  function baseReduce (line 10961) | function baseReduce(collection, iteratee, accumulator, initAccum, eachFu...
  function baseSortBy (line 10980) | function baseSortBy(array, comparer) {
  function baseSum (line 10999) | function baseSum(array, iteratee) {
  function baseTimes (line 11022) | function baseTimes(n, iteratee) {
  function baseToPairs (line 11041) | function baseToPairs(object, props) {
  function baseUnary (line 11054) | function baseUnary(func) {
  function baseValues (line 11070) | function baseValues(object, props) {
  function cacheHas (line 11084) | function cacheHas(cache, key) {
  function charsStartIndex (line 11097) | function charsStartIndex(strSymbols, chrSymbols) {
  function charsEndIndex (line 11114) | function charsEndIndex(strSymbols, chrSymbols) {
  function countHolders (line 11129) | function countHolders(array, placeholder) {
  function escapeStringChar (line 11167) | function escapeStringChar(chr) {
  function getValue (line 11179) | function getValue(object, key) {
  function hasUnicode (line 11190) | function hasUnicode(string) {
  function hasUnicodeWord (line 11201) | function hasUnicodeWord(string) {
  function iteratorToArray (line 11212) | function iteratorToArray(iterator) {
  function mapToArray (line 11229) | function mapToArray(map) {
  function overArg (line 11247) | function overArg(func, transform) {
  function replaceHolders (line 11262) | function replaceHolders(array, placeholder) {
  function setToArray (line 11285) | function setToArray(set) {
  function setToPairs (line 11302) | function setToPairs(set) {
  function strictIndexOf (line 11322) | function strictIndexOf(array, value, fromIndex) {
  function strictLastIndexOf (line 11344) | function strictLastIndexOf(array, value, fromIndex) {
  function stringSize (line 11361) | function stringSize(string) {
  function stringToArray (line 11374) | function stringToArray(string) {
  function unicodeSize (line 11396) | function unicodeSize(string) {
  function unicodeToArray (line 11411) | function unicodeToArray(string) {
  function unicodeWords (line 11422) | function unicodeWords(string) {
  function lodash (line 11699) | function lodash(value) {
  function object (line 11720) | function object() {}
  function baseLodash (line 11740) | function baseLodash() {
  function LodashWrapper (line 11751) | function LodashWrapper(value, chainAll) {
  function LazyWrapper (line 11836) | function LazyWrapper(value) {
  function lazyClone (line 11854) | function lazyClone() {
  function lazyReverse (line 11873) | function lazyReverse() {
  function lazyValue (line 11893) | function lazyValue() {
  function Hash (line 11955) | function Hash(entries) {
  function hashClear (line 11973) | function hashClear() {
  function hashDelete (line 11988) | function hashDelete(key) {
  function hashGet (line 12003) | function hashGet(key) {
  function hashHas (line 12021) | function hashHas(key) {
  function hashSet (line 12036) | function hashSet(key, value) {
  function ListCache (line 12059) | function ListCache(entries) {
  function listCacheClear (line 12077) | function listCacheClear() {
  function listCacheDelete (line 12091) | function listCacheDelete(key) {
  function listCacheGet (line 12117) | function listCacheGet(key) {
  function listCacheHas (line 12133) | function listCacheHas(key) {
  function listCacheSet (line 12147) | function listCacheSet(key, value) {
  function MapCache (line 12176) | function MapCache(entries) {
  function mapCacheClear (line 12194) | function mapCacheClear() {
  function mapCacheDelete (line 12212) | function mapCacheDelete(key) {
  function mapCacheGet (line 12227) | function mapCacheGet(key) {
  function mapCacheHas (line 12240) | function mapCacheHas(key) {
  function mapCacheSet (line 12254) | function mapCacheSet(key, value) {
  function SetCache (line 12280) | function SetCache(values) {
  function setCacheAdd (line 12300) | function setCacheAdd(value) {
  function setCacheHas (line 12314) | function setCacheHas(value) {
  function Stack (line 12331) | function Stack(entries) {
  function stackClear (line 12343) | function stackClear() {
  function stackDelete (line 12357) | function stackDelete(key) {
  function stackGet (line 12374) | function stackGet(key) {
  function stackHas (line 12387) | function stackHas(key) {
  function stackSet (line 12401) | function stackSet(key, value) {
  function arrayLikeKeys (line 12434) | function arrayLikeKeys(value, inherited) {
  function arraySample (line 12468) | function arraySample(array) {
  function arraySampleSize (line 12481) | function arraySampleSize(array, n) {
  function arrayShuffle (line 12492) | function arrayShuffle(array) {
  function assignMergeValue (line 12505) | function assignMergeValue(object, key, value) {
  function assignValue (line 12522) | function assignValue(object, key, value) {
  function assocIndexOf (line 12538) | function assocIndexOf(array, key) {
  function baseAggregator (line 12559) | function baseAggregator(collection, setter, iteratee, accumulator) {
  function baseAssign (line 12575) | function baseAssign(object, source) {
  function baseAssignIn (line 12588) | function baseAssignIn(object, source) {
  function baseAssignValue (line 12601) | function baseAssignValue(object, key, value) {
  function baseAt (line 12622) | function baseAt(object, paths) {
  function baseClamp (line 12643) | function baseClamp(number, lower, upper) {
  function baseClone (line 12671) | function baseClone(value, bitmask, customizer, key, object, stack) {
  function baseConforms (line 12760) | function baseConforms(source) {
  function baseConformsTo (line 12775) | function baseConformsTo(object, source, props) {
  function baseDelay (line 12803) | function baseDelay(func, wait, args) {
  function baseDifference (line 12821) | function baseDifference(array, values, iteratee, comparator) {
  function baseEvery (line 12895) | function baseEvery(collection, predicate) {
  function baseExtremum (line 12914) | function baseExtremum(array, iteratee, comparator) {
  function baseFill (line 12943) | function baseFill(array, value, start, end) {
  function baseFilter (line 12969) | function baseFilter(collection, predicate) {
  function baseFlatten (line 12990) | function baseFlatten(array, depth, predicate, isStrict, result) {
  function baseForOwn (line 13046) | function baseForOwn(object, iteratee) {
  function baseForOwnRight (line 13058) | function baseForOwnRight(object, iteratee) {
  function baseFunctions (line 13071) | function baseFunctions(object, props) {
  function baseGet (line 13085) | function baseGet(object, path) {
  function baseGetAllKeys (line 13108) | function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  function baseGetTag (line 13120) | function baseGetTag(value) {
  function baseGt (line 13138) | function baseGt(value, other) {
  function baseHas (line 13150) | function baseHas(object, key) {
  function baseHasIn (line 13162) | function baseHasIn(object, key) {
  function baseInRange (line 13175) | function baseInRange(number, start, end) {
  function baseIntersection (line 13189) | function baseIntersection(arrays, iteratee, comparator) {
  function baseInverter (line 13253) | function baseInverter(object, setter, iteratee, accumulator) {
  function baseInvoke (line 13270) | function baseInvoke(object, path, args) {
  function baseIsArguments (line 13284) | function baseIsArguments(value) {
  function baseIsArrayBuffer (line 13295) | function baseIsArrayBuffer(value) {
  function baseIsDate (line 13306) | function baseIsDate(value) {
  function baseIsEqual (line 13324) | function baseIsEqual(value, other, bitmask, customizer, stack) {
  function baseIsEqualDeep (line 13348) | function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, ...
  function baseIsMap (line 13400) | function baseIsMap(value) {
  function baseIsMatch (line 13414) | function baseIsMatch(object, source, matchData, customizer) {
  function baseIsNative (line 13466) | function baseIsNative(value) {
  function baseIsRegExp (line 13481) | function baseIsRegExp(value) {
  function baseIsSet (line 13492) | function baseIsSet(value) {
  function baseIsTypedArray (line 13503) | function baseIsTypedArray(value) {
  function baseIteratee (line 13515) | function baseIteratee(value) {
  function baseKeys (line 13539) | function baseKeys(object) {
  function baseKeysIn (line 13559) | function baseKeysIn(object) {
  function baseLt (line 13583) | function baseLt(value, other) {
  function baseMap (line 13595) | function baseMap(collection, iteratee) {
  function baseMatches (line 13612) | function baseMatches(source) {
  function baseMatchesProperty (line 13630) | function baseMatchesProperty(path, srcValue) {
  function baseMerge (line 13653) | function baseMerge(object, source, srcIndex, customizer, stack) {
  function baseMergeDeep (line 13690) | function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customi...
  function baseNth (line 13760) | function baseNth(array, n) {
  function baseOrderBy (line 13778) | function baseOrderBy(collection, iteratees, orders) {
  function basePick (line 13803) | function basePick(object, paths) {
  function basePickBy (line 13818) | function basePickBy(object, paths, predicate) {
  function basePropertyDeep (line 13841) | function basePropertyDeep(path) {
  function basePullAll (line 13858) | function basePullAll(array, values, iteratee, comparator) {
  function basePullAt (line 13894) | function basePullAt(array, indexes) {
  function baseRandom (line 13921) | function baseRandom(lower, upper) {
  function baseRange (line 13936) | function baseRange(start, end, step, fromRight) {
  function baseRepeat (line 13956) | function baseRepeat(string, n) {
  function baseRest (line 13984) | function baseRest(func, start) {
  function baseSample (line 13995) | function baseSample(collection) {
  function baseSampleSize (line 14007) | function baseSampleSize(collection, n) {
  function baseSet (line 14022) | function baseSet(object, path, value, customizer) {
  function baseShuffle (line 14089) | function baseShuffle(collection) {
  function baseSlice (line 14102) | function baseSlice(array, start, end) {
  function baseSome (line 14132) | function baseSome(collection, predicate) {
  function baseSortedIndex (line 14154) | function baseSortedIndex(array, value, retHighest) {
  function baseSortedIndexBy (line 14188) | function baseSortedIndexBy(array, value, iteratee, retHighest) {
  function baseSortedUniq (line 14237) | function baseSortedUniq(array, iteratee) {
  function baseToNumber (line 14263) | function baseToNumber(value) {
  function baseToString (line 14281) | function baseToString(value) {
  function baseUniq (line 14306) | function baseUniq(array, iteratee, comparator) {
  function baseUnset (line 14366) | function baseUnset(object, path) {
  function baseUpdate (line 14382) | function baseUpdate(object, path, updater, customizer) {
  function baseWhile (line 14397) | function baseWhile(array, predicate, isDrop, fromRight) {
  function baseWrapperValue (line 14419) | function baseWrapperValue(value, actions) {
  function baseXor (line 14439) | function baseXor(arrays, iteratee, comparator) {
  function baseZipObject (line 14469) | function baseZipObject(props, values, assignFunc) {
  function castArrayLikeObject (line 14489) | function castArrayLikeObject(value) {
  function castFunction (line 14500) | function castFunction(value) {
  function castPath (line 14512) | function castPath(value, object) {
  function castSlice (line 14539) | function castSlice(array, start, end) {
  function cloneBuffer (line 14563) | function cloneBuffer(buffer, isDeep) {
  function cloneArrayBuffer (line 14581) | function cloneArrayBuffer(arrayBuffer) {
  function cloneDataView (line 14595) | function cloneDataView(dataView, isDeep) {
  function cloneRegExp (line 14607) | function cloneRegExp(regexp) {
  function cloneSymbol (line 14620) | function cloneSymbol(symbol) {
  function cloneTypedArray (line 14632) | function cloneTypedArray(typedArray, isDeep) {
  function compareAscending (line 14645) | function compareAscending(value, other) {
  function compareMultiple (line 14689) | function compareMultiple(object, other, orders) {
  function composeArgs (line 14727) | function composeArgs(args, partials, holders, isCurried) {
  function composeArgsRight (line 14762) | function composeArgsRight(args, partials, holders, isCurried) {
  function copyArray (line 14796) | function copyArray(source, array) {
  function copyObject (line 14817) | function copyObject(source, props, object, customizer) {
  function copySymbols (line 14851) | function copySymbols(source, object) {
  function copySymbolsIn (line 14863) | function copySymbolsIn(source, object) {
  function createAggregator (line 14875) | function createAggregator(setter, initializer) {
  function createAssigner (line 14891) | function createAssigner(assigner) {
  function createBaseEach (line 14925) | function createBaseEach(eachFunc, fromRight) {
  function createBaseFor (line 14953) | function createBaseFor(fromRight) {
  function createBind (line 14980) | function createBind(func, bitmask, thisArg) {
  function createCaseFirst (line 14998) | function createCaseFirst(methodName) {
  function createCompounder (line 15025) | function createCompounder(callback) {
  function createCtor (line 15039) | function createCtor(Ctor) {
  function createCurry (line 15073) | function createCurry(func, bitmask, arity) {
  function createFind (line 15108) | function createFind(findIndexFunc) {
  function createFlow (line 15128) | function createFlow(fromRight) {
  function createHybrid (line 15201) | function createHybrid(func, bitmask, thisArg, partials, holders, partial...
  function createInverter (line 15263) | function createInverter(setter, toIteratee) {
  function createMathOperation (line 15277) | function createMathOperation(operator, defaultValue) {
  function createOver (line 15310) | function createOver(arrayFunc) {
  function createPadding (line 15331) | function createPadding(length, chars) {
  function createPartial (line 15356) | function createPartial(func, bitmask, thisArg, partials) {
  function createRange (line 15386) | function createRange(fromRight) {
  function createRelationalOperation (line 15411) | function createRelationalOperation(operator) {
  function createRecurry (line 15438) | function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, pa...
  function createRound (line 15471) | function createRound(methodName) {
  function createToPairs (line 15507) | function createToPairs(keysFunc) {
  function createWrap (line 15545) | function createWrap(func, bitmask, thisArg, partials, holders, argPos, a...
  function customDefaultsAssignIn (line 15612) | function customDefaultsAssignIn(objValue, srcValue, key, object) {
  function customDefaultsMerge (line 15634) | function customDefaultsMerge(objValue, srcValue, key, object, source, st...
  function customOmitClone (line 15653) | function customOmitClone(value) {
  function equalArrays (line 15670) | function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
  function equalByTag (line 15748) | function equalByTag(object, other, tag, bitmask, customizer, equalFunc, ...
  function equalObjects (line 15826) | function equalObjects(object, other, bitmask, customizer, equalFunc, sta...
  function flatRest (line 15897) | function flatRest(func) {
  function getAllKeys (line 15908) | function getAllKeys(object) {
  function getAllKeysIn (line 15920) | function getAllKeysIn(object) {
  function getFuncName (line 15942) | function getFuncName(func) {
  function getHolder (line 15964) | function getHolder(func) {
  function getIteratee (line 15980) | function getIteratee() {
  function getMapData (line 15994) | function getMapData(map, key) {
  function getMatchData (line 16008) | function getMatchData(object) {
  function getNative (line 16029) | function getNative(object, key) {
  function getRawTag (line 16041) | function getRawTag(value) {
  function getView (line 16137) | function getView(start, end, transforms) {
  function getWrapDetails (line 16162) | function getWrapDetails(source) {
  function hasPath (line 16176) | function hasPath(object, path, hasFunc) {
  function initCloneArray (line 16205) | function initCloneArray(array) {
  function initCloneObject (line 16224) | function initCloneObject(object) {
  function initCloneByTag (line 16242) | function initCloneByTag(object, tag, isDeep) {
  function insertWrapDetails (line 16286) | function insertWrapDetails(source, details) {
  function isFlattenable (line 16304) | function isFlattenable(value) {
  function isIndex (line 16317) | function isIndex(value, length) {
  function isIterateeCall (line 16337) | function isIterateeCall(value, index, object) {
  function isKey (line 16359) | function isKey(value, object) {
  function isKeyable (line 16379) | function isKeyable(value) {
  function isLaziable (line 16394) | function isLaziable(func) {
  function isMasked (line 16415) | function isMasked(func) {
  function isPrototype (line 16435) | function isPrototype(value) {
  function isStrictComparable (line 16450) | function isStrictComparable(value) {
  function matchesStrictComparable (line 16463) | function matchesStrictComparable(key, srcValue) {
  function memoizeCapped (line 16481) | function memoizeCapped(func) {
  function mergeData (line 16509) | function mergeData(data, source) {
  function nativeKeysIn (line 16573) | function nativeKeysIn(object) {
  function objectToString (line 16590) | function objectToString(value) {
  function overRest (line 16603) | function overRest(func, start, transform) {
  function parent (line 16632) | function parent(object, path) {
  function reorder (line 16646) | function reorder(array, indexes) {
  function safeGet (line 16666) | function safeGet(object, key) {
  function setWrapToString (line 16722) | function setWrapToString(wrapper, reference, bitmask) {
  function shortOut (line 16736) | function shortOut(func) {
  function shuffleSelf (line 16764) | function shuffleSelf(array, size) {
  function toKey (line 16806) | function toKey(value) {
  function toSource (line 16821) | function toSource(func) {
  function updateWrapDetails (line 16841) | function updateWrapDetails(details, bitmask) {
  function wrapperClone (line 16858) | function wrapperClone(wrapper) {
  function chunk (line 16892) | function chunk(array, size, guard) {
  function compact (line 16927) | function compact(array) {
  function concat (line 16964) | function concat() {
  function drop (line 17100) | function drop(array, n, guard) {
  function dropRight (line 17134) | function dropRight(array, n, guard) {
  function dropRightWhile (line 17179) | function dropRightWhile(array, predicate) {
  function dropWhile (line 17220) | function dropWhile(array, predicate) {
  function fill (line 17255) | function fill(array, value, start, end) {
  function findIndex (line 17302) | function findIndex(array, predicate, fromIndex) {
  function findLastIndex (line 17349) | function findLastIndex(array, predicate, fromIndex) {
  function flatten (line 17378) | function flatten(array) {
  function flattenDeep (line 17397) | function flattenDeep(array) {
  function flattenDepth (line 17422) | function flattenDepth(array, depth) {
  function fromPairs (line 17446) | function fromPairs(pairs) {
  function head (line 17476) | function head(array) {
  function indexOf (line 17503) | function indexOf(array, value, fromIndex) {
  function initial (line 17529) | function initial(array) {
  function join (line 17644) | function join(array, separator) {
  function last (line 17662) | function last(array) {
  function lastIndexOf (line 17688) | function lastIndexOf(array, value, fromIndex) {
  function nth (line 17724) | function nth(array, n) {
  function pullAll (line 17773) | function pullAll(array, values) {
  function pullAllBy (line 17802) | function pullAllBy(array, values, iteratee) {
  function pullAllWith (line 17831) | function pullAllWith(array, values, comparator) {
  function remove (line 17900) | function remove(array, predicate) {
  function reverse (line 17944) | function reverse(array) {
  function slice (line 17964) | function slice(array, start, end) {
  function sortedIndex (line 17997) | function sortedIndex(array, value) {
  function sortedIndexBy (line 18026) | function sortedIndexBy(array, value, iteratee) {
  function sortedIndexOf (line 18046) | function sortedIndexOf(array, value) {
  function sortedLastIndex (line 18075) | function sortedLastIndex(array, value) {
  function sortedLastIndexBy (line 18104) | function sortedLastIndexBy(array, value, iteratee) {
  function sortedLastIndexOf (line 18124) | function sortedLastIndexOf(array, value) {
  function sortedUniq (line 18150) | function sortedUniq(array) {
  function sortedUniqBy (line 18172) | function sortedUniqBy(array, iteratee) {
  function tail (line 18192) | function tail(array) {
  function take (line 18222) | function take(array, n, guard) {
  function takeRight (line 18255) | function takeRight(array, n, guard) {
  function takeRightWhile (line 18300) | function takeRightWhile(array, predicate) {
  function takeWhile (line 18341) | function takeWhile(array, predicate) {
  function uniq (line 18443) | function uniq(array) {
  function uniqBy (line 18470) | function uniqBy(array, iteratee) {
  function uniqWith (line 18494) | function uniqWith(array, comparator) {
  function unzip (line 18518) | function unzip(array) {
  function unzipWith (line 18555) | function unzipWith(array, iteratee) {
  function zipObject (line 18708) | function zipObject(props, values) {
  function zipObjectDeep (line 18727) | function zipObjectDeep(props, values) {
  function chain (line 18790) | function chain(value) {
  function tap (line 18819) | function tap(value, interceptor) {
  function thru (line 18847) | function thru(value, interceptor) {
  function wrapperChain (line 18918) | function wrapperChain() {
  function wrapperCommit (line 18948) | function wrapperCommit() {
  function wrapperNext (line 18974) | function wrapperNext() {
  function wrapperToIterator (line 19002) | function wrapperToIterator() {
  function wrapperPlant (line 19030) | function wrapperPlant(value) {
  function wrapperReverse (line 19070) | function wrapperReverse() {
  function wrapperValue (line 19102) | function wrapperValue() {
  function every (line 19179) | function every(collection, predicate, guard) {
  function filter (line 19224) | function filter(collection, predicate) {
  function flatMap (line 19309) | function flatMap(collection, iteratee) {
  function flatMapDeep (line 19333) | function flatMapDeep(collection, iteratee) {
  function flatMapDepth (line 19358) | function flatMapDepth(collection, iteratee, depth) {
  function forEach (line 19393) | function forEach(collection, iteratee) {
  function forEachRight (line 19418) | function forEachRight(collection, iteratee) {
  function includes (line 19484) | function includes(collection, value, fromIndex, guard) {
  function map (line 19605) | function map(collection, iteratee) {
  function orderBy (line 19639) | function orderBy(collection, iteratees, orders, guard) {
  function reduce (line 19730) | function reduce(collection, iteratee, accumulator) {
  function reduceRight (line 19759) | function reduceRight(collection, iteratee, accumulator) {
  function reject (line 19800) | function reject(collection, predicate) {
  function sample (line 19819) | function sample(collection) {
  function sampleSize (line 19844) | function sampleSize(collection, n, guard) {
  function shuffle (line 19869) | function shuffle(collection) {
  function size (line 19895) | function size(collection) {
  function some (line 19945) | function some(collection, predicate, guard) {
  function after (line 20043) | function after(n, func) {
  function ary (line 20072) | function ary(func, n, guard) {
  function before (line 20095) | function before(n, func) {
  function curry (line 20251) | function curry(func, arity, guard) {
  function curryRight (line 20296) | function curryRight(func, arity, guard) {
  function debounce (line 20357) | function debounce(func, wait, options) {
  function flip (line 20544) | function flip(func) {
  function memoize (line 20592) | function memoize(func, resolver) {
  function negate (line 20635) | function negate(predicate) {
  function once (line 20669) | function once(func) {
  function rest (line 20847) | function rest(func, start) {
  function spread (line 20889) | function spread(func, start) {
  function throttle (line 20949) | function throttle(func, wait, options) {
  function unary (line 20982) | function unary(func) {
  function wrap (line 21008) | function wrap(value, wrapper) {
  function castArray (line 21047) | function castArray() {
  function clone (line 21081) | function clone(value) {
  function cloneWith (line 21116) | function cloneWith(value, customizer) {
  function cloneDeep (line 21139) | function cloneDeep(value) {
  function cloneDeepWith (line 21171) | function cloneDeepWith(value, customizer) {
  function conformsTo (line 21200) | function conformsTo(object, source) {
  function eq (line 21236) | function eq(value, other) {
  function isArrayLike (line 21384) | function isArrayLike(value) {
  function isArrayLikeObject (line 21413) | function isArrayLikeObject(value) {
  function isBoolean (line 21434) | function isBoolean(value) {
  function isElement (line 21494) | function isElement(value) {
  function isEmpty (line 21531) | function isEmpty(value) {
  function isEqual (line 21583) | function isEqual(value, other) {
  function isEqualWith (line 21619) | function isEqualWith(value, other, customizer) {
  function isError (line 21643) | function isError(value) {
  function isFinite (line 21678) | function isFinite(value) {
  function isFunction (line 21699) | function isFunction(value) {
  function isInteger (line 21735) | function isInteger(value) {
  function isLength (line 21765) | function isLength(value) {
  function isObject (line 21795) | function isObject(value) {
  function isObjectLike (line 21824) | function isObjectLike(value) {
  function isMatch (line 21875) | function isMatch(object, source) {
  function isMatchWith (line 21911) | function isMatchWith(object, source, customizer) {
  function isNaN (line 21944) | function isNaN(value) {
  function isNative (line 21977) | function isNative(value) {
  function isNull (line 22001) | function isNull(value) {
  function isNil (line 22025) | function isNil(value) {
  function isNumber (line 22055) | function isNumber(value) {
  function isPlainObject (line 22088) | function isPlainObject(value) {
  function isSafeInteger (line 22147) | function isSafeInteger(value) {
  function isString (line 22187) | function isString(value) {
  function isSymbol (line 22209) | function isSymbol(value) {
  function isUndefined (line 22250) | function isUndefined(value) {
  function isWeakMap (line 22271) | function isWeakMap(value) {
  function isWeakSet (line 22292) | function isWeakSet(value) {
  function toArray (line 22371) | function toArray(value) {
  function toFinite (line 22410) | function toFinite(value) {
  function toInteger (line 22448) | function toInteger(value) {
  function toLength (line 22482) | function toLength(value) {
  function toNumber (line 22509) | function toNumber(value) {
  function toPlainObject (line 22554) | function toPlainObject(value) {
  function toSafeInteger (line 22582) | function toSafeInteger(value) {
  function toString (line 22609) | function toString(value) {
  function create (line 22812) | function create(prototype, properties) {
  function findKey (line 22928) | function findKey(object, predicate) {
  function findLastKey (line 22967) | function findLastKey(object, predicate) {
  function forIn (line 22999) | function forIn(object, iteratee) {
  function forInRight (line 23031) | function forInRight(object, iteratee) {
  function forOwn (line 23065) | function forOwn(object, iteratee) {
  function forOwnRight (line 23095) | function forOwnRight(object, iteratee) {
  function functions (line 23122) | function functions(object) {
  function functionsIn (line 23149) | function functionsIn(object) {
  function get (line 23178) | function get(object, path, defaultValue) {
  function has (line 23210) | function has(object, path) {
  function hasIn (line 23240) | function hasIn(object, path) {
  function keys (line 23358) | function keys(object) {
  function keysIn (line 23385) | function keysIn(object) {
  function mapKeys (line 23410) | function mapKeys(object, iteratee) {
  function mapValues (line 23448) | function mapValues(object, iteratee) {
  function omitBy (line 23590) | function omitBy(object, predicate) {
  function pickBy (line 23633) | function pickBy(object, predicate) {
  function result (line 23675) | function result(object, path, defaultValue) {
  function set (line 23725) | function set(object, path, value) {
  function setWith (line 23753) | function setWith(object, path, value, customizer) {
  function transform (line 23840) | function transform(object, iteratee, accumulator) {
  function unset (line 23890) | function unset(object, path) {
  function update (line 23921) | function update(object, path, updater) {
  function updateWith (line 23949) | function updateWith(object, path, updater, customizer) {
  function values (line 23980) | function values(object) {
  function valuesIn (line 24008) | function valuesIn(object) {
  function clamp (line 24033) | function clamp(number, lower, upper) {
  function inRange (line 24087) | function inRange(number, start, end) {
  function random (line 24130) | function random(lower, upper, floating) {
  function capitalize (line 24211) | function capitalize(string) {
  function deburr (line 24233) | function deburr(string) {
  function endsWith (line 24261) | function endsWith(string, target, position) {
  function escape (line 24303) | function escape(string) {
  function escapeRegExp (line 24325) | function escapeRegExp(string) {
  function pad (line 24423) | function pad(string, length, chars) {
  function padEnd (line 24462) | function padEnd(string, length, chars) {
  function padStart (line 24495) | function padStart(string, length, chars) {
  function parseInt (line 24529) | function parseInt(string, radix, guard) {
  function repeat (line 24560) | function repeat(string, n, guard) {
  function replace (line 24588) | function replace() {
  function split (line 24639) | function split(string, separator, limit) {
  function startsWith (line 24708) | function startsWith(string, target, position) {
  function template (line 24822) | function template(string, options, guard) {
  function toLower (line 24951) | function toLower(value) {
  function toUpper (line 24976) | function toUpper(value) {
  function trim (line 25002) | function trim(string, chars, guard) {
  function trimEnd (line 25037) | function trimEnd(string, chars, guard) {
  function trimStart (line 25070) | function trimStart(string, chars, guard) {
  function truncate (line 25121) | function truncate(string, options) {
  function unescape (line 25196) | function unescape(string) {
  function words (line 25265) | function words(string, pattern, guard) {
  function cond (line 25370) | function cond(pairs) {
  function conforms (line 25416) | function conforms(source) {
  function constant (line 25439) | function constant(value) {
  function defaultTo (line 25465) | function defaultTo(value, defaultValue) {
  function identity (line 25532) | function identity(value) {
  function iteratee (line 25578) | function iteratee(func) {
  function matches (line 25610) | function matches(source) {
  function matchesProperty (line 25640) | function matchesProperty(path, srcValue) {
  function mixin (line 25739) | function mixin(object, source, options) {
  function noConflict (line 25788) | function noConflict() {
  function noop (line 25807) | function noop() {
  function nthArg (line 25831) | function nthArg(n) {
  function property (line 25932) | function property(path) {
  function propertyOf (line 25957) | function propertyOf(object) {
  function stubArray (line 26062) | function stubArray() {
  function stubFalse (line 26079) | function stubFalse() {
  function stubObject (line 26101) | function stubObject() {
  function stubString (line 26118) | function stubString() {
  function stubTrue (line 26135) | function stubTrue() {
  function times (line 26158) | function times(n, iteratee) {
  function toPath (line 26193) | function toPath(value) {
  function uniqueId (line 26217) | function uniqueId(prefix) {
  function max (line 26326) | function max(array) {
  function maxBy (line 26355) | function maxBy(array, iteratee) {
  function mean (line 26375) | function mean(array) {
  function meanBy (line 26402) | function meanBy(array, iteratee) {
  function min (line 26424) | function min(array) {
  function minBy (line 26453) | function minBy(array, iteratee) {
  function sum (line 26534) | function sum(array) {
  function sumBy (line 26563) | function sumBy(array, iteratee) {
  function sliceIterator (line 27188) | function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = ...
  function _interopRequireDefault (line 27196) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
  function _classCallCheck (line 27198) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
  function PredictProba (line 27204) | function PredictProba(svg, class_names, predict_probas) {
  function _interopRequireDefault (line 27366) | function _interopRequireDefault(obj) { return obj && obj.__esModule ? ob...
  function _classCallCheck (line 27368) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
  function define (line 27485) | function define(O, key, value) {
  function asinh (line 29723) | function asinh(x) {
  function F (line 30843) | function F() { /* empty */ }
  function getSubstitution (line 31906) | function getSubstitution(matched, str, position, captures, namedCaptures...
  function PromiseCapability (line 32640) | function PromiseCapability(C) {
  function packIEEE754 (line 33313) | function packIEEE754(value, mLen, nBytes) {
  function unpackIEEE754 (line 33361) | function unpackIEEE754(buffer, mLen, nBytes) {
  function unpackI32 (line 33386) | function unpackI32(bytes) {
  function packI8 (line 33389) | function packI8(it) {
  function packI16 (line 33392) | function packI16(it) {
  function packI32 (line 33395) | function packI32(it) {
  function packF64 (line 33398) | function packF64(it) {
  function packF32 (line 33401) | function packF32(it) {
  function addGetter (line 33405) | function addGetter(C, key, internal) {
  function get (line 33409) | function get(view, bytes, index, isLittleEndian) {
  function set (line 33418) | function set(view, bytes, index, conversion, value, isLittleEndian) {
  function F (line 34200) | function F() { /* empty */ }
  function get (line 34326) | function get(target, propertyKey /* , receiver */) {
  function set (line 34466) | function set(target, propertyKey, V /* , receiver */) {
  function flattenIntoArray (line 34570) | function flattenIntoArray(target, original, source, sourceLen, start, de...
  function wrap (line 36005) | function wrap(innerFn, outerFn, self, tryLocsList) {
  function tryCatch (line 36029) | function tryCatch(fn, obj, arg) {
  function Generator (line 36050) | function Generator() {}
  function GeneratorFunction (line 36051) | function GeneratorFunction() {}
  function GeneratorFunctionPrototype (line 36052) | function GeneratorFunctionPrototype() {}
  function defineIteratorMethods (line 36080) | function defineIteratorMethods(prototype) {
  function AsyncIterator (line 36119) | function AsyncIterator(generator) {
  function makeInvokeMethod (line 36219) | function makeInvokeMethod(innerFn, self, context) {
  function maybeInvokeDelegate (line 36301) | function maybeInvokeDelegate(delegate, context) {
  function pushTryEntry (line 36398) | function pushTryEntry(locs) {
  function resetTryEntry (line 36413) | function resetTryEntry(entry) {
  function Context (line 36420) | function Context(tryLocsList) {
  function values (line 36456) | function values(iterable) {
  function doneResult (line 36492) | function doneResult() {
  function handle (line 36543) | function handle(loc, caught) {
  function addStylesToDom (line 36900) | function addStylesToDom(styles, options) {
  function listToStyles (line 36922) | function listToStyles(list) {
  function insertStyleElement (line 36940) | function insertStyleElement(options, styleElement) {
  function removeStyleElement (line 36959) | function removeStyleElement(styleElement) {
  function createStyleElement (line 36967) | function createStyleElement(options) {
  function createLinkElement (line 36974) | function createLinkElement(options) {
  function addStyle (line 36981) | function addStyle(obj, options) {
  function applyToSingletonTag (line 37032) | function applyToSingletonTag(styleElement, index, remove, obj) {
  function applyToTag (line 37049) | function applyToTag(styleElement, obj) {
  function updateLink (line 37067) | function updateLink(linkElement, obj) {

FILE: lime/discretize.py
  class BaseDiscretizer (line 12) | class BaseDiscretizer():
    method __init__ (line 22) | def __init__(self, data, categorical_features, feature_names, labels=N...
    method bins (line 92) | def bins(self, data, labels):
    method discretize (line 100) | def discretize(self, data):
    method get_undiscretize_values (line 116) | def get_undiscretize_values(self, feature, values):
    method undiscretize (line 136) | def undiscretize(self, data):
  class StatsDiscretizer (line 150) | class StatsDiscretizer(BaseDiscretizer):
    method __init__ (line 155) | def __init__(self, data, categorical_features, feature_names, labels=N...
    method bins (line 163) | def bins(self, data, labels):
  class QuartileDiscretizer (line 175) | class QuartileDiscretizer(BaseDiscretizer):
    method __init__ (line 176) | def __init__(self, data, categorical_features, feature_names, labels=N...
    method bins (line 182) | def bins(self, data, labels):
  class DecileDiscretizer (line 190) | class DecileDiscretizer(BaseDiscretizer):
    method __init__ (line 191) | def __init__(self, data, categorical_features, feature_names, labels=N...
    method bins (line 196) | def bins(self, data, labels):
  class EntropyDiscretizer (line 205) | class EntropyDiscretizer(BaseDiscretizer):
    method __init__ (line 206) | def __init__(self, data, categorical_features, feature_names, labels=N...
    method bins (line 214) | def bins(self, data, labels):

FILE: lime/exceptions.py
  class LimeError (line 1) | class LimeError(Exception):

FILE: lime/explanation.py
  function id_generator (line 16) | def id_generator(size=15, random_state=None):
  class DomainMapper (line 23) | class DomainMapper(object):
    method __init__ (line 31) | def __init__(self):
    method map_exp_ids (line 34) | def map_exp_ids(self, exp, **kwargs):
    method visualize_instance_html (line 49) | def visualize_instance_html(self,
  class Explanation (line 73) | class Explanation(object):
    method __init__ (line 76) | def __init__(self,
    method available_labels (line 115) | def available_labels(self):
    method as_list (line 127) | def as_list(self, label=1, **kwargs):
    method as_map (line 145) | def as_map(self):
    method as_pyplot_figure (line 153) | def as_pyplot_figure(self, label=1, figsize=(4,4), **kwargs):
    method show_in_notebook (line 185) | def show_in_notebook(self,
    method save_to_file (line 201) | def save_to_file(self,
    method as_html (line 222) | def as_html(self,

FILE: lime/js/bar_chart.js
  class Barchart (line 2) | class Barchart {
    method constructor (line 5) | constructor(svg, exp_array,  two_sided=true, titles=undefined, colors=...

FILE: lime/js/explanation.js
  class Explanation (line 4) | class Explanation {
    method constructor (line 5) | constructor(class_names) {
    method show (line 19) | show(exp, label, div) {
    method show_raw_text (line 32) | show_raw_text(exp, label, raw, div, opacity=true) {
    method show_raw_tabular (line 55) | show_raw_tabular(exp, label, div) {
    method hexToRgb (line 83) | hexToRgb(hex) {
    method applyAlpha (line 91) | applyAlpha(hex, alpha) {
    method display_raw_text (line 97) | display_raw_text(div, raw_text, word_lists=[], colors=[], max_weight=1...
    method wordlists_to_positions (line 127) | wordlists_to_positions(word_lists, raw_text) {

FILE: lime/js/predict_proba.js
  class PredictProba (line 4) | class PredictProba {
    method constructor (line 8) | constructor(svg, class_names, predict_probas, title='Prediction probab...
    method map_classes (line 85) | map_classes(class_names, predict_proba) {

FILE: lime/js/predicted_value.js
  class PredictedValue (line 4) | class PredictedValue {
    method constructor (line 8) | constructor(svg, predicted_value, min_value, max_value, title='Predict...

FILE: lime/lime_base.py
  class LimeBase (line 10) | class LimeBase(object):
    method __init__ (line 12) | def __init__(self,
    method generate_lars_path (line 31) | def generate_lars_path(weighted_data, weighted_labels):
    method forward_selection (line 49) | def forward_selection(self, data, labels, weights, num_features):
    method feature_selection (line 70) | def feature_selection(self, data, labels, weights, num_features, method):
    method explain_instance_with_data (line 137) | def explain_instance_with_data(self,

FILE: lime/lime_image.py
  class ImageExplanation (line 18) | class ImageExplanation(object):
    method __init__ (line 19) | def __init__(self, image, segments):
    method get_image_and_mask (line 33) | def get_image_and_mask(self, label, positive_only=True, negative_only=...
  class LimeImageExplainer (line 89) | class LimeImageExplainer(object):
    method __init__ (line 98) | def __init__(self, kernel_width=.25, kernel=None, verbose=False,
    method explain_instance (line 129) | def explain_instance(self, image, classifier_fn, labels=(1,),
    method data_labels (line 224) | def data_labels(self,

FILE: lime/lime_tabular.py
  class TableDomainMapper (line 27) | class TableDomainMapper(explanation.DomainMapper):
    method __init__ (line 30) | def __init__(self, feature_names, feature_values, scaled_row,
    method map_exp_ids (line 54) | def map_exp_ids(self, exp):
    method visualize_instance_html (line 68) | def visualize_instance_html(self,
  class LimeTabularExplainer (line 117) | class LimeTabularExplainer(object):
    method __init__ (line 126) | def __init__(self,
    method convert_and_round (line 285) | def convert_and_round(values):
    method validate_training_data_stats (line 289) | def validate_training_data_stats(training_data_stats):
    method explain_instance (line 299) | def explain_instance(self,
    method __data_inverse (line 475) | def __data_inverse(self,
  class RecurrentTabularExplainer (line 581) | class RecurrentTabularExplainer(LimeTabularExplainer):
    method __init__ (line 596) | def __init__(self, training_data, mode="classification",
    method _make_predict_proba (line 670) | def _make_predict_proba(self, func):
    method explain_instance (line 686) | def explain_instance(self, data_row, classifier_fn, labels=(1,),

FILE: lime/lime_text.py
  class TextDomainMapper (line 18) | class TextDomainMapper(explanation.DomainMapper):
    method __init__ (line 21) | def __init__(self, indexed_string):
    method map_exp_ids (line 29) | def map_exp_ids(self, exp, positions=False):
    method visualize_instance_html (line 51) | def visualize_instance_html(self, exp, label, div_name, exp_object_name,
  class IndexedString (line 81) | class IndexedString(object):
    method __init__ (line 84) | def __init__(self, raw_string, split_expression=r'\W+', bow=True,
    method raw_string (line 144) | def raw_string(self):
    method num_words (line 148) | def num_words(self):
    method word (line 152) | def word(self, id_):
    method string_position (line 156) | def string_position(self, id_):
    method inverse_removing (line 163) | def inverse_removing(self, words_to_remove):
    method _segment_with_tokens (line 184) | def _segment_with_tokens(text, tokens):
    method __get_idxs (line 203) | def __get_idxs(self, words):
  class IndexedCharacters (line 212) | class IndexedCharacters(object):
    method __init__ (line 215) | def __init__(self, raw_string, bow=True, mask_string=None):
    method raw_string (line 253) | def raw_string(self):
    method num_words (line 257) | def num_words(self):
    method word (line 261) | def word(self, id_):
    method string_position (line 265) | def string_position(self, id_):
    method inverse_removing (line 272) | def inverse_removing(self, words_to_remove):
    method __get_idxs (line 292) | def __get_idxs(self, words):
  class LimeTextExplainer (line 301) | class LimeTextExplainer(object):
    method __init__ (line 306) | def __init__(self,
    method explain_instance (line 368) | def explain_instance(self,
    method __data_labels_distances (line 436) | def __data_labels_distances(self,

FILE: lime/submodular_pick.py
  class SubmodularPick (line 5) | class SubmodularPick(object):
    method __init__ (line 15) | def __init__(self,

FILE: lime/tests/test_discretize.py
  class TestDiscretize (line 11) | class TestDiscretize(TestCase):
    method setUp (line 13) | def setUp(self):
    method check_random_state_for_discretizer_class (line 20) | def check_random_state_for_discretizer_class(self, DiscretizerClass):
    method test_random_state (line 69) | def test_random_state(self):
    method test_feature_names_1 (line 76) | def test_feature_names_1(self):
    method test_feature_names_2 (line 99) | def test_feature_names_2(self):
    method test_feature_names_3 (line 144) | def test_feature_names_3(self):

FILE: lime/tests/test_generic_utils.py
  class TestGenericUtils (line 6) | class TestGenericUtils(unittest.TestCase):
    method test_has_arg (line 8) | def test_has_arg(self):

FILE: lime/tests/test_lime_tabular.py
  class TestLimeTabular (line 25) | class TestLimeTabular(unittest.TestCase):
    method setUp (line 27) | def setUp(self):
    method test_lime_explainer_good_regressor (line 38) | def test_lime_explainer_good_regressor(self):
    method test_lime_explainer_good_regressor_synthetic_data (line 64) | def test_lime_explainer_good_regressor_synthetic_data(self):
    method test_lime_explainer_sparse_synthetic_data (line 84) | def test_lime_explainer_sparse_synthetic_data(self):
    method test_lime_explainer_no_regressor (line 104) | def test_lime_explainer_no_regressor(self):
    method test_lime_explainer_entropy_discretizer (line 128) | def test_lime_explainer_entropy_discretizer(self):
    method test_lime_tabular_explainer_equal_random_state (line 155) | def test_lime_tabular_explainer_equal_random_state(self):
    method test_lime_tabular_explainer_not_equal_random_state (line 242) | def test_lime_tabular_explainer_not_equal_random_state(self):
    method testFeatureNamesAndCategoricalFeats (line 542) | def testFeatureNamesAndCategoricalFeats(self):
    method testFeatureValues (line 562) | def testFeatureValues(self):
    method test_lime_explainer_with_data_stats (line 583) | def test_lime_explainer_with_data_stats(self):

FILE: lime/tests/test_lime_text.py
  class TestLimeText (line 17) | class TestLimeText(unittest.TestCase):
    method test_lime_text_explainer_good_regressor (line 19) | def test_lime_text_explainer_good_regressor(self):
    method test_lime_text_tabular_equal_random_state (line 41) | def test_lime_text_tabular_equal_random_state(self):
    method test_lime_text_tabular_not_equal_random_state (line 67) | def test_lime_text_tabular_not_equal_random_state(self):
    method test_indexed_characters_bow (line 95) | def test_indexed_characters_bow(self):
    method test_indexed_characters_not_bow (line 108) | def test_indexed_characters_not_bow(self):
    method test_indexed_string_regex (line 118) | def test_indexed_string_regex(self):
    method test_indexed_string_callable (line 132) | def test_indexed_string_callable(self):
    method test_indexed_string_inverse_removing_tokenizer (line 149) | def test_indexed_string_inverse_removing_tokenizer(self):
    method test_indexed_string_inverse_removing_regex (line 159) | def test_indexed_string_inverse_removing_regex(self):

FILE: lime/tests/test_scikit_image.py
  class TestBaseWrapper (line 10) | class TestBaseWrapper(unittest.TestCase):
    method test_base_wrapper (line 12) | def test_base_wrapper(self):
    method test__check_params (line 25) | def test__check_params(self):
    method test_set_params (line 65) | def test_set_params(self):
    method test_filter_params (line 89) | def test_filter_params(self):
  class TestSegmentationAlgorithm (line 105) | class TestSegmentationAlgorithm(unittest.TestCase):
    method test_instanciate_segmentation_algorithm (line 107) | def test_instanciate_segmentation_algorithm(self):
    method test_instanciate_slic (line 120) | def test_instanciate_slic(self):
    method test_instanciate_felzenszwalb (line 123) | def test_instanciate_felzenszwalb(self):

FILE: lime/utils/generic_utils.py
  function has_arg (line 6) | def has_arg(fn, arg_name):

FILE: lime/wrappers/scikit_image.py
  class BaseWrapper (line 6) | class BaseWrapper(object):
    method __init__ (line 19) | def __init__(self, target_fn=None, **target_params):
    method _check_params (line 23) | def _check_params(self, parameters):
    method set_params (line 57) | def set_params(self, **params):
    method filter_params (line 69) | def filter_params(self, fn, override=None):
  class SegmentationAlgorithm (line 87) | class SegmentationAlgorithm(BaseWrapper):
    method __init__ (line 98) | def __init__(self, algo_type, **target_params):
    method __call__ (line 113) | def __call__(self, *args):
Copy disabled (too large) Download .json
Condensed preview — 63 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (44,795K chars).
[
  {
    "path": ".gitignore",
    "chars": 1364,
    "preview": "# Compiled python modules.\n*.pyc\n\n# Setuptools distribution folder.\n/dist/\n\n/lime/node_modules\n\n# Python egg metadata, r"
  },
  {
    "path": ".travis.yml",
    "chars": 256,
    "preview": "dist: xenial\nsudo: false\nlanguage: python\ncache: pip\npython:\n  - \"3.6\"\n  - \"3.7\"\n# command to install dependencies\ninsta"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1867,
    "preview": "## Contributing\nI am delighted when people want to contribute to LIME. Here are a few things to keep in mind before send"
  },
  {
    "path": "LICENSE",
    "chars": 1310,
    "preview": "Copyright (c) 2016, Marco Tulio Correia Ribeiro\nAll rights reserved.\n\nRedistribution and use in source and binary forms,"
  },
  {
    "path": "MANIFEST.in",
    "chars": 34,
    "preview": "include lime/*.js\ninclude LICENSE\n"
  },
  {
    "path": "README.md",
    "chars": 5770,
    "preview": "# lime\n\n[![Build Status](https://travis-ci.org/marcotcr/lime.svg?branch=master)](https://travis-ci.org/marcotcr/lime)\n[!"
  },
  {
    "path": "benchmark/__init__.py",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "benchmark/table_perf.py",
    "chars": 1194,
    "preview": "\"\"\"\nA helper script for evaluating performance of changes to the tabular explainer, in this case different\nimplementatio"
  },
  {
    "path": "benchmark/text_perf.py",
    "chars": 1484,
    "preview": "import time\nimport sklearn\nimport sklearn.ensemble\nimport sklearn.metrics\nfrom sklearn.datasets import fetch_20newsgroup"
  },
  {
    "path": "binder/environment.yml",
    "chars": 386,
    "preview": "\nname: lime-dev\nchannels:\n  - conda-forge\ndependencies:\n  - python=3.7.*\n  # lime install dependencies\n  - matplotlib\n  "
  },
  {
    "path": "citation.bib",
    "chars": 462,
    "preview": "@inproceedings{lime,\n  author    = {Marco Tulio Ribeiro and\n               Sameer Singh and\n               Carlos Guestr"
  },
  {
    "path": "doc/blog_post.md",
    "chars": 9545,
    "preview": "# LIME - Local Interpretable Model-Agnostic Explanations\r\nIn this post, we'll talk about the method for explaining the p"
  },
  {
    "path": "doc/conf.py",
    "chars": 10195,
    "preview": "# -*- coding: utf-8 -*-\n#\n# lime documentation build configuration file, created by\n# sphinx-quickstart on Fri Mar 18 16"
  },
  {
    "path": "doc/index.rst",
    "chars": 672,
    "preview": ".. lime documentation master file, created by\n   sphinx-quickstart on Fri Mar 18 16:20:40 2016.\n   You can adapt this fi"
  },
  {
    "path": "doc/lime.rst",
    "chars": 1352,
    "preview": "lime package\n============\n\nSubpackages\n-----------\n\n.. toctree::\n\n    lime.tests\n\nSubmodules\n----------\n\nlime\\.discretiz"
  },
  {
    "path": "doc/notebooks/Latin Hypercube Sampling.ipynb",
    "chars": 3516831,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Latin Hypercube Sampling \\n\",\n   "
  },
  {
    "path": "doc/notebooks/Lime - basic usage, two class case.ipynb",
    "chars": 2562813,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n "
  },
  {
    "path": "doc/notebooks/Lime - multiclass.ipynb",
    "chars": 5103507,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n "
  },
  {
    "path": "doc/notebooks/Lime with Recurrent Neural Networks.ipynb",
    "chars": 1837724,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# This network demonstrates how to "
  },
  {
    "path": "doc/notebooks/Submodular Pick examples.ipynb",
    "chars": 114229,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# SP LIME\\n\",\n    \"\\n\",\n    \"## Reg"
  },
  {
    "path": "doc/notebooks/Tutorial - Faces and GradBoost.ipynb",
    "chars": 1098893,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Overview\\n\",\n    \"The notebook sh"
  },
  {
    "path": "doc/notebooks/Tutorial - Image Classification Keras.ipynb",
    "chars": 930958,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"colab_type\": \"text\",\n    \"id\": \"LgSzX-nVxwkV\"\n   },\n"
  },
  {
    "path": "doc/notebooks/Tutorial - MNIST and RF.ipynb",
    "chars": 80665,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"deletable\": true,\n    \"editable\": true\n   },\n   \"sou"
  },
  {
    "path": "doc/notebooks/Tutorial - continuous and categorical features.ipynb",
    "chars": 8600781,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n "
  },
  {
    "path": "doc/notebooks/Tutorial - images - Pytorch.ipynb",
    "chars": 364200,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Using Lime with Pytorch\"\n   ]\n  }"
  },
  {
    "path": "doc/notebooks/Tutorial - images.ipynb",
    "chars": 918095,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {\n    \"deletable\": true,\n    \"editable\": true\n   },\n   \"sou"
  },
  {
    "path": "doc/notebooks/Tutorial_H2O_continuous_and_cat.ipynb",
    "chars": 8399031,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {\n    \"collapsed\": false,\n    \"deletab"
  },
  {
    "path": "doc/notebooks/Using lime for regression.ipynb",
    "chars": 1674332,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 14,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n"
  },
  {
    "path": "doc/notebooks/data/adult.csv",
    "chars": 3974304,
    "preview": "39, State-gov, 77516, Bachelors, 13, Never-married, Adm-clerical, Not-in-family, White, Male, 2174, 0, 40, United-States"
  },
  {
    "path": "doc/notebooks/data/co2_data.csv",
    "chars": 95567,
    "preview": ",co2,co2_detrended,rising\n1958-03-29,316.1,0.33173315343884724,True\n1958-04-05,317.3,1.524894697365255,True\n1958-04-12,3"
  },
  {
    "path": "doc/notebooks/data/imagenet_class_index.json",
    "chars": 35363,
    "preview": "{\"0\": [\"n01440764\", \"tench\"], \"1\": [\"n01443537\", \"goldfish\"], \"2\": [\"n01484850\", \"great_white_shark\"], \"3\": [\"n01491361\""
  },
  {
    "path": "doc/notebooks/data/mushroom_data.csv",
    "chars": 373703,
    "preview": "p,x,s,n,t,p,f,c,n,k,e,e,s,s,w,w,p,w,o,p,k,s,u\ne,x,s,y,t,a,f,c,b,k,e,c,s,s,w,w,p,w,o,p,n,n,g\ne,b,s,w,t,l,f,c,b,n,e,c,s,s,"
  },
  {
    "path": "lime/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "lime/bundle.js",
    "chars": 1229278,
    "preview": "var lime =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModule"
  },
  {
    "path": "lime/discretize.py",
    "chars": 8978,
    "preview": "\"\"\"\nDiscretizers classes, to be used in lime_tabular\n\"\"\"\nimport numpy as np\nimport sklearn\nimport sklearn.tree\nimport sc"
  },
  {
    "path": "lime/exceptions.py",
    "chars": 55,
    "preview": "class LimeError(Exception):\n    \"\"\"Raise for errors\"\"\"\n"
  },
  {
    "path": "lime/explanation.py",
    "chars": 11991,
    "preview": "\"\"\"\nExplanation class, with visualization functions.\n\"\"\"\nfrom io import open\nimport os\nimport os.path\nimport json\nimport"
  },
  {
    "path": "lime/js/bar_chart.js",
    "chars": 4122,
    "preview": "import d3 from 'd3';\nclass Barchart {\n  // svg: d3 object with the svg in question\n  // exp_array: list of (feature_name"
  },
  {
    "path": "lime/js/explanation.js",
    "chars": 5247,
    "preview": "import d3 from 'd3';\nimport Barchart from './bar_chart.js';\nimport {range, sortBy} from 'lodash';\nclass Explanation {\n  "
  },
  {
    "path": "lime/js/main.js",
    "chars": 360,
    "preview": "if (!global._babelPolyfill) {\n  require('babel-polyfill')\n}\n\n\nimport Explanation from './explanation.js';\nimport Barchar"
  },
  {
    "path": "lime/js/predict_proba.js",
    "chars": 4019,
    "preview": "import d3 from 'd3';\nimport {range, sortBy} from 'lodash';\n\nclass PredictProba {\n  // svg: d3 object with the svg in que"
  },
  {
    "path": "lime/js/predicted_value.js",
    "chars": 4593,
    "preview": "import d3 from 'd3';\nimport {range, sortBy} from 'lodash';\n\nclass PredictedValue {\n  // svg: d3 object with the svg in q"
  },
  {
    "path": "lime/lime_base.py",
    "chars": 9880,
    "preview": "\"\"\"\nContains abstract functionality for learning locally linear sparse model.\n\"\"\"\nimport numpy as np\nimport scipy as sp\n"
  },
  {
    "path": "lime/lime_image.py",
    "chars": 11795,
    "preview": "\"\"\"\nFunctions for explaining classifiers that use Image data.\n\"\"\"\nimport copy\nfrom functools import partial\n\nimport nump"
  },
  {
    "path": "lime/lime_tabular.py",
    "chars": 34542,
    "preview": "\"\"\"\nFunctions for explaining classifiers that use tabular data (matrices).\n\"\"\"\nimport collections\nimport copy\nfrom funct"
  },
  {
    "path": "lime/lime_text.py",
    "chars": 20256,
    "preview": "\"\"\"\nFunctions for explaining text classifiers.\n\"\"\"\nfrom functools import partial\nimport itertools\nimport json\nimport re\n"
  },
  {
    "path": "lime/package.json",
    "chars": 1268,
    "preview": "{\n  \"name\": \"lime\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"main.js\",\n  \"scripts\": {\n    \"build\": \"webpack"
  },
  {
    "path": "lime/style.css",
    "chars": 469,
    "preview": ".lime {\n  all: initial;\n}\n.lime.top_div {\n  display: flex;\n  flex-wrap: wrap;\n}\n.lime.predict_proba {\n  width: 245px;\n}\n"
  },
  {
    "path": "lime/submodular_pick.py",
    "chars": 5514,
    "preview": "import numpy as np\nimport warnings\n\n\nclass SubmodularPick(object):\n    \"\"\"Class for submodular pick\n\n    Saves a represe"
  },
  {
    "path": "lime/test_table.html",
    "chars": 387,
    "preview": "<html><head>\n<script src=\"d3.min.js\"></script>\n<script src=\"lodash.js\"></script>\n<script src=\"explanation.js\"></script>\n"
  },
  {
    "path": "lime/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "lime/tests/test_discretize.py",
    "chars": 8189,
    "preview": "import unittest\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom sklearn.datasets import load_iris\n\nfrom lime.dis"
  },
  {
    "path": "lime/tests/test_generic_utils.py",
    "chars": 4136,
    "preview": "import unittest\nimport sys\nfrom lime.utils.generic_utils import has_arg\n\n\nclass TestGenericUtils(unittest.TestCase):\n\n  "
  },
  {
    "path": "lime/tests/test_lime_tabular.py",
    "chars": 32513,
    "preview": "import unittest\n\nimport numpy as np\nimport collections\nimport sklearn  # noqa\nimport sklearn.datasets\nimport sklearn.ens"
  },
  {
    "path": "lime/tests/test_lime_text.py",
    "chars": 7518,
    "preview": "import re\nimport unittest\n\nimport sklearn # noqa\nfrom sklearn.datasets import fetch_20newsgroups\nfrom sklearn.feature_ex"
  },
  {
    "path": "lime/tests/test_scikit_image.py",
    "chars": 4058,
    "preview": "import unittest\nfrom lime.wrappers.scikit_image import BaseWrapper\nfrom lime.wrappers.scikit_image import SegmentationAl"
  },
  {
    "path": "lime/utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "lime/utils/generic_utils.py",
    "chars": 1287,
    "preview": "import sys\nimport inspect\nimport types\n\n\ndef has_arg(fn, arg_name):\n    \"\"\"Checks if a callable accepts a given keyword "
  },
  {
    "path": "lime/webpack.config.js",
    "chars": 841,
    "preview": "var path = require('path');\nvar webpack = require('webpack');\n\nmodule.exports = {\n    entry: './js/main.js',\n    output:"
  },
  {
    "path": "lime/wrappers/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "lime/wrappers/scikit_image.py",
    "chars": 4137,
    "preview": "import types\nfrom lime.utils.generic_utils import has_arg\nfrom skimage.segmentation import felzenszwalb, slic, quickshif"
  },
  {
    "path": "setup.cfg",
    "chars": 30,
    "preview": "[flake8]\nmax-line-length = 100"
  },
  {
    "path": "setup.py",
    "chars": 776,
    "preview": "from setuptools import setup, find_packages\n\nsetup(name='lime',\n      version='0.2.0.1',\n      description='Local Interp"
  }
]

About this extraction

This page contains the full source code of the marcotcr/lime GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 63 files (39.2 MB), approximately 10.3M tokens, and a symbol index with 1172 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!